Skip to Content

Glossary

One crisp definition per term. Where a term has a fuller treatment elsewhere, the definition links to it. Terms are alphabetised.


AEO / citability gate — the quality check that scores a drafted page on how likely AI answer engines are to cite it (AEO = Answer Engine Optimisation). The engine-owned review-gate skill knows how to score; the numbers (weighted dimensions, thresholds, answer-block length) are tuned in gtmesh.config.yaml under aeo:. A page passes only when every dimension clears its bar, the weighted overall clears overall_threshold, and there are no blockers.

apply — the command that makes reality (the committed graph plus the page files) match desired state. Idempotent and Terraform-style: it previews what it will do and prompts to confirm (--yes skips). It only acts when there’s a difference, so it’s always safe to re-run. apply, seal, and the lifecycle commands are the only writers of the graph.

article-writer — the repo-local skill that fills page bodies (and the editorial meta fields). The one and only step where a model runs. It reads a page’s _brief, schema stubs, templates, and foundation (where brand.md carries the strategic “why”); fills the content; runs the humanizer and gtmesh page validate; then invokes the review-gate. It never touches the slug, the mesh links, or the committed graph.

the bag — the data/raw/ directory: immutable, timestamped keyword/search exports written by pull. plan reads the frozen bag and never re-fetches, so a plan is reproducible from committed data.

built hashes — the provenance hashes seal stamps onto a built page: built_brief_hash, built_schema_hash, and body_hash. They record what a page was built from, which is what makes later diffs precise (the engine can tell exactly what changed). There’s no projection hash — the projection re-derives into site.manifest.json, so there’s nothing to stamp. See also brief_hash.

catalogue — a reconcile action: a brand-new identity is recorded in the graph with no page created yet, because it isn’t promoted to an actionable status. (Contrast create.)

catalogue loop vs production loop — the two rhythms GoToMesh runs in. The catalogue loop (pull → plan → apply) is cheap and automatic: it keeps the map of everything that could exist in sync, and is safe to schedule. The production loop (promote → apply → write → seal → publish) is deliberate: it decides which catalogued pages to actually build, then builds, reviews, and ships them. promote is the gate between the two.

axis — a single-valued domain axis, declared under taxonomy.axes: an entity-valued axis like category (crm, messaging, payments — what the page is about), left open (category: []) because its values are entities validated against the entity nodes in the graph. A page relates to its value through a HAS_<AXIS> edge — the same edge a facet uses; the only difference is that an axis declared here carries one value per page. These axes drive sibling links and are authority-bearing (a page rolls up to its axis hub). See facet, domain relationship, and the mental models.

domain relationship — a page’s HAS_<AXIS> edge to a domain value: the factual substrate (“this pump is a rotary lobe pump, made by Alfa Laval”). It is the one place a page’s domain facts live — Page.edges carries that edge set itself ({ type, to } with real node ids), on the committed side and the desired side alike. The target is the value’s owner hub where one exists (an owned value and its hub are the same graph node), else a bare <axis>/<value> node. Contrast the topical relationships (MEMBER_OF/HUB_OF/PILLAR_OF), which ride the same Page.edges but carry authority rather than facts.

cluster vs axis — say which layer you mean

