Skip to Content
DocumentationFeaturesPlatformThe mesh store

The mesh store

The committed graph is the one thing everything in GoToMesh orbits: graph/nodes.jsonl (one node per page that could exist) plus graph/edges.tsv (the typed relationships between them). It is the state file — the single source of truth.

What it is

graph/nodes.jsonl is a committed, canonically-serialized list of LPG nodes — one per page identity, each carrying a label set (page + its page type, plus any axis label a hub owns) and minimal props: identity (id, slug, anchor), the classification-determined spec (section, intent), the demand assignment, folded entity facts, and carried build state (status, the built_* hashes). graph/edges.tsv carries the typed edges — MEMBER_OF, HUB_OF, PILLAR_OF, HAS_<axis>, ALIAS_OF — every node and edge stamped with provenance. It holds catalogued pages (recorded, no body yet) and built pages alike.

The graph is desired state expressed as a committed artifact. Because it’s canonically serialized (id-sorted nodes, tuple-sorted edges, key-sorted props), every real change shows up as a clean, reviewable Git diff — a rewrite whose values didn’t change produces zero diff — and Git becomes the audit log. The derived site.manifest.json is the denormalized projection your SSG reads (resolved links, cards, redirect table, render sets).

Why it matters

Treating the graph as the state file is what makes the whole engine trustworthy:

  • The diff is graph-to-graph. GoToMesh compares the hashes stored in the graph against freshly computed desired state — it never scans your rendered pages to figure out what changed. That is what keeps plan fast and exact.
  • Re-running apply is always safe — it only acts where a node actually differs.
  • Nothing drifts, because there is no second copy of the truth. Mesh links, roles, redirects, and the rest are derived from the graph, not stored on the page. A relink is a re-projection of the manifest, not a page rewrite.

Never hand-edit the committed graph. It is computed. apply, seal, and the lifecycle commands (promote/demote/publish/…) are its only writers. To change a node, change the input — a keyword pull, a config rule, a reference table — and re-plan.

How it works

You change an input and run gtmesh apply. The engine recomputes desired state, diffs it against the committed graph by identity, and emits one action per node (catalogue, create, recompute, rewrite, redirect, or noop). The actions are what update the nodes. seal later stamps the built_* provenance hashes that make the next diff precise. A projection-only change — a moved link, an added sibling — never rewrites a page: it re-derives the manifest, a zero-rewrite change you review in the manifest diff.

A node’s identity is carried, not recomputed: it’s minted once (the id is the frozen first slug) and the resolver re-attaches an incoming demand pull to the same node across re-clustering. Two pulls that resolve to the same id are the same page, which is how the diff knows what to compare against.

Key files & commands

ThingWhat it is
graph/nodes.jsonlThe committed state — one LPG node per page identity
graph/edges.tsvThe typed mesh edges (MEMBER_OF, HUB_OF, HAS_<axis>, ALIAS_OF, …)
site.manifest.jsonThe derived projection the SSG reads (resolved links, cards, redirects)
gtmesh planRead-only: recompute desired state, print the diff
gtmesh applyThe writer: enact the diff into the graph
gtmesh graph get <id>Read one node (labels + props + folded facts) as JSON
  • plan — compute the graph-to-graph diff
  • apply — the only writer of the graph
  • The mental models — the graph-as-state idea in full
  • Glossary — the committed graph, identity, desired state, built hashes
Last updated on