feat: formal-synthesis paper features (v2) — know, precommit, verify --deep, radar, ledger sync, deja, dash v2, report + Mintlify docs#68
Merged
CodeWithJuber merged 12 commits intoJul 17, 2026
Conversation
…omes Implements the formal-synthesis paper's A7 step as code (Theorem T6 totality): src/knowledge_router.js routes any fact to one of seven storage homes (claude-md / rule / skill / state / decision / ledger-fact / recall) with the same exemplar k-NN math as intent.js (labeled HOME_EXEMPLARS bank + setOverlap + confidence gate, reusing intentGrams). Below the gate the fact falls back to `ledger-fact` with provenance:"fallback" — never "none": the ledger's decay-toward-unsure semantics make an unsure placement safe. storeFact dispatches to the EXISTING stores verbatim: appendDecision (decide.js), shadowFact into the repo ledger (ledger_bridge.js), and recall add + personal-ledger shadow (the exact `forge recall add` CLI path). Curated-file homes (claude-md/rule/skill/state) are advise-only — routing returns advice naming the right command instead of a blind write. Secrets are refused before any dispatch (hasSecret), and storeFact never throws. Surfaces: - CLI `forge know "<fact>" [--dry-run|--json]` (Memory group). - Cortex hook: distilled lessons (ENABLE_CORTEX_DISTILL=1) that route to decision/ledger-fact at confidence >=0.5 also shadow there, try/catch fail-open inside enrichCreated. - Docs: README + GUIDE command mentions, GUIDE worked section, CHANGELOG [Unreleased] bullet. No new env vars, no new deps, no new ledger KINDS. Tests (test/knowledge_router.test.js, 12): totality fuzz (100 arbitrary strings all land in a real HOMES member), per-family routing from unseen phrasings, dry-run never writes, advise-only homes never write, secret refusal, decision/ledger/recall auto-writes verified against their stores, CLI --dry-run --json smoke. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
… wired via harden Adds the middle rung of the gate lattice (turn ⊂ commit ⊂ PR): - src/commit_gate.js — stagedFiles (git diff --cached -z), classifyPath reuse from gate.js (code staged with no doc/state artifact → completeness finding), and secrets.js detection over staged ADDED lines only as the gitleaks fallback (confirmed at redaction-grade precision so ordinary code like `token = process.env.TOKEN` is never a false block). - Modes via FORGE_COMMIT_GATE: warn (default, print + allow), block (refuse), 0/off (kill switch); a detected secret blocks in every mode (mizan — a credential in history is not repairable). Fail-open like stopGate. - forge precommit CLI command (+ --json), registered in commands.js (Quality). - harden.js: pre-commit hook is now gitleaks-if-present + `node <root>/src/cli.js precommit`, fail-open when node/package are missing, and no-clobber — a user-authored hook is kept and ours lands beside it as pre-commit.<cli>. - Docs in the same change: README/GUIDE command rows, GUIDE env table row for FORGE_COMMIT_GATE, CHANGELOG [Unreleased] bullet. - Tests: test/commit_gate.test.js (warn/pass/block/secret/removed-lines/kill- switch/fail-open/unicode -z/pure-table) + harden hook install/no-clobber. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
New applyUpdateTo in src/update.js: for a git checkout it fetches tags
(best-effort, offline-safe), verifies the release tag exists (accepts
0.17.0 or v0.17.0, and both v-prefixed and bare tag names), then does a
detached checkout at the tag with a note on how to return to latest.
npm/copy installs get the exact 'npm i -g <pkg>@<version>' instruction.
Never throws: missing version, unknown tag, and dirty-tree checkout
failures are honest {ok:false, reason} results.
CLI: 'update --to <version>' wired before --check/bare paths (--json
supported); commands.js row, README table row, GUIDE prose, and a
CHANGELOG [Unreleased] bullet updated in the same change. Eight new
tests in test/update.test.js cover pin/idempotence/bare-tag/miss/
non-git/dirty-tree/arg-validation plus a CLI --json path, all on tmp
git fixtures with no network.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…ional N-sample reviewer) New src/consensus.js closes GAP 2 (self-consistency / majority-of-N review): `forge verify --deep` runs a LENSES table of independent checks — tests (solo-trusted outcome), unknown symbols, unreviewed impact radius (atlas dependents not in the diff, the gate.js repairReason traversal), docs drift (gate.js classifyPath F1 signal), secrets in added lines (solo-trusted), spec-lock drift, and an opt-in reviewer panel — and aggregates them exactly like lessons.js scoreMistake: noisy-OR P(defect)=1−∏(1−wᵢsᵢ) plus the cross-family gate (≥2 evidence families or a solo lens), so correlated structural signals stay advisory while a failing suite or leaked secret blocks alone. Every run reports the Theorem-D residual ∏(1−cⱼ) over the lenses that ran (mizan: a PASS states what it still can't see), extends .forge/provenance.json with per-lens evidence, and appends one stage:"verify" metrics record. Reviewer lens: N=3 independent adjudicate() samples, strict-majority vote, abstains below ⌈n/2⌉ usable replies; gated on llmEnabled (FORGE_LLM=1 or `--llm`), injectable runner — tests never touch a model or the network. verify() now also returns the added diff lines so the deep lenses read the same bytes the base pass parsed. CLI renders the lens table with fmt.js; README/GUIDE/CHANGELOG updated in the same change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…rding + pre-edit advisory New zero-dep src/radar.js implements `forge radar` (paper crosswalk GAP 4 = I4 verified currency). It reads this repo's Node manifests, probes the registry via an injectable fetch (metadata + bulk advisories, 4s timeout, never touches the network in tests), and classifies each dependency into an adopt/trial/assess/hold ring from a formula over evidence — staleness (540-day half-life), major-version lag, severity- weighted advisories, deprecation; atlas import-sites are stakes, not risk. Mizan: every ring ships the evidence that earned it, and missing evidence never upgrades a dep (deprecated/critical → hold; <2 verified evidence kinds → assess). Cached at .forge/radar.json (FORGE_RADAR_TTL_H, default 24h); --offline serves the stale cache flagged with its age or fails honestly; --refresh re-probes; --json for tooling. A network scan records I4 evidence into the ledger (one currency:<dep> fact per dependency, shadowFact supersede semantics keep the latest verification live with history in tombstones) plus a stage:radar metrics line. The cortex pre-edit hook surfaces a cache-only advisory (hooks never fetch) when a file imports a hold dependency; kill switch FORGE_RADAR=0. Every-surface: commands.js row + Quality group; README + docs/GUIDE command mention; FORGE_RADAR / FORGE_RADAR_TTL_H documented; CHANGELOG [Unreleased] bullet; one test file (test/radar.test.js, network fully injected). Gates: node --test, biome, tsc, docs check all green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…rtability `forge ledger sync` moves the proof-carrying-memory ledger between machines without a merge-path argument. The ledger is already a state-based CRDT (content-addressed claims + hash-deduped append-only logs joined by the `mergeStates` semilattice); sync is a transport that ships that state and re-runs the join. New module src/ledger_sync.js (zero deps, injectable git runner, fail-open): - Target discovery (syncTarget): --dir > --remote/--ref > the repo's git remote > FORGE_SYNC_DIR > an honest "no target". Pure + injectable env/run. - Dir mode (syncDir): bidirectional mergeDirs with a shared directory — both replicas converge to the union. - Ref mode (syncRef): git plumbing over refs/<cli>/ledger — pull = fetch the ref, cat-file the state.json blob, importState; push = canonicalize → hash-object → mktree → commit-tree → update-ref → push, skipped when the remote tree already equals ours (byte-level idempotence). A non-fast-forward race re-fetches, re-imports (monotone), rebuilds on the new parent and retries ≤3 — nothing lost. - --personal targets the per-user ledger the recall store shadows into, so recall facts become portable across machines. - Offline, a missing remote, or a corrupt remote blob all degrade to an honest reason (never throws). Tests drive real git with local bare remotes — no network. Every surface, one commit: commands.js ledger row (+ sync); cli.js `sync` branch + usage string; README + docs/GUIDE prose (incl. FORGE_SYNC_DIR env contract); CHANGELOG [Unreleased]; test/ledger_sync.test.js (target discovery, dir/ref convergence to byte-identical state, idempotence, race retry, honesty, --personal portability). Gates green: node --test, biome, tsc, docs check. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…advisory Anti-repetition memory closing W2d. The user's "why do I keep re-solving the same task across sessions" root cause: Cortex only mints on CORRECTION episodes, so a clean first-try success leaves no durable trace — clearSession discards it and the next session starts blind. - src/deja.js: recordSessionSummary mints ONE `summary` claim (existing ledger KIND — no protocol change) at session Stop, with a deterministic, secret- redacted gist (first prompt via redactSecrets) + files touched. A passing test run attaches one `test.run` confirm outcome, so `val` separates solved-and- verified from merely-attempted. dejaLookup ranks prior summary/lesson/diagnosis claims with the SAME Eq.3 retrieve() as `ledger query` (rel × rec × val). - src/cortex_hook_main.js: stop mode mints the summary before clearSession (fail-safe, kill switch FORGE_DEJA=0); preflight mode emits a one-line "déjà vu" advisory when a prompt matches prior solved work (cache-only read). - CLI `forge deja "<task>"` (+ --json) ranks prior sessions with fmt.js bars. - commands.js row + GROUPS.Memory; README + docs/GUIDE mention `forge deja`; FORGE_DEJA documented; CHANGELOG [Unreleased] bullet; test/deja.test.js. Because summaries are ordinary ledger claims, `forge ledger merge` (and a future `forge ledger sync`) carry them between machines — anti-repetition across surfaces. Zero new runtime deps; no new ORACLES/KINDS rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…line panels Extend the localhost dashboard (src/dash.js + src/dash.html) into a v2 lens over the durable .forge/ stores, keeping the dashData/serve split and append-only write discipline (the only writes remain POST /api/ratify and /api/retract). New read-only endpoints, each a pure section builder that never throws and degrades to an empty payload on corrupt/missing stores: - GET /api/history — metrics.jsonl bucketed by day×stage, 90-day window, per-stage daily series for sparklines (historyData). - GET /api/claims?q=&kind= — memory browser ranked via ledger retrieve (Eq.3 rel×rec×val) with confidence + freshness, budget 50 (claimsData). - GET /api/radar — dependency-currency rings read from the .forge/radar.json cache only (never fetches); tolerant of shape drift, empty panel when absent (radarData). - GET /api/timeline — durable mint/tombstone events from the ledger, newest first (timelineData) — not the ephemeral session logs. dash.html gains four panels (Radar rings, Trends sparklines, Memory browser with live debounced search + kind filter, Session timeline), a ~30-line inline-SVG sparkline helper, and 5s live polling paused on document.hidden. Self-contained, no CDN, brand tokens only. Docs move in the same commit: commands.js summary, README + docs/GUIDE.md dash descriptions, CHANGELOG [Unreleased]. New tests in test/dash.test.js cover each lens payload-first plus the serve routes and corrupt-store degradation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
Add `forge report` — the offline twin of `forge dash`. New zero-dep src/report.js emits ONE self-contained .forge/report.html (no server, no fetch, no CDN, no JS to read it) that opens offline, mails, or attaches to a PR. - renderReport(root) is PURE: reuses dashData(root) (dash.js) for the ledger and metrics payload, buckets metrics.jsonl into a 90-day activity sparkline via a ~15-line server-side inline SVG helper (no xmlns → zero external refs), and reads the .forge/radar.json cache DIRECTLY and defensively — report.js never imports radar.js, so absent/corrupt cache simply omits the radar section. - Palette comes from rootTokensCss() (brand.js), so the report's tokens are the brand's single source, never a forked copy. All dynamic strings escaped. - writeReport(root) is the only side-effecting entry point; CLI `forge report` writes .forge/report.html (or `--out <path>`). Every-surface: commands.js row + Config group placement, README + GUIDE command docs, CHANGELOG [Unreleased] bullet, one test file (test/report.test.js: self-containment, brand token block, escaping, radar defensiveness, history bucketing, sparkline). No new env vars, zero new runtime deps. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
Add a self-contained Mintlify documentation site under mintlify/, additive to the existing docs/ Markdown (which remains the source of truth). Derived from README.md, ARCHITECTURE.md, ONBOARDING.md, and src/commands.js. Pages (18): - Get started: introduction, quickstart, installation - Core concepts: config compiler, proof-carrying memory, pre-action gate, cross-session memory, verification gates, model routing - CLI reference: overview + one page per GROUP (core, memory, substrate, quality, config); documents all 37 commands plus v0.19+ additions (know, deja, precommit, radar, report, tools, verify --deep, update --to) - Guides: zero-config onboarding, team memory, keeping deps current with radar Also adds docs.json (Mintlify config: ember brand palette from brand.json, tabs→groups→pages navigation), brand favicon + light/dark logo SVGs, a mintlify/README.md (local preview + GitHub-App deploy notes), and an advisory, non-blocking .github/workflows/docs-links.yml running `npx mintlify broken-links` on PRs touching mintlify/. No deploy workflow (Mintlify deploys via its GitHub App). Zero runtime/dev dependencies added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
…ead, honest deprecated=unknown Three correctness fixes from the integrated-branch code review: - consensus.js secretsLens is a solo-trusted BLOCKING lens but used the broad hasSecret() detector; a diff line like `const k = process.env.API_KEY` would false-block `verify --deep`. Now uses the same redaction-grade check (hasSecret && redactSecrets !== text) commit_gate.js uses for its blocking path. - dash.js radarData read d.version/d.evidence, but radar.js writes installed/reasons, so the dash radar panel showed empty versions. Now reads d.installed (+ reasons), tolerating the legacy shape; test covers radar's real cache shape. - radar.js probeRegistry set deprecated=false when the latest version doc was missing; that asserts "not deprecated" on unverified evidence. Now null (unknown) so classifyDep never counts a spurious evidence kind (mizan). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
CI Biome check failed on 4 format errors introduced when the review fixes were reflowed by a local editor hook into non-canonical form. Ran `biome check --write` on the affected files (consensus.js, dash.js, radar.js, test/dash.test.js). No behavior change; tests 851 pass, docs check green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
CodeWithJuber
marked this pull request as ready for review
July 17, 2026 13:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
The first two research-paper commits (crosswalk fix +
fmt.js) landed in #67 and released as v0.19.0. This PR delivers the remaining 9 features that close the verified gaps betweenresearch/formal-synthesis/("A Formal Theory of the Cognitive Substrate for Coding Agents") andsrc/, plus the two priority tracks (UI/UX and cross-session memory), plus a user-facing Mintlify docs site.Features (one conventional commit each):
feat(know)— A7 knowledge-router: totalroute(fact) → storage home(paper Theorem T6), exemplar k-NN,ledger-factfallback so it is total by construction.forge know "<fact>".feat(precommit)— commit-level gate rung (the paper's missing middle of turn ⊂ commit ⊂ PR): staged F1 classifier + secret scan, wired viaharden.FORGE_COMMIT_GATE=warn|block|0.feat(update)—--to <version>pin/downgrade (git tag checkout or npm instruction).feat(verify)— multi-lens consensus (verify --deep): noisy-OR + cross-family gate (thescoreMistakeshape), Theorem-D residual reporting, optional N-sample LLM reviewer (never solo).feat(radar)— dependency-currency rings (paper invariant I4): adopt/trial/assess/hold computed from registry evidence (staleness half-life, major-lag, advisories, deprecation), never hardcoded lists; missing evidence never upgrades a dep; recorded as I4 ledger claims; cache-only pre-edit advisory.FORGE_RADAR=0,FORGE_RADAR_TTL_H.feat(ledger)—sync: CRDT push/pull over a git ref or shared dir,--personalrecall portability.FORGE_SYNC_DIR.feat(deja)— anti-repetition: session-summary claims at Stop + similar-task lookup, so first-try successes leave durable, cross-machine memory.forge deja "<task>",FORGE_DEJA=0.feat(dash)— dash v2: live refresh, history trends, radar/memory/gate/timeline panels (append-only write discipline preserved).feat(report)— self-contained HTML report emit.docs(mintlify)— user-facing docs site (mintlify/docs.json+ 18 MDX pages: intro, quickstart, installation, 6 concepts, CLI reference, 3 guides) + advisory broken-link CI. Deploys via the Mintlify GitHub App (connect the repo once in the dashboard).A final
fix(review)commit resolves 3 correctness findings from an integrated-branch code review:verify --deep's secret lens now uses redaction-grade precision (no false-block onx = process.env.KEY), the dash radar panel reads radar's realinstalled/reasonsfields, and radar recordsdeprecated=unknownrather than assertingfalseon unverified metadata.Checklist
npm testpasses — 851 pass / 0 fail / 2 pre-existing skipsnpm run checkpasses (Biome — 6 pre-existing warnings unchanged, 0 errors)*.test.jsper new module)feat:/fix:/docs:…)CHANGELOG.mdupdated under## [Unreleased]commands.js+ README +docs/GUIDE.md;docs checkgreen (incl. the crosswalk reconciler)Risk & rollback
FORGE_COMMIT_GATE=0,FORGE_RADAR=0,FORGE_DEJA=0); no ledger schema change (no new ORACLES/KINDS rows) so cross-version merges stay clean.Extra checks (tick if applicable)
npm run typecheckpasses (JSDoc/tsc)127.0.0.1only)🤖 Generated with Claude Code
https://claude.ai/code/session_017Ebv4QDTqzPzgApBW2KUsU
Generated by Claude Code