<plugin-root>names the directory that holds this plugin's.codex-plugin/plugin.json. Resolve it once from where this file was loaded, then substitute it into every path below that starts with it. Arguments:<target> [--critical] [--comments] [--depth=lite|full] [--partition <path>] [--partition-name <name>] [--skip-interconnect] [--skip-synthesis] [--run-name <name>] [--yes] [--update] [--no-update]. Wherever<arguments>appears below, substitute the text the user typed after the skill name.
team-analyze
Execution harness
Selected topology: parallel-subagents, with role delivery by inline-prompt. Start one isolated
runtime subagent per dispatched worker. When role delivery is inline-prompt, paste that role's
Markdown body into the dispatch prompt verbatim: the worker must receive the whole role, not a
summary of it.
Harness obligations, none of them optional:
- Every dispatched worker runs in its own subagent context, and never reads another worker's result.
- Follow the dispatch plan below in phase order. A phase starts only after every phase it needs has
closed, and a phase closes only when every worker it dispatched is recorded
deliveredorfailed. A worker reports delivered or failed in its final message; there is no shared task list, so the coordinator keeps that record itself. - Dispatch only roles from this set, and only as the plan says:
partition-behavior-worker,partition-quality-worker,partition-structure-worker,partition-synthesizer,semantic-interconnect-mapper - Only the phase that declares the report artifact may write it.
Dispatch plan:
partition-selection: runs in the orchestrating context; producesselection:partitions.structure: onepartition-structure-workerper item ofselection:partitions, each in its own isolated context, in parallel where the host allows; barrierall-delivered; needspartition-selection; producesartifact:partition-structure.behavior: onepartition-behavior-workerper item ofselection:partitions, each in its own isolated context, in parallel where the host allows; barrierall-delivered; needsstructure; consumesartifact:partition-structure; producesartifact:partition-behavior.quality: onepartition-quality-workerper item ofselection:partitions, each in its own isolated context, in parallel where the host allows; barrierall-delivered; needsstructure; consumesartifact:partition-structure; producesartifact:partition-quality.interconnect: onesemantic-interconnect-mapperin an isolated context; needsbehavior; consumesartifact:partition-behavior; producesartifact:interconnect-map.synthesis: onepartition-synthesizerin an isolated context; needsbehavior,quality,interconnect; consumesartifact:partition-structure,artifact:partition-behavior,artifact:partition-quality,artifact:interconnect-map; producesartifact:xray-report.
Role bodies ship with this package under roles/, and the phase graph and record schemas under
contracts/team-analyze.workflow.toml.
Method
Execution requirements
This workflow fans out over partitions. Dispatch, scheduling and result collection belong to the host
harness, which is generated from contracts/team-analyze.workflow.toml. What this workflow requires of
any harness is fixed:
- every partition worker runs in its own context and owns exactly one partition directory
- Wave 2 starts only after every Wave 1 worker has been recorded delivered or failed
- synthesis runs only after every partition has been accounted for
- nothing writes outside the roots named by the
write-confinementpolicy
If the host cannot run workers in isolated contexts, stop and say so. Do not fall back to a single shared context: a partition analysis that read another partition's output is not the artifact this workflow claims to produce.
Team X-Ray Analysis
Orchestrate a partitioned multi-agent codebase analysis plus global interconnect map.
CRITICAL RULES
- Execute phases in order. No skipping unless
--skip-synthesisor--skip-interconnectis set. - Spawn agents with file ownership. Every spawn prompt enumerates the owned output files.
- Run isolation. All output goes to
$RUN_DIRuntil the publish step. Concurrent runs never share files. - Wait for the global Wave 1 barrier before spawning Wave 2 workers.
- Never enter plan mode. Execute immediately.
- Resume-safe. Re-spawn only missing workers on resume.
Pre-flight Checks
Confirm the harness can dispatch isolated workers; stop if it cannot
Parse
<arguments>:<target>: directory to analyze (default: cwd)--critical: prioritize auth/payment/persistence in Phase 3-4--comments: activate comment audit in Phase 6--depth=lite|full: lite skips Phases 3, 4, and 6 (behavior workers not spawned; quality workers write only 05-risks.md; synthesizer skips 03/04/06)--partition <path>: manual partition (repeatable; overrides auto-detect)--partition-name <name>: symbolic name for the N-th manual partition (1-indexed; optional)--skip-interconnect: skip Phase 3--skip-synthesis: skip Phase 2 AND Phase 3--run-name <name>: explicit run identity for concurrent or repeated analyses--yes: auto-accept partition checkpoint--update: require an update base; error out if no usable parent team run exists (the checkpoint still offers both the update and a full run)--no-update: skip parent detection and run every partition fresh- REJECT with explicit error if
--phase Nor--docs-onlyare passed (suggest classic/codebase-xray:analyze)
Resolve the run (see
## Concurrent Runs Modelin thecodebase-xray:xray-methodskill):- Compute
run-id:--run-name(normalized to[a-z0-9-]) or<slug-of-target>-<YYYYMMDD-HHMMSS>; append-2,-3, ... on collision - Set
RUN_DIR = .codebase-xray/runs/<run-id> - Read
.codebase-xray/runs.json: list active runs; offer to resume a matching in-progress team run or start this new run alongside. A rootstate.jsonwithcurrent_phaseand noruns.jsonis a pre-runs legacy layout: offer to migrate it into.codebase-xray/runs/legacy-<date>/first - Register the run in
runs.json(read-modify-write, append{run_id, target, mode: "team", started_at}toactive)
- Compute
Detect an update base, unless
--no-updatewas passed. Fromruns.json, takelatest_completed. It is a candidate parent when it is a completed team run, itstargetnormalizes to this target, and.codebase-xray/runs/<id>/snapshot/manifest.jsonexists. With a candidate, run the change set once over the whole target:python <plugin-root>/skills/xray-method/scripts/snapshot.py diff \ .codebase-xray/runs/<parent-id> <target> --out $RUN_DIR --flags '<this run's flags as JSON>'Hold
changes.jsonfor the partition checkpoint. With--updateand no candidate, stop and say which condition failed (no completed run for this target, a completed run that is not team mode, or a parent with no manifest), and that a full run is the way to create one. Never fabricate a parent. With a candidate present,--updatechanges nothing else: the checkpoint still presents the update and full-run options and waits for a choice, unless--yesauto-accepts.
Phase 0: Run Setup + Partition Detection
Worker dispatch
There is no explicit team-creation step. The host harness dispatches each worker as the phases below require, and the harness is what records every worker as delivered or failed. The run identity lives in {run-id} and the run directory, never in anything the harness names.
Initialize state
Create $RUN_DIR/ and $RUN_DIR/state.json:
{
"run_id": "<run-id>",
"target": "$ARGUMENTS_TARGET",
"mode": "team",
"status": "in_progress",
"flags": {
"critical": false,
"comments": false,
"depth": "full"
},
"parent_run": null,
"base_snapshot_created_at": null,
"git": null,
"incremental": null,
"partitions": [],
"phases": {
"phase_0_detection": "pending",
"phase_1_partition_workers": "pending",
"phase_2_synthesis": "pending",
"phase_3_interconnect": "pending"
},
"agents_spawned": [],
"files_created": [],
"started_at": "<ISO_TIMESTAMP>",
"completed_at": null
}
Pre-flight point 4 already ran the change set before this file is written. On an incremental run, parent_run (the parent's run-id), base_snapshot_created_at (the parent manifest's created_at) and incremental (holding {affected_files, files_in_snapshot} from the change set's totals) are written here with their real values, not left for later. git cannot follow that rule: the snapshot that supplies it is not written until after the checkpoint is accepted, so it starts null here and is copied in right after that write. A full run leaves parent_run and incremental as null and still records git and the snapshot: every run is a possible parent.
Register parent_run in the run's runs.json entry as well, null for a full run.
Project Knowledge Discovery (X-ray Phase 0)
Runs once for the whole run, inline in the orchestrating context, before partition detection. This is the same Phase 0 as /codebase-xray:analyze, and it is global: it does not run per partition, and no partition worker owns any of its output. Read CLAUDE.md, AGENTS.md, and any equivalent project instruction file at the repository root and in the target's ancestors. Locate the canonical indexes the project actually uses, at minimum **/SEARCH_INDEX.md, **/INDEX.md, docs/README.md, README.md, **/BY_DOMAIN.md, **/adr/**, **/decisions/**, **/architecture/**, **/domains/**, .codebase-map/INDEX.md. For each concept, symbol and subsystem the run will cover across all partitions, search the located documents for an entry and record the concept, the document, and the anchor or heading that matched. Every row is a lead with status documented or unverified; nothing here is verified, because this phase reads no code.
Output file: $RUN_DIR/knowledge/navigation.md
Output file: $RUN_DIR/knowledge/documentation-leads.md
See ## Phase 0: Project Knowledge Discovery in /codebase-xray:analyze for the full output templates.
Run partition detection algorithm
If --partition was provided one or more times, skip auto-detect: use the manual list directly. Apply --partition-name mappings if provided; otherwise derive names from path basename.
Otherwise, run the detection chain (first rule that matches wins):
- Explicit workspace manifests (in order):
pnpm-workspace.yaml->packagesfield pathspackage.jsonwithworkspacesfieldlerna.jsonpackagesnx.json+apps/+libs/turbo.json+apps/+packages/Cargo.toml[workspace] memberspyproject.toml[tool.uv.workspace] membersor equivalent
- Convention-based monorepo:
apps/,packages/, orservices/at root with >1 subdirectorysrc/with sub-dirs each having their ownpackage.json/pyproject.toml
- Layer split:
src/{backend,frontend},src/{api,web},src/{server,client}, or root-levelbackend/+frontend/
- Language split:
- Use
<plugin-root>/skills/xray-method/scripts/classifier.pyto count files per language - If ≥2 languages with ≥20 files each: partition per language (
*.py-> "python",*.ts/*.tsx-> "typescript")
- Use
- Fallback: single partition wrapping the entire target, name =
root
Always excluded paths: node_modules/, dist/, build/, .next/, target/, vendor/, __pycache__/, .venv/.
Partition naming rules:
- From workspace path -> basename
- On collision -> slug-ified path
- From language fallback -> language name
- From single-partition fallback ->
root
Normalize names: lowercase, separators -> hyphen, strip accents, allowed chars [a-z0-9-].
For each partition, compute file_count and loc_estimate (use classifier.py + wc -l or cloc if available).
Partition-level update
The unit of an update here is the partition, deliberately coarser than the claim-level update of /codebase-xray:analyze. A partition either changed or it did not, and a touched partition is worth re-analyzing whole: threading a change set through every worker would put it into every spawn prompt for a saving the partition split already provides most of.
Available only when pre-flight point 4 found a candidate parent and its change set does not recommend full; the checkpoint below still presents it as a choice, never as a forced path.
- The partition set must match. The names this detection produced must be the same set as the parent's
state.json -> partitions. Any difference means a full run, with the difference named at the checkpoint. A partition that appeared, vanished or was renamed changes what every other partition's boundaries mean. - Assign the affected files. For each partition, its affected files are the
affected_filesof the change set that fall under its path. Recordpartitions[i].updateas"copied"when that list is empty and"re-analyzed"(with the affected-file count) otherwise, before either branch below runs: the completion summary in Phase 4 and the## Partitionstable both read this field, and neither can be reconstructed later, sincepartitions[i].statusends at"done"for both outcomes. - A partition with no affected file is copied, whole, from
.codebase-xray/runs/<parent-id>/partitions/<name>/into$RUN_DIR/partitions/<name>/, once the checkpoint's update option is accepted. Mark itspartitions[i].statusas"done"directly. Phase 1's Wave 1 loop and its post-barrier status update both exclude a partition already"done", so no worker is ever dispatched for it in either wave, and Wave 2'sstructure_donegate excludes it too since its status never changes from"done". - A partition with at least one affected file is re-analyzed, both waves, exactly as in a fresh run. Its workers receive their normal prompts and never see the change set.
- Synthesis and the interconnect map always run, over the mix of copied and fresh partition output. Both are cross-partition by construction, so neither can be carried.
changes.mdholds the change set's three mechanical sections plus a## Partitionstable naming each partition as copied or re-analyzed, read frompartitions[i].update.
Checkpoint
When a partition-level update applies, present each partition as unchanged (copied) or re-analyzed ([N] affected files), with the parent run-id and the change set totals above the table, and offer the update as option 1 and a full run as option 2. When the change set recommends full, or the partition set does not match the parent's, present the reasons (from changes.json's reasons, plus "the partition set changed since the parent run" when that is why) and reverse the options. Otherwise present the block below unchanged.
Present to the user:
X-ray team-mode scope:
Target: <target>
Run: <run-id> (concurrent active runs: <count or "none">)
Detected partitioning strategy: <strategy name>
Proposed partitions (<N>):
P1: <path> (<language>, <file-count> files, ~<loc>k LOC)
...
Spawn plan: <N> partitions × 3 agents = <3N> workers + 1 synthesizer + 1 interconnect-mapper = <3N+2> agents total.
Note: token cost scales linearly with file count × agents. Consider `--depth=lite` for monorepos with many partitions.
Options:
[A] Accept and start
[M] Modify partition list (rename, regroup, exclude one)
[m] Manual: provide partition paths
[c] Cancel
If --yes, auto-select [A].
If [M], prompt for changes:
rename <old> <new>exclude <name>merge <name1> <name2> [<merged-name>]doneto finalize
If [m], prompt for paths and optional names.
If [c], set state to cancelled, remove the run from active in runs.json, and exit.
Finalize partitions array in state.json with {name, path, language_primary, file_count, loc_estimate, status: "pending"} for each. Mark phase_0_detection: "complete".
Immediately after the checkpoint is accepted, write this run's snapshot over the whole target, before any worker is dispatched:
python <plugin-root>/skills/xray-method/scripts/snapshot.py write \
<target> --out $RUN_DIR/snapshot/manifest.json
It is global, like Phase 0: no partition owns it, and no worker writes to it. Copy the manifest's own git field into $RUN_DIR/state.json's git field right after: it is the only state.json field this step fills, since parent_run, base_snapshot_created_at and incremental were already written with their real values when state.json was created. When the accepted option is a partition-level update, apply ### Partition-level update now, before Phase 1 begins.
Phase 1: Partition Workers (2 waves)
Wave 1: Structure workers (parallel)
For each partition P_i in state.json whose status is not already "done":
- Create directory
$RUN_DIR/partitions/<P_i.name>/ - Dispatch one
partition-structure-worker(how the role reaches the worker is the harness's business):- Worker title:
"P<i>.A — Structure+Interfaces for partition <P_i.name>" - Worker prompt:
- Worker title:
You are partition-structure-worker on partition "<P_i.name>".
Identity: P<i>.A
Run directory: <RUN_DIR>
Owned files:
- <RUN_DIR>/partitions/<P_i.name>/01-structure.md
- <RUN_DIR>/partitions/<P_i.name>/02-interfaces.md
DO NOT touch any other file under .codebase-xray/.
Target path for this partition: <P_i.path>
Active flags: --critical=<bool> --comments=<bool> --depth=<lite|full>
Sibling partitions (for cross-partition citation lookup if needed):
<list each P_j.name -> P_j.path>
Required reads before writing:
- <P_i.path>: all source files within scope
- <plugin-root>/skills/xray-method/SKILL.md
- Scripts at <plugin-root>/skills/xray-method/scripts/
Completion: when both owned files are written, report delivered and name them. If you could not write them, report failed and say why.
- Record the dispatch in
agents_spawned[]with{name: "P<i>.A", role: "partition-structure-worker", partition: "<P_i.name>", status: "dispatched"}.
After dispatching every P_i.A: hold the Wave 1 barrier. Every P_i.A worker must be recorded delivered or failed before anything else starts. A partition already "done" (copied at the partition-level update) has no P_i.A to wait for: the barrier skips it and its status stays "done".
For each partition whose status is not already "done": if P_i.A failed, mark partitions[i].status = "failed". If completed, mark partitions[i].status = "structure_done".
Mark phase_1_partition_workers: "wave1_done".
Wave 2: Behavior + Quality workers (parallel)
Skip behavior workers (B) if --depth=lite.
For each partition P_i where partitions[i].status == "structure_done":
- If
--depth != lite: dispatch onepartition-behavior-worker:- Worker title:
"P<i>.B — Flows+Semantics for partition <P_i.name>" - Worker prompt:
- Worker title:
You are partition-behavior-worker on partition "<P_i.name>".
Identity: P<i>.B
Run directory: <RUN_DIR>
Owned files:
- <RUN_DIR>/partitions/<P_i.name>/03-flows.md
- <RUN_DIR>/partitions/<P_i.name>/04-semantics.md
DO NOT touch any other file under .codebase-xray/.
Target path for this partition: <P_i.path>
Active flags: --critical=<bool> --comments=<bool> --depth=<lite|full>
Sibling partitions: <list>
Required reads before writing:
- <P_i.path>: source files
- <RUN_DIR>/partitions/*/01-structure.md (ALL partitions, already written by Wave 1)
- <RUN_DIR>/partitions/*/02-interfaces.md (ALL partitions)
Cross-partition citations: when you find an outgoing call/import that leaves
your partition, cite it as <other-partition>::<symbol>.
Completion: report delivered when both owned files are written, failed (with the reason) otherwise.
- Dispatch one
partition-quality-worker:- Worker title:
"P<i>.C — Risks+Docs for partition <P_i.name>" - Worker prompt: same template as B, but for the
partition-quality-workerrole. Owned files:05-risks.mdand06-documentation.mdat full depth;05-risks.mdonly under--depth=lite(the worker skips Phase 6 in lite mode).
- Worker title:
Record both dispatches in agents_spawned[].
Hold the Wave 2 barrier. For each partition, when both P_i.B and P_i.C are recorded delivered (only P_i.C in lite mode):
- Mark
partitions[i].status = "done"
When all partitions reach done or failed: mark phase_1_partition_workers: "complete" (or "failed" if EVERY partition is failed).
Phase 2: Synthesis
Skip if --skip-synthesis.
Dispatch one partition-synthesizer:
- Worker prompt:
You are partition-synthesizer.
Identity: SYNTH
Run directory: <RUN_DIR>
Owned files: <RUN_DIR>/01-structure.md through <RUN_DIR>/07-final-report.md (skip 03, 04, 06 if depth=lite).
DO NOT touch <RUN_DIR>/08-interconnect-map.md, any partition file, or anything at the .codebase-xray/ root.
Active flags: <flags from state.json>
Partitions to consolidate:
<for each partition: {name, path, status, language_primary}>
For any partition with status=failed, add a "⚠ Missing partitions" callout in every consolidated file. The 07-final-report.md opens with a "Partial Completeness Warning" section.
Read <RUN_DIR>/partitions/*/ and apply the consolidation rules in your agent definition.
Completion: report delivered when every owned file is written, failed (with the reason) otherwise.
Wait for delivery. On delivery: mark phase_2_synthesis: "complete". On failure: mark phase_2_synthesis: "failed" and phase_3_interconnect: "skipped_due_to_phase_2_failure", then jump to Phase 4.
Phase 3: Interconnect Map
Skip if --skip-interconnect or --skip-synthesis or Phase 2 failed.
Dispatch one semantic-interconnect-mapper:
- Worker prompt:
Build the interconnect map for this codebase using the team X-ray consolidated output as primary context.
Primary context source: `<RUN_DIR>/01-07.md` (consolidated from partition outputs by the synthesizer).
Scope: the cross-partition surface only. Read `<RUN_DIR>/02-interfaces.md ## Cross-Partition Exports`,
`<RUN_DIR>/03-flows.md ## Cross-Partition Flows`, `<RUN_DIR>/04-semantics.md ## Hidden Contracts (cross-partition)`
and `<RUN_DIR>/05-risks.md ## Cross-Partition Risk Attribution` (whichever exist at this depth), then the
source files those sections cite. Partition-internal contracts are already in the partition outputs;
do not re-derive them here.
Output path: `<RUN_DIR>/08-interconnect-map.md`
Produce the full structured map following your agent definition: Call Graph limited to the symbols that cross a partition boundary (2-3 hops out from each crossing, cross-partition edges marked), Contracts (formal / structural / implicit), Invariants, Domain Rules, Assumptions (verified / documented / unverified / disputed), Integration Hot-Spots, Change Impact Radius, Reviewer Hints.
Every claim must cite file:line. No recommendations, no fixes. Empty sections are acceptable if nothing applies. Scale the map with the number of cross-partition edges, never with the size of the codebase.
Wait for delivery. On delivery: mark phase_3_interconnect: "complete". On failure: mark phase_3_interconnect: "failed" and continue to Phase 4 (failure is non-blocking).
Phase 4: Publish, Completion & Next Steps Menu
- Update
$RUN_DIR/state.json:status: "complete",completed_at: <ISO_TIMESTAMP>. - Publish (skip if
--skip-synthesis): copy$RUN_DIR/01-*.md..$RUN_DIR/07-final-report.md(those that exist),$RUN_DIR/08-interconnect-map.md(if Phase 3 ran), and$RUN_DIR/state.jsonto the.codebase-xray/root, overwriting the previous mirror. Updateruns.jsonwith read-modify-write: remove this run fromactive, setlatest_completed. The root mirror is the downstream contract for/senior-review:team-review,/codebase-mapper:map-codebase, and/project-setup:create-claude-md. - No worker may still be writing after publish. Every dispatched worker has been recorded
deliveredorfailedby now, and the harness owns whatever cleanup its workers need. - Present summary:
X-ray (team mode) complete for: <target>
Run: <run-id> (published to .codebase-xray/ root)
Parent: <parent-id or "none (full run)">
Partitions: <N> (<list of names + status>)
Output Files:
Knowledge discovery: .codebase-xray/runs/<run-id>/knowledge/navigation.md, documentation-leads.md (Phase 0)
Per-partition reports: .codebase-xray/runs/<run-id>/partitions/*/01..06.md
Consolidated reports: .codebase-xray/runs/<run-id>/01-structure.md .. 07-final-report.md
Interconnect map: .codebase-xray/runs/<run-id>/08-interconnect-map.md (if Phase 3 ran)
Root mirror: .codebase-xray/01..08.md (for downstream consumers)
Summary:
- Files analyzed: <count>
- Anti-patterns: <count> | Red flags: <count> | Tech debt: <count>
- Documentation gaps: <count>
- Cross-partition flows: <count>
On an incremental run, name the parent run-id on the Parent: line and list each partition using partitions[i].update in place of its raw status: <name>: copied or <name>: re-analyzed ([N] affected files), except a partition whose status is "failed" still reports failed. Point at .codebase-xray/runs/<run-id>/changes.md ## Partitions for the full detail. A full run keeps today's format: Parent: none (full run), and every partition reports done or failed.
- Show Next Steps Menu:
What would you like to do next?
1. Start fixing — execute the action plan
2. Apply quick fixes
3. Analyze further — re-run a single partition (as a new run)
4. Generate documentation
4a. CLAUDE.md (suggests /project-setup:create-claude-md or maintain-claude-md)
4b. Codebase map (suggests /codebase-mapper:map-codebase)
4c. API / interface docs (suggests /codebase-mapper:docs-create)
5. Run code review — launch /senior-review:team-review (will reuse the published .codebase-xray/ mirror + 08-interconnect-map.md)
6. Export report
7. Nothing for now
Wait for user choice before proceeding.
Resume Logic
On pre-flight detection of an active run in runs.json with mode == "team" whose $RUN_DIR/state.json says status == "in_progress", offer to resume it:
- If
phases.phase_0_detection != "complete": remove the run and restart from zero - If
phases.phase_1_partition_workers == "pending": re-run Phase 1 Wave 1 - If
phases.phase_1_partition_workers == "wave1_done": skip Wave 1, re-run Wave 2 for every partition withstatus == "structure_done"(noBandCoutputs yet) - If
phases.phase_1_partition_workers == "complete"andphase_2_synthesis != "complete": re-run Phase 2 - If
phases.phase_2_synthesis == "complete"andphase_3_interconnect != "complete": re-run Phase 3 - If
phases.phase_3_interconnect == "complete": run the Phase 4 publish step and present the menu directly
Resuming dispatches fresh workers as needed. Worker contexts are not restored across sessions, and the run directory carries the run identity.
Quick Examples
/codebase-xray:team-analyze .— auto-detect, full depth/codebase-xray:team-analyze . --depth=lite— lite mode (2N+2 agents)/codebase-xray:team-analyze . --critical— prioritize security paths in Phase 3-4/codebase-xray:team-analyze . --partition packages/api --partition packages/web --yes— manual partitions, auto-accept/codebase-xray:team-analyze . --skip-interconnect— stop at Phase 2/codebase-xray:team-analyze . --skip-synthesis— only per-partition reports (no consolidation, no publish)/codebase-xray:team-analyze apps/backend --run-name backend— named run, safe alongside other active runs