Multi-phase Gantt visualization for proof timeline

The pipeline Gantt chart on proof detail pages always renders 4 bars (Think, Plan, Build, Verify) regardless of how many phases a proof went through. A 3-phase proof like content-pages (108 minutes across 3 build/verify cycles) shows a single "Build 57m" bar and "Verify 30m" bar — hiding that phase 1 took 32+7 minutes, phase 2 took 14+13 minutes, and phase 3 took 11+10 minutes. The temporal shape of the pipeline run is invisible.

verdict PASSscore 22 / 22findings 9 (1 risk · 1 debt · 7 obs)duration 5h 8mrejection cycles 0shipped May 14, 2026

Pipeline timeline

Intent to proven code in 5h 8m across Think, Plan, Build, and Verify.

Think
2m
Plan
7m
Build
13m
Verify
6m

Assertion ledger

22 claims, each independently verified. Showing 8 — show all →

IDSaysMatcher
A001Multi-phase proofs include per-phase timing segments in the proof chainverifiedok
A002Each segment records which pipeline stage it representsverifiedok
A003Build and verify segments include their phase numberverifiedok
A004Segments are ordered temporally from think through final verifyverifiedok
A005Three-phase segments follow think, plan, build-1, verify-1, build-2, verify-2, build-3, verify-3 orderverifiedok
A006Three-phase build segment 3 has phase number 3verifiedok
A007Segment minutes match the per-phase duration from save timestampsverifiedok
A008Single-phase proofs do not include timing segmentsverifiedok

Findings 9 total

debtpackages/cli/tests/utils/proofSummary.test.tsclosed
Gantt bar assertions (A014-A018, A022) test a re-implemented copy of buildGanttBars, not the production function in PipelineGantt.tsx
obswebsite/components/docs/proof/PipelineGantt.tsxclosed
buildGanttBars and GanttBar exported from PipelineGantt.tsx but never imported — YAGNI exports for potential cross-package testing that doesn't happen
obswebsite/components/docs/proof/PipelineGantt.tsxclosed
OPACITY_MAP duplicates opacity values already in STAGES array — two sources of truth for the same constants
obspackages/cli/src/commands/proof.tspromoted
formatHumanReadable exported solely for test access — was previously private, scope widened for testing
obswebsite/app/docs/proof/[slug]/page.tsxclosed
Multi-phase timeline text derives phase count via Math.max on filtered segments — works correctly but couples rendering to segment internals when entry.phases field exists for this purpose
+4more findings

Integrity seal

scopesha256:d9e45a144ef07...
contractsha256:460e8b3f42f3d...
plansha256:eb1fa686d36a1...
specsha256:8ed5dbd7fb16a...
build-reportsha256:7d446d7f9ef3d...
build-datasha256:90f37cda086f9...
verify-reportsha256:46d20eab27ac5...
verify-datasha256:a9f4f83446545...
audit cmd$ ana proof audit gantt-multi-phase   → all hashes match