22 KiB
Chronology v2 Redo — Design Spec
Date: 2026-07-01
Track ID: chronology_v2_20260701
Priority: A (meta-tooling / infrastructure)
Status: design (pre-spec)
Ancestors:
conductor/tracks/chronology_20260619/spec.md(the v2 rewrite spec, 354 lines — designed but never executed)docs/reports/2026-06-15/CHRONOLOGY_TRACK_HANDOVER_20260620.md(the v1 failure report, 128 lines)docs/reports/2026-06-15/CHRONOLOGY_MIGRATION_20260619.md(the v1 migration report)docs/reports/2026-06-15/TRACK_COMPLETION_chronology_20260619.md(the v1 end-of-track report)
Overview
The chronology_20260619 track produced a broken conductor/chronology.md (v1):
167 of 216 rows had wrong status (the classifier read stale metadata.json.status
instead of git history), summaries were metadata-field text instead of track
descriptions, and the per-row cross-check was bypassed. A v2 rewrite was specced
and planned in detail but never executed. The track sits at current_phase=10
pending user sign-off that never came, blocking superpowers_review_20260619.
This track is the redo: a fresh track that closes out the old one, adopts the v2 design as a starting point, revises it for the current project state (5+ days of desync, new track patterns, the tracks.md bloat), and executes it through to a user sign-off that is actionable this time.
What v1 Got Wrong (from the records)
Per CHRONOLOGY_TRACK_HANDOVER_20260620.md:
_classify_status()readsmetadata.json.status— a stale field set when each track was created, rarely updated when work completed or was abandoned. 167/216 rows had wrong status.- Summaries are metadata-field text (
**Priority:** A (foundational...),**Date:** 2026-06-20) not actual track descriptions. - Phase 8 per-row cross-check was bypassed in favor of bulk structural verification; the manual summary-adequacy check was partial (15-row sample).
- Phase 6 user review gate was bypassed in the autonomous session.
- No quality gate to detect a broken classifier before the chronology ships.
- No maintenance plan — the chronology desynced within days because nobody regenerated it after new tracks shipped.
The five lessons from the handover (lines 88-98):
- Bypassing the manual review clause was the original sin.
metadata.jsonis a snapshot, not a source of truth.- Git history is the project's audit log — use it.
- Default to "when in doubt, ask" — the chronology is read by humans.
- The user said "manual review" twice; both times an interpretation was found to be less strict — listen to the literal request.
Goals
- Produce a correct
conductor/chronology.mdwhere every row's status is backed by git-history evidence, not stale metadata. - Produce a per-row evidence artifact (the quality report) so the user can audit the classification without re-deriving it.
- Close out
chronology_20260619(mark superseded, archive, unblocksuperpowers_review_20260619). - De-gunk
conductor/tracks.md— remove shipped/completed tracks from the active queue, remove the Phase 0-9 history sections that duplicate chronology.md, leave only the active queue + standby + a pointer. - Add a
conductor/workflow.mdmaintenance rule so the chronology is regenerated after each track ships (closes the desync root cause). - Ship a quality-gate script that catches a broken classifier before it ships (closes the "no quality gate" root cause).
Non-Goals
- Fixing or executing
superpowers_review_20260619(just unblocking it). - Changing how
metadata.json.statusis maintained going forward (the classifier uses git history, not metadata; metadata staleness is no longer the problem). - Archiving the 66 folders in
conductor/tracks/that are already shipped (separate cleanup; the chronology indexes them regardless of location). - Renaming or restructuring
conductor/archive/(out of scope; the chronology walks it as-is). - A broader
workflow.mdreview for other stale rules (the only workflow.md change is the chronology maintenance section).
Design
1. New track identity + old track close-out
New track: chronology_v2_20260701 (Priority A; meta-tooling/infrastructure).
Fresh track, not a continuation of chronology_20260619.
Old track close-out (Phase 1):
- Mark
chronology_20260619as superseded in itsstate.toml(status = "superseded",current_phase = 10, add a[supersession]section pointing tochronology_v2_20260701). - Update its tracks.md row (line 64) to reflect supersession.
- Archive
conductor/tracks/chronology_20260619/→conductor/archive/chronology_20260619/. The v2 spec/plan are preserved in git history; the new track references them by commit SHA. - Unblock
superpowers_review_20260619— removechronology_20260619from itsstate.toml[blocked_by]entirely (no re-gating on the new track).
v2 design adoption: The new track's spec explicitly cites
conductor/tracks/chronology_20260619/spec.md (the v2 rewrite spec) and
CHRONOLOGY_TRACK_HANDOVER_20260620.md (the failure report) as its design
ancestors. It adopts the v2 status enum, the git-history classifier approach,
and the quality-gate concept — with the revisions below.
2. The six revisions to v2
Revision 1 — The desync gap (regenerate from current filesystem)
v2 was specced when the newest track was ~2026-06-20. The chronology now needs
to cover 5+ more days of tracks: the layout saga
(default_layout_install_20260629, default_layout_extract_20260629,
default_layout_install_followup_20260629), the MMA quarantine
(mma_quarantine_rag_test_decoupling_20260701), the module_taxonomy abort +
cleanup (module_taxonomy_refactor_20260627, post_module_taxonomy_de_cruft_20260627),
cruft_elimination_20260627, directive_hotswap_harness_20260627,
enforcement_gap_closure_20260627, test_engine_integration_20260627,
fix_mma_concurrent_tracks_sim_20260627, type_alias_unfuck_20260626,
video_analysis_campaign_2_20260627.
Change: The new track's first generation pass runs against the current
filesystem (all conductor/tracks/ + conductor/archive/ as of execution
day), not the 2026-06-19 snapshot. The generation script walks both directories
fresh each run.
Revision 2 — superpowers_review_20260619 blocker resolution
v2 didn't address this because it was rewriting the same track in place. The
new track explicitly closes out chronology_20260619 and removes it from
superpowers_review_20260619/state.toml [blocked_by] (no re-gating).
Revision 3 — Classifier heuristics updated for recent track patterns
v2's 5-step git-history algorithm was designed 2026-06-20. Since then, new patterns emerged that it would misclassify:
- Aborted tracks (
module_taxonomy_refactor_20260627): manyconductor(track):+conductor(plan):commits but aTRACK_ABORTED_*.mdreport — classifier must detect the abort report as anAbandoned/Supersededsignal. - Phase 9 patches after "completion" (
result_migration_cruft_removal_20260620): a track that "shipped" then got a patch commit days later — classifier must look at the latest commit, not just count. - Tier 2 autonomous tracks: produce many
conductor(plan):commits (one per task) — the "feat/fix/refactor vs chore/docs" heuristic must not countconductor(plan):as a work commit. - Follow-up tracks (
default_layout_install_followup_20260629): short, few commits, but legitimatelyCompleted— the "0-1 commits + >14 days old = Abandoned" rule would misfire.
Change: The classifier's commit-message pattern list is extended:
conductor(plan):,conductor(state):,conductor(track):,docs(spec):,docs(plan):are metadata commits, not work commits (don't count toward the "≥3 work commits = Completed" threshold).feat:,fix:,refactor:,perf:,test:,docs(report):are work commits.- Presence of
TRACK_ABORTED_*.mdorTRACK_COMPLETION_*.mdindocs/reports/matching the track ID is a strong signal that overrides commit-count heuristics. - The "last commit > 14 days = Abandoned" rule is removed; replaced with "no work commits AND no completion/abort report = Needs Review".
- Confidence is reported per-row; anything below a threshold goes to the Needs Review queue for manual classification.
Revision 4 — tracks.md de-gunk
v2's scope was only chronology.md. The new track also restructures
conductor/tracks.md:
Current state (96KB, bloated):
- 60-row "Active Tracks (Current Queue)" table — ~40 of these rows are shipped/completed tracks that belong in history, not the active queue.
- Phase 0-9 chronological sections with Completed/Archived subsections — duplicates chronology.md.
- 4 backlog/follow-up sections — some entries are shipped, some pending.
- "Recently Shipped Tracks (2026-06-29)" section at the bottom.
Target state:
- Section 1: Active Queue — only tracks that are genuinely unblocked and
ready to start OR in-progress. Shipped tracks are removed (they're in
chronology.md). Each row:
| # | Priority | Track | Status | Blocked By |(same columns, filtered to active-only). - Section 2: Standby / Pending Spec — tracks with spec TBD or pending decision (the backlog). Same columns.
- Section 3: Pointer — one line:
> Full project history: see [chronology.md](./chronology.md) - Delete: Phase 0-9 sections, Completed/Archived subsections, backlog/ follow-up sections that duplicate chronology.md, the "Recently Shipped" section, the "Archived (Closed 2026-06-23)" video analysis section.
- Keep: the "Editing this file" / archiving convention notes at the bottom (from v1 Phase 4).
Migration safety: the full tracks.md is preserved in git history; the
de-gunk is a single commit. If anything is lost,
git show HEAD~1:conductor/tracks.md recovers it.
Revision 5 — workflow.md maintenance rule
v2 had no maintenance plan (the root cause of the desync). The new track adds
a section to conductor/workflow.md:
New subsection under "Documentation Refresh Protocol" (or a new top-level section "Chronology Maintenance"):
Chronology regeneration cadence. After every track ships (completion commit + TRACK_COMPLETION report), the implementing agent must run
uv run python scripts/audit/generate_chronology.pyto regenerateconductor/chronology.md. The regeneration is a single atomic commit (docs(chronology): regenerate after <track-id> shipped). If the regeneration produces a diff beyond the new row (e.g., status changes on other rows), the agent must investigate before committing — a status drift on an unrelated row indicates a stale classifier, not a chronology bug.Quality gate.
scripts/audit/chronology_quality_gate.pyruns as part of the regeneration. It fails (exit 1) if >30% of rows are classified asNeeds Review. A failing quality gate blocks the regeneration commit.
This makes regeneration a per-track-shipping obligation, not a one-shot.
Revision 6 — Report(s)
Two reports:
docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md— the standard end-of-track report (what was done, files changed, verification results).docs/reports/CHRONOLOGY_QUALITY_20260701.md— the chronology-quality report (new, not in v1). Contents:- Total rows generated + breakdown by status (Active / In Progress / Completed / Abandoned / Superseded / Special / Needs Review)
- Confidence distribution (high / medium / low)
- The Needs Review queue (list of rows that need manual classification, with the evidence the classifier found)
- Comparison vs v1 (row count delta, status-correction count: "N rows changed status vs v1")
- The desync gap closed (list of tracks added that were missing from v1)
- Classifier heuristics summary (which patterns matched, which were overridden by completion/abort reports)
The quality report is the evidence artifact — it's what makes this track auditable rather than "trust the script." v1 failed because there was no quality gate and no evidence per row; this report is the fix.
3. Architecture — the generation script + quality gate
scripts/audit/generate_chronology.py (rewritten)
Inputs: conductor/tracks/ + conductor/archive/ (walked fresh each
run); git log per folder for commit evidence; docs/reports/TRACK_COMPLETION_*.md
TRACK_ABORTED_*.mdfor override signals.
Extraction pipeline (per folder):
- Date — slug date from folder name (regex, unchanged from v1).
- ID — folder name (unchanged).
- Status — the new classifier (see below), returns
(status, confidence, reason). - Summary — rewritten extractor: rejects lines starting with
**Priority:**,**Date:**,**Initialized:**,**Track:**,**Parent umbrella:**,**Status:**,**Confidence:**; prefersmetadata.json.descriptionif it's actual prose (not metadata-field text); falls back to first non-heading, non-metadata line ofspec.md; truncates to 25 words. - Folder — path (unchanged).
- Range —
git log --oneline -- <folder>→ first + last SHA + count.
The new classifier (_classify_status, returning (status, confidence, reason)):
Evidence sources, in priority order:
- Override signals (highest confidence):
TRACK_COMPLETION_*.mdexists indocs/reports/matching this track ID →Completed, confidence=high, reason="completion report found".TRACK_ABORTED_*.mdexists →Abandoned, confidence=high, reason="abort report found". (Ifstate.tomlalso sayssuperseded, theSupersededclassification wins — see next row.)state.tomlstatus = "superseded"→Superseded, confidence=high (overrides the abort-report signal if both exist).
- Git commit evidence (medium confidence):
- Count work commits (
feat/fix/refactor/perf/test/docs(report):prefixes) viagit log --oneline -- <folder>, excluding metadata commits (conductor(plan):,conductor(state):,conductor(track):,docs(spec):,docs(plan):). - ≥3 work commits →
Completed, confidence=medium, reason="N work commits". - 1-2 work commits + in
tracks/→In Progress, confidence=medium. - 0 work commits + in
tracks/→Active(spec/plan only), confidence=medium.
- Count work commits (
- Directory location (low confidence):
- In
archive/+ no override signal →Completed, confidence=low, reason="archived but no completion report". - In
archive/+ 0 commits →Abandoned, confidence=low, reason="archived with 0 commits".
- In
- Fallback:
Needs Review, confidence=none, reason="classifier inconclusive".
Status enum: Active / In Progress / Completed / Abandoned /
Superseded / Special / Needs Review (7 values; v2 had 5, adding
Superseded + Needs Review).
Output format: Markdown table with 6 columns (Date, ID, Status, Summary,
Folder, Range) + a "Needs Review" section at the bottom listing rows with
Needs Review status, each with its evidence reason. Sorted newest-first. A
preamble header with generation date + row count.
scripts/audit/chronology_quality_gate.py (new)
Purpose: detect a broken classifier before the chronology ships.
Checks:
- Needs Review threshold: if >30% of rows are
Needs Review, exit 1 (the classifier is failing on too many rows). - Status distribution sanity: if 0 rows are
Completed, exit 1 (the classifier is misclassifying everything). - Summary quality: if >20% of summaries still contain metadata-field
text (
**Priority:**etc.), exit 1 (the summary extractor is broken). - Per-row evidence: every row must have a non-empty
reasonfrom the classifier; if any row has no reason, exit 1.
Modes: default informational (exits 0, prints report); --strict CI
gate (exits 1 on any violation). Follows the project's audit-script
convention (per conductor/workflow.md "Audit Script Policy").
Tests (TDD)
tests/test_generate_chronology.py (rewritten) +
tests/test_chronology_quality_gate.py (new). Tests for:
- The classifier's 7 status values + the evidence priority chain (override signals > git evidence > directory > fallback).
- The summary extractor's rejection of metadata-field lines.
- The quality gate's 4 checks.
- Edge cases: aborted tracks with completion reports (override conflict), tracks with 0 commits, archive folders with no metadata.json.
4. Execution plan structure (phases)
6 phases, each a checkpoint with atomic per-task commits.
Phase 1: Close out the old track + scaffold the new one
- Task 1.1: Update
chronology_20260619/state.toml→status = "superseded", add[supersession]section. Commit. - Task 1.2: Update
chronology_20260619row in tracks.md (line 64) to "superseded bychronology_v2_20260701". Commit. - Task 1.3: Archive
conductor/tracks/chronology_20260619/→conductor/archive/chronology_20260619/. Commit. - Task 1.4: Update
superpowers_review_20260619/state.toml[blocked_by]— removechronology_20260619entirely. Commit. - Task 1.5: Create
conductor/tracks/chronology_v2_20260701/withspec.md,metadata.json,state.toml,plan.md. Commit.
Phase 2: TDD the classifier + quality gate (Red)
- Task 2.1: Write
tests/test_generate_chronology.py— tests for the 7-status classifier, evidence priority chain, summary extractor. Red. - Task 2.2: Write
tests/test_chronology_quality_gate.py— tests for the 4 quality-gate checks. Red.
Phase 3: Implement the classifier + quality gate (Green)
- Task 3.1: Rewrite
scripts/audit/generate_chronology.py— the new_classify_statusreturning(status, confidence, reason), the rewritten summary extractor, the git-history evidence pipeline. Green. - Task 3.2: Create
scripts/audit/chronology_quality_gate.py— the 4 checks +--strictmode. Green.
Phase 4: Regenerate chronology.md + write the quality report
- Task 4.1: Run the generator against the current filesystem. Capture
output to
conductor/chronology.md(replacing v1). Commit. - Task 4.2: Run the quality gate. If it fails, iterate on the classifier (back to Phase 3) until it passes. Commit the passing state.
- Task 4.3: Write
docs/reports/CHRONOLOGY_QUALITY_20260701.md— the quality report. Commit.
Phase 5: De-gunk tracks.md + add workflow.md maintenance rule
- Task 5.1: Restructure
conductor/tracks.md— remove shipped/completed rows from the active queue, remove Phase 0-9 history sections, remove backlog/follow-up sections that duplicate chronology.md, add the pointer to chronology.md, keep the "Editing this file" notes. Single commit. - Task 5.2: Add the "Chronology Maintenance" section to
conductor/workflow.md— the regeneration cadence + quality gate obligation. Commit.
Phase 6: Verification + end-of-track report
- Task 6.1: Run the quality gate
--strictmode. Confirm exit 0. Commit. - Task 6.2: Verify the Needs Review queue is empty or small (the user reviews any remaining rows). Commit.
- Task 6.3: Write
docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md. Commit. - Task 6.4: User sign-off (the final gate — same as v1's Phase 10, but this time the quality report + evidence per row makes it actionable).
Commit strategy
- Per-task atomic commits (no batching).
- Git notes per commit (task summary).
- Phase checkpoints after each phase (per the workflow protocol).
Verification Criteria
conductor/chronology.mdexists with one row per track folder (tracks/- archive/), sorted newest-first, 6 columns, generated from the current filesystem (no 2026-06-19 snapshot pin).
- Every row's status is backed by git-history evidence (not
metadata.json.status); the evidencereasonis non-empty for every row. - No summary contains metadata-field text (
**Priority:**,**Date:**,**Initialized:**,**Track:**,**Parent umbrella:**,**Status:**,**Confidence:**). scripts/audit/chronology_quality_gate.py --strictexits 0.conductor/tracks.mdcontains only the active queue + standby/pending + a pointer to chronology.md + the "Editing this file" notes. No Phase 0-9 history sections, no shipped-track rows in the active queue.conductor/workflow.mdcontains the "Chronology Maintenance" section (regeneration cadence + quality gate obligation).docs/reports/CHRONOLOGY_QUALITY_20260701.mdexists with the status distribution, confidence distribution, Needs Review queue, v1 comparison, desync gap list, and heuristics summary.docs/reports/TRACK_COMPLETION_chronology_v2_20260701.mdexists.chronology_20260619is archived (inconductor/archive/) withstatus = "superseded"in its state.toml.superpowers_review_20260619/state.toml[blocked_by]no longer containschronology_20260619.tests/test_generate_chronology.py+tests/test_chronology_quality_gate.pypass.- User sign-off recorded in the TRACK_COMPLETION report.
Risks
- R1 (medium): The git-history classifier may still misclassify some
edge cases (e.g., tracks with
conductor(checkpoint):commits only). Mitigation: the Needs Review queue surfaces these for manual classification; the quality gate fails if >30% are Needs Review. - R2 (medium): The tracks.md de-gunk may accidentally remove a row
that's still active. Mitigation: the full tracks.md is preserved in git
history; recovery is
git show HEAD~1:conductor/tracks.md. - R3 (low): The workflow.md maintenance rule may not be followed by future agents. Mitigation: the rule is in the operational workflow doc that agents read at session start; the quality gate catches a desync when the next regeneration runs.
Out of Scope
- Fixing or executing
superpowers_review_20260619(just unblocking it). - Changing how
metadata.json.statusis maintained going forward. - Archiving the 66 folders in
conductor/tracks/that are already shipped. - Renaming or restructuring
conductor/archive/. - A broader
workflow.mdreview for other stale rules. - The
superpowers_review_20260619track's execution.