11 — Tabletop (executed): publishing pipelines
What is happening in this document
This is the pack's second executed tabletop — the form is explained on the first one's page: a security-style walkthrough where the agent plays every party and actually runs the commands rather than imagining their output. Here the cast is a publisher, a zero-secret CI runner, a private-vault runner holding a key as a secret, a fork contributor who gets no secrets, a reader, and a rollback operator.
This run is in simulated-hosting mode, at the maintainer's instruction: GitHub, Actions and Pages are stand-ins, marked SIMULATED at every appearance, while everything sgit-shaped — the CLI, the crypto, the server — is real. What simulation cannot measure is not fudged: it is marked NOT MEASURABLE and deferred, and those markers now define exactly what a future real-GitHub run must cover.
Once again the exercise changed the spec it tested. F5: a dead host was indistinguishable from an empty vault, sending the operator toward re-keying when the truth was “server down”. F6: the attach command's two acceptance criteria were discovered by the shipped clone-mode guard refusing bad states. F7: a workaround applied in the wrong order silently deployed a stale site. And the pre-registered keyed-backup leak from the brief was confirmed by executing it — one keyed backup plus git add -A stages the vault key.
Summary
All ten steps of the brief, run with the real CLI and simulated hosting. Proven executed: the canonical three-line .gitignore (the keyed-backup zip staged under the old ignore, excluded under the new); the attach drill (wrong key refused with nothing written; the workflow file swept into the vault and arriving in the reader's clone — the F1-generalisation policy is now ACCEPTED and demonstrated); the full public pipeline with a zero-secret runner; R3 demonstrated (a forgotten --visibility silently drops the key file — the safe direction); the keyless staleness check catching a forgotten republish from manifest hashes alone; and rollback as git revert — the site follows the repo timeline, not the vault's. New findings F5 (dead host reads as empty vault — only 404 means absent), F6 (attach must be mode-exclusive and schema-exact), F7 (refs-checkout after a successful push destroys the head; safe ordering now in the committed workflow template), plus a sharpened F2. The closing table records who held what and for how long — the private-vault runner is the one key-holding service in the whole model.
Key concepts
- F5: a dead host reads as an empty vault — connection failure was indistinguishable from 404-absent, diagnosing 'no named ref' when the truth was 'host down' — P1 acceptance now requires connection errors to raise loudly, naming the host
- The workflow template, hardened by breaking — F7's safe ordering (restore refs before sgit operations, commit after push) and the fork-guard glob fix live as comments in a committed artifact — decision 15's generator will emit it
- The site follows the repo timeline — rollback is git revert: surface and store roll together because both live in one git commit; the SG server's head still shows v2 — a published site is a projection of a git commit
- The one key-holding service — the closing table: the private-vault runner holds a read key for the job lifetime — scoped, ephemeral, read-only; the public runner held only what the world already had
Key ideas
- The fork PR skips legibly with zero secrets — and fixing its guard surfaced a classic shell trap: an unmatched glob is a truthy literal, so the naive emptiness check never fires.
- sgit's own output never printed the key (grep: zero occurrences); masking the invoking command line is GitHub's job, asserted in the real run.
- The definition-of-done check closes the loop against the brief item by item — with the deployer table's measured rows explicitly failed and deferred to real GitHub.