07 — The publish output
Summary
The first version of this file was a rule policing where an output directory may live — the maintainer removed the question instead: sgit publish takes no target, writes .sg_vault/publish/ and nothing else on disk, and deployment is a separate act. Five things disappear at once: the containment rule, the --force-on-an-ancestor disaster, the amplification loop (gone by construction, since .sg_vault is always ignored), the escape hatch, and the naming decision. The folder is a finished, target-agnostic artefact — no CNAME, no .nojekyll, no netlify.toml; those belong to the deployer — which is what keeps the published bytes identical regardless of destination. And the two index.html files are kept apart at last: the loader is generated plaintext, always sgit's template; the vault's own index.html is encrypted content — the choice between them happens at deployment, where decryption creates the second candidate, and the decrypted page wins.
Key concepts
- Remove the question rather than police it — no target argument means no containment rule, no refusal messages, no escape hatch — and the amplification loop is impossible by construction, not by rule
- A deployer can be dumb — rsync, s3 sync, git add, or a static server pointed at the folder — nothing needs to interpret the contents, because nothing target-specific is in them
- The two index.html files — the loader (generated, plaintext, byte-identical everywhere) versus the vault's own page (ordinary encrypted content) — conflating them was the earlier framing's one real error
Key ideas
- .sg_vault/publish/ contains no vault content at all, which is why it is safe to commit to a public repository even for a private vault.
- The secondary vault.html loader copy was dropped: it guarded a partial-expansion mode that does not exist.
- manifest.json records which file ended up at the served root and its hash, so the choice is auditable from the artefact rather than from console history.