Phase 2 (openai_schemas) progress:
- t2_1-t2_5+t2_7-t2_8 (a96f946b): 19 tests pass; NormalizedResponse +
OpenAICompatibleRequest refactored to dataclasses
- t2_6 (deferred): _send_grok + _send_minimax + _send_llama in
src/ai_client.py still use legacy NormalizedResponse(text=..., tool_calls=[], usage_*_tokens=...)
kwargs. These will be updated in Phase 3 (provider_state) as part of
the ai_client refactor.
- t2_9: Phase 2 checkpoint (commit hash filled in this commit)
current_phase: 2 -> 3
phase_2.status: pending -> completed
Next: Phase 3 - provider_state (15 tasks; the largest phase).
Phase 1 of any_type_componentization_20260621. Migrates ai_client.py:
- Line 560: new_tools = {name: False for name in mcp_client.TOOL_NAMES}
-> mcp_tool_specs.tool_names()
- Line 582: _agent_tools = {name: True for name in mcp_client.TOOL_NAMES}
-> mcp_tool_specs.tool_names()
- Line 1012: is_native = name in mcp_client.TOOL_NAMES
-> name in mcp_tool_specs.tool_names()
Plus adds: from src import mcp_tool_specs
Verified:
uv run pytest tests/test_mcp_tool_specs.py tests/test_mcp_client_beads.py tests/test_mcp_client_paths.py tests/test_audit_dataclass_coverage.py tests/test_type_aliases.py
39 passed in 11.79s
No regressions. The mcp_client.TOOL_NAMES re-export is preserved for
backward compatibility with any external test/code that imports it.
Phase 1 of any_type_componentization_20260621. Migrates the 4 call sites
in src/mcp_client.py to use the new typed module:
- Line 1944: native_names = {t['name'] for t in MCP_TOOL_SPECS}
-> native_names = mcp_tool_specs.tool_names()
- Line 1958: res = list(MCP_TOOL_SPECS)
-> res = [s.to_dict() for s in mcp_tool_specs.get_tool_schemas()]
- Line 2747: TOOL_NAMES = {t['name'] for t in MCP_TOOL_SPECS}
-> TOOL_NAMES = mcp_tool_specs.tool_names()
Plus: removes the legacy MCP_TOOL_SPECS list literal (lines 1973-2746;
774 lines of dict literals). The data lives in src/mcp_tool_specs.py
now; the canonical registry. (The legacy dict shape is preserved via
ToolSpec.to_dict() for downstream serialization.)
Adds import: from src import mcp_tool_specs
Verified:
uv run pytest tests/test_mcp_tool_specs.py tests/test_audit_dataclass_coverage.py tests/test_type_aliases.py
32 passed in 5.48s
uv run pytest tests/test_mcp_client_beads.py tests/test_mcp_client_paths.py
7 passed in 3.20s
Cross-module invariant (test_tool_names_subset_of_models_agent_tool_names):
the 45 mcp_tool_specs.tool_names() are all in models.AGENT_TOOL_NAMES.
Phase 0 of any_type_componentization_20260621. Adds the canonical
decision rule that future contributors can apply without re-deriving:
- TypeAlias conditions: open shape, self-describing, transient
- dataclass(frozen=True) conditions: known fields, multi-site access,
stable serialization, shared across modules
- The src/vendor_capabilities.py reference pattern (5 properties)
- Decision tree
- The 5 worked examples (89 sites promoted per the audit)
- Cross-references to audit scripts + input artifact + track
This is the canonical artifact for the 'when to dataclass' question;
subsequent phases refer to it via 'see styleguide 12' rather than
re-deriving the rule.
Phase 0 of any_type_componentization_20260621. Extends src/type_aliases.py
with two recursive-friendly TypeAliases for JSON wire format (used by
Phase 5 api_hooks WebSocketMessage):
- JsonPrimitive: str | int | float | bool | None
- JsonValue: JsonPrimitive | list['JsonValue'] | dict[str, 'JsonValue']
The forward-ref 'JsonValue' strings work because from __future__ import
annotations is at the top of the module (PEP 563 + PEP 613 TypeAlias).
Tests added (4 new, 14 total):
- test_json_primitive_alias_resolves_to_union: hints exposes JsonPrimitive
- test_json_value_alias_resolves_to_recursive_union: hints exposes JsonValue
- test_json_value_accepts_primitive_dict: dict[str, JsonValue] runtime use
- test_json_value_accepts_nested_structures: nested dict+list round-trip
Verification:
uv run pytest tests/test_type_aliases.py --timeout=30
14 passed in 2.97s
GREEN phase for Phase 0. Mirrors scripts/audit_weak_types.py design with
3 additions specific to the any-type componentization track:
1. PROMOTED_SITE_MODULES allowlist: the 3 new src/ modules
(mcp_tool_specs.py, openai_schemas.py, provider_state.py) are exempt
from Any-counting (their new dataclasses intentionally have raw_response: Any
and SDK holder fields that stay as Any per Pattern 3).
2. INLINE_PROMOTED_SITE_MODULES: log_registry.py + api_hooks.py get their
dataclasses added inline in Phase 4 + 5 (not new modules); same exemption.
3. Combined counter: counts both Any AND weak-struct patterns
(dict_str_any, list_of_dict, optional_dict, etc.).
Modes:
- default: informational (exits 0; prints human report)
- --json: machine-readable with by_file, by_category, total_weak
- --strict: CI gate (exits 1 when current > baseline)
- --baseline: path to baseline file (default: scripts/audit_dataclass_coverage.baseline.json)
Baseline: scripts/audit_dataclass_coverage.baseline.json = 207 weak sites
(captured pre-Phase-1; expected to drop to ~118 after 89 sites promoted).
Verification:
uv run python scripts/audit_dataclass_coverage.py --strict
STRICT OK: 207 weak sites <= baseline 207
uv run pytest tests/test_audit_dataclass_coverage.py --timeout=30
7 passed in 5.15s
RED phase for Phase 0. Mirrors tests/test_audit_weak_types.py structure:
- test_audit_script_exists: AUDIT_SCRIPT.is_file() sanity
- test_audit_help_runs: --help exits 0
- test_audit_json_mode_emits_valid_json: --json emits valid JSON with expected fields
- test_audit_default_mode_emits_human_report: default mode prints a report
- test_audit_strict_mode_against_existing_baseline_passes: --strict exits 0 when current <= baseline
- test_audit_strict_mode_fails_when_baseline_is_zero: --strict exits 1 when current > baseline=0
- test_audit_baseline_field_shape: --json output has expected baseline-shape fields
7 tests total. Run with: uv run pytest tests/test_audit_dataclass_coverage.py --timeout=30
NOTE: 6 of 7 tests fail at this commit (audit script not yet implemented).
This is the RED phase; GREEN comes in the next commit.
The spec.md was approved 2026-06-21 without a plan.md (the metadata.json
noted 'plan.md (to be authored by writing-plans skill after spec
approval)'). This plan mirrors the state.toml's per-task ledger and
specifies the TDD protocol, tier-3 delegation conventions, hard bans,
failcount contract, and per-phase verification commands.
Plan structure: 7 phases, 61 tasks, ~50 atomic commits per the spec.
Reads all 13 conductor/code_styleguides/*.md per the agent mandate.
Each child spec is lightweight (~100 lines): references the umbrella, gives video details, specifies the 7 deliverables (transcript.json, frames/, ocr.md, report.md 1000-10000 LOC, summary.md), and the 5-phase pipeline.
Children in execution order:
1. cs229_building_llms (Stanford CS229, Cluster E)
2. probability_logic (Cluster A)
3. entropy_epiplexity (Cluster A)
4. score_dynamics_giorgini (Cluster A)
5. platonic_intelligence_kumar (Cluster B)
6. free_lunches_levin (Cluster B)
7. generic_systems_fields (Cluster C)
8. brain_counterintuitive (Cluster C)
9. neural_dynamics_miller (Cluster C)
10. multiscale_hoffman (Cluster C)
11. cs336_architectures (Stanford CS336, Cluster E)
12. creikey_dl_cv (Cluster D)
Plus 1 synthesis track (video_analysis_synthesis_20260621) blocked_by all 12 children.
Replaces the v1 plan (10 phases, single-stage cross-check) with an 11-phase
plan that executes the v2 spec's git-history classifier + 3-stage cross-check
+ 30% quality gate. Plan Phase 2 = Spec Phase 2 part 1; renumbering shifts
from Plan Phase 4 onwards (per the spec-vs-plan mapping in the summary table).
11 phases, 28 tasks, 4 hard pause points (Plan Phase 6 quality gate, Plan
Phase 7 Tier 1 review, Plan Phase 10 user sign-off, plus the Plan Phase 6
ABORT fallback to manual review). TDD red+green cycles for Phases 2-4 (8
new tests for _classify_status + 4 for extract_summary + 3 for format_markdown
+ 5 for the quality gate).
Test runner: scripts/run_tests_batched.py (per Tier 2 sandbox rule #1).
Throw-away scripts: scripts/tier2/artifacts/chronology_20260619/ (rule #4).
Default branch: master (rule #2). Line endings: preserve existing (rule #3).
The first run shipped chronology.md with a status classifier that read stale
metadata.json.status, marking 167/216 rows with wrong status. This v2 spec
replaces FR1 (5-value status enum + per-row evidence + confidence), FR5
(git-history classifier with the 5-step algorithm from the handover), FR6
(3-stage cross-check), and adds FR7 (classifier quality gate at 30% low
confidence threshold with abort-to-manual-review fallback).
Substantive changes from v1:
- 7 FRs (was 6); FR7 is new
- 14 VCs (was 12); VC10-VC14 are new
- 10 Risks (was 9)
- 5-value status enum: Active / In Progress / Completed / Abandoned / Special
(was 6-value: Shipped/Superseded/etc.)
- Per-row evidence line format documented with worked example
- 'Needs Review' section as a 5th section in chronology.md
- Quality gate hard-codes the user's 'A only if classifier is good, else B'
fallback design from chat 2026-06-21
Out of scope: 24 v1 commits + conductor/chronology.md.broken-v1 remain as the
foundation; this is a continuation, not a re-do. state.toml still shows
current_phase=10 from v1's false completion; the Tier 2 implementing agent
will reset it in Phase 1.4 of the plan.