Skip to content

Latest commit

 

History

History
305 lines (238 loc) · 16.4 KB

README.md

File metadata and controls

305 lines (238 loc) · 16.4 KB

The Forge Cognitive Substrate

Coding agents forget what they learned, assume what they don't know, and break code they can't see. The substrate is a fast, mostly-deterministic check that runs before an agent edits your code: it flags an unclear task, picks the cheapest capable model, and shows what an edit will break — all from the repo you already have, with no extra LLM call.

In Claude Code it runs automatically. In other tools you (or the agent) run one command.

Why this exists, in one line: a model with frozen weights keeps no durable state between independent calls, sees only a bounded context, never updates its weights from outcomes, and cannot reliably verify itself without external evidence. Prompting does change what it does inside one context, but it cannot supply those guarantees; this layer supplies persistence and verification from the outside — one tested way to do it, not the only possible one. Full argument: the white paper (HTML, with the 2026-09-21 and 2026-09-26 corrections · PDF, a pre-correction edition). (Corrected 2026-09-26: this line used to say "no memory, no foresight, a fixed window. Those faculties can't be prompted in"; see the white paper's Corrections.)


Install

Install Forge (plugin · npm · github:) per README → 60-second quickstart, then inside any project:

forge init      # writes each AI tool's native config from one source
forge atlas     # build the code graph (needed for blast-radius checks)

forge init configures Claude Code, Codex, Cursor, Gemini, Aider, Copilot, Windsurf, Zed, Continue, and OpenClaw (plus MCP config for Roo and VS Code). On Claude Code the check then runs on every prompt automatically.


It runs itself (the main benefit)

You don't have to remember to use it.

In Claude Code — a hook runs the substrate on every prompt and adds a short note only when something needs attention (unclear task, big blast radius, pricey model). It never blocks and never nags on a clean, simple task. Real example — you type "refactor computeTax in math.js" and the agent silently receives:

Forge substrate — pre-action advisory (advisory, never blocks):
- Under-specified (high risk). Ask before editing:
    • What constraints must be respected: performance, dependencies, style, or compatibility?
- Suggested model: Haiku 4.5 (simple); escalate only on a verifier failure.
- Predicted blast radius (2: 2 reverse): invoice.js (reverse), math.js (reverse). Review these before editing.
- Verify with: review impacted files before editing · run the narrowest affected test first

In other AI tools (Codex, Cursor, Gemini, Aider…) — forge init writes a rule into their config file telling the agent to run the check itself, and exposes it as MCP tools it can call. See In other AI tools.


The one command

forge substrate "<what you want to do>"

It runs the whole check and gives a plain verdict. Two real examples:

Vague task → it tells you to ask first:

$ forge substrate "make the auth better"

  proceed: ASK FIRST
  assumption: high risk · completeness 0.23
  clarify:
    - What exactly should this produce, and how will we know it is correct?
  impact: 0 file(s) predicted

Clear task → it clears you and shows the blast radius:

$ forge substrate "Change verifyToken in src/auth.js to require length > 20; update tests"

  proceed: yes
  assumption: low risk · completeness 0.88
  route: Haiku 4.5 (simple)
  impact: 3 file(s) predicted — 3 reverse
    - src/auth.js (reverse)
    - src/login.js (reverse)      ← imports verifyToken; you didn't mention it
    - src/session.js (reverse)    ← imports verifyToken; you didn't mention it
  verify:
    - run the narrowest affected test first, then the broader suite

The second run found the two files that import verifyToken but you never named — the "forgot the coupled file" bug, caught before the edit. Each file is tagged with the relation that reached it: reverse (depends on the change), sibling (shares a dependency with it) or forward (the change depends on it). The check walks all three by default because the reverse-only walk missed the sibling files that were 94.7% of the empirical refutation's misses; siblings and forward files are co-change candidates, lower precision than dependents, and the enforce gate counts dependents only. Add --json for machine-readable output (see Use it in a script).


The checks (each is also its own command)

forge substrate bundles these. Run any one on its own when that's all you need.

Command Answers One-line example
forge preflight "<task>" Is this task clear enough to start? flags names not in the repo + vague words
forge route "<task>" Which model is cheapest-but-capable? trivial → Haiku · hard → Opus/Fable
forge impact <symbol|file> What will this edit break? reverse-dependency blast radius
forge scope <file…> Can this be split into sessions? independent vs. coupled files
forge anchor "<goal>" Are my changes still on the stated goal? flags changed files that drifted off-goal
forge verify Did it actually work? runs the real tests/build, not the model's word

Inside an agent session (FORGE_SESSION_ID, or Claude Code's CLAUDE_CODE_SESSION_ID), forge substrate's goal-drift and minimality checks, forge anchor and forge lean read only what that session changed since its SessionStart baseline. Older dirt is left out, and so is a file another live session's trail claims (the completion gate's attribution rule). Before the session has changed anything, minimality reports "pre-existing diff (not measured)" instead of critiquing someone else's diff.

The wider v0.5 surface — forge context (budgeted assembly + completeness gate), forge imagine [--run] (predicted breaks + minimal dry-run suite), forge diagnose (doom-loop), forge ledger / forge reuse (proof-carrying memory + code cache), and forge uicheck (the design gate) — is documented with real outputs in docs/GUIDE.md → Command reference.

Real output for the two most-used:

$ forge preflight "fix the thing in authManager so it works properly"

- `authManager` — not found in the code. Different name, or should it be created?
- Ambiguous: "properly" — state concrete acceptance criteria.
- Which specific file, module, component, or symbol should this change touch?
$ forge impact verifyToken
  target: verifyToken  ✓ found
  impacted files: 3
    - src/auth.js
    - src/login.js
    - src/session.js

Read the result (what to do)

Field-by-field: what each verdict means and the action to take — docs/GUIDE.md → Reading substrate output. The short version: ASK FIRST means ask, route means start cheap, impact means read those files first, and verify means show the output before saying "done".


In other AI tools

Tools without a hook surface get the substrate two ways, both written by forge init: a rule in their native config telling the agent to run forge substrate "<task>" --json before ambiguous/expensive/mutating work, and MCP tools (substrate_check, assumption_gate, predict_impact, route_task, scope_files) any MCP-capable agent can call directly. Details + the exact rule wording: docs/GUIDE.md → Auto-use inside an agent.

Forge never pretends it can force a hook into a tool that has none — it's ambient on Claude Code, and agent-invoked everywhere else.

OpenClaw is agent-invoked in exactly this sense. It picks up the rules on its own (the execution folder's AGENTS.md becomes project context), but its MCP registry is your global ~/.openclaw/openclaw.json, which Forge will not write to. forge sync leaves the definition in .openclaw/mcp.json; you register it once with openclaw mcp add forge-cortex --command forge --arg cortex-mcp. Forge installs nothing into OpenClaw's own hook system.


Use it in a script

Add --json to any command for machine-readable output — gate your agent's next step on okToProceed, feed route.tier to your model picker, read impact.impactedFiles before editing. Every knob (ask threshold, blast-radius sensitivity, routing signals, assumption questions, the verify checklist, the ambient hook wording) is a small pure function or a JSON default. Full JSON shape and the extension table: docs/GUIDE.md → Use it in a script · Extending Forge.


Optional: LLM-assisted judgments (FORGE_LLM=1)

The substrate's default judgments are deterministic rubrics — no model call, no dependency. Set FORGE_LLM=1 to add a thin, opt-in semantic layer on top: a cheap claude -p call proposes a completeness reading (M2), a complexity band (M1), the coupled edges the regex graph misses (impact), and whether an off-goal file actually serves the goal (M4).

Rubric first, LLM second: a task or edit goes to the deterministic rubric and, when FORGE_LLM=1, to an LLM proposer whose proposal is verified against the rubric band, repository grounding (grep) and tests; the verdict moves (llm-cleared, lowered, raised or verified) only when the proposal passes those checks, and otherwise the deterministic verdict holds

Open the interactive diagram: pan, zoom, search, and trace any node.

The model proposes; the deterministic rubric, the code graph, and the tests verify. The verdict only moves when the proposal survives that check — otherwise it falls back, unchanged.

The model is never the judge — only a proposer. Every proposal is verified before it can move a verdict, in the direction of the paper's tabayyun gate (49:6). By default the reconcile is bidirectional but rail-guarded — a verified reading can lower caution as well as raise it, but never past a hard floor:

  • routing — the proposer votes a band and the reconcile compares it with the band the deterministic score is already in. A vote for a lower band moves the score to that band's ceiling only when the vote's p(band) reaches llm.minConfidence, and never below a strong-signal (algorithmic/architectural) floor, so a "distributed rate-limiter" can't be talked down to the cheap tier. A vote for a higher band is not applied — escalation follows a verifier failure, never the model's self-assessment (§5.1). The tier it would have picked is reported as llm.escalateTo, an advisory recommendation that nothing acts on at routing time: it is recorded against the task, and forge diagnose --task "<task>" names it once the same failure signature has recurred THRASH_K times — a real external check failing, which is the only thing that may buy a bigger model (§5.1). The one exception is opt-in: with route.mode: "unattended" (or forge route --mode unattended) a vote with p(premium) ≥ 0.9 raises to the premium tier and a mid-or-higher vote with p ≥ 0.5 to at least mid, because an agent nobody watches has no cheap retry loop; that mode also adds a writes-code floor, a keyword risk floor and a top-tier gate, each reported in policy.steps (see docs/ORCHESTRATION.md);
  • the assumption gate — can clear a false ask or add one, but never clears a task with no concrete anchor, or one naming symbols/files the repo doesn't define (those floors guard clearing only — they never raise an ask the rubric didn't). The rubric's completeness and the proposer's are on different scales, so only their ask/proceed verdicts are compared, and the proposer flips the rubric only when it holds its verdict with p ≥ llm.minConfidence;
  • impact edges — kept only if the file is real and a grep confirms the reference;
  • goal-drift — rescues an off-goal file only with a goal-referencing reason (off→on only).

Note — set llm.bidirectional: false in source/substrate.json for the conservative mode (caution can only ever increase: the gate can only tighten, the tier never moves).

It is fail-safe: any error, timeout, or unparseable reply falls back to the deterministic path (behaviour is byte-identical with the flag off), and it never blocks. --json output carries an llm.provenance map (deterministic / llm-cleared / llm-tightened / llm-lowered / llm-raise-deferred / llm-overruled / llm-verified) per faculty so every model-touched decision is auditable. Off by default; the ambient Claude Code hook stays deterministic unless you also set FORGE_LLM_AMBIENT=1. Config lives in source/substrate.json → llm.


Honest limits

Heuristic, not benchmarked; the graph is regex-approximate; assumption detection is lexical by default (FORGE_LLM=1 adds the verified refinement above — proposals are checked against the repo/graph/tests before they count, never trusted blind); auto-run needs a hook surface. Tests and human corrections always win. The full, canonical list: docs/GUIDE.md → Honest limits.


Learn more

  • White paper — the full argument: HTML (with the 2026-09-21 and 2026-09-26 corrections) · PDF (historical, pre-correction edition; provenance in research/HISTORICAL_EDITIONS.md). Its two prototype results were refuted on real data — see research/empirical-refutation/.
  • Package overview — headline results (refuted; see its banner) and prototypes
  • Evidence map — every load-bearing statistic re-graded against primary sources (5 confirmed, 5 vendor-reported, 2 dropped); since 2026-09-26 it also grades claim support, study design, replication and transfer scope separately
  • Ecosystem map — each capability vs. the real 2026 tool stack
  • Prototype source — the auditable Python originals
  • Claim status registry — every load-bearing headline with its status (implemented / measured / refuted / hypothesis / partial / reported) and evidence

Which copy is canonical

research/cognitive-substrate/ is the canonical source. Four files here are byte-identical copies kept for readers of docs/, and node scripts/claims-status.mjs --check fails when they drift (sha256):

Copy in docs/cognitive-substrate/ Canonical source
cognitive_substrate_whitepaper.html research/cognitive-substrate/cognitive_substrate_whitepaper.html
cognitive_substrate_whitepaper.pdf research/cognitive-substrate/cognitive_substrate_whitepaper.pdf
evidence_map.md research/cognitive-substrate/evidence/evidence_map.md
ecosystem_map.md research/cognitive-substrate/evidence/ecosystem_map.md

Edit the canonical file, then copy it over (node scripts/claims-status.mjs --sync-copies does that). deliverable-package.md is not a copy: it is an adapted edition of research/cognitive-substrate/EXECUTIVE_SUMMARY.md with links rewritten for this folder, so it is edited by hand alongside it.

How the paper maps to what ships (all 11): memory → recall/cortex/ledger · learning → cortex + ledger oracles · imagination → imagine [--run]/impact · self-correction → verify/diagnose · impact-awareness → atlas/impact · M1 routing → route · M2 assumption gate → preflight/context · M3 decomposition → scope · M4 goal-anchoring → anchor · M5 minimality → lean/uicheck design · M6 verification → verify/substrate.