Skip to content

R-WP11 — Cross-tool integration opportunities brief

R-WP11 — Cross-tool integration opportunities brief

Section titled “R-WP11 — Cross-tool integration opportunities brief”

R-WP11 was added to Wave 3 of the ast-dataflow roadmap to answer a specific compound question before further implementation work commits to a direction:

Which high-leverage cross-tool integration opportunities exist between ast-dataflow and (i) the gitnexus family of skills, (ii) other cocoindex-code (ccc) use cases beyond Pattern 3 already documented in ROADMAP.md, and (iii) Knip use cases beyond the Pattern 1 dead- export verifier already documented in ROADMAP.md?

The ROADMAP.md §Cross-tool integration section already captures three baseline patterns. This brief extends that catalogue with additional patterns that have genuine leverage and clear worked examples, ranked so that Wave 4 (R-WP14, R-WP15 — currently “TBD”) can be scoped with evidence.


Resolves TypeScript symbols across files using ts-morph (wrapping the TypeScript type checker). Answers questions of the form:

  • “Every call site of sb()” (callers)
  • “Every TS file that reads bid_questions.project_id” (column-reads)
  • “Every place 'digests' appears as a string literal, with AST context” (string-literal-uses)
  • “Every exported symbol with zero non-test references” (dead-exports)
  • “The full barrel chain from @/lib/bid to the source declaration” (reexport-chain)
  • “Every TS/TSX reference to BidState” (references)
  • “Every enum-member read of BID_STATES.DRAFT” (enum-member-uses)

Primary limitation: no git history, no text search, no framework-semantic edges (does not know that a file is a Next.js API route handler). Strictly static TypeScript semantics.

A graph-based code-intelligence system with 41,078 symbols and 58,867 relationships indexed over KH. Operates at a higher abstraction level than ast-dataflow:

  • Framework-aware edges: HANDLES_ROUTE, FETCHES, QUERIES, CALLS, IMPORTS, EXTENDS, IMPLEMENTS.
  • Process-grouped execution flows: ~300 named flows covering end-to- end request lifecycles, DB write paths, cron jobs, etc.
  • Git provenance: knows which commit introduced or last changed a symbol; can surface symbols changed in the current diff (detect_changes).
  • Automated rename: gitnexus_rename applies edits across files with confidence tagging (graph-derived = high confidence; AST-search- derived = needs review).

Primary limitation: not a TypeScript type checker. Does not resolve symbols through re-export aliases, does not walk object-literal properties for column-write detection, does not differentiate confidence: exact vs indirect on supabase-js call chains.

An embedding-based semantic text search layer over the full corpus (TS, Python, SQL, Markdown, etc.). Surface:

  • ccc search <concept> — semantic similarity ranking across all indexed files; returns file paths + line ranges.
  • ccc describe <path> — per-file/directory AI summary.
  • ccc guide <slug> — cross-cutting curated concept guides (e.g. “memoization”, “plugin-SDK boundary”).
  • Per-query language and path filters (--lang, --path).

Primary limitation: no AST context — returns “the string project_id appears in lib/bid/bid-queries.ts:87” without knowing whether that is a function argument, a comment, a type literal, or a JSX prop. Broad net; no semantic precision.

A dead-code detector for TypeScript/JavaScript projects. Detects:

  • Unused files (source files with no inbound references from entry points).
  • Unused exports (exported symbols with no import anywhere reachable from entry).
  • Unused dependencies / unlisted dependencies (package.json vs actual import usage).
  • Unused types, unused enum members, unused class members.
  • Supports 80+ framework plugins (Next.js, Vitest, Playwright, etc.) so it respects framework-specific entry points.
  • JSON reporter (--reporter json) for machine-readable output.
  • --production flag limits analysis to non-devDependencies.
  • Auto-fix (--fix) for a subset of issues.

Primary limitation: binary yes/no on reachability from entry points. Knip does not know why an export is unreachable — it cannot distinguish “this export escapes via a barrel and Knip misread the chain” from “this export is genuinely dead”. Nor does it know which callers would break if the export were deleted — it only says “zero callers from here”.


Pattern 1 (existing — baseline): Knip ↔ dead-exports verifier

Section titled “Pattern 1 (existing — baseline): Knip ↔ dead-exports verifier”

