Skip to Content

gtmesh apply

Previews the plan, prompts to confirm, then executes it — the one command that writes the committed graph and scaffolds page bundles.

gtmesh apply # show the actions, prompt to confirm, then enact gtmesh apply --yes # skip the prompt (scripts/CI)

What it does

apply is Terraform-style: it prints the intended actions (the same diff as plan) and prompts Proceed? [y/N] before writing. It is idempotent — it only acts when there’s a difference, so it’s always safe to re-run.

What it does depends on each page’s status. On the first run, catalogued pages are recorded in the graph with no page files created. Once you promote pages to an actionable status, the next apply scaffolds each as a bundle folder — content/<id>/index.yaml holding the schema skeleton plus an engine-owned _brief — and flips the status to writing. So the rule of thumb is: promote pages first, then apply builds them.

_brief is derived — apply re-bakes it for whoever is about to read it

The _brief block is a projection of the page’s node, not a write-once scaffold artifact. So apply owns it and re-bakes it wherever the on-disk block differs from the node’s brief:

  • missing — a bundle hand-authored outside the scaffold path (or scaffolded before _brief existed) gains one, whatever its status. Otherwise it’s stuck outside the provenance system: the scaffold step only ever writes a bundle that doesn’t exist yet.
  • stale, on a page the writer is about to read — the page was never built, or has been re-opened by page recreate or page amend. This is how a demand refresh reaches the writer: without it the page keeps handing the writer the old assignment, because apply decides what to write from a page’s status.

A built page keeps the brief its body was written against

A page that has been sealed and nobody has re-opened keeps its _brief exactly as it was, even when demand moves the node’s brief_hash. That block is the only record of the assignment the prose answersbuilt_brief_hash is a hash, so once the block is overwritten nothing can say which way the brief moved.

Keeping it is what lets two things work:

  • doctor’s built-drift reports a brief that lost questions separately from one that gained them. Only the first can destroy content, and it prescribes amend (which keeps the prose) rather than recreate.
  • page recreate refuses when the body still answers a question the brief has dropped.

To release it, re-open the page — page amend for a light re-stamp, page recreate to re-author — and the next apply bakes the current assignment.

Nothing else in the bundle is touched — the body and meta are preserved. It’s hash-neutral (body_hash covers the content and authored meta, not _brief), so no status moves and no page is rewritten. It is idempotent: an in-sync bundle is not rewritten, so a second apply produces no diff.

apply has no destructive --prune flag — a removed identity is tombstoned (its id is never reused, and authored edges never dangle); retire it by editing the graph.

Arguments & flags

OptionDescriptionDefault
--yesSkip the confirmation prompt (required in a non-interactive shell)off (prompt)

Reads & writes

  • Reads: the same inputs as plan — config, reference tables, seeds, the frozen data bag, and the committed graph.
  • Writes: nodes/edges into graph/{nodes.jsonl,edges.tsv}; on promoted pages, scaffolds content/<id>/index.yaml bundles and flips status to writing; auto-emits site.manifest.json. On a slug change it moves the bundle and mints a url/ALIAS_OF alias. It re-bakes the derived _brief on any existing bundle where it is missing, or stale on a page the writer is about to read — a built page keeps the brief its body was written against (hash-neutral — the body is preserved and no status moves). It also self-heals a missing .gtmesh/manifest.json — the tracked upgrade baseline — recreating it from the bundled engine files (even on a no-op apply); no project file is touched.
  • Committed: yes — commit the graph change after each apply.

Examples

gtmesh apply # first run: catalogue every page (no page files yet) gtmesh page promote --section glossary gtmesh apply # now scaffolds the promoted pages → writing gtmesh apply --yes # non-interactive (CI)
Last updated on