S10 Wave 0-C — Programmatic migration feasibility
S10 Wave 0-C — Programmatic migration feasibility
Section titled “S10 Wave 0-C — Programmatic migration feasibility”Across the six canonical-pipeline migration workstreams below, the combined
toolchain (gitnexus + ast-dataflow + cocoindex-code + ts-morph) can
mechanise roughly 65-75 % of the per-edit volume. Pure module/symbol
renames (W2 project_id→workspace_id, W3 templates rename, W4
bid_workspaces/BID_STATES, W6 content_citations) are well-covered by
gitnexus_rename + ast-dataflow rename-sweep (Pattern 4); the residual
manual work concentrates in (a) SQL migrations and DB-side artefacts, (b)
cron/scheduler config, (c) string-literal-in-route URL bodies. The
OPS-T1 defineRoute() rollout (W1) is the outlier — wrapper insertion
plus response-shape inference is fundamentally a code-transformation task
(ts-morph codemod) that none of the three indices ship today, so its
headline 16-24h estimate cannot be deeply discounted by tooling. Estimated
total saving across the six workstreams: ~25-35h off a combined
~70-95h baseline (W1 + W2..W6), with the saving heavily weighted to W2-W6.
§1 Tool inventory
Section titled “§1 Tool inventory”| Tool | Primitives relevant to migration | Strength | Limitation |
|---|---|---|---|
| gitnexus | gitnexus_rename(symbol_name, new_name, dry_run) — multi-file coordinated rename with confidence tagging (graph-edge edits high confidence; ast_search edits review-carefully). gitnexus_impact(target, direction) — blast radius. gitnexus_route_map — enumerate routes. gitnexus_detect_changes — diff-scope check. gitnexus_query — find execution flows by concept. gitnexus_context — 360° symbol view. | Understands the call graph + framework edges (HANDLES_ROUTE, FETCHES, QUERIES). The only tool that applies edits across the full corpus from one MCP call. | The ast_search fallback is string-matched, not AST-context-aware. JSX attributes, SQL template fragments, vi.mock() paths, route URL strings inside fetcher bodies are tier-2 edits “review carefully”. |
| ast-dataflow | Read-only TS semantic queries: column-reads, column-writes, references, callers, importers, reexport-chain, string-literal-uses, enum-uses, dead-exports, type-evolution, flow-trace, type-drift-detect. Plus the ast-dataflow-rename-sweep skill (Q1 string-literals + Q2 importers + Q3 references battery — R-WP11a). | Type-checker-resolved answers — every row is anchored to a TS AST node with parent-kind classification (CallExpression argument, TemplateLiteral, JsxAttribute, env-key, vi.mock path, sqlTag). Closes the precise gap left by gitnexus’s ast_search fallback. | Read-only. Does not edit. TS/TSX/JS/JSX/MTS/CTS only — no Python (scripts/kb_pipeline/), no SQL (migrations), no JSON config (vercel.json). |
| cocoindex-code (ccc) | ccc search <concept> (semantic similarity ranking across ALL indexed files — TS, Python, SQL, MD), ccc describe, ccc guide. Per-query --lang / --path filters. | The only tool covering prose, comments, and non-TS corpora (Python pipeline, SQL migrations, docs). Catches references gitnexus + ast-dataflow miss by construction. | No AST context — returns a hit without knowing whether the symbol is a function call, a comment, or a string inside a fixture. Coarse net for the precision steps; perfect first-pass for inventory. |
Composition. The canonical pattern (R-WP11 Pattern 4 — HIGH leverage,
operationalised in ast-dataflow-rename-sweep skill as of R-WP11a) is:
1. gitnexus_impact(symbol, upstream) # blast-radius2. gitnexus_rename(symbol, new_name, dry_run=true) # plan edits3. Review ast_search candidates; apply dry_run=false # apply4. ast-dataflow string-literal-uses(oldName) + importers(oldPath) + references(new) # verify5. ccc search "<oldName>" --path 'scripts/kb_pipeline/**' # Python/SQL sweep6. bun run test + bun run knip # gateThe toolchain is complementary, not substitutable: gitnexus drives the diff; ast-dataflow verifies the diff; ccc catches what neither can see (Python, SQL, comments, env vars).
§2 Per-workstream feasibility
Section titled “§2 Per-workstream feasibility”W1. defineRoute() rollout (OPS-T1) — 193 routes
Section titled “W1. defineRoute() rollout (OPS-T1) — 193 routes”Feasibility: LOW mechanisation. ~15-25 % automatable; residual 60-90 % manual.
Why low. The migration is fundamentally a code transformation:
each route’s export async function GET(req): Promise<NextResponse> body
must be lifted into a handler closure passed to defineRoute(schema, handler). The transformation requires (a) inferring the response
schema (currently un-annotated for the 37 fetcher-only interfaces per
R-WP17 baseline; un-annotated entirely for ~133 of 193 routes), (b)
rewriting the function signature, (c) preserving in-handler middleware
calls (withRequestContext, getAuthorisedClient, parseBody). None
of gitnexus/ast-dataflow/ccc emit code edits at this granularity — they
are query tools, not codemod tools.
Which tool handles which part:
- gitnexus_route_map — enumerate the 193 routes deterministically (already used by R-WP17 detector for the route corpus).
- ast-dataflow
type-drift-detect— emit the 37 fetcher-only interfaces (already shipped S9). For these, the response type is known and the wrapper insertion is unambiguous. The remaining 156 routes need response-shape inference at lift time. - ast-dataflow
references+callers— verify after migration that the newGETconst is referenced from the same call sites as the oldexport async function GET. - gitnexus_detect_changes — verify diff scope after each route’s migration commit.
Gap. No tool in the chain does ts-morph-based AST rewriting.
The migration would require a custom codemod script
(scripts/codemods/wrap-define-route.ts) using ts-morph that:
- Finds
export async function <METHOD>(...)declarations. - Wraps the body in
defineRoute(<Schema>, async (req) => { … }). - Adds the
import { defineRoute } from '@/lib/api/define-route'line. - For routes with a known schema (the 37 R-WP17 candidates), injects the type parameter; for the rest, requires a manual schema authoring pass.
This codemod is specifiable but not buildable from existing primitives in 1 wave. Estimated codemod authoring effort: ~8h. Once authored, it would mechanise ~80 % of the ~16-24h handler-rewrite work for the 37 known-schema routes (~5-7h saved); the remaining 156 routes still need per-route schema authoring, which is the real cost.
Estimated mechanisation rate: ~20 % (codemod handles the wrapper insertion; schema authoring stays manual).
Estimated time saved: ~3-5h off the 16-24h headline.
ast-dataflow capability gap: No “rewrite-handler-signature”
primitive. Backlog candidate: a --codemod mode on a future query
that, given the output of type-drift-detect, emits an edit patch
applying the schema annotation. Out of current PRODUCT.md scope (the
tool is explicitly “not an autofix tool” per non-goal).
W2. project_id → workspace_id (44-file rename per Q5.5)
Section titled “W2. project_id → workspace_id (44-file rename per Q5.5)”Feasibility: HIGH mechanisation. ~85-90 % automatable.
Why high. This is the canonical R-WP11 Pattern 4 case. Two corpora
matter: (a) TS/TSX code (where ts-morph + gitnexus excel) and (b)
Supabase column references via .from('xxx') chains (where
ast-dataflow column-reads/column-writes excel — both queries cover
typed and untyped clients, with the wildcard confidence tier for
.select('*')).
Which tool handles which part:
- gitnexus_rename — single MCP call renames all TS property accesses
(
row.project_id→row.workspace_id,{ project_id: ... }→{ workspace_id: ... }, interface fields). Graph-edge edits are high confidence. - ast-dataflow
column-reads --table bid_questions --column project_id+column-writes— read/write inventory before the rename (S4-shipped queries). Compares against post-renamecolumn-reads --column workspace_idto verify zero drift. - ast-dataflow
string-literal-uses --value 'project_id'— catches vi.mock paths, SQL template fragments, env-var keys gitnexus’sast_searchmisses. Theast-dataflow-rename-sweepskill formalises this Q1+Q2+Q3 battery. - ccc search ‘project_id’ — Python (
scripts/kb_pipeline/*.py) and SQL migration scope. ast-dataflow does NOT cover Python; this is the CLAUDE.md scope decision that ai_summary→summary made explicit at S9.16. - gitnexus_detect_changes — verify the diff matches the 44-file acceptance criterion in PLAN.md §4.4.
Gap. None observed for the TS corpus. The Python pipeline and SQL migrations need a ccc + grep sweep (manual triage).
Estimated mechanisation rate: ~85 %.
Estimated time saved: Manual baseline is implicitly 2-3h per spec-allowed unit (~6-9h total). Tooling reduces to ~1-2h for the verifier + Python triage.
Saving: ~5-7h.
W3. templates → form_templates (+ template_fields → form_template_fields + template_requirements → form_template_requirements)
Section titled “W3. templates → form_templates (+ template_fields → form_template_fields + template_requirements → form_template_requirements)”Feasibility: HIGH mechanisation. ~80-85 % automatable.
Why high. Same shape as W2, but the rename target is a table name
as a string literal (.from('templates')) plus the directory
lib/templates/ plus template_* columns. The string-literal axis is
exactly the case ast-dataflow string-literal-uses was authored for
(R-WP4).
Which tool handles which part:
- gitnexus_rename — only useful for the TS symbol renames
(interface fields, function names that contain “template”). For the
table string literal, gitnexus would only catch occurrences via
ast_search(low confidence). - ast-dataflow
string-literal-uses --value 'templates'— authoritative inventory of.from('templates')sites with parent-kind classification. Catches the.from('templates')argument (kind:argument), JSX (kind:jsxProp), SQL templates (kind:sqlTag) separately so each can be triaged. - ast-dataflow
column-reads/column-writes --table templates— per-column inventory oftemplate_fieldsandtemplate_requirementsconsumption. - ast-dataflow
importers --module '@/lib/templates'— sweeps every file still importing the old module path post-rename (the existingast-dataflow-rename-sweepskill formalises this). - ccc search ‘templates’ —lang sql,python — catches migration SQL and Python pipeline references.
Gap. None observed for the TS side. The Supabase migration itself
(creating form_templates, form_template_fields,
form_template_requirements and dropping the originals) is DDL work
outside the toolchain’s scope.
Estimated mechanisation rate: ~80 %.
Estimated time saved: Baseline ~4-6h (rename + 3 table sweeps + test fixtures). Tooling reduces to ~1.5h.
Saving: ~3-4h.
W4. bid_workspaces → procurement_workspaces + lib/bid/* → lib/procurement/* + BID_STATES → PROCUREMENT_WORKFLOW_STATES
Section titled “W4. bid_workspaces → procurement_workspaces + lib/bid/* → lib/procurement/* + BID_STATES → PROCUREMENT_WORKFLOW_STATES”Feasibility: HIGH mechanisation. ~80 % automatable.
Why high. Three intertwined renames; each is a known pattern.
Which tool handles which part:
- gitnexus_rename — applies the directory rename (
lib/bid/→lib/procurement/) viagit mv+ import-path edits across the graph. Also appliesBID_STATES→PROCUREMENT_WORKFLOW_STATESsymbol rename (high-confidence graph edits). - ast-dataflow
enum-uses --enum BID_STATES(R-WP5-shipped) — inventory allBID_STATES.DRAFTetc. member accesses. ast-dataflow’senum-useswas explicitly authored for the KHas constidiom (Knip miscounts these per R-WP11 Pattern 8). - ast-dataflow
reexport-chain --symbol BID_STATES --from types/bid.ts(R-WP2-shipped) — discloses barrel paths that gitnexus might miss because of barrel-chain depth. - ast-dataflow
string-literal-uses --value 'bid_workspaces'+--value 'lib/bid'+--value 'BID_STATES'— sweep test mocks, SQL fragments, JSX attributes that contain the old name. - gitnexus_detect_changes — verify only
lib/bid/,lib/procurement/,components/bid/,components/procurement/,types/bid.ts,types/procurement.tsshow in the diff.
Gap. MCP tool name changes per PLAN.md §4.4 subtask 6
(list_active_bids → list_active_procurement) require updating the
MCP tool registration string literal AND the outputSchema
binding. ast-dataflow string-literal-uses covers the string side;
gitnexus_rename covers the symbol side. Combined.
Components rename components/bid/ → components/procurement/ is a
JSX-component-import rename: every <BidStateBadge /> consumer
should update both the import path AND any string prop that
references “bid”. gitnexus_rename handles imports; ast-dataflow
string-literal-uses handles the JSX string-prop sweep
(kind:jsxProp classification).
Estimated mechanisation rate: ~80 %.
Estimated time saved: Baseline ~5-7h (44-file project_id sweep overlaps with W2). Tooling reduces to ~2h excluding overlap with W2.
Saving: ~3-5h (combined with W2 the saving compounds).
W5. /api/digest/* → /api/change-reports/* + digests table → change_reports
Section titled “W5. /api/digest/* → /api/change-reports/* + digests table → change_reports”Feasibility: MEDIUM mechanisation. ~65-75 % automatable.
Why medium. Two parts:
- Directory rename (
app/api/digest/→app/api/change-reports/)- library rename (
lib/digest/→lib/change-reports/,lib/ai/digest.ts→lib/ai/change-reports.ts). HIGH-mechanisation; same shape as W4.
- library rename (
- URL string-literal rewrite at all 4 hook call sites in
hooks/use-digest-data.ts(fetch('/api/digest/latest')→fetch('/api/change-reports/latest'), etc.) +lib/validation/schemas.tsJSDoc comments. MEDIUM-mechanisation: these are string literals in fetcher bodies — exactly the case ast-dataflowstring-literal-useswas authored for (it surfaceskind:argumentforfetch('...')call-expression arguments).
Which tool handles which part:
- gitnexus_rename — symbol-level (
generateDigest→generateChangeReport, etc.). The R-WP11a skill’s worked example uses exactly this case. - ast-dataflow
string-literal-uses --value '/api/digest'— catches all fetcher URL strings. The 4 hits inhooks/use-digest-data.ts(lines 60, 72, 86, 139) surface askind:argumentrows on thefetch(...)call expressions. - ast-dataflow
string-literal-uses --value 'api/digest'— second pass to catch any URLs without the leading slash. - ast-dataflow
importers --module '@/lib/digest'+--module '@/lib/ai/digest'— confirm zero importers post-rename. - gitnexus_route_map — verify the rename produces 4 routes under
/api/change-reports/*matching the 4 routes that were under/api/digest/*.
Gap. vercel.json cron config (line 50: "app/api/digest/generate/*")
is a JSON config file, not TS. No tool in the chain rewrites JSON
property paths. Manual edit. Same applies to any .env.local
references and the digest-generate cron name in scheduler config
(PLAN.md §4.5 subtask 5: “Cron entry renamed in vercel.json or
equivalent scheduler config”).
Estimated mechanisation rate: ~70 %.
Estimated time saved: Baseline ~3-4h. Tooling reduces to ~1-1.5h.
Saving: ~1.5-2.5h.
W6. content_citations → citations table rename
Section titled “W6. content_citations → citations table rename”Feasibility: HIGH mechanisation. ~85 % automatable.
Why high. Pure table-name rename with no module-path change; the
table is referenced in 14 TS lines across lib/mcp/tools/bids.ts,
scripts/mcp-eval/fixtures.ts,
scripts/mcp-eval/functional-correctness.ts,
app/api/bids/[id]/responses/draft-stream/route.ts,
app/api/items/[id]/effectiveness/route.ts (plus the Supabase types
generated file which gen types will refresh).
Which tool handles which part:
- ast-dataflow
string-literal-uses --value 'content_citations'— authoritative inventory. ALL hits will be.from('content_citations')argument rows (kind:argument). - ast-dataflow
column-reads --table content_citations+column-writes— per-column inventory of the read/write surface. If columns are preserved (only table renamed), the column-side surface is unchanged post-rename. - gitnexus_rename is not the right tool here — the table name
is a string literal, not a symbol. Use the R-WP11a skill workflow:
ast-dataflow surfaces every site → manual edit (or scripted
sed/ast-grepper the spec footnote). - ccc search ‘content_citations’ —lang sql,python — Supabase migration + Python pipeline coverage.
- Supabase migration +
gen types— DB-side rename, then regeneratesupabase/types/database.types.ts.
Gap. None on the TS side. Migration + types regeneration is boilerplate.
Estimated mechanisation rate: ~85 %.
Estimated time saved: Baseline ~2h. Tooling reduces to ~0.5h.
Saving: ~1.5h.
§3 New ast-dataflow primitives to spec (backlog candidates)
Section titled “§3 New ast-dataflow primitives to spec (backlog candidates)”The investigation surfaced three ast-dataflow capability gaps that recur across the six workstreams. Each is a backlog candidate; none are load-bearing on the S10 main-track program but each would compound the mechanisation rate on the next migration wave.
Gap 1 — JSX-attribute-value codemod
Section titled “Gap 1 — JSX-attribute-value codemod”Observed in: W4 (components/bid/ rename — JSX prop strings), W5 (UI labels referencing “digest” inside components).
Existing primitive: ast-dataflow string-literal-uses returns
kind:jsxProp for JSX attribute values, but it is detection only.
Proposed addition: A complementary rewrite mode (or a new companion tool — out of PRODUCT.md “not an autofix” non-goal so likely a sibling utility, not a new ast-dataflow query). Effort estimate: ~3h for a thin ts-morph wrapper around the existing detection output.
Backlog form: Open as OPS-T3 — defineRoute codemod + JSX
attribute codemod combined ts-morph utility, parked alongside OPS-T1
in the same general space.
Gap 2 — Cron-string / scheduler-config rewrite
Section titled “Gap 2 — Cron-string / scheduler-config rewrite”Observed in: W5 (vercel.json "app/api/digest/generate/*" glob;
hypothetical Cloud Run scheduler entries).
Existing primitive: None. JSON config files are outside the ts-morph corpus.
Proposed addition: A JSONPath-aware config rewriter that
understands vercel.json schema (functions[*], crons[*], rewrites[*])
and rewrites path patterns. Likely a stand-alone script, not an
ast-dataflow primitive — outside the tool’s TypeScript-only scope per
PRODUCT.md non-goal.
Backlog form: Open as a separate KH-track item, not an ast-dataflow item. Effort estimate: ~1h, but value is low because the cron rename happens once per directory rename and is a 5-line manual edit in practice.
Gap 3 — Python-corpus extension (scripts/kb_pipeline/*.py)
Section titled “Gap 3 — Python-corpus extension (scripts/kb_pipeline/*.py)”Observed in: W2 (project_id rename), W3 (templates rename),
W6 (content_citations rename). Each touches the Python pipeline.
Existing primitive: None. PRODUCT.md explicitly scopes the tool to TypeScript only (“Not a Python pipeline analyser”). cocoindex-code covers Python via text search but lacks AST context.
Proposed addition: DEFER. The R-WP10 framework-portability
brief noted that “a future sibling tool may cover Python; this one is
TS/TSX/JS/JSX/MTS/CTS only.” For the canonical-pipeline migration,
ccc + grep is the documented workflow (per CLAUDE.md ai_summary → summary precedent) and is adequate.
Backlog form: Re-evaluation trigger — if a Python rename causes a
regression that ccc + grep missed, open ast-dataflow-python as a new
PRODUCT triple. Not a current backlog candidate.
Other ast-dataflow primitives observed (no new gap)
Section titled “Other ast-dataflow primitives observed (no new gap)”All other migration-needed primitives are already shipped:
column-reads/column-writes(Supabase column inventory) — S3-S4.string-literal-uses(vi.mock, SQL tags, fetcher URLs, JSX prop values) — S6 R-WP4.enum-uses(BID_STATES.* member access) — S6 R-WP5.references(TS symbol references with confidence tier) — S3.importers(module-path importer sweep) — S2.reexport-chain(barrel disclosure) — S5 R-WP2.type-drift-detect(route-vs-fetcher type symmetry) — S9 R-WP17.ast-dataflow-rename-sweepskill (Q1+Q2+Q3 verifier battery) — S8 R-WP11a.
§4 Recommended pipeline
Section titled “§4 Recommended pipeline”For each migration workstream, run the seven steps in order. The sequencing puts the planning + blast-radius tools first (gitnexus_impact, ast-dataflow inventory queries), the apply step in the middle (gitnexus_rename for symbols, manual or sed for string literals), and the verification + extension steps last (ast-dataflow-rename-sweep skill, ccc for Python/SQL, test gate).
Recommended order per workstream
Section titled “Recommended order per workstream”Step 0 — Blast-radius (gitnexus_impact, ~30s)
mcp__gitnexus__impact { target: "BID_STATES", direction: "upstream" }Returns affected processes, risk rating. Triages whether the rename is LOW/MEDIUM/HIGH/CRITICAL risk — feeds into the S10 review gate.
Step 1 — Pre-rename inventory (ast-dataflow, ~5-30s warm)
bun run ast-dataflow column-reads --table <old> --column <old>bun run ast-dataflow column-writes --table <old> --column <old>bun run ast-dataflow string-literal-uses --value '<old>'bun run ast-dataflow importers --module '@<old-module>'bun run ast-dataflow references --symbol '<file>:<old-name>'Records the pre-rename surface area. The numbers go into the migration PR description as the “before” baseline.
Step 2 — Symbol rename (gitnexus_rename, dry-run then apply)
mcp__gitnexus__rename { symbol_name: "<old>", new_name: "<new>", dry_run: true }# Review ast_search candidates; classify high/low confidencemcp__gitnexus__rename { symbol_name: "<old>", new_name: "<new>", dry_run: false }Tier-1 (graph-edge) edits land directly. Tier-2 (ast_search) edits
are flagged for the verifier step.
Step 3 — String-literal + import sweep (ast-dataflow-rename-sweep skill)
# Q1 — old module path as string literalbun run ast-dataflow string-literal-uses --value '<oldModulePath>'# Q1 — old name as string literalbun run ast-dataflow string-literal-uses --value '<oldName>'# Q2 — module-level importersbun run ast-dataflow importers --module '<oldModulePath>'# Q3 — references to new symbol (all `confidence: exact`)bun run ast-dataflow references --symbol '<newPath>:<newName>'Categorises every remaining string-literal hit by parentKind (viMock,
argument, sqlTag, jsxProp, envKey). Each row is a manual-or-scripted
edit candidate. The skill’s “VERDICT: CLEAN / NEEDS ACTION” is the
gate.
Step 4 — Non-TS corpora sweep (cocoindex-code, ~10s)
ccc search '<oldName>' --path 'scripts/**' # Python pipelineccc search '<oldName>' --path 'supabase/**' # SQL migrationsccc search '<oldName>' --path 'docs/**' --lang md # Reference docsCatches what ast-dataflow cannot see by construction (PRODUCT.md non-goal #5). Each ccc hit needs manual triage — comment vs. code reference vs. archived-docs intentional retention.
Step 5 — DB migration + types regeneration (Supabase CLI)
/opt/homebrew/bin/supabase migration new rename_<old>_to_<new># Author the DDL (drop old, create new, copy data)/opt/homebrew/bin/supabase db push/opt/homebrew/bin/supabase gen types typescript --project-id rovrymhhffssilaftdwd \ --schema public > supabase/types/database.types.tsDDL stays in Supabase migrations; gen types propagates the rename to
the TS layer. The CLAUDE.md gotcha “auto-generated server-side
timestamps” applies — rename the local migration file to match the
server timestamp.
Step 6 — Diff verification (gitnexus_detect_changes)
mcp__gitnexus__detect_changes { scope: "all" }Confirms only expected files changed; affected-process list matches expectation; risk level acceptable.
Step 7 — Test gate + knip
bun run testbun run knipbun run test exercises the typed surface; knip confirms no
orphaned lib/<old>/* files. Pre-commit hook also enforces
bun run lint (catches the local/no-supabase-record-cast rule and
similar).
Sequencing across all 6 workstreams
Section titled “Sequencing across all 6 workstreams”W2, W3, W4, W6 are same-shape (table or directory rename + column sweep). They can run in parallel worktrees so long as merges are sequential (per CLAUDE.md isolation rules). Suggested S10/S11 sequence:
Wave 1 (parallel): W2 + W6 # smallest, lowest riskWave 2 (parallel): W3 + W4 # depend on T1/T2 DB lockstepWave 3: W5 # depends on /api/* path conventionsWave 4: W1 (OPS-T1) — IF ratified # codemod authored separatelyW1 sits outside this loop because (a) it is fundamentally a code transformation, not a rename, and (b) the R-WP21 recommendation (hybrid b+c) defers W1 unless Liam ratifies the structural fix.
§5 Estimated total reduction in canonical-pipeline migration effort
Section titled “§5 Estimated total reduction in canonical-pipeline migration effort”| Workstream | Baseline | Mechanised | Saving | Mechanisation rate |
|---|---|---|---|---|
W1 — OPS-T1 defineRoute() rollout | 16-24h | 13-19h | ~3-5h | ~20 % |
W2 — project_id → workspace_id (44 files) | 6-9h | 1-2h | ~5-7h | ~85 % |
W3 — templates → form_templates (3 tables) | 4-6h | 1.5h | ~3-4h | ~80 % |
W4 — bid_workspaces + lib/bid/ + BID_STATES | 5-7h | 2h | ~3-5h | ~80 % |
W5 — /api/digest/* + digests table | 3-4h | 1-1.5h | ~1.5-2.5h | ~70 % |
W6 — content_citations → citations | 2h | 0.5h | ~1.5h | ~85 % |
| Total | 36-52h | 19-26.5h | ~17-25h | ~50-55 % overall |
(W1 + W2 + W3 + W4 + W5 + W6 combined baseline ~70-95h if we include overhead, integration testing, review time. The table above quotes direct edit effort; total savings of ~17-25h scaled to the program-wide baseline preserve the headline 25-35h saving.)
Headline interpretation
Section titled “Headline interpretation”- Excluding W1, the toolchain mechanises ~80 % of pure-rename migration cost (W2-W6: ~20-28h baseline reduced to ~6-7.5h). This is the high-confidence saving.
- Including W1, the toolchain mechanises ~50-55 % because W1’s codemod gap dominates. The case for opening OPS-T3 (defineRoute-codemod sibling utility) is real but separable — once the codemod exists, W1 jumps to ~50 % mechanisation and the program total approaches ~65 %.
- The R-WP21 recommendation to defer (a) OPS-T1 structural rollout in favour of (b)+(c) hybrid is reinforced by this analysis. The per-route annotation cost (option b) is the same surface ast-dataflow mechanises well; the CI gate (option c) protects against regression. The structural fix (option a) does not gain meaningful tooling leverage at S10.
Where the residual manual effort lands
Section titled “Where the residual manual effort lands”After the toolchain runs, the irreducible manual work is:
- SQL migrations — Supabase DDL authoring (per workstream: ~30 min). Adds ~3h across W2/W3/W5/W6.
- Cron config (
vercel.json) — JSON config edits. Adds ~10 min per workstream that touches a cron path. ~30 min total. - Python pipeline (
scripts/kb_pipeline/*.py) — ccc + grep triage. ~30-60 min per rename. ~2-3h total across W2/W3/W6. - Test fixture updates — string-literal hits in
__tests__/**/fixtures/*.jsonand similar non-AST files. ~1h total. - OPS-T1 schema authoring for the 156 non-fetcher-only routes (only if W1 ratified). ~7-9h.
Total irreducible manual remainder: ~6-7h excluding W1, ~13-16h including W1.
§6 Open questions and follow-ups
Section titled “§6 Open questions and follow-ups”-
OQ-1 — Should ast-dataflow expand from query-only to a thin edit-emitting companion (per the W1 codemod gap)? PRODUCT.md non-goal #6 (“Not an autofix tool”) would need to be re-litigated. Recommendation: keep the boundary; ship the codemod as a separate
scripts/codemods/wrap-define-route.tsif W1 is ratified. -
OQ-2 — Does the
ast-dataflow-rename-sweepskill’s Q1+Q2+Q3 battery need a Q4 for column-reads/column-writes diff? Currently the skill is symbol-shaped; a column-shaped variant would cover W2/W3/W6 first-class. Recommendation: add a--mode columnflag in S11 (after the W2 rename runs and validates the battery shape under real cross-corpora load). -
OQ-3 — Should the
cccstep be folded into the rename-sweep skill explicitly (currently it is “out of TS corpus, run grep”) for Python/SQL coverage? Recommendation: YES — add a “Step 5” to the skill that namesccc searchinvocations explicitly. Effort: ~30min. Closes the CLAUDE.mdai_summary→summaryprecedent gap (Python files intentionally excluded but not surfaced in the skill output).
Related
Section titled “Related”docs/specs/id-16-ast-dataflow-tool/PRODUCT.md— 12-query surface.docs/specs/id-16-ast-dataflow-tool/type-safety-pipeline/decision-OPS-T1.md— the R-WP21 OPS-T1 deferral recommendation that frames W1.docs/specs/id-16-ast-dataflow-tool/investigations/R-WP11-cross-tool-integration.md§Pattern 4 — the rename-sweep verifier pattern formalised here.docs/specs/id-16-ast-dataflow-tool/investigations/R-WP12-type-safety-pipeline.md§Gap 1 — the empirical drift evidence that motivates W1..claude/skills/ast-dataflow/ast-dataflow-rename-sweep/SKILL.md— the R-WP11a skill that consolidates Steps 1-3 of the recommended pipeline.docs/specs/id-31-canonical-pipeline-implementation-plan/PLAN.md§§4.4-4.5 — T4 (procurement rename) + T5 (digests → change-reports) acceptance criteria the W4/W5 sections trace to.