All notable changes to this project are documented here. The format is based on Keep a Changelog and this project adheres to Semantic Versioning.
0.17.0 - 2026-07-15
- OpenAI + Gemini provider detection —
autoDetectProvider()now recognizesOPENAI_API_KEYandGEMINI_API_KEY(orGOOGLE_API_KEY) as zero-config fallbacks after Anthropic, exposingopenaiandgeminias built-in providers with tier→model maps. Both are reached over their OpenAI-compatible chat/completions surface:src/llm.jsgained an OpenAI-compatible wire format (resolveHttpProvider()now returns aformatfield) alongside the Anthropic Messages path, so a native key from either vendor works with no manual config. Anthropic credentials still win when present.forge configstatus andlistDetectedProviders()surface the new keys.
0.16.0 - 2026-07-15
- Playwright interaction loop —
forge uicheck interact <file-or-url>drives the page headless underprefers-reduced-motionand checks what it does (console-clean, keyboard-reachable, focus-visible, reduced-motion), whereuicheck visualonly fingerprints what it paints. The verdict is recorded through the ledger's cross-family-gatedbehavioraloracle (advisory by default;--recordappends it as evidence on the projectfingerprintclaim,--enforcegates). Reuses the visual gate's Playwright resolver + loopback-only target guard; Playwright stays an optional tier (ADR-0005) with a graceful skip. Newsrc/uiinteract.js(runInteractions,summarizeVerdict,verdictOutcome,recordInteraction) with a browser-free test suite.
0.15.0 - 2026-07-15
- measured-promotion gate + outcome-calibrated routing
0.14.0 - 2026-07-15
- Measured-promotion gate + outcome-calibrated routing (
forge route calibrate) — a reusablesrc/promote.jsgeneralizes the risk predictor's kill-criteria: an advisory signal (a calibrated weight, later a consolidation cluster or hazard estimate) may become active only if it beats the current baseline on held-out data under a metric+margin — the honesty register (overview §4), never an assertion. First application:forge route calibratefits an affine correction of the routing rubric toward a held-out labeled fixture and promotes it only if it lowers held-out MAE. Advisory by default — routing keeps the rubric until a promotion is adopted (calibratedComplexitymirrorspredictor.riskFor). Zero deps, fully unit-tested. - Legacy-store retirement (
FORGE_LEDGER_ONLY) — the PCM ledger can now be the only store. Since P1 it has been the convergent write store (dual-write) with a merged read (ledger_read); withFORGE_LEDGER_ONLY=1the legacy files (.forge/lessons/*.md, recall/brain fact files) stop being written and every read materializes from the ledger — cortex confirm/create/distill dedup againstledgerLessons,mergedLessonsreturns the ledger view, andrecall.readFactfalls back to the ledger (also fixing merged teammate facts that had no local file). Runforge ledger importfirst to backfill. Default off keeps the legacy files canonical.
0.13.0 - 2026-07-15
- Custom-gateway model remap (
src/gateway_model_map.js). The tier table pins public Anthropic IDs that a self-hosted LiteLLM/proxy gateway may not serve; when a non-default gateway base URL is set, Forge fetchesGET /v1/modelsonce per process and scores each advertised model against every tier's family (family-word gate +setOverlapname-token score, deterministic tie-break) to remaphaiku/sonnet/opus/fableonto the gateway's real IDs.forge doctorsurfaces the resolvedtier→modelmapping under a gateway models row. Zero breaking change — theMODELSexport shape is unchanged, it fails safe to the stock ID on no gateway / unreachable/v1/models/ no family match, and an explicit.forge/providers.jsonalias orANTHROPIC_MODELoverride always wins. Directapi.anthropic.comsessions never probe and are byte-identical.
0.12.4 - 2026-07-11
- security: drop two inert
curl-pipe deny rules from the settings template. Claude Code only honors:*as a trailing wildcard, so the trailing pipe made the colon a literal and the rules matched nothing. Real pipe-to-shell enforcement already lives inprotect-paths.sh, now tightened to also catch a no-space pipe and azshtarget. Adds a regression test for template rule shape.
0.12.3 - 2026-07-11
- bump.mjs keeps ROADMAP's "Now" marker in sync
0.12.2 - 2026-07-11
- allowlist bibliography citation-key false positives in gitleaks
- don't let an empty Unreleased section blank the status page changelog
0.12.1 - 2026-07-11
- don't let an empty Unreleased section blank the status page changelog
0.12.0 - 2026-07-11
- Goal-drift classification is graded and identifier-aware (
src/anchor.js). A changed file's on-goal/off-goal call is now a noisy-OR (1 − (1 − p)^hits) over how many distinct goal concepts it exhibits in its path and the identifiers it defines (via the atlas), thresholded at the single-hit floor — replacing the binary path-substring match, so a file that implements the goal but never names it in its path is caught deterministically, not just by the opt-in LLM pass.driftScorestays the off-goal fraction, so the CUSUM detector's operating point is unchanged (an on-goal checkpoint scores 0 and drains the chart); the sharper classification is what improves the signal. - Specification completeness is a logistic estimator (
src/preflight.js). The M2 assumption gate'ss(x)completeness score is now a logistic over its features (concreteness, named specifics, vagueness, a smoothtanhlength term) — replacing the additive scorer's magic coefficients and discontinuous word-count steps. Thesigmoidbounds it to (0,1) with no clamp, each feature's pull stays attributable, and a labeled bank could refine the weights viapredictor.js'strainLogistic. Calibrated to keep the documented examples (a bare "make the auth better" ≈ 0.23 → ask; a concrete verifyToken edit ≈ 0.63 → proceed).
forge docs checknow guards intra-repo links and roadmap freshness — two more reconcilers close recurring "docs rot" classes:checkLinksresolves every Markdown anchor (#xandpath.md#x) against the target file's real headings using GitHub-exact slugs (an em-dash yields--, never collapsed), catching dead anchors like a renamed#install;checkRoadmapfails when ROADMAP's "Now" marker trails the shippedpackage.jsonversion.
- Dead and fabricated docs — a fabricated
forge routeexample indocs/GUIDE.md(an impossibleFable 5 / Opus/ "premium tier" output) now shows the real routed verdict; broken#installanchors inONBOARDING.mdand the substrate README now point to#60-second-quickstart; a dead#use-it-in-a-scriptself-link resolves; and ROADMAP's "Now" marker is current (v0.11.0). All now enforced by the new docs-check guards.
0.11.0 - 2026-07-11
forge stack— dynamic stack detection: reads the repo's dependency manifests (package.json,pyproject.toml,go.mod,Cargo.toml,Gemfile,composer.json,pom.xml/build.gradle,*.csproj) and reports its real languages, frameworks, package managers, and test commands — data-driven (extend by adding aSIGNATURESrow), not a hardcoded menu. The detected test commands now drive the substrate's verification checklist instead of assuming npm.- Six more atlas languages — Ruby, C#, PHP, Kotlin, Swift, and C/C++ join JS/TS,
Python, Go, Rust, and Java (whose method defs are now indexed too). One
RULEStable; the walk, completion gate, and docs sweep pick each up automatically. forge update— self-update:--checkreports whether a newer version is available (commits behind upstream, from a cached hourly fetch), bare applies it (git pull --ff-onlyfor a checkout, or thenpm i -gcommand otherwise).forge doctorsurfaces a non-nagging "update available" notice;FORGE_NO_UPDATE_CHECK=1silences it. Fail-open: offline / non-git / detached-HEAD never error.- Self-dogfood — a committed
.claude/settings.jsonwires forgekit's own guards via${CLAUDE_PROJECT_DIR}, so the repo runs its own completion gate, cortex, and guards during local dev without a marketplace install. - Auto-release on merge — pushing a
feat/fix/perf/breaking change tomasternow cuts the release automatically (bump → tag → npm publish → GitHub Release); a chore/docs-only merge skips cleanly (bump.mjs autoexits3). When[Unreleased]is empty,bump.mjssynthesizes the changelog body from commit subjects so every release still describes itself. Manual Actions → Bump version dispatch stays available. forge docs checknow guards diagrams, model prices, and benchmark numbers — three new reconcilers close the blind spots behind recurring complaints: everymermaidblock across all Markdown must carry the branded theme and use<br/>(not a literal\n); model prices in the docs must matchsrc/model_tiers.json; and every boldedN msclaim in the README must be a valuereports/benchmarks.mdactually measured.
- CLI output is quiet by default — the
Forge <command> — …title line no longer prints on every command; results come first.--verboseorFORGE_VERBOSE=1restores it. The--help/--versionbanner is unchanged. - Unified public design system — the landing page and the generated status page now
share one warm ember/near-black palette and a system font stack (the landing page no
longer declares the Inter webfont it never loaded).
test/pages.test.jsenforces token parity, a non-empty changes list, and no phantom webfont. - Restyled the terminal statusline — a restrained palette (muted structure, one ember
accent, green/red reserved for the diff) with consistent
·separators and a subtle context-limit marker instead of an alarming red block. - Plain-language docs pass — the README and GUIDE openings lead with what forgekit is
and does; the deep math (
y = f(x), join-semilattice, Beta posteriors) moved into parentheticals or the white paper, and comparison-table cells no longer cite code identifiers as if they were user features.
- Broken diagrams — two
mermaiddiagrams rendered in Mermaid's off-brand default theme, one with literal\nnode breaks GitHub showed as garbage; both fixed, and the over-wide 13-node pre-action pipeline was regrouped so it reads at GitHub width. - Status page "Latest changes" list — wrapped CHANGELOG bullets were truncated mid-sentence (and could render empty); the parser now joins lazy/indented continuation lines into the full item.
0.10.0 - 2026-07-10
- The completion gate — a synchronous Stop hook (
global/guards/completion-gate.sh→src/gate.js) that blocks a session ONCE when code changed but no doc or state artifact moved with it, answering with the repair checklist (forge docs sync,forge handoff,forge decide, plus a CUSUM goal-drift alarm when the session's recorded drift sustained). Loop-safe (stop_hook_active+ once-per-session marker), fail-open on every error path, kill switchFORGE_STOPGATE=0. Classification derives from the atlas registries + the shared test-file predicate — no parallel regex lists. forge handoff— the bounded session snapshot: rewrites.forge/state.md(≤150 lines; goal/phase, acceptance criteria, done, next, gotchas, recorded assumptions, in-progress git files) and SessionStart re-injects it, so the next session resumes instead of re-assuming. Refuses secrets like every forge store.forge decide— append-only ADR-lite decision log (.forge/decisions.md,D-####numbering) + a machine-readabledecisionledger twin; bareforge decidelists the last ten. Supersede with a new entry, never an edit.forge docs sync— the diff-driven half of docs↔code alignment: changed identifiers (paths, definitions, called symbols — from added AND removed lines) swept against every doc artifact → UPDATED / STALE (file:line hits) / VERIFIED-UNAFFECTED (reason recorded). Advisory by default,--strictfor CI,--base <ref>to widen; CHANGELOG and the decision log are exempt (append-only history).- Session baseline + rehydration — SessionStart records the session's git anchor
(
.forge/sessions/<sid>.base; a resume never moves it), prunes week-old session artifacts, and injects the handoff snapshot + last 10 commits + uncommitted changes. - Intent protocol cards — UserPromptSubmit classifies the prompt with the same
exemplar k-NN math as routing (labeled bank incl. Hinglish rows, overlap similarity,
confidence gate) and injects a bugfix/feature/refactor/release protocol card once per
run of that intent; questions get no ceremony. Kill switch
FORGE_INTENT=0. - Recorded assumptions — when preflight proceeds without asking, the assumption is appended to the session log, named in the advisory, and surfaces in the next handoff; the per-prompt goal-drift score is recorded the same way and feeds the gate's CUSUM.
- Config artifacts in the atlas — CI workflows (
.githubis now walked), manifests, and Dockerfiles becomeconfig:nodes withreferencesedges to the code paths they name, soforge impactlists the configs a change can break (lockfiles excluded as generated churn). - End-to-end skills + agent —
handoff,sync-docs, andcatchupskills, adoc-synccrew agent that repairs stale docs in its own context, and anend-to-endrules section (Definition of Done, no silent assumptions, decision log) compiled into every tool byforge sync.
cortex.shhook entry resolution in symlink installs —~/.forge/src/…pointed at the nonexistentglobal/src/, silently no-opping every cortex hook outside plugin mode; the shim now resolves through the symlink (pwd -P), same assecret-redact.sh.- Twelve defects found by a two-angle adversarial review of the new layer, all with
regression tests — the gate no longer attributes pre-session dirt, branch-switch/pull
commits, or vendor trees to the session (session-scoped changed set: committer-time
window + SessionStart dirty snapshot);
-zNUL parsing keeps unicode/space/arrow paths correctly classified; an unwritable block-once marker stands down instead of blocking every turn; a missingsession_iddisables gating instead of sharingdefaultstate; a >7-day resume re-anchors instead of losing its baseline to the prune;readStateno longer truncates snapshots whose rows contain<!--;forge decidetakes a lock so concurrent appends can't mint duplicate D-#### ids; the docs sweep stopped scanning its own bookkeeping (.forge/state.md), scans touched docs for REMOVED symbols (the rename case), counts lowercase symbols only inside backticks, dedupes recorded assumptions, and errors on an unknown--baseinstead of mislabeling the report.
0.9.0 - 2026-07-10
- Gateway environments work end to end —
ANTHROPIC_AUTH_TOKENis recognized everywhereANTHROPIC_API_KEYis;ANTHROPIC_MODEL/FORGE_MODELpin one model (bypassing tier routing); a gateway-lookingANTHROPIC_BASE_URLauto-classifies as LiteLLM; and the LLM proposer falls back to direct HTTP (src/llm.js, Anthropic Messages API) when theclaudeCLI is absent — or onFORGE_LLM_HTTP=1. forge docs check(+ CI job + doctor check) — reconciles README/GUIDE/ ARCHITECTURE/ROADMAP against the code: every CLI command documented, every env var read is documented and every documented var is real, MCP tool counts/names match the registry, CHANGELOG sections non-empty. First run found 56 real drift issues, including a phantom env var.scripts/bump.mjsnow refuses to rotate an empty[Unreleased].- Docs are in the impact graph — the atlas parses markdown into doc nodes with
referencesedges to the code they name, soforge impact src/foo.jslists the docs that go stale, and the pre-edit hook says so before the edit. - Persistent goal —
forge anchor set/show/clearstores the active goal in.forge/goal.md; SessionStart re-injects it and a bareforge anchorchecks against it.goalDriftalso returns a gradeddriftScorefor the CUSUM detector. - AGENTS.md auto-repair — the Stop hook re-runs sync when the managed AGENTS.md
drifts from its canonical inputs (disable:
FORGE_AUTOSYNC=0). - Entropy secret detection —
src/secrets.jsis the single source of truth (format grammars + Shannon-entropy gate for unknown-vendor tokens); thesecret-redactguard now imports it, ending the JS/shell regex divergence. src/math.js— Shannon entropy, charset classes, exact set Jaccard/overlap.
- Routing scores by exemplar similarity, not keyword lists — the text rubric is
similarity-weighted k-NN over a labeled
EXEMPLARSbank (overlap-coefficient on stopword-filtered unigram+bigram sets, credibility-shrunk); the four topic keyword regexes and their additive magic weights are gone. Tune routing by adding labeled rows, not by editing weights. - Lesson matching is graded — the keyword tier of
matchScorescores by token overlap (same-module partial credit) instead of all-or-nothing string equality. - Substrate minimality warnings derive from computed signals (preflight missing dimensions + route score) instead of a second keyword copy.
forge scandetects obfuscated payloads — long high-entropy base64 blobs flag as findings alongside the signature rules.providerStatusprobes/healthon any custom base URL and reports behavioral gateway evidence (a proxy that answers /health is a gateway, whatever its hostname).
0.8.1 - 2026-07-08
- MCP write tools —
forge_remember,forge_ledger_ratify,forge_ledger_retractjoin the read tools (19 tools total).
- Simplified CLI surface and improved dashboard UX empty states.
- Stale documentation across command references.
0.8.0 - 2026-07-08
- Forge work system — auto-install flow, multi-provider routing, the cost
dashboard (
forge dash), and the cortex MCP server's read-path tools. - Zero-config provider auto-detection —
autoDetectProvider()resolves the provider from the environment (LiteLLM local/hosted, OpenRouter, Anthropic);forge initreports what it found. - Hosted LiteLLM gateway support —
emitGatewayConfig()writes alitellm.config.yamlexposing complexity tiers as model aliases.
- TypeScript errors and Biome 2.5.2 lint warnings across source and tests.
0.7.0 - 2026-07-08
- Optional embeddings tier (
src/embed.js, ADR-0005; ROADMAP "Next"): setFORGE_EMBED=cmd:<command>(stdin/stdout JSON protocol — any local model or script) orFORGE_EMBED=http:<url>(OpenAI-compatible,$FORGE_EMBED_MODEL/$FORGE_EMBED_KEY, key never logged) andforge reuse query+forge ledger queryreplace the MinHashrelterm with embedding cosine (near/adapt ≥ 0.85/0.7 — a higher bar than Jaccard's 0.8/0.6 to match dense cosine's noise floor), fixing the documented weak spot on very short specs. Vectors are disk-cached (.forge/embed-cache.jsonl, content-hash keyed, corrupt-tolerant, truncate-oldest); both commands print the backend that served (sim: minhash/sim: embed(cmd)); any provider failure degrades silently to MinHash.dependenciesstays empty — the tier is configuration, not a package; the pure ledger core never imports it. forge uicheck visual <file-or-url>— the Playwright visual loop (07-ui-quality-gate §5): renders the page headless at two viewports, fingerprints the computed styles of every visible element (what the cascade and runtime theming actually painted, with usedauto-margins and never-painted UA noise filtered out), and runs the identicaldesigngate over that rendered vector — screenshots land in.forge/ui/. Playwright stays an optional tier (ADR-0005):package.jsongains no dependency, absence degrades to a "skipped (no browser runtime)" note with exit 0 (npm i -D playwright-coreorFORGE_PLAYWRIGHT=…to enable), and non-loopback http(s) targets are refused by default (--remoteto override) — a gate that fetches arbitrary URLs is an exfiltration hazard.
- Ledger read-path flip (P2). Reads are now a merged view (legacy ∪ ledger) via the
new
src/ledger_read.js, so teammate knowledge that arrives withforge ledger mergeactually reaches injection and retrieval: cortex lesson surfaces (lessonsForContext,startupBlock,summary, the substrate advisory and routing past-mistake density) map ledgerlessonclaims onto the legacy lesson shape with an evidence-derived status (tombstoned → retired, val ≥ 0.6 → active, val < 0.45 with a contradiction → quarantined, else candidate), and fact surfaces (recall list/MEMORY.md, brain'sAGENTS.mdindex) include live ledgerfactclaims — always deduped by legacy id/slug with the local file winning, and best-effort (a missing or corrupt ledger degrades to legacy-only). Write paths (recordMistake's confirm-vs-create lookup,recordContradiction,applyDistillation) deliberately keep reading the legacy store they edit; convergence comes from content-addressed claim ids.reconcileFactsnow only tombstones locally-authored claims, so a merged teammate fact survivesforge recall consolidate. Legacy formats are still written — full retirement is the next step. - Professional redesign of the public site, gated by forge's own UI system. The
landing page (
landing/index.html) and the generated status page (scripts/build-pages.mjs→public/index.html) are rebuilt on one design system — theforge dasheight-color warm-ink/ember palette, a strict 4px spacing base, three radius levels, one shadow — and both now passforge uicheck designand the renderedforge uicheck visualgate (the old pages failed with 15–19 accumulated colors and 5–9 radius levels; a project fingerprint claim is minted so conformance is checked too). Scroll-reveal is JS-gated progressive enhancement (no-JS UAs, crawlers, and reduced-motion users see the full page), and the Pages workflow (static.yml) now builds and deploys an assembled_site/— landing at the site root, status page at/status/— instead of uploading the entire repository as the artifact.
0.6.0 - 2026-07-07
- Docs consolidation pass: deduplicated cross-doc prose into single canonical homes
(the substrate README now points at the GUIDE's command reference, output table, and
honest-limits list instead of repeating them), added orientation diagrams
(ARCHITECTURE four-layer compiler + ledger, substrate-v2 phase graph with all phases
marked shipped, the GUIDE daily loop), brought the ROADMAP current, and refreshed the
model-facing skills/crew guidance for the v0.5.0 surface (
forge context,forge imagine --run,forge diagnose,forge ledger blame,forge cost --stages,forge uicheck design --taste) without growing the skills' context payload.
0.5.0 - 2026-07-07
-
Security & OSS hardening: CodeQL, gitleaks secret-scan (blocking; verified clean on the full history), and OSSF Scorecard workflows; refreshed repo topics; SECURITY.md now states the supported line (0.5.x) and documents the ledger's forgery-resistance properties (content-hash verification; oracle weights never trusted from records).
-
UI fingerprints resolve CSS
var()indirection, so design systems declared as custom properties fingerprint fully (the dashboard now reads as a 6-value 4px scale with two radius levels instead of one lonely spacing value), and the five taste profiles gain machine-readable constraint JSONs (global/taste/<name>.json) wired intoforge uicheck design --taste <name>— with auto-pickup from aforge taste-managed DESIGN.md. Prose steers generation; the JSON is what the gate checks. -
One-click release automation.
scripts/bump.mjs(node stdlib only, unit-tested) bumps every version field in one shot —package.json,package-lock.json, both plugin manifests,CITATION.cff, the landing page — rotates the CHANGELOG[Unreleased]section under a dated heading, and prints the new version;npm run bump -- <patch|minor|major|auto>(auto = conventional commits since the last tag: BREAKING → major, feat → minor, else patch). The newbump.ymlworkflow makes a release one click from the Actions tab (commit + tag + dispatch ofrelease.yml);release.ymlnow soft-skips npm publish whenNPM_TOKENis missing instead of failing, and CI gained a version-drift guard (node scripts/bump.mjs check). -
Benchmark harness (
npm run bench) + measured results doc.bench/bench.mjs(node stdlib only) measures the substrate primitives as medians of N runs after warmup — atlas build/incremental/impact latency on this repo, ledger mint+put/loadClaims/mergeDirs/val() on seeded synthetic fixtures, reuse fingerprint + exact/near-LSH lookup at 100 and 1000 artifacts,assemble()and fullsubstrateCheckwall time — and writes the tables plus an environment block intoreports/benchmarks.md. The same run scoresimpact()precision/recall/F1 against a committed, hand-labeled case set from this repo's real import graph (bench/impact_cases.mjs, every reference cited; one known-miss alias case kept in on purpose), reported next to — never blended with — the paper prototype's mutation-derived numbers, plus a structural-only contrast with adjacent tools (note stores, LLM gateways, plain RAG), every row checkable from the named source. -
Loop closure (P5 of the substrate-v2 plan): doom-loop diagnosis, imagination, CUSUM drift, checkpoint cadence.
forge diagnose "<error>"hashes each failure into a signature (line numbers, addresses, timestamps, and absolute paths normalized out) and counts recurrences in a 50-entry ring; the 3rd identical hit is thrash — it mints a content-addresseddiagnosisclaim into the team ledger and tells the agent to STOP retrying and escalate ONE model tier with the diagnosis as the prompt's head (the same loop becomes a one-per-team event, not one-per-session).forge imagine "<task>"is the static half of the consequence simulator (paper Eq. 4): entities → blast radius → predicted breaks with confidence, plus the minimal dry-run test suite via weighted greedy set cover (weight = file size as a duration proxy; classic ln-n approximation) andriskScore = Σ confidence.forge imagine --runexecutes that minimal suite in a sandboxed ephemeral git worktree (HEAD-only — refused on a dirty tree unless--allow-dirty), parses the TAP summary into per-file verdicts, always removes the worktree (verified in a finally), and meters the run (stage: "imagine"); on this repo the 8-test selected suite measured 1.3 s where the full suite takes ~60 s.anchor.cusum()adds the M4 one-sided CUSUM control chart (k = 0.35, h = 1.0): sustained small drift alarms, a single exploratory spike drains back to zero.verify.checkpointCadence()prices M6's "when to check?" as the optimal-stopping threshold rulen* = ⌈checkCost / (pErr·tokensPerStep·costPerToken)⌉, clamped to [1, 50] — every input measured or priced, no magic constants. -
Context assembly + completeness gate (P4 of the substrate-v2 plan).
forge context "<task>"makes what goes into the window a budgeted optimization and makes sufficiency a computed set. The required-knowledge setR(edit)— the target's definitions, its hop-1 dependents from the atlas, sibling tests, and team lessons trusted past val ≥ 0.8 — is derived, then covered by pinned items with a compression ladder (full → head → pointer): a tight budget downgrades granularity instead of silently dropping coverage. Optional items (trusted facts) fill remaining budget greedily with per-source diminishing returns.missing = R \ coveredbecomes derived clarifying questions ("the task namesXbut the repo doesn't define it — which file implements it?"), shown inforge substrateand — underFORGE_ENFORCE=1— blocking: acting on missing context is acting on a guess. Incomplete context stops being a feeling and starts being a set difference. -
Generated-UI quality gate (P6 of the substrate-v2 plan). Taste becomes measurable:
src/uifingerprint.jsextracts a deterministic design fingerprint from CSS/JSX/Tailwind classes — pure static parsing, no LLM, no screenshots — covering palette (HSL + 12-bin hue histogram), spacing (base unit by residual-minimization approximate GCD, on-scale fraction), font families, radius and shadow levels. Two distances gate generated UI:slopDistanceto a shipped, rationale-documented generic-template signature set (default-Tailwind blue/indigo, stock Bootstrap, the AI-landing gradient) must stay HIGH, andconformanceto the project's own fingerprint — stored as a sharedfingerprintledger claim viamintProjectFingerprint— must stay LOW;uiGatefailures are actionable per-feature edits, never a bare score. Scale-conformance checks (spacing-on-base, radius/shadow level caps, palette bound) joinASSERTABLE_CHECKS.forge uicheckgainsfingerprint <file...> [--mint]anddesign <file...>(exit 1 on fail) alongside the unchanged contrast math. -
Local dashboard (P7 of the substrate-v2 plan).
forge dash [--port N]serves a read-only lens on the substrate's state: anode:httpstdlib server (localhost-only, zero runtime deps) with ONE self-contained HTML page — inline CSS/JS, no CDN, no framework, no build step. Panels: Ledger (claims with val bars, kind filter, contested claims — val ∈ [0.4, 0.6] with ≥1 contradiction — and per-author trust), Cost/Cache (stage counters + measured saved-token estimates from.forge/metrics.jsonl), and Impact (atlas blast-radius explorer via/api/impact?target=X). Every claim row shows itsforge ledger blame <id>command — no unexplained scores anywhere in the UI. Data is separated from serving (dashData()vsserve()insrc/dash.js) so the payload is tested without sockets, and corrupt/missing stores degrade to empty sections instead of taking down the lens. The ratify/retract POSTs are a follow-up; this phase never writes. -
Measured cost report (P8 of the substrate-v2 plan).
forge cost --stages [--json]computes per-stage cost factors as pure arithmetic over.forge/metrics.jsonl(src/cost_report.js): gate halt rate, tier-weighted cache hit rate (exact 1.0 / near 0.85 / adapt 0.5), route saving priced against the always-premium baseline, and context assembly — then composesC = C₀ · Π(1 − fᵢ)over ONLY the measured stages. A stage with no events reports "no data", never a default; the composed figure is a lower bound whose caveats name every unmeasured stage; the paper's 62 % routing figure is cited as context, and ~90 % appears only as a labeled target.substrateChecknow meters the assumption gate on the explicit path (onegatehalt/pass line per decision; ambient hooks stay write-free),recordGate/recordRoutegive future stage wiring one obvious call each, andreports/cost-eval.mdscaffolds the paired-run harness report with a truthful empty state. -
Proof-carrying reuse cache (P3 of the substrate-v2 plan).
forge reuseturns "reuse already-generated code" from prose into a deterministic system: verified code becomes anartifactclaim keyed by a normalized task fingerprint (volatile literals → typed placeholders; MinHash sketch + 16×8 LSH banding for near-match), looked up through the exact → near → adapt → miss ladder. An artifact serves ONLY while its proof holds — confidence above the 0.6 floor (an unverified mint sits at the 0.5 prior and does not serve) and every declared dependency still resolving in the atlas; a failed revalidation appends agraph.revalcontradiction, so stale code demotes itself for the whole team.forge reuse query|mint|stats, a reuse stage inforge substrate(read-only on the ambient hook path), andsrc/metrics.js— the stage-tagged.forge/metrics.jsonlthe cost model's measured savings are computed from. Thereuse-firstskill now calls the cache before advising a repo search. -
Team memory (P2 of the substrate-v2 plan). The PCM ledger becomes shared:
forge ledger merge <path>performs the conflict-free semilattice merge of any other ledger tree (a teammate's checkout, a worktree, a backup) — identical knowledge minted independently converges to one claim with every author preserved in its provenance log.forge ledger blame <id>is the accountability view (every mint, every oracle outcome, every retraction, per-author trust).forge ledger query "<text>"ranks live claims by the paper's Eq. 3. Every claim, evidence record, and tombstone now carries the git identity (FORGE_AUTHORoverride; cached; best-effort). Per-author trustu(author) ∈ [0.5, 1]is computed from the oracle track record of the claims an author minted — smoothed to 1.0 for new teammates, floored at 0.5, self-confirmation excluded — and optionally weightsval().forge doctornow checks the union-merge driver is present (a populated ledger without it WILL conflict) and the ledger's normal form.
- PCM ledger hardened after an 8-angle adversarial review of the P1 merge. The
conflict-free-merge guarantee is now structural: claim file bytes are a pure function of
(kind, body, scope) — byte-identical on every replica — while provenance and tombstones
move into per-claim append-only logs (hash-deduped, union-merged like evidence), so
concurrent mints and concurrent retractions can never produce a git conflict or a
merge-order-dependent state. Forged evidence is now powerless AND detectable:
val()takes oracle weights from the ORACLES table (never the stored record) and skips unknown oracles, whileforge ledger verifyrecomputes every record's content hash and flags mismatches, ghost oracles, and inflated weights.forge ledger importis truly idempotent (claims already tracked live are never re-synthesized — no double counting). Cortex shadow-writes: distillation now supersedes (evidence carried over, template claim tombstoned); evidence refs carry the confirmation counter so same-day sessions with colliding episode ids stay distinct; regex-detected reverts contradict at the conservative bridge weight instead of the full-weight human oracle. Fact claims: one CRLF-tolerant parser (recall.readFact), trimmed bodies (shadow path and import path mint one id), same-name updates supersede the stale claim, andforge recall consolidatereconciles deletions into tombstones.putClaimrepairs corrupt/truncated claim files instead of trustingexistsSync.forge ledger --personalreaches the personal ledger (previously write-only);forge ledger showresolves by shard instead of scanning;forge initemits the union-merge.gitattributesrule into consumer repos.SCOPE_WEIGHThas one home (ledger core; lessons re-exports).
- Substrate v2 plan: the whitepaper, completed (
docs/plans/substrate-v2/). Nine specs- two ADRs mapping every remaining paper faculty/mechanism to a concrete algorithm, unified
by the Proof-Carrying Memory (PCM) protocol: every stored unit (lesson, fact, cached
artifact, graph edge, design fingerprint, diagnosis) becomes a content-addressed claim whose
confidence is a decayed Beta posterior over independent-oracle outcomes — retrieval implements
the paper's Eq. 3, team memory is a conflict-free CRDT ledger merged over git, code reuse is a
proof-carrying artifact cache, context assembly is a token-budget knapsack with a set-cover
completeness gate, and generated-UI quality is a measurable slop-distance/conformance gate.
ADR-0005 relaxes the zero-dependency rule to selective optional deps with stdlib fallbacks;
ADR-0006 converges all persistence on the PCM ledger.
ROADMAP.mdnow carries the P1–P8 phase plan. Docs only — no runtime behavior changes.
- two ADRs mapping every remaining paper faculty/mechanism to a concrete algorithm, unified
by the Proof-Carrying Memory (PCM) protocol: every stored unit (lesson, fact, cached
artifact, graph edge, design fingerprint, diagnosis) becomes a content-addressed claim whose
confidence is a decayed Beta posterior over independent-oracle outcomes — retrieval implements
the paper's Eq. 3, team memory is a conflict-free CRDT ledger merged over git, code reuse is a
proof-carrying artifact cache, context assembly is a token-budget knapsack with a set-cover
completeness gate, and generated-UI quality is a measurable slop-distance/conformance gate.
ADR-0005 relaxes the zero-dependency rule to selective optional deps with stdlib fallbacks;
ADR-0006 converges all persistence on the PCM ledger.
- Visual flow diagrams in the entry-point docs. A "one source → every tool + pre-action gate"
mermaid in
README.mdand a "your day with Forge" loop inONBOARDING.md(alongside the propose→verify diagram in the substrate README) — making the model easier to grasp at a glance, while preserving the docs' existing dry-precise voice.
- Proof-Carrying Memory ledger (P1 of the substrate-v2 plan).
src/ledger.js— the pure PCM core (ADR-0006): content-addressed claims over canonical JSON, an oracle taxonomy in which only independent signals (tests, CI, human accept/revert) may move confidence, a time-decayed Beta-posteriorvalthat decays toward uncertainty (never toward false), the paper's Eq. 3 retrieval score, dependency-free MinHash similarity + union-find consolidation clustering, and a join-semilattice merge (property-tested: commutative, associative, idempotent — teammate ledgers converge in any order).src/ledger_store.js— the git-native on-disk ledger (.forge/ledger/): one immutable file per claim sharded by id, append-only hash-deduped evidence logs (union-merge safe, see.gitattributes), tombstones, attic,LEDGER.mdindex, and a CI-friendly normal-formverify.forge ledger stats|verify|show|importCLI. The legacy stores stay the read path in P1: cortex shadow-writes every lesson event (create/confirm/ human-revert contradiction) into the ledger,forge remember/forge recall addshadow facts, andforge ledger importback-fills history idempotently (src/ledger_bridge.js). Secret-refusal now lives in the ledger core so no claim kind can store a credential (re-exported fromrecall.jsfor compatibility). - Uniform
--json.doctor,route,preflight,verify, andscopenow accept--json(previously onlyimpact/substrate/anchordid) — so CI and scripts can gate on the health check, the routed tier, the assumption gap, and the verification result. forge doctorsees more silent misconfiguration. New checks: guard scripts present and executable,jq/gitavailability (several guards degrade withoutjq), atlas presence + freshness (a stale graph misleads impact/verify), and model-pricing staleness (warns when the verified date is >90 days old).- Evaluation harness (
src/eval.js). The deterministic core of the prototype's mutation-testing idea: score the impact oracle's precision/recall/F1 over labeled cases and against the edited-file-only baseline the paper measured against — so the graph-quality claim is checkable in CI.
-
Model tiers carry a currency + a verified date.
model_tiers.jsexportsPRICING_CURRENCY("USD") andPRICING_VERIFIED, whichforge doctoruses for the staleness warning. -
One shared call-site extractor (
src/extract.js).atlas.jsandverify.jseach kept their own copy of the call regex + builtins ignore-list; they now share one module so the two can't drift apart. -
Opt-in enforcing gate (
FORGE_ENFORCE=1). The substrate's assumption gate can now be a real halt (the paper's Eq 5 / M2 "block on insufficient input"), not just advice. On the Claude Code ambient path it blocks a prompt with no concrete anchor at all ("fix it", "make it better") — or an action into a very large predicted blast radius — and returns the clarifying questions. Deliberately low-false-positive: a specified task is never blocked, and it's off by default (enforceDecision()insrc/substrate.js). -
M5 anti-over-engineering is now measured, not guessed (
forge lean). The paper'sφ(y) − φ*(x)check replaces the old three-keyword stub:src/lean.jsreads the working diff and flags the footprint beyond what the task asked for — new abstractions the task never named, a large diff for a short ask, files touched beyond the stated scope. Folded intoforge substrate(aminimality.footprintfield) and available standalone asforge lean "<task>". -
Doom-loop breaker (self-correction). Complements the shell guard (which catches the same action repeated) by catching the subtler loop the paper names — different edits that keep producing the same test failure.
cortex_hooknow captures a normalized signature of failing test output;detectDoomLoopfires when one signature recurs past a threshold, and the pre-edit hook surfaces a "stop and find the root cause" advisory with the diagnosis. -
Consequence simulation — failing-tests class (Eq 4).
forge substratenow predicts the tests likely to break before an edit (impact.predictedTests): the impacted files that are tests, plus each impacted source file's sibling test — surfaced so you run the narrowest affected tests first, not after the fact.
forge syncnow adopts an existing projectCLAUDE.mdinstead of skipping it. Previously a repo with its ownCLAUDE.mdwas left untouched — which meant Forge's shared rules never reached Claude Code there. Sync now prepends the one-line@AGENTS.mdimport (idempotent, every original line preserved) and reportsadopted.AGENTS.mdkeeps its back-up-then-write behaviour; your skills and other tool files are untouched.
- The Cortex capture/learn loop now works in the dotfile install too.
global/settings.template.jsonwired onlycortex.sh preflight(1 of 6 modes), so dotfile users got the substrate advisory but never captured events or distilled lessons — the learning loop was dead for them while plugin users had it. The template now wires all six modes (session-start,prompt,preflight,pre-edit,capture,stop), matchinghooks/hooks.json. forge verifycan't hang.runTestsnow bounds the test run with a timeout (FORGE_VERIFY_TIMEOUT_MS, default 10 min); a timeout is reported honestly as "did not complete", never as a pass.- Secret-refusal no longer guts auth-related work.
SECRET_REmatched the bare wordssecret/password/api key, so any task or lesson merely mentioning them was silently refused — disabling the LLM proposer (adjudicate) and blocking memory persistence (recall/lessons) for exactly the high-risk code you most want help on. The word arm now requires a value-shaped assignment (password = "…",SECRET_KEY: …); credential formats (sk-…,ghp_…, JWTs, …) are still refused. - One malformed file no longer takes down memory.
lessons_store.load/readEpisodesandcortex_hook.readSessionnow skip a corrupt lesson file / JSONL line instead of throwing (which previously broke retrieval, routing, and the pre-edit advisory everywhereloadis used). recordMistakereportsrefused(notcreated) when a save is rejected, so the Stop hook never tries to distill a phantom lesson;applyDistillation/recordContradictionsurface the real write result too.- Atlas emits
inheritsedges (class X extends Y; Pythonclass X(Base)) — the weight was defined but never produced, so base-class changes were invisible to blast-radius. - Atlas is incremental + staleness-aware.
build()reuses per-file extraction by content hash (a sidecar cache) instead of re-parsing the whole repo;isStale()letsverifyrebuild when the cached graph is out of date (post-edit hallucination detection was running on a stale atlas). A capped graph now degrades to "uncertain" rather than raising false "unknown symbol". - Performance:
resolveEdgesis O(E) (was O(E·N) — a full node scan per edge);impact()reuses one memoized reverse-adjacency map across the up-to-8 calls persubstraterun. substrateno longer recomputes preflight twice (or fires a redundant assumption model call): the gap is computed once and threaded into routing.
- Opt-in LLM adjudication for the substrate (
FORGE_LLM=1) — one shared, fail-safeclaude -pproposer (src/adjudicate.js) wired thinly into the assumption gate (M2), model routing (M1), impact/blast-radius, and goal-drift (M4). The model only proposes; every proposal is verified against the deterministic rubric, the code graph, or a grep before it can move a verdict. Off by default — behaviour is unchanged unless enabled — never blocks, and the ambient Claude Code hook stays deterministic unlessFORGE_LLM_AMBIENT=1.forge substrate --jsoncarries anllm.provenancemap per faculty for auditability. - Bidirectional verified reconcile (default on when
FORGE_LLM=1;llm.bidirectionalinsource/substrate.jsonto disable). A verified reading may now reduce caution as well as add it — clear a false "ASK FIRST" (llm-cleared) and route a task down a tier (llm-lowered) — but only withinbandand never past the hard floors: the gate can't clear a task with no concrete anchor or one naming symbols/files the repo lacks, and routing can't drop below a strong-signal (algorithmic/architectural) floor. Setllm.bidirectional: falsefor the conservative tighten-/raise-only mode. Impact edges stay graph-+-grep-verified; goal-drift stays off→on with a goal-referencing reason. - Explicit memory
valterm — lesson retrieval now decomposes into the white paper'srelevance × freshness × validity × scope, withvalidity()(a ground-truth Beta posterior over confirmed vs. contradicted outcomes) exported and ranked so outcome-confirmed lessons outrank merely-recent ones.
- Unified the model-call path — the Cortex distiller now shares the
adjudicaterunner instead of its ownclaudeshell-out.
0.4.0 - 2026-07-06
- Forge Cognitive Substrate — one pre-action command (
forge substrate) plus an MCP surface (substrate_check,predict_impact,assumption_gate,route_task,scope_files): assumption gate, transparent model routing, impact/blast-radius, scope decomposition, Cortex lessons, minimality, and a verification checklist. - M4 goal-anchoring (
forge anchor) — a deterministic goal-drift check that flags changed files off the stated goal. All 11 white-paper capabilities now ship a real mechanism. - Atlas v2 graph — dependency nodes/edges + reverse-dependency impact traversal (the symbol-query API is preserved).
docs/GUIDE.md(the complete command guide) anddocs/RELEASING.md(release runbook).- Repo automation —
repo-settings.yml(About/topics/Discussions as code) andlabels.yml(label sync) workflows; a Codex plugin manifest andcognitive-substrateskill; the paper bundle underdocs/cognitive-substrate/.
- Publish to public npm.
@codewithjuber/forgekitnow publishes to npmjs with provenance, sonpm install -g @codewithjuber/forgekitneeds no token (replacing the GitHub Packages route, which required auth even for public installs). The release workflow was fixed to trigger on a tag, publish, and cut a GitHub Release with generated notes. - Substrate auto-runs in Claude Code via a
UserPromptSubmithook — it surfaces only when something needs attention and never blocks — andforge initemits a "run substrate before risky work" rule into every other tool's config. - Docs overhaul — README rewritten (problem → solution → how, npm-first, SEO-friendly); the install, honest-limits, frozen-model, and substrate blocks are single-sourced instead of copied across files; the supported-tool list is reconciled everywhere.
- Security (research prototype): removed the pickle-based cache in
impact_oracle/world_model.py— an insecure-deserialization (RCE) vector on a caller-suppliedcache_dir. Now JSON node-link only, withcache_dircontained insideroot. - Smaller npm package — stopped publishing the ~2 MB paper bundle and the redundant
*_src.zip(source lives unzipped underresearch/). - Perf —
substrateCheckno longer recomputes the assumption assessment.
0.3.1 - 2026-07-05
- Publish to GitHub Packages instead of npmjs. Package renamed to the scoped
@codewithjuber/forgekit;publishConfig.registry→https://npm.pkg.github.com. The release workflow now authenticates with the built-inGITHUB_TOKEN(packages: write) — no externalNPM_TOKENsecret. A committed.npmrcmaps the scope to the registry and setsmin-release-age=7(supply-chain cooldown). Note: GitHub Packages requires consumers to authenticate even for public installs, so thebash install.shclone path stays the friction-free primary channel.
0.3.0 - 2026-07-05
- Forge Preflight — a deterministic, math-first layer that runs BEFORE tokens are spent,
on the premise that an LLM is a fixed-capacity stochastic predictor: size the task to the
model, fill the context, detect assumptions. All advisory, never blocks.
- Assumption detector (
forge preflight, UserPromptSubmit hook): scans a task for code identifiers/files the repo doesn't define — what the model would otherwise ASSUME — and surfaces the known-unknowns so it asks instead of confabulating. The research whitespace. - Complexity routing (
forge route): recommends the cheapest CAPABLE model (Haiku → Sonnet → Opus → Fable) from code-task signals (files, fan-out, churn, past-mistake density, ambiguity).forge route gatewayemits a LiteLLM config for real auto-routing. - Decomposition (
forge scope): a zero-dep import graph → connected components → independent clusters (run as separate sessions) + the coupled files you didn't name. - Design-quality: emitted AI-UX rules (anti-slop, WCAG, functional empty states, specific
errors, confidence/transparency, pattern selection) +
forge uicheck(exact WCAG contrast math) + a calibrated frontend-verifier that ASSERTS only the deterministic and keeps hierarchy/taste ADVISORY (the fix for hallucinated UI audits). - Cross-tool via
preflight_check/route_task/scope_filesMCP tools.
- Assumption detector (
0.2.0 - 2026-07-05
- Forge Cortex — self-correcting project memory. Detects a genuine recurring mistake
on this repo (test-fail→fix, revert, symbol thrash, explicit human undo), distills a
structured lesson, and re-confirms it against independent outcomes — with an
anti-self-reinforcement lifecycle (
Betaconfidence + decay; injection never confirms; a green build always wins) so a wrong lesson decays out instead of ossifying.forge cortex,forge cortex why <symbol>. - Ambient hooks (fail-safe, never block): capture signals during a session, distill at
Stop, inject learned lessons atSessionStart, and aPreToolUseadvisory before a risky edit. - Local error predictor (heuristic + a tiny logistic model) gated by an AUC-PR kill-switch — it only ships if it measurably beats the heuristic; otherwise it falls back or disables.
- Cross-tool: lessons inlined into
AGENTS.md+ a zero-dependency MCP server (forge cortex-mcp, registered insource/mcp.json). - Optional LLM lesson distiller (
ENABLE_CORTEX_DISTILL=1) — replaces the deterministic template with a real distilled lesson viaclaude -p. forge doctorreports Cortex lesson state;forge cataloglists Cortex.
0.1.0 - 2026-07-05
- Cross-tool config emitter (
forge sync) — one source → each tool's native format; three install channels (Claude plugin + marketplace, installer, npm);forge doctor; code-graph (atlas);leandiscipline; guard/skill/crew layers. - Verification layer:
forge verify(tests + hallucinated-symbol catch + provenance), doom-loop breaker guard, bias-safeindependent-revieweragent. - Security gate:
forge scan(skill-gate),secret-redactguard, structuredpermissionDecisioninprotect-paths,forge harden(gitleaks + sandbox). - Cross-tool MCP emit; portable memory (
forge brain/forge remember); design-taste menu (forge taste);forge specspec-lock + OpenSpec wiring; MCP ~6-server hygiene check; coverage + type-checking (tsc --checkJs); 2026 production-standard rules; OWASP-LLM / NIST SSDF / SLSA control mapping.