skills/dev-loop/investigate/SKILL.md
Companion prompt for dev-loop investigate mode. Proactively scans project health (code, vault, transcripts, deep-research) and queues structured, schema-valid findings in the vault. Invoked via /dev-loop investigate [high] [topic]. Requires query_vault in BACKEND_CAPS.
npx skillsauth add karlorz/agent-skills investigateInstall 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.
Proactive finding queue pipeline. Scans project health across four sources,
deduplicates against existing work, and writes schema-valid queued findings in
the vault. Findings stay non-executable until a human promotes them into
status: planned work items.
Vault required. If query_vault not in BACKEND_CAPS, refuse:
"Investigate mode requires a vault — run /setup-dev-loop to configure one."
This gate is an architectural decision (ADR: projects/{slug}/architecture/ investigate-mode-vault-required.md). See the ADR for trade-off rationale
and upgrade path.
The parent dev-loop controller parses args and delegates here with:
INTENSITY: normal | highINVESTIGATE_TOPIC: string or empty/dev-loop investigate → normal, no topic
/dev-loop investigate high → high, no topic
/dev-loop investigate "plugin SDK changes" → normal, topic set
/dev-loop investigate high "plugin SDK changes" → high, topic set
| Step | Model | Rationale | |------|-------|-----------| | 1. QUERY | sonnet (agent) | Vault search — mechanical lookup | | 2. SCAN | sonnet (agent) | Research-worker already runs on sonnet | | 3. DEEPEN | sonnet (agent) | Deep-research manages its own model internally | | 4. TRIAGE | parent (inline) | Judgment: which findings matter, ranking, dedup | | 5. SPEC | parent (inline) | Writing specs is creative/architectural | | 6. RETRO | parent (inline) | Low token, always inline | | 7. SAVE | parent (inline) | Vault auto-commit, low token |
~70% token spend on sonnet (SCAN + DEEPEN), ~30% on parent (TRIAGE + SPEC).
Read from investigate section in .claude/dev-loop.config.md:
investigate:
max_items: 5 # cap per invocation (high doubles it)
topic_seeds: [] # fallback when no user topic; reuses idle_deep_research.topic_seeds if empty
Defaults when absent:
max_items: 5topic_seeds: falls back to idle_deep_research.topic_seeds from config.
If that's also empty, DEEPEN step is skipped unless user provides a topic.┌─────────────────────────────────────────────────────────┐
│ 0. REFRESH (already done by parent dev-loop) │
├─────────────────────────────────────────────────────────┤
│ INVESTIGATE CORE │
│ 1. QUERY Context check — existing work items, │
│ prior investigate runs, retros │
│ 2. SCAN Research-worker (Track A + Track B) │
│ + unclaimed transcripts │
│ 3. DEEPEN Deep-research (high or user topic only) │
│ 4. TRIAGE Deduplicate, rank, cap │
│ 5. SPEC Queue findings (schema-adaptive output) │
├─────────────────────────────────────────────────────────┤
│ POSTLUDE │
│ 6. RETRO Log investigation results │
│ 7. SAVE Vault auto-commit │
└─────────────────────────────────────────────────────────┘
Gather existing state to prevent duplicate work-item creation:
ls {vault}/projects/{slug}/work/ to get
all current slugs and their statuses. Parse spec.md frontmatter for
status, name, title, and kind.ls {vault}/projects/{slug}/history/ for
archived work-item slugs (completed work that shouldn't be re-proposed).
If history/ is absent, treat as empty.{vault}/raw/transcripts/ for
ad-hoc captures with project: "[[<project-slug>]]" and slugs matching
investigation output (YYYY-MM-DD-<kind>-<slug>.md).{vault}/log.md for the last 10 retro
entries to understand what's been investigated recently.investigate-cycle
entries. If the last investigate run was <24h ago AND intensity is the
same, warn: "Investigate ran recently (<time> ago) — findings may overlap.
Continue anyway." Do not block.Store results as EXISTING_SLUGS (set of name slugs + statuses) and
HISTORY_SLUGS (set) for TRIAGE. Store queued transcript slugs as
QUEUED_CAPTURE_SLUGS.
Invoke the existing research-worker with the same interface as IDLE step 4:
Agent(description: "Investigate scan", subagent_type: "dev-loop:research-worker",
model: "sonnet", prompt: "Run research cycle with intensity: <INTENSITY>.
BACKEND_CAPS: <caps>. VAULT_TYPES: <types>. CRITICAL_PATHS: <paths>.
Scan code health and vault health per research/SKILL.md.
Return ALL findings regardless of P-score — do not filter.
Output as structured findings list.")
Key difference from IDLE: request ALL findings, not just top-N. TRIAGE handles filtering — the scan should be exhaustive.
Inline fallback: If agent spawn fails (1M-context error per session
memory), run the research scan inline using Skill("dev-loop:research").
Unclaimed transcripts — after research-worker returns, scan
{vault}/raw/transcripts/ for files matching the project slug that are
NOT referenced by any existing work item's closes: list. Each unclaimed
transcript is a candidate finding:
kind: idea → P3 findingkind: bug → P2 findingkind: task → P2 findingHard skip gate (always):
deep-research:deep-research in DEP_DRIFTWhen this dependency is missing, skip DEEPEN regardless of intensity/topic. Continue with SCAN-only findings.
Run if ANY of (when dependency is available):
INTENSITY == high (use topic_seeds round-robin or first unused seed)INVESTIGATE_TOPIC is non-empty (user explicitly asked — run regardless
of intensity)Otherwise skip:
INTENSITY == normal AND INVESTIGATE_TOPIC is emptyExecution:
If INVESTIGATE_TOPIC is set:
Invoke Skill("deep-research") with topic = INVESTIGATE_TOPIC
If topic is empty (high mode, no user topic):
investigate.topic_seeds (or fall back to
idle_deep_research.topic_seeds). Round-robin based on which seeds
have NOT been investigated in the last 7 days (check vault query pages).Output: Extract actionable ideas from deep-research results. Each idea becomes a candidate finding with:
ideadeep-research: <topic>Budget: Honor idle_deep_research.budget.* caps if configured.
Default: max_sources: 5, max_tokens: 50000.
This step runs inline on the parent model — it's the judgment core of investigate.
Input: Combined findings from SCAN + DEEPEN (if run).
Step 4a — Deduplicate:
For each candidate finding, generate a slug from its title (lowercase, hyphens, strip common words). Then check:
EXISTING_SLUGS:
proposed or planned → skip (already queued)in-progress → skip (being worked on)completed → skip unless the finding references changes
since the completion dateQUEUED_CAPTURE_SLUGS → skip (already queued as a raw
transcript capture)HISTORY_SLUGS → skip (work completed and archived)Log skipped duplicates: "Skipped: <slug> (existing: <status>)"
Step 4b — Rank:
Sort remaining findings by:
CRITICAL_PATHS set)Step 4c — Cap:
Apply intensity-based cap:
normal: investigate.max_items (default 5)high: investigate.max_items * 2 (default 10)Discard findings beyond the cap. Log: "Capped at <N> items (<M> total findings, <K> deduplicated)."
Step 4d — Tier assignment:
For each surviving finding, assign an output tier:
Heuristic: if the finding references specific file paths or has a clear
acceptance criteria expressible as a command (test passes, lint clean,
version matches), it's a full spec. Otherwise, stub.
For each triaged finding, create a schema-valid queued artifact. The queue format is schema-adaptive because skillwiki installations differ on whether a non-executing work-item status exists.
Schema probe (before first output):
status: proposed.skillwiki validate <candidate-spec.md>.status: proposed, kind, or lifecycle fields,
delete the candidate and use Mode B: raw transcript capture queue.Do not continue after a validation failure with the same invalid shape.
Use this mode only when the local schema validates non-executing proposed work
items. For each triaged finding, create a work item via proj-work and
validate the resulting spec.md.
Common frontmatter:
---
title: "<conventional-commit-style title>"
name: <slug>
description: "<one-paragraph summary>"
kind: <feature|issue|refactor|decision>
status: proposed # only when local schema supports it
priority: <high|medium|low> # derived from P-score: P0-P1→high, P2→medium, P3+→low
project: "[[<project-slug>]]"
created: YYYY-MM-DD
updated: YYYY-MM-DD
tags:
- <project-slug>
- investigate
- <source-track> # e.g., code-health, vault-health, transcript, deep-research
source_investigate: true # marker for investigate-created items
---
Full spec body:
# <title>
## Problem
<What's wrong or missing — from the finding>
## Requirements
<Concrete changes needed — files, functions, expected behavior>
## Acceptance
<Verifiable outcomes — commands to run, states to check>
## Sources Used
- <finding source reference>
Stub body:
# <title>
## Problem
<What's wrong or missing — from the finding>
## Investigation Questions
- <What needs to be explored before this can be spec'd>
- <What alternatives exist>
## Acceptance
- Investigation questions answered
- Decision recorded (ADR if architectural)
- Follow-up work item created if action needed
Work-item kind mapping:
| Finding source/type | Work-item kind |
|---|---|
| Concrete bug or failing behavior | issue |
| User-facing capability or new workflow | feature |
| Internal cleanup with no behavior change | refactor |
| Exploratory architecture choice | decision |
Use this mode when skillwiki validate rejects proposed work items. Create a
schema-valid ad-hoc capture under:
{vault}/raw/transcripts/YYYY-MM-DD-<capture-kind>-<slug>.md
Frontmatter:
---
source_url:
ingested: YYYY-MM-DD
kind: <task|bug|idea|note>
project: "[[<project-slug>]]"
---
No sha256 is used for ad-hoc captures; they are mutable working notes, not
immutable raw sources. Validate each capture with skillwiki validate.
Capture kind mapping:
| Finding source/type | Capture kind | Claim behavior |
|---|---|---|
| Concrete actionable change | task | Appears in unclaimed transcript discovery |
| Concrete defect/regression | bug | Appears in unclaimed transcript discovery |
| Exploratory improvement | idea | Preserved but not executable by default |
| Context-only observation | note | Preserved but not executable by default |
Capture body:
# <title>
## Problem
<What's wrong or missing — from the finding>
## Recommended Promotion
Promote this capture into a `planned` project work item only after a human
confirms scope and priority.
## Requirements Or Questions
<Concrete requirements for task/bug, or investigation questions for idea/note>
## Acceptance
<Verifiable outcomes, or decision/output expected from investigation>
## Sources Used
- <finding source reference>
Rate limiting: If creating >3 items, batch-commit vault changes after every 3 items to avoid large uncommitted working trees.
Append to {vault}/log.md:
## [YYYY-MM-DD] retro | investigate-cycle: <project-slug>
- Mode: investigate (<intensity>)
- Topic: <user topic or "autonomous">
- Scanned: <N> total findings
- Deduplicated: <K> skipped
- Queued: <M> findings (<A> proposed work items, <B> raw captures)
- Items: <slug1> (P<x>), <slug2> (P<y>), ...
- Friction: <any issues during investigation>
- Generalize?: no
- ClaudeMd?: no
- WorkflowShift?: no
Same as CORE step 7:
VAULT_AUTO_COMMIT is true AND vault is dirty:
git -C $VAULT add -A && git -C $VAULT commit -m "dev-loop[investigate]: <N> queued findings for <slug>"VAULT_SYNC_PEER_AWARE: acquire lock, push, release.status: planned items. Investigate output is queued,
not executable. The human promotes.max_items * (2 if high else 1).
If TRIAGE produces more, discard the lowest-ranked.status: proposed fails
validation, switch to raw transcript captures for the whole invocation.| Scenario | Behavior |
|----------|----------|
| /dev-loop investigate then /dev-loop | CORE picks up only promoted planned work; raw task/bug captures surface as unclaimed transcripts |
| /dev-loop investigate then /dev-loop investigate | TRIAGE dedup prevents duplicates |
| /loop 2h /dev-loop investigate | Recurring investigation, safe due to dedup + 24h warning |
| /dev-loop investigate with no vault | Refuses with actionable message |
| IDLE research finds P2+ | Does NOT auto-create items (IDLE stays passive) |
testing
Audit and improve CLAUDE.md files in repositories. Use when user asks to check, audit, update, improve, or fix CLAUDE.md files. Scans for all CLAUDE.md files, evaluates quality against templates, outputs quality report, then makes targeted updates. Also use when the user mentions "CLAUDE.md maintenance" or "project memory optimization".
tools
Use when porting Claude Code plugins to Codex or Agy/Gemini packages, installing or running the agent-plugin-porter CLI, verifying generated plugin output, preparing Codex personal-marketplace installs, or planning npm publish/release steps for the porter.
tools
Use when porting Claude Code plugins to Codex or Agy/Gemini packages, installing or running the agent-plugin-porter CLI, verifying generated plugin output, preparing Codex personal-marketplace installs, or planning npm publish/release steps for the porter.
development
Scaffold per-repo dev-loop config (PRD layer, knowledge layer, release config, vault path) and build the project glossary with grill-with-docs. Run once per repo before using dev-loop.