Progressive Disclosure: The 5-Phase Code Intelligence Pipeline¶
Design Tenet¶
Progressive disclosure: exhaust deterministic, pattern-based, and structural analysis before spending a single LLM token. Every dollar of model inference should be spent on reasoning that static tools cannot perform — narrative synthesis, business logic interpretation, risk judgment, and cross-cutting insight correlation.
Architecture Overview¶
graph TD
CLI["CLI (cyclopts)"]
subgraph "Phase 1 — Deterministic Exhaustion (~30-90s)"
IDX["Indexer Pipeline"]
GITNEXUS["GitNexus Analyze (graph indexing)"]
GIT["Git Archaeology (hotspots + co-changes)"]
REPOMIX["Repomix (signatures + orientation)"]
BM25["BM25 Index"]
SEMGREP["Semgrep (auto + OWASP)"]
TYPECHECK["Type Checker (ty/pyright)"]
LINT["Linter (ruff)"]
COMPLEX["Complexity (radon)"]
DEADCODE["Dead Code (vulture/knip)"]
DEPS["Dependency Graph"]
HEURISTIC["heuristic_summary.json"]
end
subgraph "Phase 2 — Coordinator Team Planning (~1-2 min)"
COORD["Coordinator Agent"]
PLAN["Team Plan Decision"]
end
subgraph "Phase 3 — Parallel Team Execution (~3-8 min)"
T1["Team A (swarm)"]
T2["Team B (swarm)"]
TN["Team N (swarm)"]
TR1[".code-context/tmp/teams/team-a/findings.md"]
TR2[".code-context/tmp/teams/team-b/findings.md"]
TRN[".code-context/tmp/teams/team-n/findings.md"]
end
subgraph "Phase 4 — Consolidation (~1-2 min)"
CONSOL["Coordinator reads team findings"]
FOLLOWUP{"Gaps?"}
EXTRA["Follow-up Team"]
end
subgraph "Phase 5 — Bundle Generation"
BUNDLES["Bundle Writer"]
CONTEXT["CONTEXT.md"]
B1["BUNDLE.{area-1}.md"]
B2["BUNDLE.{area-2}.md"]
BN["BUNDLE.{focus}.md"]
end
CLI --> IDX
IDX --> GITNEXUS & GIT & REPOMIX & BM25
IDX --> SEMGREP & TYPECHECK & LINT & COMPLEX & DEADCODE & DEPS
GITNEXUS & GIT & REPOMIX & BM25 --> HEURISTIC
SEMGREP & TYPECHECK & LINT & COMPLEX & DEADCODE & DEPS --> HEURISTIC
HEURISTIC --> COORD
COORD --> PLAN
PLAN --> T1 & T2 & TN
T1 --> TR1
T2 --> TR2
TN --> TRN
TR1 & TR2 & TRN --> CONSOL
CONSOL --> FOLLOWUP
FOLLOWUP -- "Yes" --> EXTRA --> CONSOL
FOLLOWUP -- "No" --> BUNDLES
BUNDLES --> CONTEXT & B1 & B2 & BN Phase 1: Deterministic Exhaustion (~30-90s)¶
Run every tool that requires zero LLM inference. These tools operate on Tree-sitter parsing, graph algorithms, static analysis, and git archaeology. All outputs land in .code-context/ as structured JSON or markdown artifacts.
Indexer pipeline (indexer.py, 16 steps):¶
| Step | Tool | Output | What it captures |
|---|---|---|---|
| 1 | ripgrep --files | files.all.txt | Complete file manifest |
| 1a | Write manifest | files.all.txt on disk | Persisted for BM25 and downstream tools |
| 2 | Extension mapping | Language groups | Files grouped by language (py, ts, go, etc.) |
| 3 | gitnexus analyze | .gitnexus/ graph index | Tree-sitter parsing, symbol graph, clustering, execution flows |
| 4 | git log + git show | git_hotspots.json, git_cochanges.json | Commit frequency hotspots and co-change pairs |
| 5 | repomix --compress | CONTEXT.signatures.md | Compressed source signatures (tree-sitter body stripping) |
| 6 | repomix --no-files --token-count-tree | CONTEXT.orientation.md | Token-aware project overview |
| 7 | rank_bm25 | In-memory BM25 index | Pre-built search index for zero-latency first query |
| 8 | semgrep --config auto | semgrep_auto.json | General quality, anti-patterns, security smells |
| 9 | semgrep --config p/owasp-top-ten | semgrep_owasp.json | OWASP Top 10 vulnerability matches |
| 10 | ty check / pyright | typecheck.json | Type errors, missing annotations, inference gaps |
| 11 | ruff check --output-format json | lint.json | Style violations, complexity warnings, import issues |
| 12 | radon cc -j | complexity.json | Cyclomatic complexity per function |
| 13 | vulture | dead_code_py.json | Unused Python functions, classes, imports, variables |
| 14 | knip --reporter json | dead_code_ts.json | Unused TS/JS exports, dependencies, files, types |
| 15 | pipdeptree --json / npm ls --json | deps.json | Direct + transitive dependency tree |
| 16 | Aggregation | heuristic_summary.json | Bridge artifact for coordinator (see below) |
Every tool follows the same pattern: shutil.which() check, subprocess.run() with timeout, parse structured output, write artifact. Failures are graceful -- if a tool is missing or times out, the step is skipped and indexing continues.
Heuristic Summary: The Progressive Disclosure Boundary¶
After all deterministic tools complete, the indexer generates heuristic_summary.json -- the only artifact the coordinator reads before making its team-planning decision. It is the narrowest possible surface that lets the coordinator decide depth and breadth without reading source code.
graph LR
subgraph "Deterministic (cheap)"
A["16 index steps"] --> B["heuristic_summary.json"]
end
subgraph "Model-driven (expensive)"
B --> C["Coordinator"]
C --> D["Teams"]
D --> E["Bundles"]
end
style B fill:#f96,stroke:#333,stroke-width:3px Structure:
{
"volume": {
"total_files": 1847,
"total_lines": 142000,
"estimated_tokens": 35500000,
"languages": {"py": 1200, "ts": 500, "go": 147}
},
"health": {
"semgrep_findings": {"critical": 2, "high": 14, "medium": 47, "low": 12, "info": 3},
"owasp_findings": {"injection": 1, "xss": 3},
"type_errors": 23,
"lint_violations": 156,
"dead_code_symbols": 89,
"avg_cyclomatic_complexity": 6.2
},
"complexity": {
"top_complex_functions": [
{"name": "process_order", "file": "src/orders/engine.py", "lines": "142-298", "complexity": 34}
],
"bus_factor_risks": ["src/billing/ (1 contributor, 40 files)"]
},
"git": {
"total_commits_analyzed": 200,
"active_contributors": 12,
"most_coupled_pairs": [
"src/orders/engine.py <-> src/orders/models.py",
"src/api/router.py <-> src/api/schemas.py"
]
},
"gitnexus": {
"indexed": true,
"repo_name": "my-project",
"community_count": 8,
"process_count": 24,
"symbol_count": 6400,
"edge_count": 18200,
"top_communities": [
{"name": "Order Processing", "symbols": 340, "cohesion": 0.82},
{"name": "Auth & Sessions", "symbols": 210, "cohesion": 0.91}
]
},
"mcp": {
"context7_available": true
}
}
The schema reflects the actual _generate_heuristic_summary implementation in indexer.py. Key sections:
volume-- file count, line count, estimated tokens, language distributionhealth-- aggregated findings from semgrep, type checker, linter, dead code toolscomplexity-- top complex functions (from radon) and bus factor risks (from git)git-- commit count, contributor count, most-coupled file pairsgitnexus-- structural graph metadata: community/process/symbol/edge counts, top communities with cohesion scoresmcp-- availability flags for optional MCP providers (context7)
Phase 2: Coordinator Team Planning (model-driven, ~1-2 min)¶
The coordinator agent receives heuristic_summary.json and the user's optional --focus argument.
Key design principle: tools teach themselves¶
The coordinator prompt stays lean. Instead of embedding agent spec templates, tool usage rules, and dispatch instructions in the system prompt, those behaviors live in tool docstrings:
- A
@tool-decorateddispatch_teamwrapper (aroundstrands_tools.swarm) carries its own description of team sizing, agent specs, and dispatch patterns - A
@tool-decoratedread_team_findingscarries its own description of how to read and interpret team results - A
@tool-decoratedwrite_bundlecarries its own description of bundle structure and format
The coordinator prompt provides only: identity, pre-computed heuristic summary, the user's focus (if any), and the goal (produce bundles). The tools guide the how.
Decision inputs (available in heuristic summary):¶
- Volume metrics -- file count, token count, language count -> breadth
- Health signals -- semgrep criticals, OWASP findings, high complexity -> mandatory targets
- GitNexus topology -- community count, process count, top communities -> structural organization
- Complexity signals -- top complex functions, bus factor risks -> structural hotspots
- Git coupling -- most-coupled file pairs -> implicit dependencies
- Focus argument -- if provided, guarantees at least one dedicated team
Decision outputs (per team):¶
- Team ID (e.g.,
team-structure,team-security,team-focus-auth) - Mandate -- what to investigate and why
- File scope -- specific files/directories/modules
- Tool subset -- which tools this team needs
- Key questions -- what the coordinator wants answered
- Artifact pointers -- which Phase 1 artifacts to consult
Phase 3: Team Execution (parallel, ~3-8 min)¶
Each team executes as a Swarm (2-3 agents) dispatched via dispatch_team. Teams run in parallel via ConcurrentToolExecutor.
What teams do that deterministic tools cannot:¶
- Read actual source code and understand business domain semantics
- Correlate findings across tools (a high-complexity function that is also a git hotspot AND has a semgrep finding is a critical risk)
- Identify implicit contracts not captured by type systems or call graphs
- Assess architectural intent vs. implementation reality
- Produce narrative explanations of why code exists and what it does
Team result persistence:¶
graph TD
subgraph ".code-context/"
HEUR["heuristic_summary.json"]
SIG["CONTEXT.signatures.md"]
ORI["CONTEXT.orientation.md"]
subgraph "tmp/teams/"
TA["team-structure/"]
TB["team-security/"]
TC["team-focus-auth/"]
end
TA --> TA_F["findings.md"]
TA --> TA_M["metadata.json"]
TB --> TB_F["findings.md"]
TB --> TB_M["metadata.json"]
TC --> TC_F["findings.md"]
TC --> TC_M["metadata.json"]
subgraph "bundles/"
CTX["CONTEXT.md"]
B1["BUNDLE.hotspots.md"]
B2["BUNDLE.security.md"]
B3["BUNDLE.auth.md"]
end
end File-based handoff (vs. passing results through swarm return values) enables:
- Findings persist even if a team times out or errors
- Coordinator reads findings incrementally
- Results are inspectable by the user during execution
- Future runs can diff against previous team findings
Phase 4: Coordinator Consolidation (model-driven, ~1-2 min)¶
The coordinator reads all team result files via read_team_findings.
- Cross-reference -- where do multiple teams agree? (high confidence) Where do they disagree or leave gaps? (needs follow-up)
- Synthesis -- merge structural + historical + security + business logic
- Follow-up dispatch -- if critical gaps remain, dispatch one targeted team
- Bundle planning -- decide what bundles to produce
Phase 5: Bundle Generation¶
A bundle is a self-contained narrative document about a specific area of the codebase, written for a developer who needs to work in that area.
Bundle selection logic:¶
flowchart TD
START["Coordinator consolidation complete"]
FOCUS{"--focus provided?"}
FOCUS_BUNDLE["Generate BUNDLE.{focus}.md"]
ALWAYS["Generate preemptive bundles"]
BLAST["BUNDLE for high blast radius areas"]
HOTSPOT["BUNDLE for hot spots"]
BIZ["BUNDLE for critical business logic"]
CONTEXT["Generate CONTEXT.md (executive summary)"]
START --> FOCUS
FOCUS -- "Yes" --> FOCUS_BUNDLE
FOCUS -- "No" --> ALWAYS
FOCUS_BUNDLE --> ALWAYS
ALWAYS --> BLAST & HOTSPOT & BIZ
BLAST & HOTSPOT & BIZ --> CONTEXT If --focus was specified: guaranteed bundle for the focus area that answers "I need to change X -- what do I need to know?" with blast radius analysis.
Always (regardless of focus): preemptive bundles for:
- High blast radius areas -- extreme fan-in/fan-out nodes
- Hot spots -- high churn + high complexity + multiple contributors
- Critical business logic -- core domain operations (not framework glue)
Bundle format:¶
Each BUNDLE.{area}.md follows a consistent structure:
- One-paragraph summary -- what this area does in business terms
- Key files -- ranked list with role descriptions and line ranges
- Call flow -- how data/control flows through this area
- Blast radius -- what breaks if you change this area
- Risk assessment -- security, complexity, coupling, test coverage
- Change guidance -- where to start, what to watch out for
- Git context -- ownership, churn frequency, implicit coupling
Output layout:¶
.code-context/
CONTEXT.md # Executive summary + cross-cutting narrative
heuristic_summary.json # Phase 1 bridge artifact
CONTEXT.signatures.md # Compressed source (repomix)
CONTEXT.orientation.md # Token-aware overview (repomix)
git_hotspots.json # Commit frequency hotspots
git_cochanges.json # Co-change pairs for top hotspot files
semgrep_auto.json # Semgrep general findings
semgrep_owasp.json # Semgrep OWASP findings
typecheck.json # Type checker output
lint.json # Linter output
complexity.json # Radon cyclomatic complexity
dead_code_py.json # Vulture dead code (Python)
dead_code_ts.json # Knip dead code (TS/JS)
deps.json # Dependency tree
bundles/
BUNDLE.{area-1}.md # Per-area deep-dive narrative
BUNDLE.{area-2}.md
BUNDLE.{focus}.md # Guaranteed if --focus provided
tmp/
teams/
{team-id}/
findings.md # Raw team narrative
metadata.json # Stats: files read, tools used, duration
Design Constraints¶
Tools teach themselves¶
Agent system prompts stay lean. Tool behavior, usage patterns, and parameter semantics live in @tool docstrings -- not in the coordinator prompt. This means:
dispatch_team-- a@tool-decorated wrapper aroundstrands_tools.swarmwhose docstring describes team sizing heuristics, agent spec format, tool inheritance, and dispatch patternsread_team_findings-- a@tool-decorated reader whose docstring describes the team result directory structure and how to interpret findingswrite_bundle-- a@tool-decorated writer whose docstring describes bundle structure, format, and naming conventionsread_heuristic_summary-- a@tool-decorated reader whose docstring describes the heuristic summary schema and how to interpret each section
The coordinator prompt provides: identity, the heuristic summary data, the user's focus (if any), and the goal. The tools guide the how.
Never prescribe tool call counts¶
Agent prompts never say "make 2-5 tool calls" or "use at most 3 queries." The agent decides how many calls it needs based on the data. Prescribing counts leads to either premature stopping or wasteful padding.
Mermaid over ASCII¶
All diagrams in markdown outputs use Mermaid code-fenced blocks. Never ASCII art.
Implementation Notes¶
The original design document proposed these changes, all of which have been implemented:
- Indexer steps 8-16 (semgrep, typecheck, lint, complexity, dead code, deps, heuristic summary) are fully implemented in
indexer.py. - Coordinator tools (
dispatch_team,read_team_findings,write_bundle,read_heuristic_summary,score_narrative,enrich_bundle) are implemented intools/coordinator_tools.py. - Bundle model and
bundles: list[Bundle]onAnalysisResultare implemented inmodels/output.py. - Lean coordinator prompt (
coordinator.md.j2, ~35 lines) references the heuristic summary and delegates behavior to tool docstrings. --bundles-onlyflag is available on the CLI for re-running Phase 5.- GitNexus replaced the previous internal graph model (LSP symbols, AST-grep rules, jscpd clone detection, framework detection, test mapping). Structural code intelligence (symbol graphs, clustering, execution flows) is now handled entirely by GitNexus via its MCP tools.