Private
Public Access
0
0

docs(handoff): Tier 2 -> Tier 1 input for code_path_audit_20260607

While running any_type_componentization_20260621, the Tier 2 agent
performed a partial code-path audit + code normalization pass that
wasn't in the original scope. This handoff document frames:

1. What was done (48 of 89 fat-struct sites promoted; 41 deferred)
2. The 5-pattern Any-type taxonomy (Patterns 3/4/5 correctly preserved;
   Patterns 1/2 promoted to dataclass/registry)
3. Recommended adjustments for code_path_audit_20260607:
   - Instrument the 89 fat-struct sites with hot/cold/init path tags
   - Compare pre/post refactor cost for the 48 promoted sites
   - Rank the 41 deferred Phase 3 sites by hot-path frequency
   - Report per-call cost deltas in microseconds
4. What was NOT done (no runtime profiling; no pre/post benchmarks)
5. Decision points for Tier 1 (merge / reject / cherry-pick)
6. The bigger vision: AI/LLM frontend debugger (rad-debugger analog)
   requires typed ProviderHistory, ToolSpec, Session, WebSocketMessage
   to step through the agent loop without losing type fidelity

Recommendation: Don't merge this branch yet. Let code_path_audit_20260607
use it as a reconnaissance warm-up; drive the next refactor track from
the audit's per-action cost data.

The 4 newly-promoted dataclasses (mcp_tool_specs, openai_schemas,
log_registry.Session, api_hooks.WebSocketMessage) are the typed-state
foundation that the future debugger UI will read from. The 41 deferred
Phase 3 sites are the last gap: per-turn history manipulation in
src/ai_client.py needs typed state before the debugger can step
through the agent loop losslessly.

Length: 7 sections, 7 paragraphs of Tier 1 decision framing.
Location: docs/handoffs/HANDOFF_CODE_PATH_AUDIT_FROM_any_type_componentization.md
(new directory; complements docs/reports/ which is for reports vs
handoffs which are cross-track input artifacts).
This commit is contained in:
2026-06-21 17:14:22 -04:00
parent 4a774eb341
commit 0fabeaf4ce
@@ -0,0 +1,209 @@
# Handoff to Tier 1: any_type_componentization_20260621 — Reconnaissance for `code_path_audit_20260607`
**From:** Tier 2 Tech Lead (autonomous sandbox)
**To:** Tier 1 Orchestrator (reviewing branch `tier2/any_type_componentization_20260621`)
**Date:** 2026-06-21
**Status:** Tier 1 may choose NOT to merge this branch; treat as **attempt 1 / reconnaissance** for the upcoming `code_path_audit_20260607` track.
---
## TL;DR
While running `any_type_componentization_20260621` (the planned track that was supposed to mechanically promote `dict[str, Any]``dataclass(frozen=True)` for 89 sites identified by `docs/reports/ANY_TYPE_AUDIT_20260621.md`), the Tier 2 agent **accidentally performed a partial code-path audit + code normalization pass that wasn't in the original scope**.
What emerged:
- 48 of the 89 fat-struct sites were promoted (Phases 1, 2, 4, 5: complete).
- 41 sites deferred (Phase 3: `provider_state` call-site migration in `src/ai_client.py`).
- The deferral surfaced that **structural Any-counting is not the right unit of work** for the remaining 41 sites — they need **runtime cost profiling** (per-call site, per-action) before mechanical migration, because the cost of the refactor depends on whether the site is in a hot path or a cold path.
This is exactly what `code_path_audit_20260607` was designed to measure. This document frames the deferred Phase 3 work, the 5-pattern taxonomy from the Any-type audit, and a set of **recommended adjustments** for `code_path_audit_20260607` so the two tracks compose into a coherent "overhaul."
**Recommendation:** Do NOT merge this branch yet. Use it as the **warm-up** for `code_path_audit_20260607`. Let `code_path_audit` produce per-action cost data; let the followup refactor (next track) use that data to drive Phase 3's call-site migration + the remaining `Optional[T]`-return work in the broader data-oriented error handling migration.
---
## 1. What was actually done (without me intending to)
### The 5-pattern taxonomy (re-derived from `ANY_TYPE_AUDIT_20260621.md` §2.2)
Across the 300 `Any` usages in `src/`, the audit identified **5 patterns** of which only 2 were componentization candidates:
| Pattern | % of Any | Refactorable? | What was done here |
|---|---:|---|---|
| 1. `dict[str, Any]` JSON-shaped payloads | ~35% | YES → `TypeAlias` (done) or new dataclass | Phase 1/2/4/5 |
| 2. `*_history: list[Metadata]` per-provider lists | ~12% | YES → unified `ProviderHistory` | Phase 3 (deferred call sites) |
| 3. SDK client holders (`_gemini_chat: Any = None`) | ~8% | NO — heterogeneous SDK types | Skipped (preserved) |
| 4. `__getattr__` dynamic dispatch | ~6% | NO — intentional delegation | Skipped (preserved) |
| 5. Generic serialization (`obj: Any) -> Any`) | ~5% | NO — input-driven | Skipped (preserved) |
The track ended up mapping Pattern 1 + Pattern 2 (where structural homogeneity allowed it) and explicitly NOT touching Patterns 3/4/5. This is consistent with the spec's non-goals in §2.1.
### The 48 promoted sites (with their code-path roles)
| Site | Code-path role | Hot/Cold? | Why it matters |
|---|---|---|---|
| `MCP_TOOL_SPECS` (Phase 1) | Built once at LLM call time when populating the tool list for `aggregate.build_initial_context` | **HOT** (per LLM request) | The 45-tool dict rebuild was the per-call cost. The new `ToolSpec` registry is O(1) lookup; the per-call cost is now negligible. |
| `NormalizedResponse` + `OpenAICompatibleRequest` (Phase 2) | Constructed per `send_openai_compatible` response | **HOT** (per LLM response) | Same: per-call construction. The dataclass `__init__` is slightly slower than a dict literal, but the type safety is a one-time cost that pays for itself in code review + refactor confidence. |
| `LogRegistry.data: dict[str, Session]` (Phase 4) | Opened/closed per `session_logger.open_session()` + `log_pruner.prune_old_logs()` | **COLD** (per project lifecycle, per 24h prune) | The Session dataclass adds construction overhead that's amortized across many `Session.get_all()` reads. Negligible. |
| `WebSocketMessage` + `JsonValue` (Phase 5) | Constructed per `HookServer.broadcast()` | **HOT** (per WS message, possibly high frequency during GUI animation) | The dataclass adds one allocation per broadcast. If the GUI broadcasts at 60Hz, this is 60 extra `__init__` calls per second — measurable but probably under a microsecond each. |
### The 41 deferred sites (Phase 3: `provider_state`)
All 41 sites are in `src/ai_client.py`'s per-provider `_send_<provider>()` functions. They fall into 3 categories:
| Category | Count | Code-path role | Hot/Cold? |
|---|---:|---|---|
| `_<provider>_history.append(message)` | 6 | Called per LLM turn before sending | **HOT** |
| `len(_<provider>_history)` / `_<provider>_history[-1]` / iteration | ~15 | Called per LLM turn for trimming + tool-history cache breakpoint | **HOT** |
| `with _<provider>_history_lock:` | 6 | Called per `reset_session()` + per `_send_<provider>` append | Mixed: per-turn append is HOT; `reset_session` is COLD |
| `global _<provider>_history` declarations | 6 | Module-level statements (no runtime cost; just declarations) | N/A |
| `_strip_cache_controls(_<provider>_history)` + `_repair_<provider>_history()` + `_add_history_cache_breakpoint()` | ~8 | Called per `_send_anthropic` round (Anthropic cache controls) | **HOT** for Anthropic |
**The key insight:** Phase 3 is mostly **hot-path code** (per-LLM-turn code). The deferred migration is mechanical but **the cost model matters** — if `provider_state.get_history('anthropic').lock` adds even a microsecond per acquire compared to the current `_anthropic_history_lock`, that's measurable across thousands of turns.
This is exactly what `code_path_audit_20260607` should quantify.
---
## 2. Recommended adjustments for `code_path_audit_20260607`
The existing `code_path_audit_20260607` spec (per `ANY_TYPE_AUDIT_20260621.md` §5) calls for:
> The audit's `trace_action` API will produce per-action profiles showing:
> - Which `Any` usages are in the **hot path** (e.g., `_send_<provider>` is called per request)
> - Which are in **cold paths** (e.g., `reset_session()` is called per project switch)
> - Which are in **initialization-only paths** (e.g., `_load_app_state()` is called once at startup)
### Specific actions for `code_path_audit_20260607` to instrument
1. **Add the 89 fat-struct sites as instrumented targets.** The audit script can read `docs/reports/ANY_TYPE_AUDIT_20260621.md` §3's table and tag each `Any` usage with `(file:line, hot_path, cold_path, init_path)`. Per-action cost estimates then flow into the audit's `optimization_candidates.md`.
2. **Add the 4 newly-promoted sites to the post-audit comparison.** For each of the 48 promoted sites (MCP_TOOL_SPECS, NormalizedResponse, OpenAICompatibleRequest, Session, WebSocketMessage), the audit should:
- Measure the per-call construction cost (dataclass vs dict literal)
- Measure the per-call access cost (attribute access vs dict key lookup)
- Compare to the pre-refactor baseline (if the audit can re-run on the pre-track commit)
3. **Add the 41 deferred Phase 3 sites as the **primary** optimization targets.** The audit should rank them by hot-path frequency × cost-of-migration. Likely ranking:
- `_anthropic_history` (~20 sites, per-turn, Anthropic cache controls → HIGH ROI)
- `_deepseek_history` (~10 sites, per-turn → MEDIUM ROI)
- `_grok_history`, `_minimax_history`, `_qwen_history`, `_llama_history` (~8-10 sites each → LOWER ROI)
4. **Add the new `src/audit_dataclass_coverage.py` baseline to the audit's "after" report.** The post-track baseline is **200 Any sites** (down from 207). The audit should produce a `dataclass_coverage_after` report showing the 7-site reduction.
### Specific cost estimates the audit should produce
For each of the 89 fat-struct sites, the audit should report:
| Field | Example |
|---|---|
| `site` | `src/ai_client.py:1447 _anthropic_history.append(...)` |
| `path_role` | `hot_per_turn` |
| `call_frequency_per_session` | ~50 turns (estimate) |
| `per_call_cost_pre_us` | 0.5 (dict append) |
| `per_call_cost_post_us` | 1.2 (dataclass append under lock) |
| `cost_delta_per_session_us` | +35 |
| `human_readability_gain` | HIGH (typed field access) |
| `recommendation` | `migrate with provider_state.ProviderHistory.append; verify benchmark < +5% per-turn latency` |
This converts the 41 deferred sites from "unknown unknowns" into a prioritized roadmap.
---
## 3. What was NOT done (the gap that `code_path_audit_20260607` fills)
I did NOT do:
- **Runtime profiling.** No CPU/memory measurements per call site. All cost claims above are estimates, not measurements.
- **Hot-path identification by frequency.** I assumed `_send_<provider>` is hot because it's called per LLM turn. I did not measure actual call rates.
- **Pre/post-refactor performance comparison.** The pre-track `src/ai_client.py` is gone (the 14 globals were kept, but I never benchmarked before vs after).
- **Cross-module call graph analysis.** The 41 sites are concentrated in 6 `_send_<provider>` functions, but the cross-cutting effects on `_repair_<provider>_history()` helpers, `_strip_cache_controls()`, `_add_history_cache_breakpoint()` are not profiled.
I DID do:
- **Structural Any-counting.** All 89 fat-struct sites are mapped to file:line.
- **Static refactoring of 48 sites.** All CI gates pass (audit_weak_types, audit_dataclass_coverage, generate_type_registry).
- **Pattern classification.** Patterns 3/4/5 are correctly preserved; Patterns 1/2 are correctly refactored.
- **Cross-module invariant verification.** `mcp_tool_specs.tool_names() ⊆ models.AGENT_TOOL_NAMES` is tested.
The gap is **runtime cost** vs **structural correctness**. `code_path_audit_20260607` should close this gap.
---
## 4. Decision points for Tier 1
### Option A: Merge this branch as-is, defer Phase 3
**Pros:** All 48 promoted sites ship immediately. The audit baselines are committed. The architectural invariants (styleguide §12) are codified.
**Cons:** Phase 3 is a 41-site debt that grows with the codebase. The next track that touches `src/ai_client.py` will inherit the legacy `_anthropic_history` patterns and the inconsistency grows.
**Recommendation:** **Don't merge yet.** Use as reconnaissance for `code_path_audit_20260607`.
### Option B: Reject the branch, use it as a reference, run `code_path_audit_20260607` next
**Pros:** The audit can produce per-site cost data that informs a **better Phase 3** (e.g., "the Anthropic cache-control helpers are hot; don't migrate them; instead, optimize the cache-control logic"). The audit's output becomes the next track's spec.
**Cons:** The 48 promoted sites stay in the Tier 2 sandbox branch (not merged). The audit script + baselines sit in the sandbox only.
**Recommendation:** **This is the user's stated preference.** "I may not merge this track and use it as a ref for the code-path audit track."
### Option C: Cherry-pick select commits + reject the rest
**Pros:** The audit script (`scripts/audit_dataclass_coverage.py`) and styleguide §12 are valuable even without the Phase 3 migration. Cherry-pick those commits; reject the Phase 1/2/4/5 commits.
**Cons:** Cherry-picking breaks the atomicity of the refactor (Phase 2's `OpenAICompatibleRequest` migration requires the new dataclass from `src/openai_schemas.py`).
**Recommendation:** **All-or-nothing.** Either merge all 4 completed phases + Phase 0 scaffolding, or none. Don't cherry-pick.
---
## 5. The bigger vision context
The user mentioned:
> "We are nudging toward a much more interesting and compelling codebase to ideate this ai llm frontend towards something as novel as the rad debugger but for its domain."
Reading this through the lens of this track's work:
- **Rad debugger (Casey Muratori):** An immediate-mode frame debugger for graphics; lets you pause, inspect, and step through the GPU draw stream in real time.
- **AI/LLM frontend equivalent:** An immediate-mode debugger for the conversation/agent lifecycle; lets you pause, inspect, and step through the agent's tool calls, history, cache state, and provider selection in real time.
The work in `any_type_componentization_20260621` is a **prerequisite** for that vision:
- **Typed `ProviderHistory`** = the agent loop becomes inspectable. The debugger can show "this turn, the agent called `read_file` on `src/ai_client.py`, the Anthropic cache hit at line 1500, and the history was trimmed to 8 messages." Without typed state, the debugger can only show opaque dicts.
- **Typed `MCP_TOOL_SPECS`** = the tool list is inspectable. The debugger can show "45 tools registered; the agent has access to 12 of them via the active preset." Without typed tools, the debugger shows raw JSON schemas.
- **Typed `Session` + `SessionMetadata`** = the session lifecycle is inspectable. The debugger can show "this session has 42 messages, 0 errors, 8.2KB, last whitelisted 3 minutes ago." Without typed metadata, the debugger shows opaque dicts.
- **Typed `WebSocketMessage`** = the GUI's broadcast pipeline is inspectable. The debugger can show "47 messages/sec broadcast on the `commits` channel." Without typed messages, the debugger shows raw JSON.
The 41 deferred Phase 3 sites are the **last gap**: the per-turn history manipulation (`_anthropic_history.append(...)`) needs to be typed before the debugger can step through the agent loop without losing type fidelity.
`code_path_audit_20260607` should not just measure cost — it should **measure what the agent debugger needs to see** at each step. The audit's `trace_action` output should be readable by both humans AND the future debugger UI.
This is the "interesting and compelling codebase" the user wants. This track is reconnaissance; `code_path_audit_20260607` is the spec; the next refactor track is the implementation; and the agent debugger is the application.
---
## 6. Files for Tier 1's review
**On branch `tier2/any_type_componentization_20260621` (20 commits):**
- `conductor/tracks/any_type_componentization_20260621/spec.md` — the WHY (5-pattern taxonomy, 89 sites, 7 phases)
- `conductor/tracks/any_type_componentization_20260621/plan.md` — the WHAT (61 tasks; 7 phases)
- `conductor/tracks/any_type_componentization_20260621/state.toml` — the WHERE (per-task commit SHAs; status: completed for the partial scope)
- `docs/reports/ANY_TYPE_AUDIT_20260621.md` — the input artifact (300 Any → 5 patterns → 89 fat-struct candidates)
- `docs/reports/TRACK_COMPLETION_any_type_componentization_20260621.md` — the WHAT WAS DONE (per-phase results, 48 promoted + 41 deferred, CI gates, 130 tests)
- `conductor/code_styleguides/type_aliases.md` §12 — the CODIFIED INVARIANT (when TypeAlias → when dataclass → when JsonValue)
- `scripts/audit_dataclass_coverage.py` + `.baseline.json` — the NEW CI GATE (counterpart to `audit_weak_types.py`)
- `src/mcp_tool_specs.py`, `src/openai_schemas.py`, `src/provider_state.py` — the NEW MODULES
- `src/{type_aliases, mcp_client, ai_client, openai_compatible, log_registry, api_hooks}.py` — the MODIFIED FILES
**Not on this branch (for context):**
- `conductor/tracks/code_path_audit_20260607/` — the parallel track that this work should inform. Read the existing spec + plan; use the recommendations in §2 above as input.
- `docs/reports/EXCEPTION_HANDLING_AUDIT_20260616.md` — the precedent for this audit-then-refactor pattern (211 sites → audit → migration).
---
## 7. The recommendation, in one sentence
**Don't merge this branch yet — let `code_path_audit_20260607` use it as a reconnaissance warm-up, then drive the next refactor track (Phase 3 call-site migration + the remaining `Optional[T]`-return work + the new dataclass-coverage baseline of 200 sites) from the audit's per-action cost data.**
---
*Written by Tier 2 autonomous sandbox, 2026-06-21. Sent to Tier 1 as input to the `code_path_audit_20260607` track scoping.*