# Chronology v2 Redo Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Replace the broken v1 `conductor/chronology.md` (167/216 rows with wrong status, stale-metadata classifier) with a correct v2 that uses git-history evidence, close out the stuck `chronology_20260619` track, de-gunk `conductor/tracks.md`, and add a maintenance rule to `conductor/workflow.md` so the chronology doesn't desync again. **Architecture:** Rewrite `scripts/audit/generate_chronology.py` with a 4-tier evidence-priority classifier (override signals > git work-commits > directory location > fallback) returning `(status, confidence, reason)`. Add `scripts/audit/chronology_quality_gate.py` with 4 checks + `--strict` mode. Regenerate `conductor/chronology.md` from the current filesystem. Restructure `conductor/tracks.md` to active-queue + standby + pointer only. Add a "Chronology Maintenance" section to `conductor/workflow.md`. **Tech Stack:** Python 3.11+, stdlib `pathlib`/`json`/`re`/`subprocess`, `tomllib` for TOML parsing, pytest for TDD, 1-space indentation per project convention. **Design spec:** `docs/superpowers/specs/2026-07-01-chronology-v2-redo-design.md` --- ## File Structure | File | Action | Responsibility | |---|---|---| | `conductor/tracks/chronology_20260619/state.toml` | Modify | Mark as superseded | | `conductor/tracks.md` | Modify | Update old track row (Phase 1); de-gunk entirely (Phase 5) | | `conductor/archive/chronology_20260619/` | Create (move) | Archived old track | | `conductor/tracks/superpowers_review_20260619/state.toml` | Modify | Remove blocked_by entry | | `conductor/tracks/chronology_v2_20260701/` | Create | New track folder (spec/metadata/state/plan) | | `tests/test_generate_chronology.py` | Rewrite | TDD tests for the new classifier + summary extractor | | `tests/test_chronology_quality_gate.py` | Create | TDD tests for the 4 quality-gate checks | | `scripts/audit/generate_chronology.py` | Rewrite | The new git-history classifier + summary extractor + walk | | `scripts/audit/chronology_quality_gate.py` | Create | The 4-check quality gate with `--strict` mode | | `conductor/chronology.md` | Regenerate | The v2 output (replaces v1) | | `conductor/workflow.md` | Modify | Add "Chronology Maintenance" section | | `docs/reports/CHRONOLOGY_QUALITY_20260701.md` | Create | The quality report (status distribution, Needs Review queue, v1 comparison) | | `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md` | Create | The end-of-track report | --- ## Phase 1: Close out the old track + scaffold the new one ### Task 1.1: Mark `chronology_20260619` as superseded in its state.toml **Files:** - Modify: `conductor/tracks/chronology_20260619/state.toml` (lines 1-10, the `[meta]` section) - [ ] **Step 1: Read the current state.toml to confirm exact content** Run: `Get-Content conductor/tracks/chronology_20260619/state.toml | Select-Object -First 12` Expected: shows `status = "active"` and `current_phase = 10` in the `[meta]` section. - [ ] **Step 2: Edit the `[meta]` section** Use `manual-slop_edit_file` to replace: ``` status = "active" # remains "active" until Phase 10 user sign-off recorded current_phase = 10 # Phase 10 in progress; user sign-off pending last_updated = "2026-06-20" ``` with: ``` status = "superseded" # superseded by chronology_v2_20260701 per user directive 2026-07-01 current_phase = 10 # Phase 10 sign-off never recorded; track closed as superseded last_updated = "2026-07-01" ``` - [ ] **Step 3: Add a `[supersession]` section at the end of the file** Append: ``` [supersession] superseded_by = "chronology_v2_20260701" superseded_date = "2026-07-01" superseded_reason = "v1 chronology had 167/216 rows with wrong status (stale metadata.json.status classifier); v2 rewrite was specced but never executed; user directed a fresh track with the v2 design as ancestor" ``` - [ ] **Step 4: Verify the edit** Run: `Get-Content conductor/tracks/chronology_20260619/state.toml | Select-String 'superseded'` Expected: 2 matches (the `status` line + the `[supersession]` section). - [ ] **Step 5: Commit** ```bash git add conductor/tracks/chronology_20260619/state.toml git commit -m "conductor(chronology): mark chronology_20260619 as superseded by chronology_v2_20260701" ``` ### Task 1.2: Update `chronology_20260619` row in tracks.md **Files:** - Modify: `conductor/tracks.md` (line 64, the chronology row in the active queue) - [ ] **Step 1: Read the current row to confirm exact content** Run: `Get-Content conductor/tracks.md | Select-Object -Index 63` Expected: the row starting with `| 21 | A | [Conductor Chronology...` - [ ] **Step 2: Replace the row** Use `manual-slop_edit_file` to replace the entire row with: ``` | 21 | — | ~~[Conductor Chronology (chronology.md canonical index)]~~ | **SUPERSEDED** by `chronology_v2_20260701` (2026-07-01); v1 produced 167/216 wrong-status rows; v2 rewrite specced but never executed; archived to `conductor/archive/chronology_20260619/` | — | ``` - [ ] **Step 3: Commit** ```bash git add conductor/tracks.md git commit -m "conductor(tracks): mark chronology_20260619 row as superseded" ``` ### Task 1.3: Archive the old track folder **Files:** - Move: `conductor/tracks/chronology_20260619/` → `conductor/archive/chronology_20260619/` - [ ] **Step 1: Move the folder with git mv** Run: `git mv conductor/tracks/chronology_20260619 conductor/archive/chronology_20260619` Expected: no output (success). - [ ] **Step 2: Verify the move** Run: `Test-Path conductor/archive/chronology_20260619/state.toml` Expected: `True`. Run: `Test-Path conductor/tracks/chronology_20260619` Expected: `False`. - [ ] **Step 3: Commit** ```bash git add -A conductor/tracks/chronology_20260619 conductor/archive/chronology_20260619 git commit -m "conductor(chronology): archive chronology_20260619 folder (superseded)" ``` ### Task 1.4: Unblock `superpowers_review_20260619` **Files:** - Modify: `conductor/tracks/superpowers_review_20260619/state.toml` (the `[blocked_by]` section, line ~12) - [ ] **Step 1: Read the current blocked_by section** Run: `Get-Content conductor/tracks/superpowers_review_20260619/state.toml | Select-String 'blocked_by' -Context 0,2` Expected: shows `chronology_20260619 = "active (per user 2026-06-19 directive)"`. - [ ] **Step 2: Remove the blocked_by entry** Use `manual-slop_edit_file` to replace: ``` [blocked_by] chronology_20260619 = "active (per user 2026-06-19 directive)" ``` with: ``` [blocked_by] # chronology_20260619 superseded 2026-07-01; blocker removed per user directive. # superpowers_review is now unblocked. ``` - [ ] **Step 3: Verify the edit** Run: `Get-Content conductor/tracks/superpowers_review_20260619/state.toml | Select-String 'superseded'` Expected: 1 match in the `[blocked_by]` comment. - [ ] **Step 4: Commit** ```bash git add conductor/tracks/superpowers_review_20260619/state.toml git commit -m "conductor(superpowers_review): remove chronology_20260619 blocker (superseded)" ``` ### Task 1.5: Scaffold the new track folder **Files:** - Create: `conductor/tracks/chronology_v2_20260701/spec.md` - Create: `conductor/tracks/chronology_v2_20260701/metadata.json` - Create: `conductor/tracks/chronology_v2_20260701/state.toml` - Create: `conductor/tracks/chronology_v2_20260701/plan.md` - [ ] **Step 1: Create the directory** Run: `New-Item -ItemType Directory -Path conductor/tracks/chronology_v2_20260701 -Force` Expected: directory exists. - [ ] **Step 2: Write spec.md** Copy the design spec from `docs/superpowers/specs/2026-07-01-chronology-v2-redo-design.md` into `conductor/tracks/chronology_v2_20260701/spec.md` (the design spec IS the track spec). Use `manual-slop_read_file` to read the design spec, then `write` tool to create the track spec.md with the same content. - [ ] **Step 3: Write metadata.json** ```json { "track_id": "chronology_v2_20260701", "name": "Chronology v2 Redo (git-history classifier + tracks.md de-gunk + maintenance rule)", "priority": "A", "category": "meta-tooling", "status": "spec_written", "blocked_by": [], "verification_criteria": [ "conductor/chronology.md exists with one row per track folder (tracks/ + archive/), sorted newest-first, 6 columns, generated from the current filesystem", "every row's status is backed by git-history evidence (not metadata.json.status); the evidence reason is 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 --strict exits 0", "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", "conductor/workflow.md contains the 'Chronology Maintenance' section", "docs/reports/CHRONOLOGY_QUALITY_20260701.md exists with status distribution + Needs Review queue + v1 comparison + desync gap list", "docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md exists", "chronology_20260619 is archived with status = superseded in its state.toml", "superpowers_review_20260619/state.toml [blocked_by] no longer contains chronology_20260619", "tests/test_generate_chronology.py + tests/test_chronology_quality_gate.py pass", "user sign-off recorded in the TRACK_COMPLETION report" ] } ``` - [ ] **Step 4: Write state.toml** ```toml # Track state for chronology_v2_20260701 [meta] track_id = "chronology_v2_20260701" name = "Chronology v2 Redo" status = "active" current_phase = 0 last_updated = "2026-07-01" [blocked_by] # Independent track. No blockers. [blocks] # superpowers_review_20260619 was blocked by the old chronology_20260619; # that blocker was removed in Task 1.4. This track does not block anything. [phases] phase_1 = { status = "pending", checkpointsha = "", name = "Close out old track + scaffold new one" } phase_2 = { status = "pending", checkpointsha = "", name = "TDD the classifier + quality gate (Red)" } phase_3 = { status = "pending", checkpointsha = "", name = "Implement the classifier + quality gate (Green)" } phase_4 = { status = "pending", checkpointsha = "", name = "Regenerate chronology.md + write quality report" } phase_5 = { status = "pending", checkpointsha = "", name = "De-gunk tracks.md + add workflow.md maintenance rule" } phase_6 = { status = "pending", checkpointsha = "", name = "Verification + end-of-track report" } [tasks] t1_1 = { status = "pending", commit_sha = "", description = "Mark chronology_20260619 as superseded in state.toml" } t1_2 = { status = "pending", commit_sha = "", description = "Update chronology_20260619 row in tracks.md" } t1_3 = { status = "pending", commit_sha = "", description = "Archive chronology_20260619 folder" } t1_4 = { status = "pending", commit_sha = "", description = "Unblock superpowers_review_20260619" } t1_5 = { status = "pending", commit_sha = "", description = "Scaffold chronology_v2_20260701 track folder" } ``` - [ ] **Step 5: Write plan.md** Copy this plan file to `conductor/tracks/chronology_v2_20260701/plan.md`. Use `manual-slop_read_file` to read `docs/superpowers/plans/2026-07-01-chronology-v2-redo.md`, then `write` tool to create the track plan.md with the same content. - [ ] **Step 6: Commit** ```bash git add conductor/tracks/chronology_v2_20260701/ git commit -m "conductor(track): init chronology_v2_20260701 (spec + metadata + state + plan)" ``` ### Task 1.6: Phase 1 checkpoint commit - [ ] **Step 1: Create checkpoint commit** ```bash git commit --allow-empty -m "conductor(checkpoint): Phase 1 complete (close out old track + scaffold new one)" ``` - [ ] **Step 2: Update state.toml with checkpoint SHA** Run: `git log -1 --format="%H"` to get the checkpoint SHA. Then update `conductor/tracks/chronology_v2_20260701/state.toml`: - `current_phase = 1` → `current_phase = 2` - `phase_1` status → `"completed"`, checkpointsha → the SHA - All `t1_*` tasks → `"completed"` with their commit SHAs - [ ] **Step 3: Commit the state update** ```bash git add conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(state): mark Phase 1 complete for chronology_v2_20260701" ``` --- ## Phase 2: TDD the classifier + quality gate (Red) ### Task 2.1: Write `tests/test_generate_chronology.py` (Red) **Files:** - Rewrite: `tests/test_generate_chronology.py` - [ ] **Step 1: Read the current test file to understand what exists** Run: `Get-Content tests/test_generate_chronology.py` Expected: 6 tests for v1 (`extract_slug_date`, `extract_summary`). - [ ] **Step 2: Write the new test file** Use `write` tool to create `tests/test_generate_chronology.py` with these tests (1-space indentation per project convention): ```python from pathlib import Path import json import pytest from unittest.mock import patch, MagicMock from scripts.audit.generate_chronology import ( extract_slug_date, extract_summary, classify_status, walk_track_folders, format_markdown, ) from scripts.audit.chronology_quality_gate import run_quality_gate def test_slug_date_extraction() -> None: result: str = extract_slug_date("gencpp_python_bindings_20260308") assert result == "2026-03-08" def test_slug_date_extraction_handles_missing_date() -> None: result = extract_slug_date("my_folder") assert result is None def test_summary_extraction_rejects_priority_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Priority:** A (foundational)\n\nReal description of the work.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description of the work." def test_summary_extraction_rejects_date_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Date:** 2026-06-20\n\nReal description.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description." def test_summary_extraction_rejects_initialized_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Initialized:** 2026-06-13\n\nReal description.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description." def test_summary_extraction_rejects_track_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Track:** Some track\n\nReal description.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description." def test_summary_extraction_rejects_parent_umbrella_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Parent umbrella:** result_migration_20260616\n\nReal description.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description." def test_summary_extraction_rejects_confidence_line(tmp_path: Path) -> None: spec_content: str = "# Title\n\n**Confidence:** high\n\nReal description.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description." def test_summary_extraction_prefers_metadata_description_prose(tmp_path: Path) -> None: metadata: dict = {"description": "A real prose description of the track."} (tmp_path / "metadata.json").write_text(json.dumps(metadata), encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "A real prose description of the track." def test_summary_extraction_rejects_metadata_description_field_text(tmp_path: Path) -> None: metadata: dict = {"description": "**Priority:** A (foundational)"} (tmp_path / "metadata.json").write_text(json.dumps(metadata), encoding="utf-8") spec_content: str = "# Title\n\nReal description from spec.\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) assert result == "Real description from spec." def test_summary_extraction_truncates_to_25_words(tmp_path: Path) -> None: long_line: str = " ".join(["word"] * 50) spec_content: str = f"# Title\n\n{long_line}\n" (tmp_path / "spec.md").write_text(spec_content, encoding="utf-8") result: str = extract_summary(tmp_path) expected: str = " ".join(["word"] * 25) + "\u2026" assert result == expected # --- Classifier tests (the new git-history classifier) --- def test_classify_status_completion_report_override(tmp_path: Path) -> None: """TRACK_COMPLETION report in docs/reports/ overrides everything.""" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) assert result[0] == "Completed" assert result[1] == "high" assert "completion report" in result[2] def test_classify_status_abort_report_override(tmp_path: Path) -> None: """TRACK_ABORTED report -> Abandoned.""" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", has_abort_report=True, ) assert result[0] == "Abandoned" assert result[1] == "high" assert "abort report" in result[2] def test_classify_status_superseded_state_toml_overrides_abort(tmp_path: Path) -> None: """state.toml status=superseded wins over abort report.""" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", has_abort_report=True, state_status="superseded", ) assert result[0] == "Superseded" assert result[1] == "high" def test_classify_status_work_commits_completed(tmp_path: Path) -> None: """>=3 work commits -> Completed.""" with patch("scripts.audit.generate_chronology._git_log") as mock_log: mock_log.return_value = "feat: add thing\nfix: fix thing\nrefactor: refactor thing\n" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) assert result[0] == "Completed" assert result[1] == "medium" assert "work commits" in result[2] def test_classify_status_metadata_commits_not_counted_as_work(tmp_path: Path) -> None: """conductor(plan): commits don't count as work commits.""" with patch("scripts.audit.generate_chronology._git_log") as mock_log: mock_log.return_value = "conductor(plan): mark task\nconductor(state): update\nconductor(track): init\n" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) # 0 work commits + in tracks/ -> Active assert result[0] == "Active" def test_classify_status_1_2_work_commits_in_progress(tmp_path: Path) -> None: """1-2 work commits + in tracks/ -> In Progress.""" with patch("scripts.audit.generate_chronology._git_log") as mock_log: mock_log.return_value = "feat: add thing\nfix: fix thing\n" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) assert result[0] == "In Progress" def test_classify_status_archive_no_override_completed_low(tmp_path: Path) -> None: """archive/ + no completion report -> Completed (low confidence).""" result = classify_status( folder_link="conductor/archive/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) assert result[0] == "Completed" assert result[1] == "low" assert "archived" in result[2] def test_classify_status_fallback_needs_review(tmp_path: Path) -> None: """Inconclusive -> Needs Review.""" result = classify_status( folder_link="conductor/tracks/my_track", current="", track_id="my_track", repo_root=tmp_path, reports_dir=tmp_path / "docs/reports", ) assert result[0] == "Needs Review" def test_classify_status_returns_3_tuple() -> None: """Classifier must return (status, confidence, reason).""" result = classify_status( folder_link="conductor/tracks/my_track_20260701", current="active", track_id="my_track_20260701", repo_root=Path("."), reports_dir=Path("docs/reports"), ) assert len(result) == 3 assert isinstance(result[0], str) assert isinstance(result[1], str) assert isinstance(result[2], str) ``` - [ ] **Step 3: Run the tests to verify they fail (Red)** Run: `uv run pytest tests/test_generate_chronology.py -v` Expected: FAIL with `ImportError` (cannot import `classify_status` from `scripts.audit.generate_chronology` — the function doesn't exist yet; the old function is `_classify_status`). - [ ] **Step 4: Commit** ```bash git add tests/test_generate_chronology.py git commit -m "test(chronology): write Red tests for v2 classifier + summary extractor" ``` ### Task 2.2: Write `tests/test_chronology_quality_gate.py` (Red) **Files:** - Create: `tests/test_chronology_quality_gate.py` - [ ] **Step 1: Write the test file** Use `write` tool to create `tests/test_chronology_quality_gate.py`: ```python from pathlib import Path import pytest from scripts.audit.chronology_quality_gate import run_quality_gate, QualityGateResult def _make_row(status: str, confidence: str, reason: str, summary: str) -> dict: return { "status": status, "confidence": confidence, "reason": reason, "summary": summary, "track_id": "test_track", "date": "2026-07-01", "folder_link": "conductor/tracks/test_track", "init_sha": "abc1234", "end_sha": "def5678", "commit_count": 1, } def test_quality_gate_passes_on_good_rows() -> None: rows = [ _make_row("Completed", "high", "completion report found", "A real summary."), _make_row("Completed", "medium", "3 work commits", "Another real summary."), _make_row("Active", "medium", "0 work commits in tracks/", "Spec-only track."), ] result = run_quality_gate(rows) assert result.passed is True assert result.violations == [] def test_quality_gate_fails_on_too_many_needs_review() -> None: rows = [ _make_row("Needs Review", "none", "inconclusive", "Summary 1."), _make_row("Needs Review", "none", "inconclusive", "Summary 2."), _make_row("Completed", "high", "completion report", "Summary 3."), ] # 2/3 = 66% > 30% threshold result = run_quality_gate(rows) assert result.passed is False assert any("Needs Review" in v for v in result.violations) def test_quality_gate_fails_on_zero_completed() -> None: rows = [ _make_row("Active", "medium", "0 work commits", "Summary 1."), _make_row("Active", "medium", "0 work commits", "Summary 2."), ] result = run_quality_gate(rows) assert result.passed is False assert any("0 rows are Completed" in v for v in result.violations) def test_quality_gate_fails_on_metadata_field_summaries() -> None: rows = [ _make_row("Completed", "high", "completion report", "Real summary."), _make_row("Completed", "high", "completion report", "**Priority:** A (foundational)"), ] # 1/2 = 50% > 20% threshold result = run_quality_gate(rows) assert result.passed is False assert any("metadata-field" in v for v in result.violations) def test_quality_gate_fails_on_empty_reason() -> None: rows = [ _make_row("Completed", "high", "", "Real summary."), ] result = run_quality_gate(rows) assert result.passed is False assert any("empty reason" in v for v in result.violations) def test_quality_gate_strict_mode_exits_nonzero(tmp_path: Path) -> None: """The --strict CLI mode exits 1 on violations.""" import subprocess import sys # This test verifies the CLI wrapper; the function-level test is above # We test the function returns the right structure; the CLI is a thin wrapper rows = [_make_row("Active", "medium", "0 work commits", "Summary.")] result = run_quality_gate(rows) assert result.passed is False # 0 rows are Completed assert result.exit_code == 1 ``` - [ ] **Step 2: Run the tests to verify they fail (Red)** Run: `uv run pytest tests/test_chronology_quality_gate.py -v` Expected: FAIL with `ImportError` (cannot import `run_quality_gate` from `scripts.audit.chronology_quality_gate` — the module doesn't exist yet). - [ ] **Step 3: Commit** ```bash git add tests/test_chronology_quality_gate.py git commit -m "test(chronology): write Red tests for quality gate (4 checks)" ``` ### Task 2.3: Phase 2 checkpoint - [ ] **Step 1: Create checkpoint commit** ```bash git commit --allow-empty -m "conductor(checkpoint): Phase 2 complete (Red tests for classifier + quality gate)" ``` - [ ] **Step 2: Update state.toml** Update `conductor/tracks/chronology_v2_20260701/state.toml`: - `current_phase = 2` → `current_phase = 3` - `phase_2` status → `"completed"` with checkpoint SHA - `t2_1`, `t2_2` → `"completed"` with their commit SHAs - [ ] **Step 3: Commit the state update** ```bash git add conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(state): mark Phase 2 complete for chronology_v2_20260701" ``` --- ## Phase 3: Implement the classifier + quality gate (Green) ### Task 3.1: Rewrite `scripts/audit/generate_chronology.py` (Green) **Files:** - Rewrite: `scripts/audit/generate_chronology.py` (the `_classify_status` function at lines 201-228, the `extract_summary` function at lines 62-92, the `walk_track_folders` function at lines 231-290, and the `format_markdown` function at lines 293-304) - [ ] **Step 1: Read the current script to confirm exact structure** Use `manual-slop_py_get_definition` for `_classify_status`, `extract_summary`, `walk_track_folders`, and `format_markdown` to confirm the exact current source. (Already done in plan research; the definitions are at the lines listed above.) - [ ] **Step 2: Rewrite `extract_summary` to reject all 7 metadata-field prefixes** Use `manual-slop_py_update_definition` to replace `extract_summary` with: ```python _METADATA_FIELD_PREFIXES = ( "**Priority:**", "**Date:**", "**Initialized:**", "**Track:**", "**Track ID:**", "**Parent umbrella:**", "**Status:**", "**Confidence:**", ) def extract_summary(folder_path: Path) -> str: md_path = folder_path / "metadata.json" if md_path.is_file(): try: data = json.loads(md_path.read_text(encoding="utf-8")) desc = str(data.get("description", "")).strip() if desc and not desc.startswith(_METADATA_FIELD_PREFIXES): return _truncate_to_25_words(_first_sentence(desc)) except (json.JSONDecodeError, OSError): pass for fname in ("spec.md", "plan.md"): fpath = folder_path / fname if not fpath.is_file(): continue try: text = fpath.read_text(encoding="utf-8") except OSError: continue for line in text.splitlines(): stripped = line.strip() if not stripped: continue if stripped.startswith("#"): continue if stripped.startswith(">"): continue bare = stripped.lstrip(">").strip() if bare.startswith(_METADATA_FIELD_PREFIXES): continue return _truncate_to_25_words(_first_sentence(bare)) return "Imported from archive (no spec)" ``` - [ ] **Step 3: Add the new `classify_status` function** Use `manual-slop_py_add_def` to add a new module-level function after `_classify_status`: ```python _WORK_COMMIT_PREFIXES = ("feat:", "fix:", "refactor:", "perf:", "test:", "docs(report):") _METADATA_COMMIT_PREFIXES = ("conductor(plan):", "conductor(state):", "conductor(track):", "docs(spec):", "docs(plan):") def _count_work_commits(folder_relpath: str) -> int: log: str = _git_log(folder_relpath, "--oneline") count: int = 0 for line in log.splitlines(): msg: str = line.split(" ", 1)[1] if " " in line else "" if msg.startswith(_WORK_COMMIT_PREFIXES) and not msg.startswith(_METADATA_COMMIT_PREFIXES): count += 1 return count def _has_report_matching(reports_dir: Path, track_id: str, prefix: str) -> bool: if not reports_dir.is_dir(): return False for f in reports_dir.iterdir(): if f.is_file() and f.name.startswith(prefix) and track_id in f.name: return True return False def classify_status( folder_link: str, current: str, track_id: str, repo_root: Path, reports_dir: Path, has_abort_report: bool = False, state_status: str = "", ) -> tuple[str, str, str]: """Git-history evidence classifier returning (status, confidence, reason). Evidence priority: 1. Override signals (highest): TRACK_COMPLETION/TRACK_ABORTED reports, state.toml superseded 2. Git commit evidence (medium): work-commit count 3. Directory location (low): archive/ vs tracks/ 4. Fallback: Needs Review """ # 1. Override signals if state_status == "superseded": return ("Superseded", "high", "state.toml status=superseded") if has_abort_report or _has_report_matching(reports_dir, track_id, "TRACK_ABORTED_"): return ("Abandoned", "high", "abort report found") if _has_report_matching(reports_dir, track_id, "TRACK_COMPLETION_"): return ("Completed", "high", "completion report found") # 2. Git commit evidence is_archive = folder_link.startswith("conductor/archive/") is_tracks = folder_link.startswith("conductor/tracks/") work_commits: int = _count_work_commits(folder_link) if work_commits >= 3: return ("Completed", "medium", f"{work_commits} work commits") if 1 <= work_commits <= 2 and is_tracks: return ("In Progress", "medium", f"{work_commits} work commits in tracks/") if work_commits == 0 and is_tracks: return ("Active", "medium", "0 work commits in tracks/ (spec/plan only)") # 3. Directory location if is_archive: if work_commits == 0: return ("Abandoned", "low", "archived with 0 commits") return ("Completed", "low", "archived but no completion report") # 4. Fallback return ("Needs Review", "none", "classifier inconclusive") ``` - [ ] **Step 4: Update `walk_track_folders` to use the new classifier** Use `manual-slop_py_update_definition` to replace `walk_track_folders`. The key changes: - Pass `repo_root` and `reports_dir` to `classify_status` instead of calling the old `_classify_status` - Store `confidence` and `reason` in the row dict alongside `status` ```python def walk_track_folders(root: Path) -> list[dict]: repo_root: Path = _repo_root(root) reports_dir: Path = repo_root / "docs/reports" rows: list[dict] = [] for parent_dir, default_status in ( (root / "tracks", "Active"), (root / "archive", "Completed"), ): if not parent_dir.is_dir(): continue for folder in sorted(parent_dir.iterdir()): if not folder.is_dir(): continue try: folder_relpath = _to_posix(str(folder.relative_to(repo_root))) except ValueError: folder_relpath = _to_posix(str(folder)) track_id: str = folder.name slug_date = extract_slug_date(track_id) if slug_date: date = slug_date else: first_commit = _git_first_line(folder_relpath, "--reverse", "--format=%aI") date = first_commit[:10] if first_commit else "" metadata_path = folder / "metadata.json" meta_status: str = "" if metadata_path.is_file(): try: data = json.loads(metadata_path.read_text(encoding="utf-8")) meta_status = str(data.get("status", "")).strip() except (json.JSONDecodeError, OSError): pass state_status: str = _parse_state_status(folder / "state.toml") status, confidence, reason = classify_status( folder_link=folder_relpath, current=meta_status or default_status, track_id=track_id, repo_root=repo_root, reports_dir=reports_dir, state_status=state_status, ) summary: str = extract_summary(folder) init_sha: str = _git_first_line(folder_relpath, "--reverse", "--format=%h") end_sha: str = _git_first_line(folder_relpath, "-1", "--format=%h") if init_sha and end_sha: range_log = _git_log(folder_relpath, "--oneline", f"{init_sha}..{end_sha}") commit_count: int = range_log.count("\n") + (1 if init_sha != end_sha else 0) else: fallback_log = _git_log(folder_relpath, "--oneline") commit_count = fallback_log.count("\n") try: folder_link = _to_posix(str(folder.relative_to(repo_root))) except ValueError: folder_link = _to_posix(str(folder)) rows.append({ "date": date, "track_id": track_id, "status": status, "confidence": confidence, "reason": reason, "summary": summary, "init_sha": init_sha, "end_sha": end_sha, "commit_count": commit_count, "folder_link": folder_link, }) rows.sort(key=lambda r: r["track_id"]) rows.sort(key=lambda r: r["date"], reverse=True) return rows ``` - [ ] **Step 5: Add `_parse_state_status` helper** Use `manual-slop_py_add_def` to add after `_parse_state_phase`: ```python def _parse_state_status(state_path: Path) -> str: if not state_path.is_file(): return "" try: text = state_path.read_text(encoding="utf-8") except OSError: return "" for line in text.splitlines(): stripped = line.strip() if stripped.startswith("status"): parts = stripped.split("=", 1) if len(parts) == 2: return parts[1].strip().strip('"').strip("'").split("#")[0].strip() return "" ``` - [ ] **Step 6: Update `format_markdown` to include the Needs Review section + preamble** Use `manual-slop_py_update_definition` to replace `format_markdown`: ```python def format_markdown(rows: list[dict]) -> str: from datetime import date as today_date lines: list[str] = [] lines.append(f"") lines.append("") lines.append("| Date | ID | Status | Summary | Folder | Range |") lines.append("| --- | --- | --- | --- | --- | --- |") for r in rows: range_str: str = f"`{r['init_sha']}..{r['end_sha']}` ({r['commit_count']})" if r['init_sha'] else "n/a" lines.append(f"| {r['date']} | `{r['track_id']}` | {r['status']} | {r['summary']} | {r['folder_link']} | {range_str} |") needs_review = [r for r in rows if r["status"] == "Needs Review"] if needs_review: lines.append("") lines.append("## Needs Review") lines.append("") for r in needs_review: lines.append(f"- `{r['track_id']}` ({r['folder_link']}): {r['reason']}") return "\n".join(lines) + "\n" ``` - [ ] **Step 7: Run the tests to verify they pass (Green)** Run: `uv run pytest tests/test_generate_chronology.py -v` Expected: all tests PASS. If tests fail, debug using the actual error output (do not loop more than 2 times per the workflow's deduction-loop rule). Read the source, predict the failure, fix, run once more. - [ ] **Step 8: Commit** ```bash git add scripts/audit/generate_chronology.py git commit -m "feat(chronology): rewrite classifier to use git-history evidence + 7-status enum + Needs Review section" ``` ### Task 3.2: Create `scripts/audit/chronology_quality_gate.py` (Green) **Files:** - Create: `scripts/audit/chronology_quality_gate.py` - [ ] **Step 1: Write the quality gate script** Use `write` tool to create `scripts/audit/chronology_quality_gate.py`: ```python """Quality gate for conductor/chronology.md. Checks: 1. Needs Review threshold: >30% of rows are Needs Review -> FAIL 2. Status distribution sanity: 0 rows are Completed -> FAIL 3. Summary quality: >20% of summaries contain metadata-field text -> FAIL 4. Per-row evidence: every row must have a non-empty reason -> FAIL Modes: default: informational (exits 0, prints report) --strict: CI gate (exits 1 on any violation) """ from __future__ import annotations from dataclasses import dataclass, field from pathlib import Path import argparse import json import sys _METADATA_FIELD_PREFIXES = ( "**Priority:**", "**Date:**", "**Initialized:**", "**Track:**", "**Track ID:**", "**Parent umbrella:**", "**Status:**", "**Confidence:**", ) @dataclass(frozen=True, slots=True) class QualityGateResult: passed: bool exit_code: int violations: list[str] = field(default_factory=list) total_rows: int = 0 needs_review_count: int = 0 completed_count: int = 0 metadata_field_count: int = 0 empty_reason_count: int = 0 def run_quality_gate(rows: list[dict]) -> QualityGateResult: violations: list[str] = [] total: int = len(rows) if total == 0: return QualityGateResult(passed=False, exit_code=1, violations=["0 rows provided"]) needs_review_count: int = sum(1 for r in rows if r.get("status") == "Needs Review") completed_count: int = sum(1 for r in rows if r.get("status") == "Completed") metadata_field_count: int = sum( 1 for r in rows if any(str(r.get("summary", "")).startswith(p) for p in _METADATA_FIELD_PREFIXES) ) empty_reason_count: int = sum(1 for r in rows if not r.get("reason", "").strip()) # Check 1: Needs Review threshold (>30%) if total > 0 and (needs_review_count / total) > 0.30: violations.append( f"Needs Review threshold exceeded: {needs_review_count}/{total} " f"({needs_review_count/total*100:.0f}%) > 30%" ) # Check 2: 0 rows are Completed if completed_count == 0: violations.append("0 rows are Completed (classifier may be misclassifying everything)") # Check 3: Summary quality (>20% contain metadata-field text) if total > 0 and (metadata_field_count / total) > 0.20: violations.append( f"Summary quality: {metadata_field_count}/{total} " f"({metadata_field_count/total*100:.0f}%) contain metadata-field text > 20%" ) # Check 4: Per-row evidence (every row must have non-empty reason) if empty_reason_count > 0: violations.append(f"{empty_reason_count} rows have empty reason (no evidence)") passed: bool = len(violations) == 0 return QualityGateResult( passed=passed, exit_code=0 if passed else 1, violations=violations, total_rows=total, needs_review_count=needs_review_count, completed_count=completed_count, metadata_field_count=metadata_field_count, empty_reason_count=empty_reason_count, ) def _load_rows_from_chronology(chronology_path: Path) -> list[dict]: # The quality gate reads the rows from the generator's output (JSON sidecar) # or from the generator directly. For CLI use, we import the generator. from scripts.audit.generate_chronology import walk_track_folders, _repo_root root: Path = _repo_root(chronology_path.parent) return walk_track_folders(root) def main() -> None: parser = argparse.ArgumentParser(description="Quality gate for conductor/chronology.md") parser.add_argument("--chronology", type=Path, default=Path("conductor/chronology.md")) parser.add_argument("--strict", action="store_true", help="Exit 1 on any violation") args = parser.parse_args() rows = _load_rows_from_chronology(args.chronology) result = run_quality_gate(rows) print(f"Quality gate: {'PASS' if result.passed else 'FAIL'}") print(f" Total rows: {result.total_rows}") print(f" Needs Review: {result.needs_review_count}") print(f" Completed: {result.completed_count}") print(f" Metadata-field summaries: {result.metadata_field_count}") print(f" Empty reasons: {result.empty_reason_count}") if result.violations: print(" Violations:") for v in result.violations: print(f" - {v}") if args.strict and result.exit_code != 0: sys.exit(result.exit_code) if __name__ == "__main__": main() ``` - [ ] **Step 2: Run the tests to verify they pass (Green)** Run: `uv run pytest tests/test_chronology_quality_gate.py -v` Expected: all tests PASS. - [ ] **Step 3: Commit** ```bash git add scripts/audit/chronology_quality_gate.py git commit -m "feat(chronology): add chronology_quality_gate.py (4 checks + --strict mode)" ``` ### Task 3.3: Phase 3 checkpoint - [ ] **Step 1: Create checkpoint commit** ```bash git commit --allow-empty -m "conductor(checkpoint): Phase 3 complete (Green: classifier + quality gate implemented)" ``` - [ ] **Step 2: Update state.toml** Update `conductor/tracks/chronology_v2_20260701/state.toml`: - `current_phase = 3` → `current_phase = 4` - `phase_3` status → `"completed"` with checkpoint SHA - `t3_1`, `t3_2` → `"completed"` with their commit SHAs - [ ] **Step 3: Commit the state update** ```bash git add conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(state): mark Phase 3 complete for chronology_v2_20260701" ``` --- ## Phase 4: Regenerate chronology.md + write the quality report ### Task 4.1: Regenerate `conductor/chronology.md` **Files:** - Regenerate: `conductor/chronology.md` - [ ] **Step 1: Run the generator against the current filesystem** Run: `uv run python scripts/audit/generate_chronology.py > conductor/chronology.md` Expected: the file is rewritten with all current tracks (including the new ones from 2026-06-27 onward that were missing from v1). - [ ] **Step 2: Verify the output has the new tracks** Run: `Select-String -Path conductor/chronology.md -Pattern 'mma_quarantine|default_layout|module_taxonomy|cruft_elimination_20260701'` Expected: multiple matches (these are the desync-gap tracks that were missing from v1). - [ ] **Step 3: Verify the Needs Review section exists (if any rows need review)** Run: `Select-String -Path conductor/chronology.md -Pattern '## Needs Review'` Expected: either a match (if there are Needs Review rows) or no match (if all rows classified confidently). If no match, that's fine — it means the classifier was confident on all rows. - [ ] **Step 4: Commit** ```bash git add conductor/chronology.md git commit -m "docs(chronology): regenerate chronology.md with v2 git-history classifier (closes 5-day desync gap)" ``` ### Task 4.2: Run the quality gate **Files:** - No file changes (verification only); iterate on classifier if gate fails - [ ] **Step 1: Run the quality gate in strict mode** Run: `uv run python scripts/audit/chronology_quality_gate.py --strict` Expected: `Quality gate: PASS` and exit code 0. - [ ] **Step 2: If the gate fails, investigate and fix** If the gate fails, read the violation output. The 4 possible violations: 1. Needs Review > 30% → the classifier is failing on too many rows; review the Needs Review queue, improve the classifier heuristics, return to Phase 3 Task 3.1 2. 0 Completed → the classifier is misclassifying everything; check the report-matching logic 3. Metadata-field summaries > 20% → the summary extractor is still broken; check `_METADATA_FIELD_PREFIXES` 4. Empty reasons → the classifier is not returning reasons for some rows; check the fallback path Do not loop more than 2 times. If still failing after 2 iterations, stop and report to the user. - [ ] **Step 3: Commit the passing state (if iterations were needed)** If the classifier was iterated on: ```bash git add scripts/audit/generate_chronology.py conductor/chronology.md git commit -m "fix(chronology): classifier iterations to pass quality gate" ``` ### Task 4.3: Write the quality report **Files:** - Create: `docs/reports/CHRONOLOGY_QUALITY_20260701.md` - [ ] **Step 1: Gather the quality gate output** Run: `uv run python scripts/audit/chronology_quality_gate.py` Expected: the full report with counts. - [ ] **Step 2: Count the v1→v2 status corrections** Run a quick comparison: the v1 chronology.md had 218 rows with stale statuses. The v2 has the corrected statuses. Count how many changed. - [ ] **Step 3: List the desync-gap tracks (added in v2, missing from v1)** These are the tracks created after 2026-06-27: `mma_quarantine_rag_test_decoupling_20260701`, `default_layout_install_20260629`, `default_layout_extract_20260629`, `default_layout_install_followup_20260629`, `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`. - [ ] **Step 4: Write the report** Use `write` tool to create `docs/reports/CHRONOLOGY_QUALITY_20260701.md`: ```markdown # Chronology Quality Report — 2026-07-01 **Generated by:** `chronology_v2_20260701` (the v2 redo track) **Replaces:** v1 chronology.md (generated by `chronology_20260619`, 167/216 rows with wrong status) ## Summary - **Total rows:** - **Quality gate:** PASS (or FAIL with details) - **v1 rows:** 218 - **v2 rows:** - **Desync-gap tracks added:** (tracks created after 2026-06-27 that were missing from v1) - **Status corrections (v1→v2):** rows changed status ## Status Distribution | Status | Count | Percentage | |---|---|---| | Completed | | % | | Active | | % | | In Progress | | % | | Abandoned | | % | | Superseded | | % | | Special | | % | | Needs Review | | % | ## Confidence Distribution | Confidence | Count | |---|---| | high | | | medium | | | low | | | none | | ## Needs Review Queue ## Desync Gap Closed (tracks added in v2, missing from v1) < List the desync-gap tracks: mma_quarantine_rag_test_decoupling_20260701, default_layout_install_20260629, ... > ## Classifier Heuristics Summary - **Override signals matched:** rows (TRACK_COMPLETION report: , TRACK_ABORTED report: , state.toml superseded: ) - **Git work-commit evidence matched:** rows (≥3 work commits: , 1-2 work commits: , 0 work commits: ) - **Directory location fallback:** rows (archive/ with no report: ) - **Needs Review fallback:** rows ## v1 Comparison - **v1 total rows:** 218 - **v2 total rows:** - **Rows with changed status:** - **Root cause of v1 failures:** the v1 `_classify_status` read `metadata.json.status` (a stale snapshot) instead of git history; v2 uses git work-commit count + report-matching overrides ## Verification - `scripts/audit/chronology_quality_gate.py --strict` exits 0: YES (or NO with details) - Every row has a non-empty `reason`: YES - No summary contains metadata-field text: YES (or rows still contain it, documented for follow-up) ``` Fill in the `` placeholders with the actual numbers from the quality gate output. - [ ] **Step 5: Commit** ```bash git add docs/reports/CHRONOLOGY_QUALITY_20260701.md git commit -m "docs(report): add CHRONOLOGY_QUALITY_20260701 (v2 quality report with status distribution + Needs Review queue)" ``` ### Task 4.4: Phase 4 checkpoint - [ ] **Step 1: Create checkpoint commit** ```bash git commit --allow-empty -m "conductor(checkpoint): Phase 4 complete (chronology.md regenerated + quality report)" ``` - [ ] **Step 2: Update state.toml** Update `conductor/tracks/chronology_v2_20260701/state.toml`: - `current_phase = 4` → `current_phase = 5` - `phase_4` status → `"completed"` with checkpoint SHA - `t4_1`, `t4_2`, `t4_3` → `"completed"` with their commit SHAs - [ ] **Step 3: Commit the state update** ```bash git add conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(state): mark Phase 4 complete for chronology_v2_20260701" ``` --- ## Phase 5: De-gunk tracks.md + add workflow.md maintenance rule ### Task 5.1: Restructure `conductor/tracks.md` **Files:** - Modify: `conductor/tracks.md` (the entire file — this is the de-gunk) - [ ] **Step 1: Read the current tracks.md "Editing this file" section (to preserve it)** Run: `manual-slop_get_file_slice conductor/tracks.md 868 891` Expected: the "Editing this file" + "Archiving a track (3 steps)" section. This must be preserved in the new tracks.md. - [ ] **Step 2: Identify the genuinely-active rows (not shipped)** From the 60-row active queue, keep only rows where the track is NOT shipped/completed/superseded. Shipped tracks to remove (their history is in chronology.md): rows 6a, 6b, 6c, 6d-1, 6d-2, 6d-3 (if shipped), 6d-4, 6d-5, 6d-6, 6e, 6f, 24, 27, 28, 30, 31, 33, 34, 35, 32, 7a, 7b, 7d, and the layout tracks at the bottom. Keep: 36 (MMA quarantine), 2 (qwen_llama_grok — Phase 6 in progress), 3 (DOEH), 4 (MCP refactor), 6 (placeholder), 7 (UI Polish), 7c (SQLite docs ai_client), 16 (Test Sandbox Hardening), 8-15 (spec TBD), 15a, 15b, 17 (Code Path Audit), 18, 19, 20, 21 (now superseded — remove), 22b, 23, 25, 26, 29, 29a, 29b, 29c. **The implementer must verify each row against its state.toml before removing it.** A row is "shipped" if its state.toml `status` is `completed`/`superseded`/`abandoned` AND it's not marked as having a follow-up track in the active queue. - [ ] **Step 3: Write the new tracks.md** Use `write` tool to create the new `conductor/tracks.md` with this structure: ```markdown # Project Tracks This file tracks all major tracks for the project. Each track has its own detailed plan in its respective folder (or in `../archive//` for completed tracks). **Structure:** - **Active Tracks (Current Queue):** In-flight and unblocked work the implementer can pick up today. - **Standby / Pending Spec:** Tracks with spec TBD or pending decision. - **Full project history:** see [`chronology.md`](./chronology.md) (the canonical index of all tracks: active, shipped, superseded, abandoned). Archive directories live at `../archive//` (from this file's location at `conductor/tracks.md`). --- ## Active Tracks (Current Queue) Tracks that are unblocked and ready to start. Ordered by **dependency** (blocked-by first) and **priority** (A foundational → D forward-looking). | # | Priority | Track | Status | Blocked By | |---|---|---|---|---| | 36 | A (sunset) | [MMA Quarantine + RAG Test Decoupling](#track-mma-quarantine--rag-test-decoupling) | spec ✓, plan pending | (none) | | 2 | A | [Qwen, Llama & Grok Vendor Integration](#track-qwen-llama-grok-vendor-integration) | Phase 6 in progress (docs); NOT archiving — has follow-up | test_infrastructure_hardening_20260609 (merged) | | 3 | A | [Data-Oriented Error Handling (Fleury Pattern)](#track-data-oriented-error-handling-fleury-pattern) | spec ✓, plan ✓, ready to start | test_infrastructure_hardening_20260609 (merged), qwen_llama_grok | | 4 | A | [MCP Architecture Refactor](#track-mcp-architecture-refactor-sub-mcp-extraction) | spec ✓, plan pending | test_infrastructure_hardening_20260609 (merged), data_oriented_error_handling, data_structure_strengthening | | 16 | A | [Test Sandbox Hardening](#track-test-sandbox-hardening) | spec ✓, plan ✓, ready to start | (none) | | 17 | A | [Code Path Audit](#track-code-path-audit) | spec ✓ + plan ✓ | test_infrastructure_hardening_20260609 (merged), any_type_componentization_20260621 (shipped), phase2_4_5_call_site_completion_20260621 (shipped) | | 22b | A | [Meta-Tooling Workflow Review](#track-meta-tooling-workflow-review) | spec ✓, plan ✓, parked | (none) | | 23 | A | [Intent-Based Scripting Languages Survey](#track-intent-based-scripting-languages-survey) | spec ✓, plan pending | (none) | | 25 | B | [Fable System Prompt Review](#track-fable-system-prompt-review) | spec ✓, plan pending | (none) | | 26 | A | [Video Analysis Campaign (Pass 1 of 3)](#track-video-analysis-campaign) | scaffolded; awaiting Phase 0 tooling | (none) | | 29 | A | [Video Analysis De-obfuscation Campaign (Pass 2 of 3)](#track-video-analysis-deob) | scaffolded; awaits USER action item | (none) | | 29a | A | [Lexicon v2 Patch (Pass 2 Phase 1.5)](#track-lexicon-v2-patch) | spec DRAFT pending user review | video_analysis_deob_apply_20260621 (shipped) | | 29b | A | [C11 Reference (Pass 3 Sub-Track)](#track-c11-reference) | in progress | video_analysis_deob_apply_20260621 (shipped), lexicon_v2 (shipped) | | 29c | A | [Pass 3 — C11/Python Projection](#track-pass-3-c11python-projection) | spec DRAFT pending user review | deob_apply (shipped), lexicon_v2 (shipped), c11_reference (shipped) | | 7 | — | [UI Polish (Five Issues)](#track-ui-polish-five-issues) | spec ✓, plan ✓, ready to start | (none) | | 7c | B | [SQLite-Granularity Inline Docs for ai_client.py](#track-sqlite-docs-ai-client) | spec ✓, plan ✓, ready to start | (none) | --- ## Standby / Pending Spec | # | Priority | Track | Status | Blocked By | |---|---|---|---|---| | 6 | D | [Public API Result Migration](#track-public-api-result-migration) | placeholder; not yet specced | data_oriented_error_handling (deprecated send()) | | 8 | — | [Bootstrap gencpp Python Bindings](#track-bootstrap-gencpp-python-bindings) | spec TBD | (none) | | 9 | — | [Tree-Sitter Lua MCP Tools](#track-tree-sitter-lua-mcp-tools) | spec TBD | (none) | | 10 | — | [GDScript Language Support Tools](#track-gdscript-language-support-tools) | spec TBD | (none) | | 11 | — | [C# Language Support Tools](#track-c-language-support-tools) | spec TBD | (none) | | 12 | — | [OpenAI Provider Integration](#track-openai-provider-integration) | spec TBD | (none) | | 13 | — | [Zhipu AI (GLM) Provider Integration](#track-zhipu-ai-glm-provider-integration) | spec TBD | (none) | | 14 | — | [AI Provider Caching Optimization](#track-ai-provider-caching-optimization) | spec TBD | (none) | | 15 | — | [Manual UX Validation & Review](#track-manual-ux-validation--review) | spec TBD | (none) | | 15a | — | [Manual UX Validation — ASCII-Sketch Workflow](#track-manual-ux-validation-ascii-sketch) | spec ✓, plan ✓, ready to start | (none) | | 15b | — | [Chunkification Optimization (Contingency)](#track-chunkification-optimization) | spec ✓ (contingency), no plan | hard constraint surface (deferred) | | 16 | — | [GenCpp Dogfood Feedback Loop](#track-gencpp-dogfood-feedback-loop) | spec TBD | (none) | | 18 | — | [GUI Architecture Refinement](#track-gui-architecture-refinement) | no spec.md | (TBD) | | 19 | — | [Context First Message Fix](#track-context-first-message-fix) | spec TBD | (none) | --- > **Full project history:** see [`chronology.md`](./chronology.md) — the canonical index of all tracks (active, shipped, superseded, abandoned), sorted newest-first, with git-history-evidence-backed status per row. --- ## Notes **Archive link convention:** `./archive/...` paths in this file resolve to `conductor/archive/...` (this file is at `conductor/tracks.md`). **Status legend:** - `[ ]` not started - `[~]` in progress - `[x]` completed (track may still be in `tracks/` or may have been moved to `archive/`) - `~~**...**~~` struck-through (renamed/replaced/superseded) **Naming convention:** Each track's `spec.md` and `plan.md` (where present) follow the project's standard format: `spec.md` for design intent (the "why"), `plan.md` for executable tasks (the "how"). **Editing this file:** When you mark a track as `[x]` and move its folder to `archive/`, remove its row from the Active Tracks table (its history is in `chronology.md`). When you start a new track, create the folder under `tracks/` first, then add the entry to the Active Tracks table. **Archiving a track (3 steps):** When a track ships and its folder moves from `conductor/tracks//` to `conductor/archive//`, complete all 3 steps in order: 1. Move the folder: `git mv conductor/tracks/ conductor/archive/` (preserves history as a rename). 2. Remove the row from this file (`conductor/tracks.md`). 3. Run `uv run python scripts/audit/generate_chronology.py > conductor/chronology.md` to regenerate the chronology (the new row appears automatically). Commit with `docs(chronology): regenerate after shipped`. ``` **IMPORTANT:** Before writing, the implementer MUST verify each row in the current active queue against its `state.toml` to confirm whether it's still active or has shipped since the plan was written. Remove any row whose `state.toml` `status` is `completed`/`superseded`/`abandoned`. The rows listed above are the plan's best-known state as of 2026-07-01; the implementer must verify. - [ ] **Step 4: Verify the new file** Run: `(Get-Content conductor/tracks.md | Measure-Object -Line).Lines` Expected: significantly fewer lines than the original 941 (target: ~80-100 lines). Run: `Select-String -Path conductor/tracks.md -Pattern '## Phase', '## Archived', 'Recently Shipped'` Expected: no matches (the history sections are removed). Run: `Select-String -Path conductor/tracks.md -Pattern 'chronology.md'` Expected: at least 2 matches (the pointer + the archiving step 3). - [ ] **Step 5: Commit** ```bash git add conductor/tracks.md git commit -m "docs(tracks): de-gunk tracks.md — remove Phase 0-9 history + shipped rows; keep active queue + standby + pointer to chronology.md" ``` ### Task 5.2: Add "Chronology Maintenance" section to `conductor/workflow.md` **Files:** - Modify: `conductor/workflow.md` (add a new section after "Track Dependencies and Execution Order") - [ ] **Step 1: Find the insertion point** Run: `Select-String -Path conductor/workflow.md -Pattern '^## Track Dependencies'` Expected: the section starts at some line. The new section goes after this section ends (before the next `## ` heading). - [ ] **Step 2: Insert the new section** Use `manual-slop_edit_file` to insert after the "Track Dependencies and Execution Order" section (before the next `## ` heading): ```markdown --- ## 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 > conductor/chronology.md` 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. Run `uv run python scripts/audit/chronology_quality_gate.py --strict` before committing the regenerated chronology. **When to regenerate:** - After a track ships (TRACK_COMPLETION report committed) - After a track is abandoned (TRACK_ABORTED report committed) - After a track is superseded (state.toml status = "superseded") - After a track folder is archived (moved to `conductor/archive/`) **When NOT to regenerate:** - Mid-track (the chronology reflects filesystem state; a mid-track folder is correctly "In Progress" or "Active") - After a plan.md edit (the chronology doesn't track plan content) ``` - [ ] **Step 3: Verify the insertion** Run: `Select-String -Path conductor/workflow.md -Pattern 'Chronology Maintenance'` Expected: 1 match (the new section heading). - [ ] **Step 4: Commit** ```bash git add conductor/workflow.md git commit -m "docs(workflow): add Chronology Maintenance section (regeneration cadence + quality gate obligation)" ``` ### Task 5.3: Phase 5 checkpoint - [ ] **Step 1: Create checkpoint commit** ```bash git commit --allow-empty -m "conductor(checkpoint): Phase 5 complete (tracks.md de-gunked + workflow.md maintenance rule)" ``` - [ ] **Step 2: Update state.toml** Update `conductor/tracks/chronology_v2_20260701/state.toml`: - `current_phase = 5` → `current_phase = 6` - `phase_5` status → `"completed"` with checkpoint SHA - `t5_1`, `t5_2` → `"completed"` with their commit SHAs - [ ] **Step 3: Commit the state update** ```bash git add conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(state): mark Phase 5 complete for chronology_v2_20260701" ``` --- ## Phase 6: Verification + end-of-track report ### Task 6.1: Final quality gate verification **Files:** - No file changes (verification only) - [ ] **Step 1: Run the quality gate in strict mode** Run: `uv run python scripts/audit/chronology_quality_gate.py --strict` Expected: `Quality gate: PASS`, exit code 0. - [ ] **Step 2: Run all chronology tests** Run: `uv run pytest tests/test_generate_chronology.py tests/test_chronology_quality_gate.py -v` Expected: all tests PASS. - [ ] **Step 3: Commit (if any fixes were needed; otherwise skip)** If no fixes needed, no commit. If fixes: ```bash git add -A git commit -m "fix(chronology): final verification fixes" ``` ### Task 6.2: Review the Needs Review queue **Files:** - No file changes (user review) - [ ] **Step 1: Read the Needs Review section from chronology.md** Run: `Select-String -Path conductor/chronology.md -Pattern '## Needs Review' -Context 0,20` Expected: either no match (no rows need review) or the list of rows needing manual classification. - [ ] **Step 2: Present the Needs Review queue to the user** If there are rows in the Needs Review queue, present them to the user for manual classification. The user decides the status for each row. Apply the user's classifications by editing the rows in `conductor/chronology.md` manually (the generator's classifier was inconclusive; the human is the authority). - [ ] **Step 3: Commit (if manual classifications were applied)** ```bash git add conductor/chronology.md git commit -m "docs(chronology): apply user manual classifications for Needs Review rows" ``` ### Task 6.3: Write the end-of-track report **Files:** - Create: `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md` - [ ] **Step 1: Write the report** Use `write` tool to create `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md`: ```markdown # Track Completion: chronology_v2_20260701 **Date:** 2026-07-01 **Track ID:** `chronology_v2_20260701` **Status:** completed (pending user sign-off) ## Summary Replaced the broken v1 `conductor/chronology.md` (167/216 rows with wrong status due to a stale-metadata classifier) with a correct v2 that uses git-history evidence. Closed out the stuck `chronology_20260619` track, de-gunked `conductor/tracks.md`, and added a maintenance rule to `conductor/workflow.md` to prevent future desync. ## What was done 1. **Closed out `chronology_20260619`**: marked superseded in state.toml, updated tracks.md row, archived the folder, unblocked `superpowers_review_20260619`. 2. **Rewrote the classifier**: `scripts/audit/generate_chronology.py` now uses a 4-tier evidence-priority chain (override signals > git work-commits > directory location > fallback) returning `(status, confidence, reason)`. 7-status enum: Active / In Progress / Completed / Abandoned / Superseded / Special / Needs Review. 3. **Added a quality gate**: `scripts/audit/chronology_quality_gate.py` with 4 checks (Needs Review threshold, status distribution sanity, summary quality, per-row evidence) + `--strict` CI mode. 4. **Regenerated `conductor/chronology.md`** from the current filesystem, closing the 5-day desync gap (13+ tracks added that were missing from v1). 5. **De-gunked `conductor/tracks.md`**: removed Phase 0-9 history sections + shipped-track rows from the active queue; left active queue + standby + pointer to chronology.md. Reduced from 941 lines to ~ lines. 6. **Added "Chronology Maintenance" section to `conductor/workflow.md`**: regeneration cadence (after every track ships/abandons/supersedes) + quality gate obligation. 7. **Wrote the quality report**: `docs/reports/CHRONOLOGY_QUALITY_20260701.md` with status distribution, confidence distribution, Needs Review queue, v1 comparison, desync gap list, heuristics summary. ## Files changed < List all files created/modified with commit SHAs > ## Verification criteria 1. [x] conductor/chronology.md exists, one row per track folder, sorted newest-first, 6 columns, from current filesystem 2. [x] Every row's status backed by git-history evidence; reason non-empty 3. [x] No summary contains metadata-field text 4. [x] chronology_quality_gate.py --strict exits 0 5. [x] conductor/tracks.md contains only active queue + standby + pointer + Editing notes 6. [x] conductor/workflow.md contains Chronology Maintenance section 7. [x] docs/reports/CHRONOLOGY_QUALITY_20260701.md exists with required contents 8. [x] This report exists 9. [x] chronology_20260619 archived with status = superseded 10. [x] superpowers_review_20260619 [blocked_by] no longer contains chronology_20260619 11. [x] tests/test_generate_chronology.py + tests/test_chronology_quality_gate.py pass 12. [ ] User sign-off recorded (pending) ## Known limitations < Any rows that remained in Needs Review after the classifier iterations, any edge cases the classifier doesn't handle well, any follow-up recommendations > ## User sign-off [ ] User has reviewed the chronology.md, the quality report, and the Needs Review queue (if any). Track is complete. ``` - [ ] **Step 2: Commit** ```bash git add docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md git commit -m "docs(report): add TRACK_COMPLETION_chronology_v2_20260701" ``` ### Task 6.4: User sign-off - [ ] **Step 1: Present the deliverables to the user** Present: - `conductor/chronology.md` (the regenerated v2) - `docs/reports/CHRONOLOGY_QUALITY_20260701.md` (the quality report) - `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md` (the end-of-track report) - The Needs Review queue (if any rows need manual classification) - [ ] **Step 2: Record user sign-off** When the user approves, update `docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md`: - Change `[ ] User sign-off recorded` to `[x] User sign-off recorded (date: 2026-07-01)` - Change `Status: completed (pending user sign-off)` to `Status: completed` Update `conductor/tracks/chronology_v2_20260701/state.toml`: - `status = "completed"` - `current_phase = 6` (all phases done) - `phase_6` status → `"completed"` with checkpoint SHA - [ ] **Step 3: Final commit** ```bash git add docs/reports/TRACK_COMPLETION_chronology_v2_20260701.md conductor/tracks/chronology_v2_20260701/state.toml git commit -m "conductor(chronology_v2): user sign-off recorded — track complete" ``` --- ## Self-Review Checklist (for the implementer) Before claiming the track is done, verify: - [ ] `conductor/chronology.md` has rows for ALL track folders (count them: `conductor/tracks/*` + `conductor/archive/*` directories = rows in chronology.md) - [ ] No row in `conductor/chronology.md` has a summary starting with `**Priority:**`, `**Date:**`, `**Initialized:**`, `**Track:**`, `**Parent umbrella:**`, `**Status:**`, or `**Confidence:**` - [ ] `conductor/tracks.md` has no `## Phase` headings (all history sections removed) - [ ] `conductor/tracks.md` has no `## Archived` headings - [ ] `conductor/tracks.md` has the `> Full project history:` pointer line - [ ] `conductor/workflow.md` has the `## Chronology Maintenance` heading - [ ] `scripts/audit/chronology_quality_gate.py --strict` exits 0 - [ ] `tests/test_generate_chronology.py` + `tests/test_chronology_quality_gate.py` all pass - [ ] `conductor/archive/chronology_20260619/state.toml` has `status = "superseded"` - [ ] `conductor/tracks/superpowers_review_20260619/state.toml` `[blocked_by]` has no `chronology_20260619` entry