# 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`: 1. **`_classify_status()` reads `metadata.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. 2. **Summaries are metadata-field text** (`**Priority:** A (foundational...)`, `**Date:** 2026-06-20`) not actual track descriptions. 3. **Phase 8 per-row cross-check was bypassed** in favor of bulk structural verification; the manual summary-adequacy check was partial (15-row sample). 4. **Phase 6 user review gate was bypassed** in the autonomous session. 5. **No quality gate** to detect a broken classifier before the chronology ships. 6. **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): 1. Bypassing the manual review clause was the original sin. 2. `metadata.json` is a snapshot, not a source of truth. 3. Git history is the project's audit log — use it. 4. Default to "when in doubt, ask" — the chronology is read by humans. 5. The user said "manual review" twice; both times an interpretation was found to be less strict — listen to the literal request. ## Goals 1. Produce a correct `conductor/chronology.md` where every row's status is backed by git-history evidence, not stale metadata. 2. Produce a per-row evidence artifact (the quality report) so the user can audit the classification without re-deriving it. 3. Close out `chronology_20260619` (mark superseded, archive, unblock `superpowers_review_20260619`). 4. 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. 5. Add a `conductor/workflow.md` maintenance rule so the chronology is regenerated after each track ships (closes the desync root cause). 6. 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.status` is 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.md` review 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_20260619` as superseded in its `state.toml` (`status = "superseded"`, `current_phase = 10`, add a `[supersession]` section pointing to `chronology_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`** — remove `chronology_20260619` from its `state.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`): many `conductor(track):` + `conductor(plan):` commits but a `TRACK_ABORTED_*.md` report — classifier must detect the abort report as an `Abandoned`/`Superseded` signal. - **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 count `conductor(plan):` as a work commit. - **Follow-up tracks** (`default_layout_install_followup_20260629`): short, few commits, but legitimately `Completed` — 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_*.md` or `TRACK_COMPLETION_*.md` in `docs/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.py` to regenerate > `conductor/chronology.md`. The regeneration is a single atomic commit > (`docs(chronology): regenerate after 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.py` runs as part > of the regeneration. It fails (exit 1) if >30% of rows are classified as > `Needs 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: 1. **`docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md`** — the standard end-of-track report (what was done, files changed, verification results). 2. **`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_*.md` for override signals. **Extraction pipeline (per folder):** 1. **Date** — slug date from folder name (regex, unchanged from v1). 2. **ID** — folder name (unchanged). 3. **Status** — the new classifier (see below), returns `(status, confidence, reason)`. 4. **Summary** — rewritten extractor: rejects lines starting with `**Priority:**`, `**Date:**`, `**Initialized:**`, `**Track:**`, `**Parent umbrella:**`, `**Status:**`, `**Confidence:**`; prefers `metadata.json.description` if it's actual prose (not metadata-field text); falls back to first non-heading, non-metadata line of `spec.md`; truncates to 25 words. 5. **Folder** — path (unchanged). 6. **Range** — `git log --oneline -- ` → first + last SHA + count. **The new classifier (`_classify_status`, returning `(status, confidence, reason)`):** Evidence sources, in priority order: 1. **Override signals (highest confidence):** - `TRACK_COMPLETION_*.md` exists in `docs/reports/` matching this track ID → `Completed`, confidence=high, reason="completion report found". - `TRACK_ABORTED_*.md` exists → `Abandoned`, confidence=high, reason="abort report found". (If `state.toml` also says `superseded`, the `Superseded` classification wins — see next row.) - `state.toml` `status = "superseded"` → `Superseded`, confidence=high (overrides the abort-report signal if both exist). 2. **Git commit evidence (medium confidence):** - Count work commits (`feat/fix/refactor/perf/test/docs(report):` prefixes) via `git log --oneline -- `, 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. 3. **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". 4. **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 `reason` from 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_20260619` row in tracks.md (line 64) to "superseded by `chronology_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]` — remove `chronology_20260619` entirely. Commit. - Task 1.5: Create `conductor/tracks/chronology_v2_20260701/` with `spec.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_status` returning `(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 + `--strict` mode. 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 `--strict` mode. 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 1. `conductor/chronology.md` exists with one row per track folder (tracks/ + archive/), sorted newest-first, 6 columns, generated from the current filesystem (no 2026-06-19 snapshot pin). 2. Every row's status is backed by git-history evidence (not `metadata.json.status`); the evidence `reason` is non-empty for every row. 3. No summary contains metadata-field text (`**Priority:**`, `**Date:**`, `**Initialized:**`, `**Track:**`, `**Parent umbrella:**`, `**Status:**`, `**Confidence:**`). 4. `scripts/audit/chronology_quality_gate.py --strict` exits 0. 5. `conductor/tracks.md` contains 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. 6. `conductor/workflow.md` contains the "Chronology Maintenance" section (regeneration cadence + quality gate obligation). 7. `docs/reports/CHRONOLOGY_QUALITY_20260701.md` exists with the status distribution, confidence distribution, Needs Review queue, v1 comparison, desync gap list, and heuristics summary. 8. `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md` exists. 9. `chronology_20260619` is archived (in `conductor/archive/`) with `status = "superseded"` in its state.toml. 10. `superpowers_review_20260619/state.toml` `[blocked_by]` no longer contains `chronology_20260619`. 11. `tests/test_generate_chronology.py` + `tests/test_chronology_quality_gate.py` pass. 12. 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.status` is maintained going forward. - Archiving the 66 folders in `conductor/tracks/` that are already shipped. - Renaming or restructuring `conductor/archive/`. - A broader `workflow.md` review for other stale rules. - The `superpowers_review_20260619` track's execution.