Skip to content

Anthropic built Scion for itself. Carbon Forge is yours →

Carbon Forge
Menu

Guide

Declare governed seams so a drift report catches stale docs before a landing

Prose that governs code goes stale without a sound when the code changes and the prose does not. Carbon Forge lets a workspace declare which pages govern which definitions, and reports the gap on a lane before it lands.

Also in: Español, Português, 日本語, Deutsch, Français

Disclosure: we build Carbon Forge at 100monkeys.ai, so read this as a maker's account. This guide was drafted by one of our AI agents from the public docs, chiefly the symbols.drift and Governed seams sections of MCP tools catalog: Semantics and "Drift between prose and code" in The Carbon paradigm, and reviewed by the company. The table and calls are the docs' own examples. Where the docs leave a question open, the last section says so.

What the report is

The paradigm page in one line: "A workspace's reserved .governed-seams page declares which pages govern which definitions of a code tree". symbols.drift "joins every definition a lane adds, removes or re-signs to the seams that govern it and reports each as changed with or without a patch to its governing page on the same lane, from the syntax index alone, so the same lane and the same seams page answer the same report byte for byte." No model reads anything. And one limit to hold onto: "The report advises and never refuses a landing."

Step 1. Pick the definitions a page describes

Start with the pages that would mislead a reader if the code moved under them: an architecture page for billing, a guide for sign-in. Find the definitions they describe with the semantic index:

symbols.search { "tree": "app", "query": "charge", "prefix": true }

Definitions come from tree-sitter's tags queries for TypeScript and TSX, JavaScript, Python, Go, Rust, C, C++, C#, Java, Ruby, PHP, Scala and Bash. CSS, HTML, JSON, YAML, TOML and HCL get syntax trees "but no definitions or references", so a seam over those files reports nothing. Names are "matched by name, not by type checking".

Step 2. Write the .governed-seams page

Create a page at the reserved path .governed-seams whose first Markdown table is headed tree | glob | symbols | records. The docs' example:

| tree | glob | symbols | records |
| --- | --- | --- | --- |
| app | src/billing/** | chargeCard, refund | architecture/billing |
| app | src/auth/*.ts | * | guides/login, architecture/security |

"A seam is declared, never inferred: no link, tag, metadata key or embedding makes one." The page is read from the trunk, "so a lane cannot ungovern its own change." Land it on the trunk before the work it should watch. A malformed page stops every report until it is fixed, with a sentence naming the line: The governed seams page .governed-seams is malformed at line <n>, ...

Step 3. Change governed code on a lane

The report reads a lane, so the change must be on one: lanes.create, then trees.apply_patch or trees.put with lane, as Working in lanes shows. Re-sign chargeCard, say, by adding a parameter.

Step 4. Read the drift report

symbols.drift { "lane": "agent/7/fix-login" }

Add tree to read one tree alone. The answer:

{ lane, composition_hash, report_sha256, findings, pending, governed_rows }

Each finding names the tree, path, symbol and kind, the from_signature on the trunk and to_signature on the lane (null where a side does not hold it), records as { path, updated_on_lane }, and callers, the count of references to the name on the lane. The class is the verdict: seam_changed_without_record when the lane holds no live patch on a governing page. That is your stale doc, caught before the landing.

Read pending before you trust an empty report: it lists changed files under a seam's glob that the index "cannot answer yet", and "the report is complete when pending is empty." A lane in conflict is refused until the conflict is resolved.

Step 5. Update the governing page on the same lane

Edit architecture/billing with pages.apply_patch and the same lane, so the page and the code wait together. The guide Land a code change and its documentation in one changeset walks that part.

Step 6. Read the report again, then land

Run symbols.drift again. The finding now reads seam_changed_with_record, and its record shows updated_on_lane. Keep the report with the review: composition_hash is the hash of the lane composition it read, and report_sha256 covers the report's canonical text, "so a report is bound to the exact change it read." A later patch changes both. Then land the lane as one changeset.

Because the report only advises, enforcement is yours to add. One pattern, ours rather than the docs': on a protected trunk, name the governed code's glob in .landing-rules with the governing page's owner as an approver, and have that approver read the drift report first.

What the docs leave unanswered

Related guides

Catch the stale page before it lands.