Ekklesia #60 was rebase-merged, so the PR head 00e5441 never became part
of main, and ci/assemble.sh rightly refuses it. 874deab is #60's merge on
main. ci-sweep.sh, ci-project.sh and smoke-deploy.sh are byte-identical
to the old pin, no package file changed, and the assembled lockfile
still passes a frozen install.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The platform's rule (its ci-sweep.sh, docs/development/security.md),
applied to the one Signage job that starts Docker stacks:
- it has its own EKKLESIA_CI_JOB_KEY;
- it sweeps stale CI stacks from the runner before it starts;
- it removes its own stacks in a final `if: always()` step, which
tolerates a failed assembly, since nothing was started then;
- the image ci/integration.sh builds is named and labeled as a CI stack
of this run and job, with the time CI built it, so the sweep finds it.
ci/platform.env moves to the platform commit that adds the sweep
(Ekklesia #60). The assembled lockfile is unchanged, and still passes a
frozen install.
Verified: SIGKILL of the integration script's whole process group
mid-run left 11 resources (2 containers, 4 networks, 4 volumes and the
image). `ci-sweep.sh --job` removed exactly those 11. A normal run
passes, and the job sweep after it finds nothing.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signage had no CI. Its tests passed while three defects shipped that
appear only inside Ekklesia, in a real browser. Every job now assembles
Signage into a pinned platform commit, as an instance does, and
installs that workspace with --frozen-lockfile:
- lint, typecheck, test: Signage's own checks;
- build: the platform's gates against exactly this module set (boundary
rules, module manifest, migrations), then the build;
- integration: the deployment image from the platform's Dockerfile,
then the platform's split-topology smoke. It pairs a kiosk display,
restarts it on the same profile, and runs the scenarios in
ci/display-scenarios.
The supporting files:
- ci/platform.env pins one platform commit. ci/assemble.sh fetches the
platform's main and refuses a pinned commit that is not on it, so CI
only runs reviewed platform code.
- ci/pnpm-lock.yaml is the assembled workspace's lockfile, regenerated
with ci/update-lock.sh.
Same trust rules as the platform: actions pinned by SHA,
persist-credentials false, no secrets, no pull_request_target.
Co-Authored-By: Claude Opus 5.5 <[email protected]>