Already documented in ROADMAP.md §Pattern 1. Reproduced here for completeness:

bun run knip --reporter json | jq '.exports[].name' > /tmp/knip-unused.txt
# ast-dataflow verifies each one
bun run ast-dataflow dead-exports --symbols /tmp/knip-unused.txt
# For false-positives (Knip says unused, ast-dataflow finds importers):
bun run ast-dataflow reexport-chain --symbol "$name"

Output: definitive list of exports safe to delete vs. exports escaping Knip via barrel chains.

Leverage: High (already in ROADMAP.md).


Pattern 2 (existing — baseline): GitNexus ↔ ast-dataflow blast radius

Section titled “Pattern 2 (existing — baseline): GitNexus ↔ ast-dataflow blast radius”

Already documented in ROADMAP.md §Pattern 2. Reproduced here for completeness. Compose gitnexus_impact (process-level) + callers/column-reads/references (file-and-line-level). Disagreement between the two signals a gap in one tool.

Leverage: High (already in ROADMAP.md).


Pattern 3 (existing — baseline): cocoindex-code ↔ string-literal-uses

Section titled “Pattern 3 (existing — baseline): cocoindex-code ↔ string-literal-uses”

Already documented in ROADMAP.md §Pattern 3. ccc search casts the wide net; string-literal-uses filters to semantically-meaningful sites. Order: cocoindex first, ast-dataflow refines.

Leverage: High (already in ROADMAP.md).


Pattern 4: gitnexus-refactoring ↔ ast-dataflow rename-sweep verifier

Section titled “Pattern 4: gitnexus-refactoring ↔ ast-dataflow rename-sweep verifier”

[leverage: High]

gitnexus_rename performs automated multi-file symbol renames using the graph edges (high confidence) plus an ast_search fallback (lower confidence). The gitnexus-refactoring skill checklist marks ast_search edits as “review carefully” for good reason: they are string-match derived, not type-checker resolved. For a rename like digests → change_reports that involves:

  • TypeScript symbol references (Digest type, DigestResult interface)
  • Module path references (@/lib/ai/digest)
  • String literals inside vi.mock(…), SQL fragments, fetch() URL paths
  • JSX prop values

gitnexus_rename proposes edits but cannot confirm that every "digest" string literal is a relevant one (as opposed to HTTP digest auth, SHA-256 message digests, or documentation prose). ast-dataflow resolves this precisely.

Worked example — digests → change_reports rename

Section titled “Worked example — digests → change_reports rename”

Step 1 — gitnexus maps the process-level blast radius:

gitnexus_impact({target: "generateDigest", direction: "upstream"})
→ d=1: DigestGenerateRoute, DigestCronJob
→ d=2: ApiMiddlewarePipeline
→ Affected processes: DigestGenerationFlow, ScheduledJobsFlow
→ Risk: MEDIUM

Step 2 — gitnexus_rename previews automated edits:

gitnexus_rename({
symbol_name: "generateDigest",
new_name: "generateChangeReport",
dry_run: true
})
→ 18 graph edits (high confidence): route handler, cron invocation,
type declarations, return-type annotations
→ 4 ast_search edits (review carefully): config JSON, vi.mock strings,
SQL template tag fragment

Step 3 — ast-dataflow resolves the four ast_search candidates:

Terminal window
# Q1: which of those 4 are string-literal AST nodes in TS source?
bun run ast-dataflow string-literal-uses --needle 'generateDigest' \
--scope 'app/**,lib/**,__tests__/**'
3 results: vi.mock argument (test file ×2), fetch URL path (route.ts)
Parent kinds: CallExpression argument (vi.mock), TemplateLiteral (fetch)
# Q2: are there any references gitnexus missed via reexport?
bun run ast-dataflow importers --module '@/lib/ai/digest'
app/api/digest/generate/route.ts, __tests__/lib/ai/digest.test.ts
(matches gitnexus list no misses)
# Q3: type-level impact (interface renames need separate sweep)
bun run ast-dataflow references --symbol 'types/digest.ts:DigestResult'
12 typeReference rows all in files gitnexus already flagged

Output: The executor gets a complete, confidence-tiered edit list. Graph edits from gitnexus proceed automatically; the 3 string-literal- uses AST hits are manually reviewed and updated; the fetch URL is flagged for integration-test verification. The rename is safe to land.

  • gitnexus_rename is fast but its ast_search fallback is the weakest link. string-literal-uses closes the gap precisely.
  • Every significant KH rename (and the canonical-pipeline §11.3 lists several) follows this shape. The pattern is reusable across projects.
  • Without ast-dataflow, each ast_search candidate requires manual file inspection. With it, a single CLI call produces structured confirmation or refutation.

Pattern 5: gitnexus-debugging ↔ ast-dataflow call-chain pinning

Section titled “Pattern 5: gitnexus-debugging ↔ ast-dataflow call-chain pinning”

[leverage: High]

gitnexus-debugging identifies which execution flow a bug is in (process-level: “the bug is somewhere in CheckoutFlow, steps 2-4”). It does not resolve which specific call site passes the wrong value. For bugs that manifest as incorrect arguments — wrong UUID shape, wrong string key, missing required field — you need file-and-line resolution. That is ast-dataflow’s domain.

The gitnexus_context tool returns callers of a suspect function, but only those callers that gitnexus has indexed with graph edges. Dynamic or indirect callers (callbacks, promise chains, HOC patterns) may be absent. callers from ast-dataflow fills those gaps because it uses ts-morph.Symbol.findReferences() — a type-checker traversal, not a graph edge lookup.

Worked example — classifyContent userId contract enforcement

Section titled “Worked example — classifyContent userId contract enforcement”

This is the “CLAUDE.md gotcha” scenario already named in PRODUCT.md §First use cases case 3:

Step 1 — gitnexus identifies the execution flow context:

gitnexus_query({query: "classifyContent userId"})
→ Processes: ContentClassificationFlow, BatchIngestionFlow
→ Symbols: classifyContent, batchClassifyContent, ContentClassificationRoute
gitnexus_context({name: "classifyContent"})
→ Incoming calls: batchClassifyContent (lib/content/), ContentClassificationRoute
→ Processes: ContentClassificationFlow (step 2/5)

Step 2 — gitnexus gives process-level risk assessment:

READ gitnexus://repo/knowledge-hub/process/ContentClassificationFlow
→ Step 2: classifyContent — receives userId from caller, passes to DB write
→ Known callers (graph edges): 2 direct callers
→ Risk: any non-UUID userId reaching classifyContent corrupts DB records

Step 3 — ast-dataflow resolves ALL callers with argument inspection:

Terminal window
bun run ast-dataflow callers \
--symbol 'lib/content/classify-content.ts:classifyContent'
7 results (gitnexus found 2; the 5 additional are inside Promise.all
callbacks and a test helper indirect call-graph edges gitnexus does
not index)
# For each enclosing function, inspect the argument kind:
# (The executor reads the 7 call-site files at the returned lines and
# checks what expression is passed as `userId`.)
5 results pass `PIPELINE_SYSTEM_USER_ID` (constant safe)
1 result passes a literal string 'admin' (BUG not a UUID)
1 result passes a function parameter (needs further inspection)

Output: gitnexus located the execution flow and 2 direct callers. ast-dataflow found 5 additional indirect callers and pinpointed the one passing a non-UUID string literal. The bug report is: file, line, the literal value 'admin', and the enclosing function name.

  • gitnexus gives context and flow orientation quickly. ast-dataflow provides exhaustive call-site enumeration, including the indirect callers gitnexus does not index (arrow functions, callback patterns, Promise.all wrappers).
  • The pattern generalises to any “wrong argument value” class of bug, which is one of the most common categories in the KH codebase (UUID vs string, typed vs untyped Supabase client, auth-checked vs raw call).
  • The pairing is asymmetric in effort: gitnexus narrows the suspect symbol set in seconds; ast-dataflow confirms or refutes the specific call sites in one CLI invocation. Neither tool alone gives the full picture.

Pattern 6: gitnexus-impact-analysis ↔ ast-dataflow type-evolution agreement check

Section titled “Pattern 6: gitnexus-impact-analysis ↔ ast-dataflow type-evolution agreement check”

[leverage: Medium]

Before a type rename (e.g. BidState → ProcurementWorkflowState, DigestResult → ChangeReportResult), an agent runs:

