Skip to content

feat: substrate-v2 P5–P8 — loop closure, UI quality gate, forge dash, measured cost report#30

Merged
CodeWithJuber merged 9 commits into
masterfrom
claude/whitepaper-implementation-plan-x8f7bh
Jul 7, 2026
Merged

feat: substrate-v2 P5–P8 — loop closure, UI quality gate, forge dash, measured cost report#30
CodeWithJuber merged 9 commits into
masterfrom
claude/whitepaper-implementation-plan-x8f7bh

Conversation

@CodeWithJuber

Copy link
Copy Markdown
Owner

What & why

The final four phases of the substrate-v2 plan (#24), built in parallel by four isolated worktree agents and integrated here. With this, every phase of the whitepaper-completion roadmap (P0–P8) is implemented.

P5 — loop closure (src/diagnose.js, src/imagine.js, + anchor/verify extensions)

  • forge diagnose "<error>" — failure signatures (line numbers/addresses/timestamps/abs-paths normalized out) counted in a 50-entry ring; the 3rd identical hit is thrash: a content-addressed diagnosis claim is minted into the team ledger and the agent is told to stop retrying and escalate one tier with the diagnosis as the prompt's head. Two sessions (or teammates) hitting the same loop converge on one claim.
  • forge imagine "<task>" — the static half of the paper's consequence simulator (Eq. 4): blast radius → predicted breaks with confidence + the minimal dry-run suite via weighted greedy set cover + riskScore. (Sandboxed worktree runner = documented follow-up.)
  • anchor.cusum() (M4): one-sided CUSUM control chart — sustained small drift alarms, a single exploratory spike drains. verify.checkpointCadence() (M6): the optimal-stopping check-cadence rule, clamped [1, 50].

P6 — generated-UI quality gate (src/uifingerprint.js, uicheck v2)

  • Deterministic design fingerprints from CSS/Tailwind-class parsing (palette HSL + hue histogram, spacing base via residual-minimizing GCD, radii/shadow levels, font families). Slop distance to three documented generic-template signatures + conformance to a stored project fingerprint claim; actionable violations, never a bare score. forge uicheck fingerprint|design, four new assertable checks, legacy contrast usage kept working.

P7 — forge dash (src/dash.js, src/dash.html)

  • Zero-dep localhost dashboard: ledger browser with val bars and contested claims, author-trust bars, cache/cost stage counters, blast-radius explorer. Data layer (dashData) split from serving and tested; the page is fully self-contained (asserted by test). Every number carries its provenance affordance (forge ledger blame <id>).

P8 — measured cost report (src/cost_report.js, forge cost --stages)

  • Per-stage factors computed from .forge/metrics.jsonl only — a stage with no events reports "no data", never an invented number; composition over measured stages is framed as a lower bound; the paper's 62% is cited as context, and the only "90" in the output is labeled target (unmet until measured). Gate metering wired into substrateCheck (explicit path only). reports/cost-eval.md scaffold with a truthful empty state.

The integration test that matters: P6's gate initially failed P7's dashboard — cool blue-gray neutrals sat 0.091 from the tailwind-default signature. The palette was warmed to the brand ember and the glow flattened; slop distance is now 0.43 and the gate passes. The system caught template-drift in its own output before any human did. (Known P6 limitation surfaced by this: the extractor doesn't resolve var() indirection — noted for the taste-profile follow-up.)

Checklist

  • npm test passes (363/363 — 68 new across the four phases; each phase's suite was green in its own worktree before integration and the union is green after)
  • npm run check passes on changed files (remaining diagnostics pre-date these phases)
  • New public functions have a test
  • Conventional commit messages (feat: per phase, merge commits for integration)
  • CHANGELOG.md updated under ## [Unreleased] (one bullet per phase)
  • No new runtime dependency
  • Substrate/docs updated — implements specs 0508 of docs/plans/substrate-v2/

Risk & rollback

  • Risk level: low-medium — new modules dominate; existing-path touches are the substrate gate metering (explicit-path-only, try/caught), the uicheck subcommand routing (legacy usage tested), and the cost --stages early-return (default path byte-identical)
  • Rollback plan: revert the merge commits; .forge/trace/ and metrics files are inert data

Extra checks (tick if applicable)

  • npm run typecheck passes (0 errors)
  • Input validated at boundaries (CLI usage errors on every new command; port validated; corrupt stores degrade, never throw)
  • Logs contain no secrets/PII (diagnose redacts secret-shaped error heads before persisting)
  • If AI-assisted: I understand it, verified the package APIs, and it has tests

🤖 Generated with Claude Code

https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs


Generated by Claude Code

claude added 9 commits July 7, 2026 17:13
…ed metrics

Per-stage cost factors computed as pure arithmetic over .forge/metrics.jsonl
(src/cost_report.js): gate halt rate, tier-weighted cache hit rate, route saving
priced against the always-premium baseline, and context assembly. Composition
C = C0 * prod(1 - f_i) runs over ONLY the measured stages — an eventless stage
reports measured:false / value:null and lands in the caveats, never a default.
The render cites the paper's 62% routing figure as context (not a local
measurement) and prints ~90% only as a labeled target.

substrateCheck now meters the assumption gate on the explicit path (halt/pass,
try/catch best-effort; ambient hooks stay write-free, same contract as
reuseQuery vs reusePeek). recordGate/recordRoute give future stage wiring one
obvious call each. reports/cost-eval.md scaffolds the paired-run harness report
with a truthful no-data-yet state and the commands that populate it.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…t radius (P7)

One self-contained page (src/dash.html: inline CSS/JS, no CDN, no framework,
no build step) served by a node:http stdlib server, localhost-only by default,
zero runtime deps. src/dash.js separates DATA from SERVING: dashData(root)
builds the whole /api/data payload (ledger stats + claims capped at 200 with
val/evidence/author, contested claims — val in [0.4,0.6] with >=1 contradiction
— author trust, metrics summary + recent-events tail, atlas presence) and
degrades corrupt/missing stores to empty sections instead of throwing;
serve(root) wires GET /, /api/data, and /api/impact?target=X (404 otherwise,
GET-only — the ratify/retract POSTs are a later phase).

Panels per docs/plans/substrate-v2/08-dashboard-ux.md: Ledger (val bars, kind
filter, contested section, per-author trust), Cost/Cache (stage counters and
measured saved-token estimates from .forge/metrics.jsonl), Impact (atlas
blast-radius explorer). Every claim row carries its provenance affordance —
click-to-copy `forge ledger blame <id8>` — so no number in the UI is
unexplained. Taste discipline: one accent (the brand ember, not framework
blue), a 4px spacing scale, two radius levels, system sans + one mono.

CLI: `forge dash [--port N]` prints the URL and stays alive serving.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
…rift, checkpoint cadence

Four loop-closure faculties from docs/plans/substrate-v2/06-faculties-and-mechanisms.md:

- forge diagnose (src/diagnose.js): failure signatures (sha256 of the normalized
  error + file + symbol, volatile parts stripped) counted in a 50-entry ring
  (.forge/trace/failures.jsonl, corrupt-tolerant); the 3rd identical hit mints a
  content-addressed `diagnosis` claim into the team ledger and directs the agent
  to stop retrying and escalate one model tier with the diagnosis as the prompt's
  head (spec §5).
- forge imagine (src/imagine.js): the static half of the consequence simulator
  (Eq. 4) — entities → blast radius → predicted breaks with confidence, plus the
  minimal dry-run suite via weighted greedy set cover (weight = file size;
  ln-n approximation) and riskScore = Σ confidence. The sandboxed worktree runner
  is the documented P5 follow-up (spec §2).
- anchor.cusum(): one-sided CUSUM control chart (k=0.35, h=1.0) — sustained small
  drift alarms, a single within-tolerance spike drains back to zero (spec §5, M4).
- verify.checkpointCadence(): the optimal-stopping threshold rule
  n* = ⌈checkCost / (pErr·tokensPerStep·costPerToken)⌉ clamped to [1, 50] —
  every input measured or priced (spec §6, M6).

Tests: 319 (31 new), typecheck clean, biome clean on touched files.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
… project conformance (P6)

Taste becomes measurable (guard-over-prose applied to design). New
src/uifingerprint.js extracts a deterministic design fingerprint from
CSS/JSX/Tailwind classes — pure static parsing, zero LLM calls, zero
screenshots: HSL palette + 12-bin hue histogram, spacing with an
approximate-GCD base unit (residual minimization over 2/4/8) and
on-scale fraction, font families, radius and shadow levels.

Two distances gate generated UI: slopDistance to a shipped,
rationale-documented generic-template signature set (default-Tailwind
blue/indigo, stock Bootstrap, the AI-landing gradient) must stay high;
conformance to the project's own fingerprint — stored as a shared
"fingerprint" ledger claim via mintProjectFingerprint — must stay low.
uiGate emits actionable per-feature violations, never a bare score.

Scale-conformance checks (spacing-on-base within ε, radius/shadow level
caps, palette bound) join uicheck's ASSERTABLE_CHECKS; the executable
versions live in uifingerprint.scaleChecks under the same ids
(drift-tested). forge uicheck gains `fingerprint <file...> [--mint]
[--json]` and `design <file...> [--json]` (exit 1 on fail); the
existing contrast surface is unchanged and also reachable as
`uicheck contrast <fg> <bg>`.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
The P6 gate judged the P7 dashboard 'too close to the tailwind-default
template' (slop distance 0.091 < 0.25): cool blue-gray neutrals and a
single soft glow. Warmed the dark neutrals to the brand ember's hue and
flattened the glow — slop distance now 0.43, gate PASSES. The dashboard
is the reference customer of the taste discipline, and the gate catching
it first is the discipline working.

Known P6 limitation surfaced by this: the CSS extractor doesn't resolve
var() indirection, so spacing tokens defined once as custom properties
count as a single value — noted for the taste-profile follow-up.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fc2MvWJbQ1cyNQ76ymv4hs
@CodeWithJuber CodeWithJuber marked this pull request as ready for review July 7, 2026 19:11
@CodeWithJuber CodeWithJuber merged commit eb68ea9 into master Jul 7, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants