AST + Dataflow Tool — ROADMAP
AST + Dataflow Tool — ROADMAP
Section titled “AST + Dataflow Tool — ROADMAP”Status: DRAFT-S8 (kh-ast-S8 Wave 1 — roadmap accuracy review post-S7). Companions:
PRODUCT.md(behaviour spec, 12 query surfaces, 30 invariants),TECH.md(data model, library layout, validation, follow-ups;flow-trace-TECH.mdfolded intoTECH.md§Query implementations on 18/05/2026). Counter: track-localkh-ast-sN. This doc is session-agnostic — slip dates, not WP positions, when timelines shift.
Why this doc exists
Section titled “Why this doc exists”S1–S3 shipped the first four queries (callers, importers, references,
column-reads) plus the structured error contract. S4 closed the
canonical-pipeline rename probe pair (column-reads + column-writes) and
added the wildcard confidence tier. S5 shipped the cross-project leverage
trio (dead-exports, reexport-chain, type-evolution). S6 shipped the
KH-specific surface (string-literal-uses, enum-uses) plus the
flow-trace-TECH.md sub-spec. S7 shipped flow-trace (R-WP6) as a
three-WP sequence and authored three cross-tool investigation briefs
(R-WP10 framework-agnostic, R-WP11 cross-tool integration, R-WP12
type-safety pipeline). With 11 queries shipped and the investigation
outputs in hand, the open work in PRODUCT.md plus the new
ROADMAP-tracked extensions need sequencing against:
- Cross-project leverage. Same Supabase + Next.js stack is shared across Knowledge Hub, sales-proposals, and other Liam-and-Claude projects. Whatever ships here should be portable. R-WP10 (S7) confirmed the tool is 95% portable already; Approach A minimal fix is queued for S8.
- Complement vs duplicate. The tool sits next to
cocoindex-code(text index),gitnexus(git provenance + framework graph), andbun run knip(unused dependency / export detection). Duplication is dead weight; gap- filling is high-leverage. R-WP11 (S7) catalogued nine cross-tool integration patterns ranked by leverage; top three are now S8/S10 candidates. - The deferred-OQ list is shorter than at S4 but the type-safety
pipeline opens a new axis of work. PRODUCT.md invariants 1, 3–10 are
shipped (9 of the 12 query surfaces). Invariants 2 (
callees), 11 (fixture-uses), and 12 (enum-member-uses) remain unshipped — none have a load-bearing trigger yet (no current rename sweep or audit demands them, and the shippedreferences+enum-uses+string- literal-usestrio covers most of what 2/11/12 would address). Invariant 28 (MCP wrapper) remains DEFERRED. R-WP12 (S7) identified five type-safety gaps that ast-dataflow can detect or close, with a 20h MVP across five WPs. Cache layer (TECH.md §Cache strategy) and Python sibling remain trigger-driven.
This roadmap is the running answer to “what next, and why.”
id-375 delta (2026-07-27) — productionisation wave
Section titled “id-375 delta (2026-07-27) — productionisation wave”Supersedes the S7 rows below where they conflict. Landed across id-375
waves 1-5 (specs: specs/id-375-ast-dataflow-productionise/RESEARCH.md,
PRODUCT.md §Amendments A1-A7):
| Change | Status | Smoke of record |
|---|---|---|
Spatial truncation (truncateSpatial, inv 14) across all coverage queries; flow-trace + reexport-chain exempt | Shipped W1 | string-literal-uses --value created_at --limit 5: 5 rows from 5 distinct files, totalEstimated: 52 |
detectIsTyped rewrite — structural Row-property proof, no text matching (inv 15 / A4) | Shipped W2 | column-reads source_documents.id: 199 rows before AND after; false-exact rows demoted to indirect |
callees query (inv 2 / A1) | Shipped W2 | lib/supabase/safe.ts:sb → 1 row (new SupabaseError), externalCount 0 |
importers algorithmic fix (P-19 breach closed) | Shipped W2 | durationMs 10.3-16.2 s → 1.6-2.2 s |
One-hop .from(CONST) table resolution (A7) | Shipped W3 (prior session) | Fires on the real corpus: .from(VERSION_TABLE) → content_propagation_version at scripts/propagate-canonical-content.ts:486 (in-corpus via transitive import — the corpus boundary is import-reachability, not the tsconfig exclude list). App-side dynamic sites are union-typed (excluded as ambiguous by design) |
fixture-uses query (inv 11 / A1) | Shipped W3 | --needle created_at: 354 hits across json/ts |
schema-coverage report (A6) — the built-not-wired audit | Shipped W4 | 807 columns / 70 tables in one 7.4 s pass: wired 310, read-only 225, undecidable 132, unwired 88, write-only 52; all baseline false negatives closed; dropped bid_questions → loud unknown_table |
Warm MCP stdio server + dispatch.ts extraction (inv 28 / A2+A3) | Shipped W5 | callers sb over stdio: first call 6.0 s wall, second 204 ms; suite 313/313 |
Cache pivot: the facts-cache design (R-WP9/OQ-R3, LMDB) is superseded — measurement showed 11 of 12 queries need the live type-checked AST; the warm path is the MCP server process (PRODUCT.md A2, ratified 2026-07-27).
Current state (kh-ast-S7 close)
Section titled “Current state (kh-ast-S7 close)”| Query | Status | Source | Smoke baseline |
|---|---|---|---|
callers | Shipped (S1) | PRODUCT.md inv. 1 | Verified against fixture corpus; 153 rows on sb() smoke. |
importers | Shipped (S2) | PRODUCT.md inv. 4 | 3 rows on @/lib/ai/change-reports smoke. |
references | Shipped (S3) | PRODUCT.md inv. 3 | 6 kinds (typeReference, jsxComponent, read, write, reexport, typeOnly); 82 rows on BidState smoke. |
column-reads | Shipped (S3) + wildcard tier (S4 WP1) | PRODUCT.md inv. 5 + 15 | 48 rows on bid_questions.project_id, 1.8 s warm; wildcard branch detects .select('*'). (historical — bid_questions since dropped; current example: form_questions.question_text, 22 exact rows) |
column-writes | Shipped (S4 WP2) | PRODUCT.md inv. 6 | 20 rows on bid_questions.project_id, 3.5 s warm; spread-one-hop chase working. (historical — see column-reads note) |
dead-exports | Shipped (S5 R-WP1) | PRODUCT.md inv. 9 | 54-symbol Knip-diff batch: 52 confirmed dead, 2 false-positives, 4.3 s warm. OQ-R2 resolved (Shape A per-row JSONL). |
reexport-chain | Shipped (S5 R-WP2) | PRODUCT.md inv. 8 | DialogClose probe: 39 rows (1 declaration + 38 direct importers), 483 ms warm. |
type-evolution | Shipped (S5 R-WP3) | PRODUCT.md inv. 7 | BidQuestion.project_id probe: 22 rows across 8 files, ~4.0 s cold. |
string-literal-uses | Shipped (S6 R-WP4) | PRODUCT.md inv. 10 | vi.mock('@/lib/supabase/safe') probe: 6 viMock rows, 3.06 s. |
enum-uses | Shipped (S6 R-WP5) | ROADMAP extension | Fixture-only smoke (KH has zero native enums); 19 rows on OrderStatus fixture, 71 ms warm. |
flow-trace | Shipped (S7 R-WP6, three-WP sequence) | ROADMAP extension; see TECH.md §Query implementations → flow-trace | Heuristic confirmed: 5-hop warm ≈ 5 ms, 8-hop warm ≈ 4 ms. Real KH smoke (lib/bid/bid-queries.ts:70) ≈ 5 ms warm, ~2 s cold. |
| Test philosophy | Audit + 23 tightenings (S4 WP3); ongoing per-query audits | docs/reference/test-philosophy.md | 163/163 AST tests passing (end S7); no weak toBeGreaterThanOrEqual(1) antipatterns. |
| Structured error contract | Shipped (S3 WP3) | PRODUCT.md inv. 29 | Four ErrorKind cases (unknown_file, parse_error, ambiguous_symbol, out_of_corpus) plus two flow-trace codes (ORIGIN_NOT_RESOLVABLE, ORIGIN_NOT_VALUE_PRODUCING). CLI exits 0 on structured error. |
| Open invariant | Title | PRODUCT.md ref | Priority |
|---|---|---|---|
| 2 | callees | inv. 2 | SHIPPED (id-375 W2, 2026-07-27) — 14 tests, fixture corpus 19-callees; PRODUCT.md A1 |
| 11 | fixture-uses | inv. 11 | SHIPPED (id-375 W3, 2026-07-27) — 21 tests, fixture corpus 20-fixture-uses; PRODUCT.md A1 |
| 12 | enum-member-uses | inv. 12 | DEFERRED (enum-uses shipped as ROADMAP extension covers the enum-rename sweep case; full per-member filter on as const tuples deferred until a concrete audit needs it) |
| 28 | MCP wrapper | inv. 28 | SHIPPED-OPTIONAL (id-375 W5, 2026-07-27, pending A3 ratification) — single dispatching ast_dataflow tool over a warm ts-morph Project; OQ-R4 trigger fired (importers P-19 breach + rename-sweep 5×-cold-CLI friction); PRODUCT.md A3 |
Tool-gap matrix
Section titled “Tool-gap matrix”With 11 queries shipped, the tool’s complement-vs-duplicate justification shifts from “which gap to fill next” (everything in PRODUCT.md is shipped except invariant 28 MCP wrapper) to “which cross-tool integration pattern gives the most leverage on top of the shipped surface”. R-WP11 (S7) is the authoritative catalogue; the table below summarises the three highest- leverage gap-filling opportunities still open.
| Pattern | Gap vs current tools | Why current tools cannot fill it | Status |
|---|---|---|---|
gitnexus_rename + string-literal-uses + importers + references (R-WP11 Pattern 4, HIGH leverage) | gitnexus_rename’s ast_search fallback is its weakest link — string-matched, not type-checker resolved. Every cross-file rename loses confidence on those candidates. | ast-dataflow’s string-literal-uses is the precise complement: it surfaces only AST-anchored string-literal nodes, with parent-kind classification (CallExpression argument, TemplateLiteral, JsxAttribute). | Queued: R-WP11a (Wave 4, S8). |
gitnexus_context + callers (R-WP11 Pattern 5, HIGH leverage) | gitnexus indexes graph edges (CALLS, FETCHES) but misses indirect callers — arrow functions inside Promise.all, callback chains, HOC wrappers. | ts-morph’s findReferences() is a full type-checker traversal; it surfaces every reference regardless of call-graph edge type. Closes the indirect-caller gap. | Queued: R-WP11b (Wave 7, S11+). |
Knip enumMembers + enum-uses (R-WP11 Pattern 8, MEDIUM leverage) | Knip has documented false-positive issues (#989, #703) on as const patterns — KH’s dominant enum idiom. | enum-uses resolves as const tuple member access via findReferences() on the index position, exactly the case Knip miscounts. | Backlog (re-evaluate at next KH enum audit). |
Roadmap sequence (S5+)
Section titled “Roadmap sequence (S5+)”Sequencing principle: cross-project queries first, then KH-specific use cases, then cross-tool integrations and orthogonal extensions (framework-agnostic adaptation, type-safety pipeline, packaging). A query is “cross-project” if any Supabase + Next.js project benefits without custom configuration.
Wave 1 — Cross-project leverage (S5) — COMPLETE
Section titled “Wave 1 — Cross-project leverage (S5) — COMPLETE”| WP | Query | Effort | Depends on | Status / Justification |
|---|---|---|---|---|
| R-WP1 | dead-exports (inv. 9) | ~3h | None | Shipped S5 R-WP1 (5fdbd9b7 lineage). Complements Knip directly. 54-symbol Knip-diff batch verified: 52 confirmed dead, 2 false-positives. Cross-project: every TS project has unused exports. |
| R-WP2 | reexport-chain (inv. 8) | ~2h | R-WP1 (shared barrel walker) | Shipped S5 R-WP2 (5fdbd9b7). Pairs with R-WP1: when dead-exports says “unused”, reexport-chain shows the barrel paths to confirm or refute. Cross-project: every barrel-using codebase. |
| R-WP3 | type-evolution (inv. 7) | ~2-3h | None | Shipped S5 R-WP3 (7a3d83ef lineage). The TS-type layer analogue of column-reads/column-writes. Cross-project: any TS project doing rename refactors. |
Wave 2 — KH-specific surface (S6) — COMPLETE
Section titled “Wave 2 — KH-specific surface (S6) — COMPLETE”| WP | Query | Effort | Depends on | Status / Justification |
|---|---|---|---|---|
| R-WP4 | string-literal-uses (inv. 10) | ~2h | None | Shipped S6 R-WP4 (d1c45aa7). Catch-all for vi.mock, SQL tags, env-var keys. |
| R-WP5 | enum-uses | ~1-2h | references (already shipped) | Shipped S6 R-WP5 (20bb0b79). Specialisation of references with enum-aware classification. ROADMAP-tracked extension beyond PRODUCT.md’s frozen 12-query surface; a future major PRODUCT.md revision may fold it in. |
| R-WP6-spec | flow-trace technical specification | ~1-2h | column-writes, references | Shipped S6 R-WP6-spec (7897a1b3). Authored flow-trace-TECH.md sub-spec locking args, hop taxonomy, termination policy, output schema, and three-WP decomposition ahead of S7 implementation. |
Wave 3 — flow-trace + cross-tool integration investigations (S7) — COMPLETE
Section titled “Wave 3 — flow-trace + cross-tool integration investigations (S7) — COMPLETE”| WP | Item | Effort | Depends on | Status / Justification |
|---|---|---|---|---|
| R-WP6 | flow-trace (ROADMAP extension; sub-spec flow-trace-TECH.md) | ~4h (3-WP sequence) | column-writes, references, R-WP6-spec | Shipped S7 across three sequential WPs (675ff73a → fd4dedd8/b31bf148 → bfc60b5b/4b15204e → 03d61fbe cleanup). WP1: core walker + 4 hop kinds. WP2: sinks + spread + indirect tier. WP3: cycle detection, depth cutoff, inter-function descent, types union, CLI. OQ-FT2/FT3 locked, OQ-FT5 resolved (heuristic confirmed: warm 5-hop ≈ 5 ms, warm 8-hop ≈ 4 ms), OQ-FT4 deferred. |
| R-WP10 | Investigation: framework-agnostic adaptation feasibility (immediate target: Vite). | ~2h | None | Shipped S7 (2e8f1f1d). Brief: investigations/R-WP10-framework-agnostic.md. Finding: tool is 95% portable; minimal 4-file fix (Approach A) achieves Vite support at S effort (2-4h). Approaches B (FrameworkAdaptor interface) and C (config file) deferred until npm-publish scenario surfaces. |
| R-WP11 | Investigation: high-value cross-tool integration opportunities (gitnexus-refactoring, gitnexus-debugging, cocoindex-code, Knip). | ~2h | None | Shipped S7 (191c9a38). Brief: investigations/R-WP11-cross-tool-integration.md. Finding: 9 patterns catalogued; top three by leverage are Pattern 4 (gitnexus_rename + string-literal-uses, HIGH), Pattern 5 (gitnexus_context + callers, HIGH), Pattern 8 (Knip enumMembers + enum-uses, MEDIUM). No new queries required — patterns compose the existing 11. |
| R-WP12 | Investigation: type-safety pipeline feasibility (ast-dataflow + cocoindex-code + GitNexus + Supabase typegen). | ~3-4h | None | Shipped S7 (ca69d1fb). Brief: investigations/R-WP12-type-safety-pipeline.md. Finding: 5 gaps identified, 20h MVP across WP-A..WP-E. Detection tooling (WP-A + WP-D) recommended before structural fix (OPS-T1 defineRoute() wrapper). DW.14 (Supabase typegen) effectively answered. |
Wave 4 — Priority outcomes from cross-tool investigation findings (S8)
Section titled “Wave 4 — Priority outcomes from cross-tool investigation findings (S8)”| WP | Item | Effort | Depends on | Justification |
|---|---|---|---|---|
| R-WP10a | Framework-portability minimal fix (R-WP10 Approach A — Vite-ready). Implement: (1) generalised path-alias strip in importers.ts; (2) deduplicated isTestFilePath (single source in resolve.ts, drop local copies in column-reads.ts / column-writes.ts); (3) relative-import refactor in scripts/ast-dataflow-cli.ts; (4) --tsconfig flag on CLI; (5) Vite-style tsconfig fixture under __tests__/lib/ast-dataflow/fixtures/15-vite/. | 2-4h (S) | None | R-WP10 brief Recommendation §5. Closes the one genuine HIGH-severity portability defect (CLI @/ imports) plus two low-severity hygiene items. Unlocks dogfooding on Liam’s non-KH Vite projects. |
| R-WP12-WPA | Mechanical structured-RPC de-cast at three known sites (R-WP12 brief §MVP §WP-B execution path, scoped to S8 sites). Remove as Record<string, unknown> casts at lib/mcp/tools/search.ts:152, lib/bid/bid-queries.ts:83, lib/mcp/tools/content.ts:84. Verify type-checker still passes. No behaviour change. | ~2h (XS) | None | R-WP12 brief Recommendation: “zero risk and immediate payback”. Disjoint files from R-WP10a so parallelisable. |
| R-WP11a | Operationalise R-WP11 Pattern 4 — gitnexus_rename + ast-dataflow rename-sweep verifier as a skill (.claude/skills/ast-dataflow-rename-sweep/SKILL.md). Form decided in S8 planning: skill (over CLI) per Liam direction, since the skill route gives us an automated skill-efficacy evaluation pattern reusable for R-WP7. Reproduce the worked example end-to-end on a real KH rename; report unmissed sites with line numbers. Document in TECH.md §Cross-tool patterns. | 3-5h (M) | R-WP10a (touches shared library paths) | R-WP11 brief Recommendation §1 — “ready to operationalise now”. Closes the single weakest link in every cross-file rename (gitnexus’s ast_search fallback); also establishes the skill-efficacy evaluation pattern feeding R-WP7. |
| R-WP12-WPB | Type-evolution sweep / drift-detection tool (R-WP12 brief MVP §WP-B, partial). New scripts/type-safety-sweep.ts (or lib/ast-dataflow/queries/type-evolution-batch.ts) scans app/api/**/route.ts for unsafe response narrowing — fetcher generics not pinned, raw RPC returns without type assertions. Output: JSONL inventory of “needs migration” sites for OPS-T1 to consume. | 3-4h (M) | R-WP12-WPA | R-WP12 brief Recommendation: “Build the detection tooling (WP A, WP D) first — before any structural fix.” Produces the empirical evidence Liam needs to decide whether OPS-T1 is worth the 2-3 day spend. |
Wave 5 — Type-safety Pipeline (S9) — COMPLETE
Section titled “Wave 5 — Type-safety Pipeline (S9) — COMPLETE”Spec triple: docs/specs/id-16-ast-dataflow-tool/type-safety-pipeline/{PRODUCT,TECH}.md
(authored S8 Wave 1 — PRODUCT.md = WP-D only, TECH.md covers WP-A..WP-F +
ESLint rule + JSONB inventory + Supabase types CI plan).
The S8 wave shipped R-WP12 WP-A (Gap 3 detection) + WP-B (Gap 1 detection
scaffold). Wave 5 closes out the remaining R-WP12 MVP and gates the OPS-T1
(defineRoute()) structural-fix decision. WP labels start at R-WP17 to avoid
collision with the S8 R-WP13/14/15 IDs reserved during the S7 close-out edit.
Per R-WP12 brief Recommendation, WP-D (route/fetcher type-drift detector) was prioritised first in this wave so OPS-T1 had empirical gap-prevalence data before the priority decision. WP-D consumed the WP-B scaffold from S8 and extended it to a full report. S9 outcome: all five Wave 5 WPs shipped (R-WP17 + R-WP18 + R-WP19 + R-WP20 + R-WP21). R-WP21 recommendation is hybrid (b) per-route annotations on intelligence cluster + (c) CI gate; defer (a) OPS-T1 structural rollout. Pending Liam ratification at S9 close-out review.
| WP | Item | Effort | Depends on | Status / Justification |
|---|---|---|---|---|
| R-WP17 | Route/fetcher type-drift detector — full report (R-WP12 brief §WP-D). For each named response interface in types/*.ts and lib/query/fetchers.ts, run references and classify which appear in fetchers but lack a matching route return-type annotation. Output: docs/generated/type-drift-report.md with JSONL backing. | ~5h | R-WP12-WPB (S8) | Shipped S9 Wave 1 (795c4c31 + cleanup 9f91eacd). New query lib/ast-dataflow/queries/type-drift-detect.ts + CLI subcommand bun run ast-dataflow type-drift-detect (flags: --json, --pretty, --ci, --scope, --limit, --interface-pattern, --update-baseline). All 30 PRODUCT invariants D-1..D-30 met (incl. D-25 no-fetchers-found sentinel + D-30 structured parse_error). 22 new tests (191 → 213). KH-wide first-run baseline at docs/generated/type-drift-baseline.json carries 37 fetcher-only rows. Canonical false-negative fixtures both surface: TaxonomySyncStatus + ReviewStatsResponse. Cold ~5s / warm ~4.5s (well under D-22’s 3-min budget). |
| R-WP18 | Mechanical cast-removal sweep (R-WP12 brief §WP-B execution; KH-wide) + ESLint rule. | ~3h | R-WP17 (uses report) | Shipped S9 Wave 2 (11ade075 + cleanup 09a1e00e). 12 cast sites cleared across lib/bid/, lib/mcp/tools/, app/api/ (full list in change-log §8 T2). New ESLint rule local/no-supabase-record-cast at error level on lib/** + app/api/**; 22-entry JSONB column allowlist + 3 escape hatches; 20 RuleTester cases. Out-of-scope deferral: 3 sites in lib/topic-inference.ts:177,309,322 (file was outside R-WP18 ALLOWED list; backlog item OPS-T2 — see product-backlog.json). |
| R-WP19 | Opaque-Json RPC inventory + fix-path (R-WP12 brief §WP-C). For each of the 14 Returns: Json RPCs, determine: (a) TS callers, (b) current return shape, (c) convertibility verdict. Migration scripts NOT executed (feasibility only). | ~4h | None (parallel with R-WP17) | Shipped S9 Wave 1 (78c8330e). Brief at docs/specs/id-16-ast-dataflow-tool/investigations/R-WP12-opaque-json-rpcs.md. Verdict counts: 5 convertible (get_dashboard_attention_counts, get_filter_counts, get_user_tag_counts, get_workspace_counts, merge_entities); 6 requires-design (get_author_analysis, get_content_gaps, get_entity_list_aggregated, get_reading_patterns, get_review_breakdown_stats, get_topic_deep_dive); 2 no-ts-callers (get_bid_summary, get_verification_stats); 1 leave-as-is (hook_restrict_signup_to_allowed_domain — Supabase Auth Hook, protocol-mandated JSONB). Recommended sprint shape: Tier 1+2 (5 convertible) ~7h. Re-runnable audit script scripts/audit-opaque-json-rpcs.ts. Feeds OQ-R9 decision (pending). |
| R-WP20 | MCP outputSchema registration scaffold (R-WP12 brief §WP-E). Register Zod outputSchema on the 5 highest-usage MCP tools using corresponding formatter interfaces as schema source. Validate via MCP SDK runtime check. | ~4h | None | Shipped S9 Wave 2 (c98d5f1c). 5 tools registered: search_knowledge_base + search_content_chunks (lib/mcp/tools/search.ts), get_governance_queue + review_governance_item (lib/mcp/tools/governance.ts), get_change_report (lib/mcp/tools/change-report.ts). 10 Zod schemas in lib/mcp/formatters/{search,governance,change-report}.ts. Smoke test __tests__/mcp/output-schema-smoke.test.ts exercises safeParse() known-good + known-bad for all 5 (29 assertions). Full 58-tool rollout queued as R-WP22 in Wave 7 (deferred per Liam OQ-4 until main-track MCP cleanup finalises which tools are retained). |
| R-WP21 | OPS-T1 decision gate (uses R-WP17 output). Liam reviews drift-report prevalence; decides: (a) OPS-T1 defineRoute() wrapper now (~2-3 days, closes Gap 1 at root); (b) per-route annotations incrementally; (c) accept gap + rely on R-WP17 detector as lint-like CI check. | ~30min (decision) | R-WP17 | RATIFIED-(c)-S10 at S10 Wave 0 close. Decision note: docs/specs/id-16-ast-dataflow-tool/type-safety-pipeline/decision-OPS-T1.md (sign-off block updated S10). Binding S10 output: investigations/S10-wave-0-synthesis.md §3.1. Wave-A (b) DROPPED — intelligence-cluster annotations would be partially overwritten by future OPS-T1 + Wave 0-C confirmed OPS-T1 needs a sibling codemod (not mechanisable today). Wave-A’ (a) DEFERRED to S11+ codemod-led rollout; specs reserved for S11 — see Wave 7 R-WP-S11-A. (c) shipped S10 WP1 (c99f5953). |
Wave 6 — Packaging + Dev-workflow integration (S10)
Section titled “Wave 6 — Packaging + Dev-workflow integration (S10)”R-WP11 (S8) is expected to produce the first skill file (ast-dataflow-rename-sweep).
R-WP7 is therefore rescoped from “first skill file” to “additional skills covering the
remaining query surface + skill efficacy evaluation across the now-multiple
ast-dataflow skills”. The create-skill skill remains the authoring tool.
| WP | Item | Effort | Depends on | Justification |
|---|---|---|---|---|
| R-WP7 | Additional ast-dataflow skill files + skill-efficacy evaluation. Beyond the rename-sweep skill from R-WP11a (S8), author skill files for the remaining HIGH-leverage R-WP11 patterns (Pattern 5: gitnexus_context + callers call-chain pinning), and for the general-purpose ast-dataflow query catalogue (.claude/skills/ast-dataflow/SKILL.md). Run the create-skill efficacy evaluation across the now-multiple skills. | ~3-4h | R-WP11a (first skill from S8 establishes the pattern) | Shipped S10 WP2 (61413dd3 + cleanup a39ab16f). Catalogue skill at .claude/skills/ast-dataflow/SKILL.md (covers all 12 queries + 9 cross-tool patterns); call-chain-pin skill at .claude/skills/ast-dataflow/ast-dataflow-call-chain-pin/SKILL.md (Pattern 5 anchored to classifyContent UUID gotcha). Efficacy eval at docs/specs/id-16-ast-dataflow-tool/skill-efficacy-S10.md (25/25 trigger phrases routed correctly). CLAUDE.md ast-dataflow section added. Two further skill candidates surfaced (Pattern 6 type-evolution-check + Pattern 8 enum-member-audit) → S11 backlog. |
| R-WP16 | ast-dataflow-tooling branch into production-readiness track so 167 commits of ast-dataflow work consolidate before main-track absorption. Wave 0-D dry-run: 12 conflicts of 363 paths; AST-dataflow primitives (135 files) merge clean; moderate difficulty; 4-6h. | ~4-6h | Wave 1 close (S10) | Per Liam direction at S10 open: “the actual wider task here is to be able to merge the AST data flow worktree back to the production readiness track”. S10 produced Wave 0-D merge plan (investigations/S10-r-wp16-merge-dry-run.md); execution reserved for S11 (final session on this worktree) — see Wave 7 R-WP-S11-D. |
Wave 7 — S11 final session on this worktree (codemod specs + cross-track merge)
Section titled “Wave 7 — S11 final session on this worktree (codemod specs + cross-track merge)”S11 is the last session on ast-dataflow-tooling. Scope per
investigations/S10-wave-0-synthesis.md §4: parallel WP-A (codemod specs)
- WP-B (merge pre-flight) + WP-C (housekeeping), gated by verifier, then sequential WP-D (merge execution). Post-S11, ast-dataflow work is owned by the production-readiness track.
| WP | Item | Effort | Depends on | Justification |
|---|---|---|---|---|
| R-WP-S11-A | OPS-T1 codemod investigation + spec authoring. Inventory 193-route handler shape variants. write-product-spec + write-tech-spec for scripts/codemods/wrap-define-route.ts ts-morph utility (dry-run + apply modes, idempotency, ast-dataflow type-drift-detect as post-migration verifier). No implementation in S11 — specs land; implementation in a later session aligned with main-track Phase 1 canonical-pipeline migration. | ~4-6h | R-WP21 RATIFIED-S10 | Wave 0-C finding: OPS-T1 not mechanisable today (no AST-rewrite primitive in any tool). Codemod sibling-utility is the path; ast-dataflow PRODUCT.md scopes the tool away from autofix. Authoring specs now decouples the OPS-T1 timing from canonical-pipeline timing. Status: SHIPPED (fa7ee857 — 3 new files, 1159 lines: PRODUCT.md 265, TECH.md 566, route-shape-inventory.md 328). |
| R-WP-S11-B | Cross-track merge pre-flight. Terminology decision (workpackage vs task ID-N) propagation; scratch-file cleanup; roadmap JSON canonicalisation. Target: ≤6 conflicts on the next dry-run (from 12 at S10 close). | ~1.5-2.5h | Wave 0-D output | Reduces S11 merge wave risk; documents Liam decisions before they propagate to production-readiness. Status: SHIPPED (b4d97ac4 — 9 files: 4 terminology files replaced with production-readiness body, 3 scratch-file cleanups, 2 doc canonicalisations). Original 12 conflicts → 4 remaining from original set + 5 new from production-readiness drift = 9 for WP-D. |
| R-WP-S11-C | Housekeeping. Move R-WP22 row to production-readiness backlog (with S9 provenance); close AST-S9-O1 + AST-S9-O2 from backlog (shipped S10); add Pattern 6 / Pattern 8 skill candidates; ROADMAP edit reflecting all S10 + S11 outcomes; TECH.md test-path-convention note. | ~1h | None (parallel) | Cleans up the “what’s done / what’s deferred / what’s now in production-readiness scope” matrix Liam will need at session close. Status: SHIPPED kh-ast-S11 Wave 1. Commit SHA stamped in front-matter. AST-S9-O1 closed (b2339cee), AST-S9-O2 closed (e07edfc5), Pattern 6 (23) + Pattern 8 (24) added to backlog. TECH.md §Testing and validation test-path note added. R-WP22 MIGRATED-to-production-readiness. |
| R-WP-S11-D | Cross-track merge execution (R-WP16 re-framed). Resolve 12 conflicts per S10-r-wp16-merge-dry-run.md §3 recipe; post-merge knip + full vitest + lint + format; push. | ~2-3h | R-WP-S11-A,B,C completion + verifier gate | Final consolidation step before this worktree closes. Production-readiness → main merge is OUT OF SCOPE for S11. Status: IN-PROGRESS — deferred to Wave 2 sequential merge on production-readiness worktree. |
| R-WP9 | Cache layer (TECH.md §Cache strategy). | ~3h | Observable warm-cache miss | Currently no load-bearing trigger — column-reads smoke at 1.8 s warm, column-writes at 3.5 s warm, flow-trace warm ≈ 5 ms, all well under the 10 s P-19 budget. dead-exports full-corpus scan (4.3 s for 54 symbols) is the slowest warm query but still inside budget. Follow cocoindex-code pattern with local LMDB if/when a smoke breaches the budget. SUPERSEDED-id-375: facts cache rejected by measurement; warm path is the MCP server (PRODUCT.md A2). |
| R-WP11b | 61413dd3). Row retained for cross-reference; no further work. | n/a | n/a | R-WP7 absorbed R-WP11b per S8 prompt’s expected overlap. |
| R-WP22 | MCP outputSchema full rollout (R-WP12 brief §WP-E continuation). Beyond the 5-tool scaffold in R-WP20, register outputSchema on the remaining ~53 tools. Estimated: ~58 × ~30m ≈ ~29h. Multi-agent parallelisation candidate. | ~29h | R-WP20 | R-WP12 brief §Open questions OQ-4. Closes Gap 4 across the full MCP surface. Status: MIGRATED-to-production-readiness — sourced from kh-ast-S9, surfaced by R-WP20 commit c98d5f1c. Added to production-readiness backlog as part of R-WP-S11-C housekeeping (kh-ast-S11 Wave 1). See §Carried forward to production-readiness below. |
| OPS-T1 | defineRoute() wrapper rollout (R-WP12 §Recommendation, conditional on R-WP21 decision). Per-route typed wrapper closing Gap 1 at the root. Estimated 2-3 days for a full sweep across 193 routes. | ~16-24h | R-WP-S11-A (specs) + main-track Phase 1 timing | DEFERRED-TO-S11+. Specs authored S11 (R-WP-S11-A); implementation queued for the session aligned with main-track Phase 1 canonical-pipeline migration. R-WP17 baseline + CI gate (shipped S10) prevent regression in the meantime. |
Cross-cutting hygiene (any session)
Section titled “Cross-cutting hygiene (any session)”- Test-philosophy audit, repeat-pass — every new query’s tests audited against
docs/reference/test-philosophy.mdin the same session it ships. S4 WP3 ran this for the existing 5 test files; S5, S6, S7 inherited the discipline inline. - PRODUCT.md / TECH.md sync — every query update locks the canonical naming (S4 WP1 caught
inferred→wildcarddrift; S5 R-WP3 added thetype-evolutionsmoke). TheLast verifiedheader bumps in the same commit that changes the body. flow-trace-TECH.mdfold-down — completed kh-ast-S9 Wave 1.flow-trace-TECH.mddeleted; full content now atTECH.md§Query implementations → flow-trace.
Cross-tool integration
Section titled “Cross-tool integration”The tool is most useful when chained with other tools. Document patterns
explicitly so agents and humans can compose them. The three baseline patterns
below shipped alongside the original library. R-WP11 (S7) extended the
catalogue with six additional patterns ranked by leverage; the highest are
queued as concrete roadmap WPs (R-WP11a in Wave 4, R-WP11b in Wave 7). See
docs/specs/id-16-ast-dataflow-tool/investigations/R-WP11-cross-tool-integration.md
for the full catalogue with worked examples.
Pattern 1: Knip ↔ ast-dataflow (R-WP1 + R-WP2 — shipped S5)
Section titled “Pattern 1: Knip ↔ ast-dataflow (R-WP1 + R-WP2 — shipped S5)”# Knip flags unused exportsbun run knip --reporter json | jq -r '.issues[].exports[].name' > /tmp/knip-unused.txt
# ast-dataflow verifies the full batch in a single ts-morph invocationbun scripts/ast-dataflow-cli.ts dead-exports --symbols /tmp/knip-unused.txt --exclude-tests
# For any false-positive (Knip says unused, ast-dataflow finds importers):bun scripts/ast-dataflow-cli.ts reexport-chain --symbol "$name" --from <file>Output: definitive list of exports safe to delete vs. exports that escape Knip
via barrel chains. Validated S5: 54-symbol Knip-diff batch → 52 confirmed dead,
2 false-positives, 4.3 s warm. The dead-exports --symbols <file> batch flag
keeps a single ts-morph invocation cost amortised across all symbols.
Pattern 2: GitNexus ↔ ast-dataflow
Section titled “Pattern 2: GitNexus ↔ ast-dataflow”GitNexus answers “which symbols changed in this commit” + framework-aware edge types (HANDLES_ROUTE, FETCHES, QUERIES). ast-dataflow answers “what’s the TS-resolver blast radius of this symbol”.
Compose: gitnexus_impact({target, direction: "upstream"}) first to get the
process-level blast radius, then callers/column-reads/references to get
the file-and-line-level blast radius. The two answers should agree at the
edges; disagreement = a gap in one of the tools.
R-WP11 Pattern 4 (rename-sweep verifier — R-WP11a, S8) and Pattern 5 (call-chain pinning — R-WP11b, Wave 7) operationalise this composition for the rename and the bug-pin scenarios respectively.
Pattern 3: cocoindex-code ↔ ast-dataflow
Section titled “Pattern 3: cocoindex-code ↔ ast-dataflow”cocoindex-code finds the string (“where does ‘project_id’ appear textually”).
ast-dataflow filters to semantically-meaningful sites (string-literal-uses,
column-reads, column-writes). Order matters: cocoindex casts the wide net,
ast-dataflow refines.
Patterns 4–9 (R-WP11 catalogue, S7 brief)
Section titled “Patterns 4–9 (R-WP11 catalogue, S7 brief)”Six additional patterns documented in
investigations/R-WP11-cross-tool-integration.md:
- Pattern 4 (HIGH):
gitnexus_rename+string-literal-uses+importers+references— rename-sweep verifier closing gitnexus’sast_searchfallback gap. - Pattern 5 (HIGH):
gitnexus_context+callers— call-chain pinning for indirect callers gitnexus does not index. - Pattern 6 (MEDIUM):
gitnexus_impact+type-evolution— runtime-vs-type blast radius agreement check before a type rename. - Pattern 7 (MEDIUM):
ccc guide+callers/string-literal-uses— concept-guide invariant verification (depends on ccc guides being populated). - Pattern 8 (MEDIUM): Knip enumMembers +
enum-uses— confirms or refutes Knip’s known false positives onas constpatterns. - Pattern 9 (LOW):
ccc search+dead-exports --scope— concept-scoped (not path-scoped) dead-export audit.
R-WP11a (Wave 4) operationalises Pattern 4. R-WP11b (Wave 7) operationalises Pattern 5. Patterns 6, 8, 9 remain documented-only until a concrete trigger fires. Pattern 7 is blocked on ccc guide library population (a separate 30-minute seeding task surfaced as a backlog item).
Python pipeline sibling — decision gate
Section titled “Python pipeline sibling — decision gate”Status: DEFERRED pending cocoindex canonical-pipeline collapse outcome.
The cocoindex canonical pipeline (docs/plans/phase-0-investigation/architecture/07-collapse-list.md) will retire substantial portions of the existing
Python pipeline. Authoring a Python ast-dataflow sibling before the collapse
list completes risks building a probe for code that’s about to be deleted.
Re-evaluation triggers (any one):
- The collapse-list verifier sign-off lands and the remaining Python surface is named — at that point, evaluate “what’s left worth probing?”.
- A KH-Python refactor surfaces that needs cross-file Python symbol-resolution answers (e.g. a Python column rename equivalent to S2-S4’s TS rename).
- A second project (sales-proposals, future) introduces a Python pipeline of similar size and shape.
Until any trigger fires, the AST tool stays TS-only and TECH.md §Follow-ups remains the bookmark.
Open questions deferred
Section titled “Open questions deferred”These need a decision before their corresponding WP can start.
| OQ | Status | Decision needed | When |
|---|---|---|---|
| OQ-R1 | DECIDED-S4 | Skill-file name: ast-dataflow (cross-project, matches the roadmap pitch). General-purpose query catalogue skill lands at .claude/skills/ast-dataflow/SKILL.md in R-WP7 (Wave 6). The first sibling skill (ast-dataflow-rename-sweep) ships earlier in R-WP11a (Wave 4). | n/a |
| OQ-R2 | DECIDED-S5 | dead-exports output shape: per-row JSONL (Shape A). Each result row in QueryResponse<DeadExportResult>.results is one {file, line, column, symbol, confidence, testOnly, reachableImporters, barrelChain?} object. Rationale: (1) the dominant consumer is a Knip-diff pipe (bun run knip --reporter json | jq … | xargs dead-exports --symbols <file>), where one-row-per-symbol is directly consumable without aggregation; (2) PRODUCT.md inv. 30 already mandates “one row per finding” + “JSONL on stdout”; (3) human reviewers can always jq -s 'group_by(.file)' to get grouped output, but the reverse (splitting a grouped structure for streaming) is much harder; (4) a --format grouped flag is deferred until a concrete consumer need surfaces. Shape A is aligned with every other query in the library. Trial on 54 KH HEAD unused exports confirmed per-row output requires zero post-processing for the pipe scenario. | n/a (decided) |
| OQ-R3 | SUPERSEDED-id-375 | LMDB facts cache rejected by measurement — 11 of 12 queries need the live type-checked AST. Warm path is the MCP server process holding the ts-morph Project (PRODUCT.md A2, ratified 2026-07-27). | n/a (superseded). |
| OQ-R4 | DECIDED-id-375 | Shape locked: single dispatching ast_dataflow tool (inv 28 option (b)) over shared dispatch.ts consumed by both CLI and server. Trigger fired: importers P-19 breach + rename-sweep 5×-cold-CLI friction (PRODUCT.md A3, ratified 2026-07-27). | n/a (decided). |
| OQ-R5 | DECIDED-S8 | Wave 4 (S8) WP composition: R-WP10a (framework-portability) + R-WP12-WPA (mechanical de-cast) parallel in dispatch wave 1; R-WP11a (rename-sweep verifier) + R-WP12-WPB (drift-detector scaffold) in dispatch wave 3. R-WP13/R-WP14/R-WP15 IDs reserved during the S7 close-out edit are NOT used — concrete WP IDs are R-WP10a/R-WP11a/R-WP12-WPA/R-WP12-WPB. | n/a (decided) |
| OQ-R6 | DECIDED-S8 | Wave 5 (S9) sequencing: WP-D (type-drift detector full report — R-WP17) runs first so OPS-T1 priority decision (R-WP21) has empirical evidence. Other Wave 5 WPs (R-WP18/19/20) run in parallel where dependencies allow. | n/a (decided) |
| OQ-R7 | DEFERRED | R-WP11a implementation form: CLI (scripts/rename-sweep.ts) vs skill (.claude/skills/ast-dataflow-rename-sweep/SKILL.md). Brief recommends CLI; skill is more agent-discoverable but requires create-skill + skill-efficacy evaluation. | S8 Wave 1 planning. |
| OQ-R8 | DECIDED-S10 | CI lint gate. Shipped S10 WP1 (c99f5953) as type-drift-parity job in .github/workflows/ci.yml. Baseline ratchet semantics: PR adding a new fetcher-only interface fails CI unless baseline is explicitly updated in the same PR. | n/a (decided) |
| OQ-R9 | DEFERRED | Opaque-Json RPC migration appetite (R-WP19 input). If WP-C inventory shows ≥8 of 14 RPCs are straightforwardly convertible to RETURNS TABLE(...), is a migration sprint warranted? | After R-WP19 inventory lands (Wave 5). |
Cross-cutting risks
Section titled “Cross-cutting risks”- ts-morph cold-start is ~3-4 s on KH corpus. Every query inherits this.
Iterative invocations (one symbol per call) bear the cost N times.
Mitigation: batch-input flags where applicable (
dead-exports --symbols <file>,flow-traceand others), keeping the corpus load amortised across the symbol set in a single CLI invocation. - Spec drift between PRODUCT.md and TECH.md. S4 WP1 caught the
inferred→wildcardconfidence-name drift. Mitigation: every WP commits PRODUCT.md + TECH.md edits in the same commit as the implementation, and theLast verifiedheader bumps each time.flow-trace-TECH.mdwas a sub-spec with its own header; folded intoTECH.md§Query implementations on 18/05/2026 (kh-ast-S9 Wave 1). - Worktree agent baseline drift. S4 WP3 reset to the wrong base SHA and the
cherry-pick auto-merged but pinned a stale
toHaveLength(8)that S4 WP1 had invalidated. Mitigation: the brief for any worktree agent that touches files modified in earlier waves must explicitly call out the post-wave base SHA; the orchestrator validatesgit log --oneline -1in the agent’s response. S5/S6/S7 dispatch all carried this rule forward without recurrence. - CWD drift in shell tool calls (S5–S7 recurrence). Worker agents
occasionally commit to the parent’s branch via shell CWD drift when they
Readcross-worktree files. Mitigation: dispatch with an explicit “commit ONLY to your worktree branch” rule; verify post-dispatch withgit log --oneline -1from both worktree and parent; cherry-pick if needed. Long-standing CLAUDE.md “Bash CWD drifts into worktree dirs” gotcha.
Carried forward to production-readiness
Section titled “Carried forward to production-readiness”Items migrated from this worktree to the production-readiness track at S11 close. Added to the production-readiness backlog as part of R-WP-S11-D (cross-track merge execution) or as a post-merge commit on that track.
| Item | Description | Effort | Provenance | Status |
|---|---|---|---|---|
| R-WP22 | MCP outputSchema full rollout (~53 remaining tools beyond the 5-tool scaffold in R-WP20). Multi-agent parallelisation candidate. | ~29h | source-session: kh-ast-S9; surfaced-by: R-WP20 commit c98d5f1c | MIGRATED-to-production-readiness (kh-ast-S11 Wave 1 housekeeping). migrated-to: production-readiness backlog (WP-D post-merge commit). |
| R-WP9 | Cache layer (TECH.md §Cache strategy). Follow cocoindex-code pattern with local LMDB if/when a smoke query breaches the 10 s P-19 budget. | ~3h | No current load-bearing trigger; carried from Wave 7. | SUPERSEDED-id-375 — facts cache rejected by measurement; warm path is the MCP server (PRODUCT.md A2). |
| OQ-R9 | Opaque-Json RPC migration appetite. 5-RPC Tier 1+2 sprint (~7h) queued after Phase 1 canonical-pipeline migration settles. | ~7h | R-WP19 inventory (kh-ast-S9) | Carry-forward — production-readiness backlog post-S11 merge. |
| AST-S3-O1 | column-reads --exclude-tests extended to cover test-adjacent infrastructure (scripts/mcp-eval/, e2e/fixtures/). | ~1h | kh-ast-S3 | SHIPPED — chore/outstanding-cleanup-investigation (es2018 + AST follow-ups commit). |
| AST-S3-O2 | wildcard confidence tier in column-reads for .select('*') calls. | ~1h | kh-ast-S3 | SHIPPED — S4 WP1 commit 9fe9b387 (ledger drift corrected at S57). |
Maintenance
Section titled “Maintenance”This doc is updated end-of-session for any session where a roadmap WP ships,
where a deferred-OQ decision lands, or where the strategic shape of the work
changes (e.g. R-WP10/11/12 outcomes restructuring the wave table). The
Last verified header bumps in the same commit. Out-of-session changes
(e.g. a new gap surfaces during normal work) are filed as a TODO at the
bottom of the relevant section and resolved in the next roadmap-touching
session.
Redaction note (04/08/2026, id-377 D7). Client-name tokens in this file were redacted per
the ID-115 redaction map (specs/id-115-data-api-schema-isolation/CUTOVER-RUNBOOK.md step 3;
full rule set in runbooks/_archive/id68-purge-redaction-map-draft.md). One occurrence:
the auth-hook identifier in the R-WP19 row, which now reads
hook_restrict_signup_to_allowed_domain — the client-neutral name that superseded it at
canonical HEAD (ID-68 {68.21}). No other content was changed by the redaction pass.