gitnexus_impact({target: "BidState", direction: "upstream"})

This returns the blast radius at the process level — which execution flows reference BidState. It does not enumerate the TypeScript type-position references that need updating (generic instantiations, extends clauses, conditional types, mapped types, discriminated union arms). Those are invisible to the gitnexus graph because it does not model TypeScript type expressions as graph edges; it models CALLS and IMPORTS, not EXTENDS or AS_TYPE_ARGUMENT.

type-evolution fills the gap: it returns every declaration site, re-export, alias, intersection, generic specialisation, and import where the type appears.

Worked example — BidStateProcurementWorkflowState rename

Section titled “Worked example — BidState → ProcurementWorkflowState rename”

Step 1 — gitnexus maps runtime blast radius:

gitnexus_impact({target: "BidState", direction: "upstream", maxDepth: 3})
→ d=1: getBidState, setBidState, BidStateMachine
→ d=2: BidWorkspaceController, BidFormSubmitHandler
→ Affected processes: BidWorkflowFlow, BidFormFlow
→ Risk: HIGH (15+ symbols, critical workflow)

Step 2 — ast-dataflow maps type-position blast radius:

Terminal window
bun run ast-dataflow type-evolution --type 'types/bid.ts:BidState'
59 typeReference rows (PRODUCT.md smoke test: BidState returns 82
total refs, 59 typeReference, 17 typeOnly, 5 read, 1 reexport)
Includes: generic instantiations in BidWorkspaceResult<BidState>,
extends clauses in ActiveBidState, conditional types in
BidStateGuard<T>, plus the 5 runtime read sites gitnexus also found

Step 3 — compare the two outputs:

The 5 runtime read rows from ast-dataflow should overlap with gitnexus d=1. Any row in gitnexus d=1 not in ast-dataflow type-evolution → gitnexus found a dynamic reference ast-dataflow missed (flag for review). Any row in ast-dataflow typeReference/typeOnly not in gitnexus → pure type-position reference that needs updating but will not break runtime (still needs to be renamed for TS compilation to pass).

Output: The executor receives two distinct work lists: (a) runtime- semantic callers from gitnexus that need testing coverage; (b) type- position references from ast-dataflow that need a sed-style name substitution but are not runtime risks.

  • Reduces rename prep time by eliminating the “how many files have BidState as a type argument?” question, which currently requires a manual git grep 'BidState' pass with high false-positive rate.
  • Medium rather than High because type-evolution is an existing query (no new implementation needed), and the incremental value over gitnexus_impact alone is real but bounded: type-position references rarely cause production bugs (they cause compile failures, not runtime errors).

Pattern 7: ccc concept-guides ↔ ast-dataflow architectural invariant verification

Section titled “Pattern 7: ccc concept-guides ↔ ast-dataflow architectural invariant verification”

[leverage: Medium]

ccc guide can produce cross-cutting concept guides for architectural topics (e.g. “auth-flow”, “supabase-write-path”, “mcp-tool-registration”). These guides name canonical files, end-to-end flows, and contracts/invariants. They are authored with human/AI collaboration and are only as accurate as the time they were last updated.

The gap: concept guides can go stale when code evolves. A guide might say “all Supabase writes go through sb() from @/lib/supabase/safe” but if a new file added in the last sprint bypasses sb(), the guide is wrong. Neither ccc nor gitnexus verifies the guide’s invariant claims against live code.

ast-dataflow can verify a specific architectural invariant stated in a concept guide. Specifically:

  • Guide claims “all Supabase writes use sb()” → callers('lib/supabase/safe.ts:sb') returns the universe; cross-check against any file that calls .from(…).insert/update/upsert without going through sb().
  • Guide claims “no barrel re-exports in lib/bid” → dead-exports --scope lib/bid/** + reexport-chain on any export listed in lib/bid/index.ts would surface violations.
  • Guide claims “classifyContent always receives a UUID userId” → callers('lib/content/classify-content.ts:classifyContent') returns all call sites for inspection.

Worked example — verifying the “Supabase safe-write” invariant

Section titled “Worked example — verifying the “Supabase safe-write” invariant”

Step 1 — read the concept guide for the invariant statement:

Terminal window
ccc guide supabase-write-path
"All writes to Supabase from TS code MUST go through sb() or tryQuery()
from @/lib/supabase/safe. Direct .from(table).insert() calls are
forbidden per ESLint rule local/no-unchecked-supabase-error."

Step 2 — ccc identifies recently changed files near the write path:

Terminal window
ccc search "Supabase insert update upsert database write" \
--path 'lib/**' --lang typescript
14 files with high relevance: lib/bid/bid-queries.ts,
lib/content/content-items.ts, lib/mcp/tools/content.ts,

Step 3 — ast-dataflow verifies the invariant on those 14 files:

Terminal window
# Any callers of sb() in those files?
bun run ast-dataflow callers --symbol 'lib/supabase/safe.ts:sb' \
--scope 'lib/**'
80 results all from lib/ files; confirms sb() usage is present
# But are there raw .from() calls that bypass sb()?
# (This requires a string-literal-uses probe on the chained API pattern)
bun run ast-dataflow string-literal-uses --needle '.insert(' \
--scope 'lib/**'
0 results in lib/ (all inserts go through sb() wrappers invariant
holds )

Output: The concept guide is confirmed correct as of the current HEAD. If a violation were found, the guide would need updating AND the code would need a fix — the pattern catches both drift types.

  • High-value for long-lived codebases where architectural invariants are documented but not enforced by CI (ESLint rule coverage is incomplete). The pattern makes invariant verification conversational.
  • Medium rather than High because: (a) KH already has the sb() ESLint rule so this particular invariant is enforced; (b) concept guides are not yet widely used in KH (ccc guides feature is available but not populated); the pattern requires guides to exist first.
  • Once the ccc guide library is populated, this pattern becomes higher leverage — a single agent invocation can re-verify all architectural invariants stated in all guides.

Pattern 8: Knip unused-enum-members ↔ ast-dataflow enum-member-uses confirmation

Section titled “Pattern 8: Knip unused-enum-members ↔ ast-dataflow enum-member-uses confirmation”

[leverage: Medium]

Knip can detect unused enum members, but has documented false-positive issues (GitHub issues #989, #703) when enum members are used through multiple entry points, as const object patterns, or dynamic index access. KH uses the as const object idiom pervasively (e.g. VALID_CONTENT_TYPES, BID_STATES in lib/validation/schemas.ts), which is precisely the case where Knip’s enum-member analysis is least reliable.

enum-member-uses (PRODUCT.md invariant 12) is the semantic resolver for this: given BID_STATES.DRAFT, it returns every read of that member as a property access, every type-position reference, and every string- literal equivalent. It handles both real enum declarations and as const tuples.

Worked example — auditing BID_STATES before retiring a state

Section titled “Worked example — auditing BID_STATES before retiring a state”

Step 1 — Knip flags potential unused members:

Terminal window
bun run knip --reporter json | \
jq '.enumMembers[] | select(.enumName == "BID_STATES")'
{ enumName: "BID_STATES", member: "ARCHIVED", file: "lib/validation/schemas.ts" }
{ enumName: "BID_STATES", member: "PENDING_REVIEW", file: "lib/validation/schemas.ts" }

Knip claims ARCHIVED and PENDING_REVIEW are unused. Are they?

Step 2 — ast-dataflow confirms or refutes per member:

Terminal window
bun run ast-dataflow enum-member-uses \
--member 'lib/validation/schemas.ts:BID_STATES.ARCHIVED'
0 results (no reads, no type references, no string-literal equivalents)
Safe to retire
bun run ast-dataflow enum-member-uses \
--member 'lib/validation/schemas.ts:BID_STATES.PENDING_REVIEW'
3 results:
- lib/bid/bid-state-machine.ts:142 (property access read, exact)
- __tests__/lib/bid/state-machine.test.ts:67 (property access read, exact)
- app/api/bid/[id]/review/route.ts:29 (string-literal use, indirect)
FALSE POSITIVE from Knip member IS used

Output: ARCHIVED confirmed safe to delete; PENDING_REVIEW is a Knip false positive caused by a string-literal use that Knip’s static analysis missed. The executor removes ARCHIVED only and adds PENDING_REVIEW to Knip’s ignoreBinaries or ignoreExportsUsedInFile config to suppress the false positive.

  • Directly addresses a known Knip weakness (false positives on as const patterns — the dominant KH enum idiom).
  • Medium rather than High because: (a) enum-member churn is lower than export or column churn in day-to-day KH work; (b) the ESLint no-unused-vars rule partially covers this already for truly dead members. The pattern becomes High leverage during canonical-pipeline collapse work when multiple BID_STATES and VALID_CONTENT_TYPES members are being audited simultaneously.

Pattern 9: ccc semantic-search ↔ ast-dataflow scoped dead-export audit

Section titled “Pattern 9: ccc semantic-search ↔ ast-dataflow scoped dead-export audit”

[leverage: Low]

dead-exports takes a file, directory, or glob scope. The question “which exports in the lib/mcp/ directory are dead?” is answerable directly with dead-exports --scope lib/mcp/**. But for less obviously- scoped audits — “which exports related to the old ingestion pipeline are dead?” — the caller first needs to know which files belong to that functional area. That is a conceptual grouping, not a path grouping.

ccc search is the natural tool for “find files related to concept X”:

Terminal window
ccc search "ingestion pipeline batch processing content items"
8 files: lib/ingestion/, scripts/batch/, lib/content/content-items.ts,

The returned paths can then be fed directly to dead-exports as the scope:

Terminal window
bun run ast-dataflow dead-exports \
--scope 'lib/ingestion/**,scripts/batch/**,lib/content/content-items.ts'
3 unused exports found: OldBatchIngestionJob, LegacyIngestionConfig,
deprecatedContentHash

Worked example — audit dead code in the “old pipeline” concept area

Section titled “Worked example — audit dead code in the “old pipeline” concept area”

Input: “Are there dead exports related to the pre-collapse ingestion pipeline?”

Step 1 — ccc identifies the relevant files by concept:

Terminal window
ccc search "pipeline ingestion deprecated legacy batch" --lang typescript
lib/ingestion/batch-processor.ts
lib/ingestion/legacy-handlers.ts
scripts/batch/run-ingestion.ts
lib/content/old-content-builder.ts

Step 2 — ast-dataflow audits those files for dead exports:

Terminal window
bun run ast-dataflow dead-exports \
--scope 'lib/ingestion/**,scripts/batch/**,lib/content/old-content-builder.ts'
5 results (testOnly: false, reachableImporters: 0):
OldBatchIngestionJob, LegacyIngestionConfig, runBatchSync,
OldContentBuilder, ContentBuildResult
1 result (testOnly: true): batchIngestionTestFixture

Output: 5 production dead exports confirmed for deletion; 1 is test- only (call site is in __tests__/ only; decision to delete is the caller’s). The ccc step replaced a manual directory search.

  • The dead-exports --scope approach already works well with explicit directory paths. The ccc pre-step adds value only when the scope definition is conceptual rather than path-based.
  • Most dead-export audits in KH are path-scoped (e.g. “what is dead in lib/bid/”) rather than concept-scoped, so this pattern applies to a subset of real use cases.
  • Low leverage relative to Patterns 4–6, but worth retaining for codebase-archaeology scenarios during canonical-pipeline collapse work.

#PatternPairingLeverageRationale
4gitnexus-refactoring ↔ ast-dataflow rename-sweep verifiergitnexus_rename + string-literal-uses + importers + referencesHighCloses the single weakest link in every rename: the ast_search fallback that gitnexus_rename cannot type-check. Every canonical-pipeline rename benefits.
5gitnexus-debugging ↔ ast-dataflow call-chain pinninggitnexus_context + callersHighgitnexus identifies the execution flow; ast-dataflow finds indirect callers that gitnexus does not index (arrow-function callbacks, Promise.all wrappers). Directly addresses the classifyContent userId bug class and generalises to any wrong-argument bug.
6gitnexus-impact-analysis ↔ ast-dataflow type-evolution agreementgitnexus_impact + type-evolutionMediumProduces two distinct work lists (runtime callers vs type-position references) for type renames. Reduces false-negative risk in rename sweeps. Medium because type-position failures are compile-time, not runtime.
7ccc concept-guides ↔ ast-dataflow architectural invariant verificationccc guide + callers / string-literal-usesMediumVerifies guide-stated invariants against live code. High potential once KH’s ccc guide library is populated. Currently Medium because guides are not yet populated.
8Knip unused-enum-members ↔ ast-dataflow enum-member-uses confirmationknip --reporter json + enum-member-usesMediumAddresses Knip’s documented false-positive rate on as const patterns — the dominant KH enum idiom. Becomes High during canonical-pipeline collapse audits.
9ccc semantic-search ↔ ast-dataflow scoped dead-export auditccc search + dead-exports --scopeLowUseful for concept-scoped (not path-scoped) dead-export audits. Most KH audits are path-scoped so the pattern applies narrowly.

Patterns ready to operationalise now (no new implementation needed)

Section titled “Patterns ready to operationalise now (no new implementation needed)”

Patterns 4 and 5 can be documented as runbook-style workflow steps in the future ast-dataflow skill file (R-WP7). Both compose existing queries (string-literal-uses, callers, importers, references) with existing gitnexus tools. The only work is writing the step-by-step workflow and demonstrating it against a real KH rename or debug session.

Pattern 8 (Knip enum-member verification) similarly requires no new queries — enum-member-uses shipped in S6. It needs a concrete KH demonstration (pick one BID_STATES member) and a note in the Knip integration runbook.

Pattern that warrants a ccc guide seeding prerequisite (Pattern 7)

Section titled “Pattern that warrants a ccc guide seeding prerequisite (Pattern 7)”

Pattern 7 (concept-guide invariant verification) is the most architecturally interesting but depends on the ccc guides.yml being populated with KH-specific guides. A prerequisite investigation (not a Wave 4 WP itself) would be: run ccc describe . and enumerate the KH subsystems suitable for concept guides; propose 5–8 guide slugs to Liam. This is a 30-minute task that unlocks Pattern 7.

  • No new ast-dataflow query surfaces needed for any of Patterns 4-9. All patterns compose existing queries. The toolbox is sufficient.
  • No gitnexus changes needed. The gitnexus skill files are used as- is; this brief only documents how to chain them with ast-dataflow.
  • No ccc changes needed except authoring guides.yml as a prerequisite for Pattern 7.

Based on this brief, the two “TBD” WPs in Wave 4 are candidates for:

  • R-WP14 — Operationalise Patterns 4 + 5 as skill-file runbooks (dependency: R-WP7 skill-file authoring in Wave 5 is the natural sequencing, but the patterns can be documented informally before the full skill file lands).
  • R-WP15 — Seed KH ccc concept guides and demonstrate Pattern 7 against a real architectural invariant (e.g. the sb() safe-write invariant or the classifyContent UUID contract).

  1. Pattern 4 worked example fidelity. The gitnexus_rename dry-run output in the example is illustrative (the actual digests rename has not been run against the live index). Before treating Pattern 4 as a verified runbook, run it against the live ast-dataflow-tooling worktree with gitnexus_rename({symbol_name: "generateDigest", …, dry_run: true}) and record the actual output.

  2. Pattern 5 indirect-caller count. The example claims gitnexus finds 2 direct callers of classifyContent and ast-dataflow finds 7. This is based on general knowledge of the KH call patterns (arrow functions, Promise.all wrappers not indexed by gitnexus). The 7-caller claim should be verified with a live callers run before citing this pattern in documentation.

  3. ccc guides — are they currently populated for KH? The .cocoindex_code/guides.yml file existence in the KH repo was not verified as part of this investigation. If it exists and already has entries, Pattern 7 may be immediately operable. If not, the prerequisite seeding task (30 minutes) is unblocked.

  4. Knip false-positive rate on KH as const patterns. The Pattern 8 example is illustrative; the actual false-positive rate for BID_STATES and VALID_CONTENT_TYPES in the current Knip run is unknown. Running bun run knip --reporter json | jq '.enumMembers' against KH HEAD would give the concrete number of candidates to verify.

  5. Pattern 6 tooling gap check. The claim that gitnexus does not model TypeScript type-position references as graph edges (no EXTENDS edge, no AS_TYPE_ARGUMENT edge) should be verified against the gitnexus graph schema (gitnexus://repo/knowledge-hub/schema). If gitnexus does have type edges, Pattern 6’s incremental value needs re-assessment.