@@ -8,6 +8,23 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
88
99### Added
1010
11+ - ** Loop closure (P5 of the substrate-v2 plan): doom-loop diagnosis, imagination, CUSUM
12+ drift, checkpoint cadence.** ` forge diagnose "<error>" ` hashes each failure into a
13+ signature (line numbers, addresses, timestamps, and absolute paths normalized out) and
14+ counts recurrences in a 50-entry ring; the 3rd identical hit is thrash — it mints a
15+ content-addressed ` diagnosis ` claim into the team ledger and tells the agent to STOP
16+ retrying and escalate ONE model tier with the diagnosis as the prompt's head (the same
17+ loop becomes a one-per-team event, not one-per-session). ` forge imagine "<task>" ` is the
18+ static half of the consequence simulator (paper Eq. 4): entities → blast radius →
19+ predicted breaks with confidence, plus the minimal dry-run test suite via weighted greedy
20+ set cover (weight = file size as a duration proxy; classic ln-n approximation) and
21+ ` riskScore = Σ confidence ` — the sandboxed worktree runner that executes the suite is the
22+ P5 follow-up. ` anchor.cusum() ` adds the M4 one-sided CUSUM control chart (k = 0.35,
23+ h = 1.0): sustained small drift alarms, a single exploratory spike drains back to zero.
24+ ` verify.checkpointCadence() ` prices M6's "when to check?" as the optimal-stopping
25+ threshold rule ` n* = ⌈checkCost / (pErr·tokensPerStep·costPerToken)⌉ ` , clamped to
26+ [ 1, 50] — every input measured or priced, no magic constants.
27+
1128- ** Context assembly + completeness gate (P4 of the substrate-v2 plan).** `forge context
1229 "<task >"` makes what goes into the window a budgeted optimization and makes
1330 * sufficiency* a computed set. The required-knowledge set ` R(edit) ` — the target's
@@ -20,6 +37,43 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
2037 implements it?"), shown in ` forge substrate ` and — under ` FORGE_ENFORCE=1 ` — blocking:
2138 acting on missing context is acting on a guess. Incomplete context stops being a
2239 feeling and starts being a set difference.
40+ - ** Generated-UI quality gate (P6 of the substrate-v2 plan).** Taste becomes measurable:
41+ ` src/uifingerprint.js ` extracts a deterministic design fingerprint from CSS/JSX/Tailwind
42+ classes — pure static parsing, no LLM, no screenshots — covering palette (HSL + 12-bin hue
43+ histogram), spacing (base unit by residual-minimization approximate GCD, on-scale
44+ fraction), font families, radius and shadow levels. Two distances gate generated UI:
45+ ` slopDistance ` to a shipped, rationale-documented generic-template signature set
46+ (default-Tailwind blue/indigo, stock Bootstrap, the AI-landing gradient) must stay HIGH,
47+ and ` conformance ` to the project's own fingerprint — stored as a shared ` fingerprint `
48+ ledger claim via ` mintProjectFingerprint ` — must stay LOW; ` uiGate ` failures are
49+ actionable per-feature edits, never a bare score. Scale-conformance checks
50+ (spacing-on-base, radius/shadow level caps, palette bound) join ` ASSERTABLE_CHECKS ` .
51+ ` forge uicheck ` gains ` fingerprint <file...> [--mint] ` and ` design <file...> ` (exit 1 on
52+ fail) alongside the unchanged contrast math.
53+ - ** Local dashboard (P7 of the substrate-v2 plan).** ` forge dash [--port N] ` serves a
54+ read-only lens on the substrate's state: a ` node:http ` stdlib server (localhost-only,
55+ zero runtime deps) with ONE self-contained HTML page — inline CSS/JS, no CDN, no
56+ framework, no build step. Panels: Ledger (claims with val bars, kind filter, contested
57+ claims — val ∈ [ 0.4, 0.6] with ≥1 contradiction — and per-author trust), Cost/Cache
58+ (stage counters + measured saved-token estimates from ` .forge/metrics.jsonl ` ), and
59+ Impact (atlas blast-radius explorer via ` /api/impact?target=X ` ). Every claim row shows
60+ its ` forge ledger blame <id> ` command — no unexplained scores anywhere in the UI. Data
61+ is separated from serving (` dashData() ` vs ` serve() ` in ` src/dash.js ` ) so the payload
62+ is tested without sockets, and corrupt/missing stores degrade to empty sections instead
63+ of taking down the lens. The ratify/retract POSTs are a follow-up; this phase never
64+ writes.
65+ - ** Measured cost report (P8 of the substrate-v2 plan).** ` forge cost --stages [--json] `
66+ computes per-stage cost factors as pure arithmetic over ` .forge/metrics.jsonl `
67+ (` src/cost_report.js ` ): gate halt rate, tier-weighted cache hit rate (exact 1.0 / near
68+ 0.85 / adapt 0.5), route saving priced against the always-premium baseline, and context
69+ assembly — then composes ` C = C₀ · Π(1 − fᵢ) ` over ONLY the measured stages. A stage with
70+ no events reports "no data", never a default; the composed figure is a lower bound whose
71+ caveats name every unmeasured stage; the paper's 62 % routing figure is cited as context,
72+ and ~ 90 % appears only as a labeled target. ` substrateCheck ` now meters the assumption
73+ gate on the explicit path (one ` gate ` halt/pass line per decision; ambient hooks stay
74+ write-free), ` recordGate ` /` recordRoute ` give future stage wiring one obvious call each,
75+ and ` reports/cost-eval.md ` scaffolds the paired-run harness report with a truthful
76+ empty state.
2377
2478- ** Proof-carrying reuse cache (P3 of the substrate-v2 plan).** ` forge reuse ` turns
2579 "reuse already-generated code" from prose into a deterministic system: verified code
0 commit comments