66 KiB
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
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
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
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
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
{
"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
# 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
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
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_1status →"completed", checkpointsha → the SHA -
All
t1_*tasks →"completed"with their commit SHAs -
Step 3: Commit the state update
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):
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
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:
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
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
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_2status →"completed"with checkpoint SHA -
t2_1,t2_2→"completed"with their commit SHAs -
Step 3: Commit the state update
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_statusfunction at lines 201-228, theextract_summaryfunction at lines 62-92, thewalk_track_foldersfunction at lines 231-290, and theformat_markdownfunction 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_summaryto reject all 7 metadata-field prefixes
Use manual-slop_py_update_definition to replace extract_summary with:
_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_statusfunction
Use manual-slop_py_add_def to add a new module-level function after _classify_status:
_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_foldersto use the new classifier
Use manual-slop_py_update_definition to replace walk_track_folders. The key changes:
- Pass
repo_rootandreports_dirtoclassify_statusinstead of calling the old_classify_status - Store
confidenceandreasonin the row dict alongsidestatus
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_statushelper
Use manual-slop_py_add_def to add after _parse_state_phase:
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_markdownto include the Needs Review section + preamble
Use manual-slop_py_update_definition to replace format_markdown:
def format_markdown(rows: list[dict]) -> str:
from datetime import date as today_date
lines: list[str] = []
lines.append(f"<!-- Generated {today_date.today().isoformat()} | {len(rows)} rows -->")
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
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:
"""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
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
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_3status →"completed"with checkpoint SHA -
t3_1,t3_2→"completed"with their commit SHAs -
Step 3: Commit the state update
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
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:
- 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
- 0 Completed → the classifier is misclassifying everything; check the report-matching logic
- Metadata-field summaries > 20% → the summary extractor is still broken; check
_METADATA_FIELD_PREFIXES - 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:
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:
# 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:** <N>
- **Quality gate:** PASS (or FAIL with details)
- **v1 rows:** 218
- **v2 rows:** <N>
- **Desync-gap tracks added:** <N> (tracks created after 2026-06-27 that were missing from v1)
- **Status corrections (v1→v2):** <N> rows changed status
## Status Distribution
| Status | Count | Percentage |
|---|---|---|
| Completed | <N> | <N>% |
| Active | <N> | <N>% |
| In Progress | <N> | <N>% |
| Abandoned | <N> | <N>% |
| Superseded | <N> | <N>% |
| Special | <N> | <N>% |
| Needs Review | <N> | <N>% |
## Confidence Distribution
| Confidence | Count |
|---|---|
| high | <N> |
| medium | <N> |
| low | <N> |
| none | <N> |
## Needs Review Queue
<List of rows with Needs Review status, each with the classifier's reason. If empty, state "No rows need manual review.">
## 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:** <N> rows (TRACK_COMPLETION report: <N>, TRACK_ABORTED report: <N>, state.toml superseded: <N>)
- **Git work-commit evidence matched:** <N> rows (≥3 work commits: <N>, 1-2 work commits: <N>, 0 work commits: <N>)
- **Directory location fallback:** <N> rows (archive/ with no report: <N>)
- **Needs Review fallback:** <N> rows
## v1 Comparison
- **v1 total rows:** 218
- **v2 total rows:** <N>
- **Rows with changed status:** <N>
- **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 <N> rows still contain it, documented for follow-up)
Fill in the <N> placeholders with the actual numbers from the quality gate output.
- Step 5: Commit
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
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_4status →"completed"with checkpoint SHA -
t4_1,t4_2,t4_3→"completed"with their commit SHAs -
Step 3: Commit the state update
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:
# 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/<track_name>/` 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/<track_name>/` (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/<id>/` to `conductor/archive/<id>/`, complete all 3 steps in order:
1. Move the folder: `git mv conductor/tracks/<id> conductor/archive/<id>` (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 <track-id> 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
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):
---
## 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 <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.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
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
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_5status →"completed"with checkpoint SHA -
t5_1,t5_2→"completed"with their commit SHAs -
Step 3: Commit the state update
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:
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)
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:
# 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 ~<N> 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
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 recordedto[x] User sign-off recorded (date: 2026-07-01) - Change
Status: completed (pending user sign-off)toStatus: completed
Update conductor/tracks/chronology_v2_20260701/state.toml:
-
status = "completed" -
current_phase = 6(all phases done) -
phase_6status →"completed"with checkpoint SHA -
Step 3: Final commit
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.mdhas rows for ALL track folders (count them:conductor/tracks/*+conductor/archive/*directories = rows in chronology.md)- No row in
conductor/chronology.mdhas a summary starting with**Priority:**,**Date:**,**Initialized:**,**Track:**,**Parent umbrella:**,**Status:**, or**Confidence:** conductor/tracks.mdhas no## Phaseheadings (all history sections removed)conductor/tracks.mdhas no## Archivedheadingsconductor/tracks.mdhas the> Full project history:pointer lineconductor/workflow.mdhas the## Chronology Maintenanceheadingscripts/audit/chronology_quality_gate.py --strictexits 0tests/test_generate_chronology.py+tests/test_chronology_quality_gate.pyall passconductor/archive/chronology_20260619/state.tomlhasstatus = "superseded"conductor/tracks/superpowers_review_20260619/state.toml[blocked_by]has nochronology_20260619entry