From crucible
Deep-scans repo and sibling repos to map structure, manifests, and cross-repo topology for onboarding unfamiliar codebases via /project-init.
npx claudepluginhub raddue/crucibleThis skill uses the workspace's default tool permissions.
<!-- CANONICAL: shared/dispatch-convention.md -->
Maintains persistent codebase maps (map.md, conventions.md, modules/) to record exploration learnings, consult structure before tasks, and load module context for subagents.
Maps unfamiliar codebases in phases: structure, entry points, data flow, patterns, landmines. Use before coding in new, inherited, or revisited projects.
Orchestrates parallel subagents to map any codebase, creating docs/CODEBASE_MAP.md with architecture, file roles, dependencies, and navigation. Updates incrementally via git or scans.
Share bugs, ideas, or general feedback.
All subagent dispatches use disk-mediated dispatch. See shared/dispatch-convention.md for the full protocol.
Eliminate cold-start penalty by proactively mapping the current repo and its neighborhood. Instead of re-discovering the codebase during every first task, project-init builds structural context upfront so that build, design, and debugging skills start informed.
Invocation: User runs /project-init. Not auto-triggered.
Two tiers:
Output:
memory/cartographer/)memory/topology/Coverage distinction: All output is tagged <!-- project-init:structural -->, marking it as breadth-first structural mapping. This is distinct from task-verified content produced by cartographer record mode during real work. Task-verified content is always preserved over structural content.
Announce at start: "I'm using the project-init skill to map this codebase and its neighborhood."
Before dispatching any agents, the orchestrator estimates work scope:
.ts, .js, .py, .go, .rs, .java, .cs, .rb, .swift, .kt, .c, .cpp, .hpackage.json, go.mod, Cargo.toml, pyproject.toml, docker-compose.yml) and sibling repos (git repos in parent directory)Present the estimate to the user:
"Found N source directories and M sibling repos. This will dispatch ~X agents. Proceed?"
User options:
Wait for user confirmation before proceeding. Do not dispatch agents without approval.
Delete /tmp/crucible-project-init/ if it exists from a prior run, then recreate it. This ensures a clean workspace for temp files.
rm -rf /tmp/crucible-project-init && mkdir -p /tmp/crucible-project-init
Scan the repository to determine:
.ts, .js, .py, .go, .rs, .java, .cs, .rb, .swift, .kt, .c, .cpp, .h)package.json → Node/JavaScript/TypeScriptgo.mod → GoCargo.toml → Rustpyproject.toml / requirements.txt → Pythonpom.xml / build.gradle → Java/Kotlin*.csproj / *.sln → C#/.NETGemfile → RubyPackage.swift → SwiftIf the entire repository has fewer than 20 source files (across all directories), skip the partition/fan-out/fan-in pipeline. Instead, dispatch a single Partition Explorer for the repo root and pass its output directly to the Init Recorder as a single partition report. This avoids unnecessary overhead for small codebases.
Split the repository into partitions for parallel exploration:
src/, lib/, pkg/, cmd/)src/ with 80 files becomes src/auth/, src/api/, src/models/, etc.
Dispatch parallel Explore subagents, one per partition:
Agent tool (subagent_type: Explore, model: sonnet)
Use the prompt template at ./partition-explorer-prompt.md. Fill in the template variables:
[partition name] — the partition directory name[Partition root directory path] — absolute path to the partition[Source file extensions detected in this partition] — which extensions were found[Project ecosystem context] — ecosystem info from Step 1When each explorer returns: The orchestrator captures the return value and writes it to /tmp/crucible-project-init/<partition-name>.md. The explorer itself does not write files — the orchestrator does.
Dispatch the Init Recorder to merge all partition reports into cartographer format:
Task tool (general-purpose, model: sonnet)
Use the prompt template at ./init-recorder-prompt.md. Fill in the template variables:
[N] — number of partition reports[File paths to partition exploration reports] — paths to temp files from Step 3[Existing cartographer data] — read and paste existing memory/cartographer/map.md, conventions.md, landmines.md if they exist, or say "No prior cartographer data."[Project name and ecosystem] — from Step 1[Output directory] — the project's memory/cartographer/ pathBatching for large repos (6+ partitions): When there are 6 or more partition reports:
/tmp/crucible-project-init/batch-N.md in explorer format (the same ## Modules Found, ## Conventions Observed, etc. sections used by partition explorers), NOT cartographer format. This is a consolidation pass, not a formatting pass. Set the Output Directory to /tmp/crucible-project-init/batch-N.md.The orchestrator passes file paths, not content for partition reports to the Init Recorder — the recorder reads the partition reports itself. Existing cartographer data (for re-invocation merge) is included directly in the dispatch file since it's small and needed for merge decisions.
After the Init Recorder completes, run a three-way check:
(a) Partition completeness — Verify each partition explorer returned a non-empty result. Check that temp files exist at /tmp/crucible-project-init/<partition-name>.md and contain non-trivial content (more than 3 lines). Also check for the completion sentinel: <!-- partition-explorer:complete --> means full scan, <!-- partition-explorer:partial --> means some directories were unscanned (flag these in map.md Unmapped Areas).
(b) Map representation — Verify every partition that returned results is REPRESENTED in map.md — either as individual modules OR as a collapsed group in "Other" (collapsed partitions count as represented). Unrepresented partitions trigger focused re-recording: dispatch the Init Recorder again with just the missing partition reports.
(c) Module field completeness — Verify module entries have required fields populated: Path, Responsibility, Key Components must all be non-empty. Also verify that a modules/<name>.md file exists for each module listed in map.md with Mapped Detail = Yes.
Partitions that returned empty results are flagged as "unmapped" in map.md under the Unmapped Areas section.
Read the following files if they exist:
README.md — project purpose, setup instructionsCONTRIBUTING.md — contribution guidelines, review processCLAUDE.md — existing agent instructionsThis is a direct read by the orchestrator, not a subagent dispatch. The orchestrator uses the extracted context for two purposes:
project type memories via the auto-memory systemIf the Init Recorder produced /tmp/crucible-project-init/claude-md-proposal.md:
CLAUDE.md (if any) to identify already-configured content/tmp/crucible-project-init/claude-md-proposal-filtered.md — this survives context compaction during Tier 2This step does NOT block Tier 2 — the pipeline continues autonomously.
| File | Target | Hard Cap |
|---|---|---|
map.md | 140 lines | 200 lines |
conventions.md | 105 lines | 150 lines |
landmines.md | 70 lines | 100 lines |
modules/<name>.md | 70 lines | 100 lines |
Target 70% of caps — leave room for task-verified additions by cartographer record mode.
When the repository has many top-level source directories:
| Other | various | 12 single-file modules | No |Orchestrator writes Tier 1 results to disk before proceeding to Tier 2.
Before scanning neighbors, verify filesystem access:
../)If access is denied, emit a clear skip message and end Tier 2:
"Cross-repo discovery requires filesystem access to the parent directory. Skipping Tier 2."
Parse supported manifest formats for cross-repo references:
| Format | What to Extract |
|---|---|
package.json | dependencies, devDependencies — look for file:../ or workspace references |
go.mod | require directives — look for local replace directives pointing to siblings |
Cargo.toml | [dependencies] — look for path = "../" references |
pyproject.toml | [project.dependencies] — look for local path references |
docker-compose.yml | services — look for build paths pointing to siblings, shared networks/volumes |
Note detected-but-unparsed formats (e.g., pom.xml found but not parsed) so the user knows what was skipped.
Scan the parent directory for git repos:
../.git/ directoryPresent discovered repos to user before scanning:
"Found N sibling repos. M are referenced in manifests (pre-selected). Confirm which to scan:"
../auth-service(referenced in docker-compose.yml)../shared-types(referenced in package.json)../unrelated-project(co-located, no reference)
Wait for user confirmation. Do not scan repos the user did not confirm.
Dispatch parallel Explore subagents, one per confirmed neighbor:
Agent tool (subagent_type: Explore, model: sonnet)
Use the prompt template at ./neighbor-scanner-prompt.md. Fill in the template variables:
[repo name] — the neighbor repository name[Neighbor repo path] — path to the neighbor[Connection context] — how it was discovered (manifest reference details)[Current repo name and purpose] — from Tier 1 resultsWrite each result to /tmp/crucible-project-init/neighbors/<repo-name>.md.
After all neighbor scans complete, the orchestrator assigns relevance:
| Relevance | Criteria | Example |
|---|---|---|
| High | Direct dependency — imported, called, or required by current repo | file:../shared-types in package.json |
| Medium | Shared infrastructure — common services, shared DB, docker-compose links | Both use same Redis instance |
| Low | Co-located, no detected link — just happens to be in same parent directory | ../unrelated-tool |
Dispatch the Topology Recorder to synthesize neighbor scans:
Task tool (general-purpose, model: sonnet)
Use the prompt template at ./topology-recorder-prompt.md. Fill in the template variables:
[N] — number of neighbor scans[File paths to neighbor scan results] — paths to temp files from Step 4[Current repo name, ecosystem, purpose] — from Tier 1[Relevance scores] — per-neighbor relevance from Step 5[Existing topology data] — read and paste existing memory/topology/topology.md if it exists, or say "No prior topology data."[Output directory] — the project's memory/topology/ pathAfter both tiers complete, the following structure exists:
~/.claude/projects/<project-hash>/memory/
cartographer/
map.md # Module map (← Tier 1)
conventions.md # Codebase patterns (← Tier 1)
landmines.md # Non-obvious breakage (← Tier 1)
modules/
<name>.md # Per-module detail (← Tier 1)
topology/
topology.md # Cross-repo dependency map (← Tier 2)
<neighbor-name>.md # Per-neighbor detail (← Tier 2)
After BOTH tiers complete (or after Tier 1 if Tier 2 was skipped), present the CLAUDE.md proposal if one was generated. Read from /tmp/crucible-project-init/claude-md-proposal-filtered.md (the filtered version from Step 7):
"Structural mapping complete. Also generated CLAUDE.md proposals based on what I found. Review below — merge what's useful."
[display proposal content]
User options:
The orchestrator appends accepted content to the project's CLAUDE.md (creating the file if it doesn't exist). Appended content is added under a clear heading.
| Agent | Model | Dispatch | Prompt Template |
|---|---|---|---|
| Partition Explorer | Sonnet | Agent tool (Explore) | ./partition-explorer-prompt.md |
| Init Recorder | Sonnet | Task tool (general-purpose) | ./init-recorder-prompt.md |
| Neighbor Scanner | Sonnet | Agent tool (Explore) | ./neighbor-scanner-prompt.md |
| Topology Recorder | Sonnet | Task tool (general-purpose) | ./topology-recorder-prompt.md |
Explorers are dispatched via the Agent tool with the specified subagent_type. Recorders are dispatched via the Task tool (general-purpose). Use the prompt templates verbatim, filling in only the bracketed template variables.
If agent teams are not available (Agent tool does not support parallel dispatch), fall back to sequential dispatch with a one-time warning:
"Agent teams not available. Running sequentially — this will take longer."
Behavior is unchanged except parallel dispatch becomes sequential. All steps, validation, and output remain the same.
When project-init is run again on a repo with existing cartographer or topology data:
| Existing Content | Action |
|---|---|
<!-- project-init:structural --> tagged | Overwrite with fresh scan data |
| Task-verified (no structural tag) | Preserve — never modify or remove |
| New modules/neighbors not in prior data | Add with structural tag |
| Prior modules/neighbors absent from scan | Flag with [STALE?] marker — do not remove |
| Overflow after merge | Prioritize task-verified content, compress structural |
This strategy ensures that knowledge accumulated through real task work is never lost by a re-scan.
Project-init is context-intensive. Follow these rules to prevent context exhaustion:
/tmp/crucible-project-init/ and passes file paths (not content) to recordersNever:
Always:
<!-- project-init:structural -->/tmp/crucible-project-init/ at the start of each runCartographer recorder-prompt.md must handle structural tags — when updating files that contain <!-- project-init:structural --> content, the recorder preserves that tag on structural sections and omits it on task-verified additions.
Skills that benefit from project-init output:
| Skill | How It Uses project-init Data |
|---|---|
crucible:cartographer (consult) | Reads map.md — structural content provides baseline even before any task exploration |
crucible:cartographer (load) | Loads modules/*.md into subagent prompts — structural context prevents wrong assumptions |
crucible:build | Gets structural awareness from cartographer consult at task start |
crucible:design | Knows module boundaries and dependencies before proposing architecture |
crucible:debugging | Loads module context and landmines for investigators |
crucible:cartographer — ongoing codebase mapping (project-init bootstraps, cartographer maintains)crucible:build — implementation workflow (consumes cartographer data)crucible:design — architecture planning (consumes map and topology)crucible:debugging — investigation workflow (consumes modules and landmines)Does not dispatch /recon -- bootstraps the cartographer data that /recon consults. Complementary, not overlapping. See #147 for rationale.
./partition-explorer-prompt.md — Structured exploration per partition for Tier 1./init-recorder-prompt.md — Multi-source fan-in recorder for Tier 1./neighbor-scanner-prompt.md — Lightweight neighbor exploration for Tier 2./topology-recorder-prompt.md — Topology file writer for Tier 2