“Cluster” names the authority layer, and only that. Say the specific one:

  • topic — a topics/<value> node: the authority unit. Pages are MEMBER_OF it; its apex (HUB_OF / PILLAR_OF) is where authority pools. This is what people mean by “a cluster of pages”, and the only thing “cluster” means in gtmesh.
  • root topic — a topic that is also a pull frontier: it carries seed_terms, so pull refreshes its demand every cycle. Rootship is a pull decision, orthogonal to authority.
  • domain axis (config taxonomy.axes / taxonomy.facets) — the factual layer, not the authority one: an axis declaration naming a single-valued axis (category, manufacturer) or a many-valued one. Both produce the same HAS_<AXIS> edge; only cardinality differs. In practice these axes are the entity kinds whose values get topic hubs — which is how the two layers meet, and why keeping the words apart matters (#371).

A page’s domain relationships are its HAS_<AXIS> edges — that and only that. A page’s topical membership is a separate layer (MEMBER_OF). Both ride Page.edges, so you select on either by naming what it points at: --has <id> (or --has <axis> for the whole axis) for the domain layer, --topic <value> for the topical one.

content-types package — the workspace TypeScript package gtmesh types emits (default packages/content-types/) for an SSG or other consumer to compile against. It carries generated per-type page interfaces plus the graph-native readers (loadGraph(), loadManifest(), page loaders). gtmesh types --check is the CI gate against drift.

brief — the writer’s content spec: identity + demand + the content-determining columns folded in + the resolved entity’s grounding facts (name, source_url, notes, aliases). It is surfaced verbatim as the page’s _brief block, so the writer reads exactly what the hash gate covers. The block is derived, not authored: every gtmesh apply re-bakes it wherever it drifted from the node, so new demand reaches the writer (the body is untouched — body_hash excludes _brief). See brief_hash.

brief_hash — the canonical hash of the brief: the body inputs (primary and secondary keywords, intent, section, template, content-determining columns) plus the folded entity facts. Changing any of them rewrites the body (so a changed fact now correctly rewrites the prose). Its built_brief_hash variant is stamped at seal. A projection change (slug, mesh links, cards) is not hashed — it re-derives into site.manifest.json with no rewrite. (brief_hash was named content_hash before the graph model.)

create — a reconcile action: a brand-new identity that is already promoted to an actionable status (queued/writing/ needs_update) gets its page scaffolded and moves to writing. (Contrast catalogue.)

demand fold — with entity-aware classification on, the mechanic by which a source-less seed hub absorbs its demand cluster (head keyword, secondaries, summed volume) instead of a competing page being minted. It fires only when the classified demand produces the seed’s exact identity — the same parent_topic (the entity’s slug), page_type, and an empty discriminator. See Folding demand into a hub.

desired state — what the committed graph should be, computed by plan from your inputs (config, reference tables, seeds, the bag). apply makes actual state match it. This is the central idea: the graph is the desired state, the plan is the diff against it, and Git is the audit log. See the mental models.

discovery — the research that establishes a mesh’s shape. After gtmesh init scaffolds the repo, the repo-local operator skill interviews you, validates demand, and builds the structure (config + reference tables) through the deterministic CLI verbs. It runs outside the deterministic loop — the engine only consumes the committed files it produces. See the walkthrough.

discriminator — one of the composite identity keys: the field that distinguishes two pages that would otherwise collide on the same parent_topic and page_type. It keeps each identity unique. A split sets it from each page’s primary_keyword; under entity-aware classification a sections_map rule can pin it via then.discriminator so synonyms collapse to one sub-page.

drift — a page that has fallen behind the graph since it was built. gtmesh status counts it in two shapes, because they have two different fixes. Content drift (brief_hash moved) means the page’s assignment changed after the prose was written — fresh demand, a changed entity fact. If the body still answers the brief, gtmesh page amendsealpublish re-stamps it; if the assignment really moved, gtmesh page recreate hands it back to the writer. Schema drift (current_schema_hash moved) means the page type’s shape changed; gtmesh apply re-validates each body, restamps the ones that still fit, and hands the rest back to the writer as needs_update. gtmesh doctor’s built-drift check names the pages and the verb. The render projection is not drift: links re-resolve into site.manifest.json on every build, so a projection change is a manifest diff with no page action. See Lifecycle & reconcile.

entity node — how you author an entity: a node carrying domain labels (its class + any domain axes) and fact props (name, source_url, aliases, specs), written with gtmesh graph upsert <id> --label <class> --prop name=…. Used in classification and to group siblings (e.g. brand hubs sibling with same-class brands). Read back with gtmesh graph get <id>; when the node also becomes a page its facts fold into the _brief. Entities live in the committed graph — the engine reconstructs the entities table straight from it (there is no reference/entities.csv); the operator skill drives bulk authoring for you.

entity / entities — a real-world thing the content is about (a brand, a product, a category) rather than a keyword string. Semantic SEO optimises for entities, not exact-match strings; GoToMesh resolves a keyword to its entity via the entity nodes in the graph, and the highest-priority class wins when several match.

entity-aware classification — an opt-in classification mode (classification.entity_aware) that consolidates all spellings and phrasings of a known entity under its canonical hub: the brand forms are stripped from each keyword and the remainder is classified (empty → the hub; an intent → a nested sub-page). Off by default; see Tuning.

pull — the command that pulls keyword/search signals into the bag (data/raw/). A cluster pull runs two pulls (matching-terms and questions) and expands a seed into many related keywords; --source seeds refreshes a curated term list’s metrics without expansion. Exports are immutable and timestamped.

facet — a many-valued domain axis, declared under taxonomy.facets. A product can relate to many values at once — several applications, several industries — so it carries one HAS_<AXIS> edge per value. That is the only difference from a cluster: same edge, riding the same Page.edges, different cardinality. A facet axis is not weighted for up-links by default (that would dilute authority convergence), so the SSG typically aggregates it into facet → member lists at build time. gtmesh page validate/doctor cross-checks every facet value names a real entity. See Tuning.

freeze (slug) — see slug anchor (head) & freeze.

funnel_target — for a page whose SERP layer is content, the landing it funnels up into (named by slug or parent_topic). It’s the edge from an informational page to the commercial page it supports. Set as a frozen discovery decision alongside funnel; inert on a non-commercial mesh.

GoToMesh — the product: a deterministic, self-refreshing programmatic-content mesh engine. The name is a play on go-to-market — it builds your go-to-market as a content mesh. gtmesh is its command-line tool.

harvest — the engine-owned skill that figures out what pages should fill an entity class (a glossary especially) from demand signals: it brainstorms candidates per taxonomy family, ranks them against a demand corpus, validates demand via Ahrefs, scores the cut, writes a curated term list to seeds/<class>.csv (terms + provenance, never metrics), then stops for human review. Configured under discovery: in gtmesh.config.yaml.

pillar / hub / sub-hub / spoke — the four roles in the authority topology of a topic cluster. The role itself is derived from the graph edges, not stamped: a PILLAR_OF edge makes a page a pillar, HUB_OF a hub (a sub-hub if it’s also a member of a higher owned topic), else a spoke — so authoring the apex edge is the promotion. Links between them are derived the same way. With a worked example (a pump catalogue):

  • hub — the navigational / commercial centre of a subject: the catalogue or conversion page breadcrumbs run through. e.g. /categories/rotary-lobe-pumps (or a brand page /manufacturers/alfa-laval). It’s an up-link target, but it stays the archive layer — it doesn’t hoard in-content weight.
  • pillar — the informational convergence vertex: the deep “what is X” page that owns the broad head-term. e.g. /guides/how-does-a-rotary-lobe-pump-work. When a topic has one, an informational spoke’s up-link prefers it over the hub — pillar and hub are co-apexes, both reachable over the topical graph. Optional — a topic without one just uses its hub.
  • sub-hub — an intermediate hub beneath the apex. e.g. a manufacturer hub /manufacturers/alfa-laval sitting under a /manufacturers section index.
  • spoke — a supporting leaf page that links up. e.g. a product /products/alfa-laval-sru, or a supporting guide.

See The mesh & links for when to pick each and how the pillar and hub relate.

humanizer — the skill that strips AI-writing tells from a draft and pulls it toward the project’s house voice (foundation/voice.md). The detection patterns are generic and engine-owned; the target voice is yours. The article-writer runs it before the review-gate.

identity / identity_keys — a page’s stable identity is a composite key: the fields in identity_keys (default parent_topic, page_type, discriminator — and market joins automatically once there’s more than one market). Two records with the same identity are the same page. Identity is what the graph diff keys on. See the mental models.

image-director — the skill that generates and places the images a page has briefed. It reads the page’s art-direction briefs plus foundation/art-direction.md and the images: config, generates via the image MCP, writes the asset files into the page bundle, and adds asset: to each slot. Invoked explicitly, separate from writing.

intent — the single search intent a page serves (e.g. transactional, commercial, branded, informational). Declared in taxonomy.intents in priority order; classify picks the first present on a keyword. Semantic SEO’s rule is one intent per page, which GoToMesh enforces by construction.

kind (site type) — the project’s authority topology, set once in gtmesh.config.yaml. One of non_commercial (content hubs discovered from demand), commercial_catalog (many product/category pages plus an order action), or commercial_pages (a few core landings that content funnels up into). How authority is arranged follows from it. See the mental models.

mesh — the whole interlinked set of pages plus the derived link graph between them. The committed graph is the mesh’s source of truth; links, redirects and breadcrumbs are all derived from it (into site.manifest.json) and re-derived on every change.

needs_update — a status: a built page whose body inputs changed and whose revision hasn’t shipped yet (the old body keeps serving until it does). Also the status a shipped page re-enters after assets are placed (gtmesh page amend).

noop — a reconcile action: nothing changed for this identity, so the engine does nothing.

opportunity / effort / winnability — the three numbers that decide which topics to invest in. A topic folds its head keyword’s demand onto itself, and from that derives opportunity (the value at stake — total_vol × cpc by default) and effort (the cost to win — keyword difficulty). Winnability is the KD-inverse, (100 − difficulty) / 100, on a 0–1 scale. gtmesh topic candidates ranks by opportunity × winnability: the commercial ∩ winnable intersection, where the commercial half rides inside opportunity (CPC is the market’s buyer signal — advertisers bid where the money is). Every other topic view orders by opportunity alone, which flatters big topics you can’t win. All three formulas are config-tunable (scoring.topic_opportunity / topic_effort / topic_selection). Winnability is read at the topic level, not the keyword level: max(head, tail), where head is the head keyword’s own KD-inverse and tail is the KD-inverse of the median difficulty of the topic’s uncovered demand. So a hard head is a horizon, not a veto — you climb the tail and the head comes into reach. See Winning a topic.

unscored (difficulty) — a keyword the provider returned no difficulty for (common across the low-volume long tail). gtmesh records it as unknown — an empty cell in the bag, never 0 — because unscored and uncontested are opposite claims: collapsing them would make every unrated tail term look trivially winnable. Shown as KD —. An unscored keyword still counts as uncovered demand, but never as evidence of an easy way in.

parent_topic — one of the identity keys, and the legacy slug stem. With slug anchoring set to head, a page’s URL is named after its head keyword rather than parent_topic, but identity still keys off parent_topic. A change to it is a rename.

plan — the command that recomputes desired state and shows the diff against the committed graph. Read-only — it prints the diff and writes a derived, git-ignored .gtmesh/plan.json, but changes nothing. apply computes the same diff itself, so plan is an optional preview you run whenever you want a look.

promote — the intent-based gate that chooses which catalogued pages to build. It writes only status (e.g. plannedqueued), builds nothing, and is reversible (demote). It selects pages by node fields (section, topic, domain relationship, page-type, slug prefix, status) or by a graph walk (--under <hub>), and applies by default (--dry-run previews). It’s the gate between the catalogue and production loops.

pulls (matching-terms, questions) — the two-pull pattern a cluster pull runs against Ahrefs: matching-terms (the broad keyword expansion) and questions. Both land in the bag.

reconcile actions — the one-action-per-identity verbs plan emits by diffing desired state against the committed graph. They are: noop (nothing changed), recompute (an unbuilt page’s inputs changed), rewrite (a built page’s body inputs changed — pulls the writer back in), redirect (a slug changed — human-gated, moves the bundle and mints the url/ALIAS_OF alias), catalogue (record a new identity, no page), and create (scaffold a new, already-promoted identity). Who acts varies: the engine handles recompute/catalogue/create; the writer handles rewrite; redirect is human-gated. A projection-only change (a moved mesh link) is not an action — it re-derives into site.manifest.json with no rewrite.

redirects — the durable record of slug changes (old slug → current). Each old URL becomes a url node with an ALIAS_OF edge to the live page node, so chains collapse intrinsically (the alias always resolves to the page’s current slug) and old URLs resolve forever — the SSG emits 301s from a manifest query. Format + SSG wiring: Redirects.

graph store / registry — the committed source of truth for every page that could exist and what state each is in: graph/nodes.jsonl (LPG nodes) + graph/edges.tsv (typed mesh edges) — the diffable state file. Never hand-edited; apply, seal and the lifecycle commands are its only writers. See the mental models.

rename — moving a page’s URL via an explicit group-edit (or a parent_topic change). A committed slug is frozen, so only a rename moves it — firing a 301 and a bundle move, and minting the url/ALIAS_OF alias (see redirects).

review-gate — the independent, blocking quality reviewer the article-writer invokes as its final pre-seal step. It scores AEO/citability and enforces the house voice in one pass, returning a PASS/FAIL report. On failure the page stays in writing with notes; on pass it returns control to the writer. It never calls gtmesh page seal.

role — the authority role a page plays — pillar / hub / sub-hub / spoke. It is a view derived from the graph edges (a PILLAR_OF/HUB_OF edge ⇒ pillar/hub, else spoke), not a stored column. The signals and an authored apex page (gtmesh page add --role hub|pillar) appoint the role — an ownership decision that makes classify emit the apex edge — and the role you read back follows from that edge. See the mental models.

seed / seeds/<class>.csv — a seed is a starting keyword or term that feeds the pipeline. seeds/<class>.csv is a curated, human-reviewed term list for an entity class (written by harvest) — terms plus provenance only, never metrics (Vol/KD live in the bag and refresh on cadence). A curated term is seed-authoritative: plan keys its identity and routing off the curated term and the seed’s section/page_type. Distinct from a seed-page.

seed-page — a source-less page you declare by hand with gtmesh page add (which writes a source: seed node into the graph) — typically an apex or pillar hub that no keyword pull would mint on its own. Distinct from a seed (a keyword/term). See the mental models.

SERP layer (layer: commercial/content/mixed) — a classification of a keyword’s search results by what’s actually ranking (derived from a SERP teardown). It separates the money layer from the content layer so a commercial page ships by business priority rather than volume. See also funnel_target.

signals.csv — the reference table (reference/signals.csv, keyed by signal) that maps keyword signals to a role — the input that tunes how keywords are classified into hubs, pillars and spokes.

slug — a page’s URL path. The only deterministic field in a page’s meta (apply-owned); the editorial meta fields are writer-authored. Don’t hand-edit the slug — fix the inputs and re-plan. See the mental models.

slug anchor (head) & freeze — with identity.anchor: head, a page’s URL is named after its head keyword (the volume-ranked primary), not a divergent parent_topic. The head can flip on re-pull, so a committed slug is frozen (sticky committed state): only an explicit rename group-edit moves it (firing a 301 and bundle-move). Identity stays parent_topic either way.

status lifecycle — the states a page’s status moves through: planned (catalogued, not authorised) → backlogqueued (promoted to build) → writing (page scaffolded, awaiting a body) → review (sealed) → published (live), plus needs_update (a built page whose inputs changed). Status moves are deliberate human edits (via promote/demote/seal/ publish), separate from the input-driven reconcile actions.

symbolic ref — how prose links to another page in the mesh: by stable identity, not by URL. Two forms: ref:page/<id> links a specific page by its unique graph id (survives a rename), and ref:links/<scope>/<n> is self-relative — the current page’s Nth link in a scope (up = its published up-links, down = its children, siblings, across). gtmesh build bakes an id→slug table into site.manifest.json (refs) and the per-page link arrays live in pages; the SSG substitutes each token for the live URL at render. The point is re-resolution: ref:links/up/0 (“my primary parent”) re-resolves when a new hub takes that slot, and ref:page/<id> follows a rename — a hardcoded URL would rot silently (no redirect). A literal internal URL in a body is therefore a validate error, as is a ref that doesn’t resolve (an unknown page id, or a ref:links index out of range). External links are written as normal URLs.

topic & apex — a topic (topics/<value>) is the unit of authority: the subject a set of pages is about. Pages join it with a MEMBER_OF edge; exactly one — its apex — owns it with a HUB_OF or PILLAR_OF edge, and members route their up-links there. (A topic may carry both a commercial hub and an informational pillar as co-apexes.) An apex edge implies membership, so an owner carries no self-MEMBER_OF. Topics are minted by ownership: an appointed apex (a signals.csv role rule, or gtmesh page add --role) mints the topic for the value it owns, and gtmesh topic authors them directly. See The mesh & links.

up-link resolution — how the engine turns a page’s up: hub_of(entity) rule into an actual parent: it links to the hub of the page’s own resolved entity sitting above it in the authority flow; else an entity-less landing that shares a cluster value; else the apex. A shared cluster alone never reaches a different entity’s hub (a cross-entity guard). See the mesh & links.

Last updated on