harness/plugins/exploration/claude/skills/explore/SKILL.md
Research phase before implementation. Given a list of entry points, spawn one subagent per entry point in parallel and write refactor-oriented research artifacts into the work-manager notes directory (`<notes-dir>/research/`). Use when the user says "explore", "research these entry points", or provides a list of files/symbols to investigate before starting a task. To render the resulting flows as an interactive HTML, use the `flow-map` skill.
npx skillsauth add popoffvg/dotfiles exploreInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build a shared understanding of unknown code before the task is implemented. The user provides N entry points; you spawn N subagents in parallel, each producing artifacts so a downstream agent (or human) can navigate the territory without re-reading the codebase.
Output lives inside the work-manager notes directory for the current task so it persists with the rest of the planning context (plan.md, worklog.md, todos/) and ships with the work, instead of vanishing from $TMPDIR.
A list of entry points. Each may be:
src/server/index.ts)HandleRequest, userController.create)If user provides a free-form description, use cocoindex to find relevant entry points.
<notes-dir> is the work-manager notes directory for the active task (commonly .notes/). Resolve it from the phase context:
.notes/ at repo root)../.notes/ in the current working directory and tell the user.--notes-dir <path>.Create the research subdirectory:
NOTES_DIR="${NOTES_DIR:-_notes}"
RESEARCH_DIR="$NOTES_DIR/research"
mkdir -p "$RESEARCH_DIR"
Per entry point <ep-slug>, three files in $RESEARCH_DIR/:
| File | Purpose |
|---|---|
| <ep-slug>.questions.md | Grill-phase questions the explorer must answer |
| <ep-slug>.md | Scannable refactor-oriented write-up. Follow the mandatory structure in "MD artifact structure" below. Every claim links to path:line. |
| <ep-slug>.workflow.ts | Human-readable workflow definition (see schema below) |
Plus, after all subagents finish:
| File | Purpose |
|---|---|
| flows.json | Aggregated flows document — input for flow-map |
| INDEX.md | One-line summary + links per entry point |
The previous $TMPDIR/claude-explore/ location is deprecated.
The .md is read by humans planning refactors. Prose paragraphs are forbidden as the primary form — use the headings below in this order. Each section is short, scannable, and citation-dense.
Use markdown links for code references: [packageName|typeName.functionName](path:line)
# <Title> — <scope one-liner>
**Scope.** What this doc covers. **Out of scope.** What it doesn't.
## Terms
The table contains terms used in the workflow and the related area.
## TL;DR
ASCII flow diagram — the whole pipeline at a glance, using `→`, `│`, `▼`, branches with `├─`/`└─`. No prose.
## 1. Workflow steps
Numbered table: | # | Step | File:line |. One row per atomic operation in happy-path order.
If there are parallel paths (e.g. prerun + main), use a second sub-table per path.
## 2. Decision points
Each decision is `DP-N` with:
- **Condition** (the exact predicate / field check)
- **Branches** as a small table or bullets, each with effect + file:line
- Cross-link to relevant EC-N if a branch has a known edge case
## 3. Identity / data carriers (when relevant)
Table: what value carries identity at each layer, how equality is defined, which fields are mutated vs immutable.
## 4. Per-variant shapes (when relevant)
Table of shape + conflict key + conflict resolution for each polymorphic case (dataset type, resource kind, message variant, …).
## 5. Edge cases
Numbered `EC-N` table: | # | Case | Effect | Source (file:line) |.
Be adversarial: empty inputs, races, partial failure, encoder ambiguity, duplicate keys, deleted resources, iteration-order non-determinism, cache staleness.
## 6. Refactor risks (hotspots)
Table: | Hotspot | Why it bites |. One row per surface that future changes will trip on — coupling, hidden invariants, non-deterministic ordering, missing rollback, silent overwrites, undocumented contracts.
## 7. File map
Table: | File | Role |. Every file referenced anywhere above.
## Grill answers
Numbered answers to every question from `<ep-slug>.questions.md`, in the same order. This is the verification trail.
Rules.
path:line must be verified — open the file before you cite it.DP-1, EC-1, …) so other docs and TODOs can reference them.Each <ep-slug>.workflow.ts is TS pseudocode written as an imperative function that reads top-to-bottom like the real code path. Same notation as work-plan-flow — real TS syntax, fake bodies, every meaningful line anchored to a verified path:line in a trailing or leading comment.
The file exports:
meta object with name + description.export const meta = {
name: "handle-request", // matches <ep-slug>
description: "HTTP request lifecycle from router to response.",
};
// Imperative pseudocode. Each line annotated with the file:line where the
// real logic lives. Reads top-to-bottom like the actual code path.
// The pseudocode should start with the entry point called `flow` and read like a real code path.
export function flow(req: Request): Response {
const body = parseBody(req); // src/server.ts:42
if (!validate(body)) { // src/validator.ts:10
return reject(400, "invalid body"); // src/errors.ts:5
}
const handler = dispatch(body.action); // src/router.ts:88
if (!handler) {
return reject(404, "no route"); // src/router.ts:104
}
try {
const result = handler(body); // src/handlers/*.ts
return write(200, result); // src/server.ts:120
} catch (e) {
log.error("handler crashed", { action: body.action, e }); // src/server.ts:131
return reject(500, "internal"); // src/errors.ts:18
}
}
Rules:
// path:line anchors. No /* ... */ blobs hiding logic.steps[] graph, no id/calls indirection.// path:line anchor to a location you opened and verified. Lines that just declare a local need no anchor.if, switch, early return, throw, async fan-out is shown.db.x, redis.x, emit, log, fs, http calls — don't hide them inside helpers.// path:line comments.Cross-reference: the .md artifact's "Workflow steps" table is the human-readable index; this .workflow.ts is the machine-readable code-shaped spec. They must agree on file:line citations.
flows.jsonAfter all subagents finish, combine their workflows into a single document at $RESEARCH_DIR/flows.json that the flow-map skill renders as interactive HTML. Schema:
{
"packages": [
{ "id": "web", "label": "Web Frontend", "kind": "app", "path": "apps/web" },
{ "id": "api", "label": "API Server", "kind": "service", "path": "services/api" },
{ "id": "db", "label": "Postgres", "kind": "store" }
],
"flows": [
{
"id": "invite-user",
"label": "Invite new user",
"description": "Admin invites a teammate; an email is queued and the user row is pre-created.",
"edges": [
{ "from": "web", "to": "api", "via": "POST /invites", "payload": "{ email, role }", "source": "apps/web/src/Invite.tsx:84" },
{ "from": "api", "to": "db", "via": "INSERT users", "payload": "{ id, email, status: 'invited' }", "source": "services/api/users.ts:201" },
{ "from": "api", "to": "mail","via": "queue invite-email","payload": "{ token, url }", "source": "services/api/users.ts:230" }
]
}
]
}
Rules: every from/to references a package id. Every source is a verified path:line. Derive packages[].id from the // path:line anchors inside each <ep-slug>.workflow.ts function (top-level dir or repo package of the cited file).
Write $RESEARCH_DIR/INDEX.md so the planner can find each artifact at a glance:
# Research index — <task slug>
Generated: <ISO date>
| Entry point | Slug | Artifacts | Summary |
|---|---|---|---|
| `src/server/index.ts` | server-index | [md](server-index.md) · [workflow](server-index.workflow.ts) · [questions](server-index.questions.md) | HTTP request lifecycle from router to response |
| `HandleRequest` | handle-request | [md](handle-request.md) · [workflow](handle-request.workflow.ts) · [questions](handle-request.questions.md) | Dispatch + middleware chain |
**Aggregated flows:** [flows.json](flows.json) — render with `/flow-map`.
TASK_SLUG.<notes-dir>. Prefer the active work-manager notes dir; fall back to ./_notes/. Create $RESEARCH_DIR = $NOTES_DIR/research if missing.$RESEARCH_DIR/INDEX.md exists, ask the user whether to append, overwrite, or bail. Don't silently overwrite previous research.claude CLI per entry point to produce $RESEARCH_DIR/<ep-slug>.questions.md. These are questions the explorer must answer — not questions for the user.Agent tool calls). Brief each with:
$RESEARCH_DIR, absolute path)<ep-slug>.questions.md — explorer must answer each question in a ## Grill answers section at the bottom of the .md artifactpath:line by reading the file — do not guess"$RESEARCH_DIR/flows.json (schema above). Deduplicate packages by id.$RESEARCH_DIR/INDEX.md (template above).<notes-dir>/worklog.md if it exists./flow-map against $RESEARCH_DIR/flows.json for an interactive HTML view.The explorer subagent works better when it has a sharp question list. We use grill-me not to interview the user but to interrogate the entry point itself: a separate Claude Opus CLI process is asked to act as a paranoid reviewer and produce the questions the explorer must answer.
For each entry point, spawn one Haiku CLI call (these can run in parallel via shell &):
EP="<entry-point>"
EP_SLUG="<ep-slug>"
QFILE="$RESEARCH_DIR/$EP_SLUG.questions.md"
cat <<PROMPT | claude --model haiku --print --output-format text > "$QFILE"
/grill-me
You are NOT interviewing a human. You are grilling the codebase entry point below to generate a research agenda for another agent (the "explorer") that will read the code and answer your questions.
Entry point: $EP
Task context: <one-line task description>
The explorer will use your questions to populate a refactor-oriented artifact organised as: workflow steps, decision points (DP-N), edge cases (EC-N), refactor hotspots. Bias your questions so the explorer is forced to surface those.
Produce a markdown file with sections:
## Workflow-step questions
- What are the ordered atomic steps from entry to exit on the happy path?
- For each step, what is the exact file:line and what state does it touch?
## Decision-point questions
- What every \`if\`/\`switch\`/dispatch table branches on; what fields it checks; what each branch does differently.
- Where the code forks into parallel paths (prerun/main, sync/async, fast-path/slow-path) and what carries identity across the fork.
## Edge-case questions (adversarial)
- Empty inputs, single-element inputs, duplicate keys, key collisions.
- Race conditions, iteration-order non-determinism, concurrent mutation.
- Partial failure mid-loop: what state has already been mutated and is there a rollback?
- Deleted/missing referenced resources, stale caches, encoder ambiguity (same input → different serialisation?).
- Silent overwrites, silent drops (\`continue\` on missing field), asymmetric branches across similar handlers.
## Identity & invariant questions
- What is "identity" at each layer (handle string, resource ID, hash, axis key, …) and how is equality defined?
- Which fields are mutable vs locked-after-creation? Which are part of dedup keys vs annotations?
## Refactor-hotspot questions
- Which surfaces couple multiple files (schema + dispatcher + handler)?
- Which contracts are implicit (cache key formula, iteration order, name canonicalisation)?
- Where would a future change most likely cause silent data loss or stale cache?
## Surprises / gotchas
- What would a new contributor most likely get wrong?
Each question must be answerable by reading the code. Be specific and adversarial — assume the code has hidden complexity. No questions for humans.
PROMPT
Outputs: one <ep-slug>.questions.md per entry point in $RESEARCH_DIR. These files become required input to the matching explorer subagent.
Notes:
--print keeps it non-interactive: Opus generates the question list and exits.claude CLI is unavailable, the main agent invokes grill-me in-session (sequentially per entry point) to produce the same .questions.md files.subagent_type: "Explore" for read-only investigation. If the entry point needs deeper reasoning (cross-file design questions), use general-purpose.$RESEARCH_DIR path.work-research saves coarse findings as <notes-dir>/research-*.md. explore complements that with per-entry-point deep dives under <notes-dir>/research/.work-plan / work-todo-prepare may reference research/<ep-slug>.md#DP-N or #EC-N from a TODO's Pre-reads so the implementer doesn't re-derive the analysis.research/ is committed alongside plan.md and todos/ — it travels with the task.testing
Use when the user asks to create test sets, enumerate scenarios, generate edge cases, or draft a coverage matrix before implementation.
testing
Use when the user asks to review, audit, score, or validate test sets for missed cases before execution or merge.
tools
Test harness plugins in isolation using tmux panes. Runs MCP servers, unit tests, typecheck, and Claude plugin loading. Use when user says "test plugin", "check plugin", "run plugin tests", "validate plugin", or names a specific plugin to test.
development
Guide for designing integration and e2e tests using BDD (Behavior-Driven Development) methodology with Cucumber-style Given/When/Then scenarios. Use when writing or reviewing tests for any service, API, or component. Language-agnostic — covers scenario structure, step notation, assertion principles, async patterns, and common anti-patterns.