원클릭으로
investigation
Create an investigation ticket + live-doc for sustained root-cause work (retros, bug archaeology, regression hunts).
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Create an investigation ticket + live-doc for sustained root-cause work (retros, bug archaeology, regression hunts).
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Review a PR for quality, security, and standards compliance. Invokes the Code Reviewer agent (Rex).
Review a technical design / migration AgDR / feature spec for architectural soundness BEFORE the Build phase. Invokes the Solution Architect agent (Tariq) — the non-code analog of /code-review.
Score a review agent (Rex/Hakim/Tariq) against a labeled PR corpus — ground-truth defect-set overlap, never a prose rubric. Headline metric is approve-precision.
Security-focused PR review for vulnerabilities and best practices. Invokes the Security Reviewer agent (Shield).
Record per-PR design-review approval (UI merge gate). ONLY on an explicit per-PR designer "approved".
Record per-PR CEO approval and merge in one turn. ONLY on an explicit per-PR "approved" — never on umbrella "go".
| name | investigation |
| description | Create an investigation ticket + live-doc for sustained root-cause work (retros, bug archaeology, regression hunts). |
| argument-hint | [short-slug-or-incident-id] |
| allowed-tools | Bash, Read, Write |
Creates a structured GitHub Issue + a sibling live-doc markdown file for an investigation — sustained root-cause work whose deliverable is a written artefact of what was observed, what we concluded, and what's next. Distinct from /spike (forward-looking hypothesis with a budget) and /bug (immediate-fix) — see the comparison block at the top of templates/tickets/investigation.md.
When to use an investigation vs a bug vs a spike. A
/bugis filed when you already know what's broken and need to coordinate the fix. A/spikeis filed when you want to test a forward-looking hypothesis ("will this approach work?") inside a time budget. An/investigationis filed when the question itself is the unknown — "why did this happen?", "what's actually going on with the metric drift?", "how does competitor X handle this?". The investigation produces a written record; the bug fix that may follow is a downstream artefact.
Read the registry path via portfolio_registry, the per-project docs dir via portfolio_projects_dir, and the ideas backlog via portfolio_ideas_backlog — all from .claude/hooks/_lib-portfolio-paths.sh. Source the helper at the top of any bash block that touches those paths:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
registry=$(portfolio_registry)
projects_dir=$(portfolio_projects_dir)
Defaults match today's single-fork layout (./apexyard.projects.yaml, ./projects, ./projects/ideas-backlog.md). Adopters in split-portfolio mode override the portfolio.{registry, projects_dir, ideas_backlog} keys in .claude/project-config.json. Don't hardcode literal apexyard.projects.yaml or projects/ paths in bash blocks — the helper resolves whichever mode the adopter is in. See docs/multi-project.md.
/investigation # asks for the trigger interactively, derives slug
/investigation order-api-spike-may-12 # pre-fills the slug; asks for the trigger detail
/investigation PD-4471 # incident ID as slug
Before any gh issue create (or other tracker CLI), write this skill's name to the active-issue-skill marker so require-skill-for-issue-create.sh lets the command through. At skill entry:
# Resolve the ops-fork root the SAME way the hooks do (_lib-ops-root.sh):
# anchor on the .apexyard-fork marker (split-portfolio v2 — onboarding.yaml
# lives in the sibling portfolio repo, NOT the ops fork), falling back to the
# onboarding.yaml + apexyard.projects.yaml pair (single-fork v1).
ops_root="$PWD"; r="$PWD"
while [ "$r" != / ]; do
if [ -f "$r/.apexyard-fork" ] || { [ -f "$r/onboarding.yaml" ] && [ -f "$r/apexyard.projects.yaml" ]; }; then
ops_root="$r"; break
fi
r=${r%/*}
done
mkdir -p "$ops_root/.claude/session"
echo "investigation" > "$ops_root/.claude/session/active-issue-skill"
Remove the marker on every exit path (success, early-exit, user cancel, error):
rm -f "$ops_root/.claude/session/active-issue-skill"
The clear-issue-skill-marker.sh SessionStart hook sweeps stale markers from killed sessions, but a clean exit should never leave one behind. See AgDR-0030.
Read .claude/session/current-ticket to determine the active project context. Then:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
registry=$(portfolio_registry)
projects_dir=$(portfolio_projects_dir)
If the active ticket is on a managed project's repo → use that project's name + repo.
Else if exactly one project is registered → use it.
Else if multiple projects are registered → ask:
Which project is this investigation for?
(Or 'framework' if it's about the apexyard framework itself.)
If no projects are registered, ask for the repo in owner/repo format. The live-doc lands at docs/investigations/<YYYY-MM-DD>-<slug>.md in the ops fork root (the framework's own investigations live there).
Read .ticket.prefix_whitelist from .claude/project-config.*.json. If Investigation (case-insensitive) is not in the list, warn and stop:
This fork's ticket schema doesn't include 'Investigation' as a valid prefix.
Either add it to .claude/project-config.json → .ticket.prefix_whitelist, or
file the ticket using whichever prefix the fork uses for root-cause work.
(The shipped default in .claude/project-config.defaults.json includes Investigation. This check exists for forks that have customised the whitelist — see apexyard#109.)
Take the slug from $ARGUMENTS (kebab-cased). If empty, ask:
What's a short slug for this investigation? (3-5 words, kebab-case)
Example: "order-api-spike-may-12" or "PD-4471".
The slug becomes part of the live-doc filename: <YYYY-MM-DD>-<slug>.md. Today's date prefixes automatically (so the same slug can be reused for a follow-up investigation next month without colliding).
Ask conversationally — do NOT batch all questions. Wait for each answer before asking the next. Mirror the section structure of templates/tickets/investigation.md so the user sees their answers slot into the artefact directly.
a) Trigger (required)
What kicked this off? One paragraph.
Examples:
- "Production incident PD-4471 at 14:03 UTC on 2026-05-12 — error rate
on /api/orders spiked from 0.2% to 11% for 22 minutes."
- "Customer report from #cs-tickets-3471 — exports >100k rows always fail."
- "Reviewing why we picked Auth0 in 2024 vs Cognito today."
Include the link / incident ID / date if you have it.
b) Hypothesis being tested (required)
What did you think was happening BEFORE starting? List 2–4 hypotheses
you wanted to confirm or rule out. I'll format them as a checkbox tree.
Example:
- Upstream dependency degradation
- Internal queue backup
- Recent deploy regressed something
Push back if the user offers only one hypothesis — investigations exist precisely because the answer isn't obvious; entertaining multiple causes upfront is the methodology. If the user genuinely has one hypothesis only, that's usually a sign they should file a /bug instead. Surface that gently:
Only one hypothesis? An investigation usually entertains 2–4 — that's
what distinguishes it from a /bug (where you already know what's broken).
Are you sure /bug isn't the right call here? If yes to investigation,
I'll proceed with the one hypothesis.
c) Evidence sources you'll consult (required)
Where will you gather evidence? List the sources.
Examples:
- CloudWatch logs for /api/orders, 14:00–14:30 UTC
- Payments provider status page
- order_events table (SQL)
- Last 4 deploys to OrderService
- Staging replay of failed payloads
These become the "Method" section — the path a reader follows.
d) Initial method sketch (optional)
Any specific queries / commands / steps you've already planned?
(or press Enter to fill in as you go)
If the user provides specifics, they go into the Method section. If they skip, the Method section starts empty in the live-doc and the investigator fills it in as evidence comes in.
Resolve the investigation template via the portfolio helper so adopter overrides win when present:
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-read-config.sh"
source "$(git rev-parse --show-toplevel)/.claude/hooks/_lib-portfolio-paths.sh"
template=$(portfolio_resolve_template tickets/investigation.md) # → custom-templates/tickets/investigation.md if present, else templates/tickets/investigation.md
Single-fork adopters (no portfolio block) and adopters with no override fall straight through to templates/tickets/investigation.md. Adopters who want a customised investigation shape (e.g. Five Whys instead of Hypothesis Tree) drop their version at <private_repo>/custom-templates/tickets/investigation.md. See templates/README.md for the path-mirroring convention.
Backward-compat fallback: if portfolio_resolve_template returns empty (template file missing — partial adopter setup or pre-#281 layout where the file lived at templates/investigation.md), fall back to the inline heredoc body below (the live-doc bootstrap structure mirroring the resolved template's sections) and print a one-line WARN on stderr (WARN: tickets/investigation.md template missing — using inline fallback).
Read the resolved template and substitute the gathered inputs into the four sections that have inputs (Trigger, Hypothesis being tested, Method sketch, plus the placeholder Findings / Conclusion / Follow-up actions sections to fill in as the investigation progresses).
Display the full ticket + the live-doc path:
Here's what I'll create:
GitHub Issue:
Title: [Investigation] {slug}
Labels: investigation
Repo: {owner/repo}
Body: (template-rendered — Trigger + Hypothesis + Method sketch
pre-filled; Findings / Conclusion / Follow-up actions empty
for now)
Live-doc:
Path: {projects_dir}/{project}/investigations/{YYYY-MM-DD}-{slug}.md
(or docs/investigations/{YYYY-MM-DD}-{slug}.md for framework
investigations)
The live-doc IS the working surface — update it as evidence comes in.
The GitHub issue tracks visibility + close state (closes when every
Follow-up action lands or is explicitly dropped).
Create both? (yes / edit / cancel)
Compute the date prefix (UTC YYYY-MM-DD) and the target path:
date_prefix=$(date -u +%Y-%m-%d)
if [ "$project" = "framework" ]; then
livedoc_dir="$(git rev-parse --show-toplevel)/docs/investigations"
else
livedoc_dir="$projects_dir/$project/investigations"
fi
mkdir -p "$livedoc_dir"
livedoc_path="$livedoc_dir/${date_prefix}-${slug}.md"
Substitute the gathered values into the resolved template and write the file via the Write tool. The Metadata block at the bottom of the file references the GitHub issue number — leave it as #{NNN} until step 8, then patch it.
Dispatch creation through tracker_create (#670 / AgDR-0072, extended by
the #709 creator sweep) so the investigation lands in this project's tracker —
GitHub, GitLab, or a custom CLI — per its tracker: block in
apexyard.projects.yaml. For a GitHub adopter this runs gh issue create
exactly as before.
# Resolve the tracker lib (it lives in the ops fork's hooks dir) by walking up
# from the cwd; source it.
tracker_lib="$(r="$PWD"; while [ -n "$r" ] && [ "$r" != / ]; do \
[ -f "$r/.claude/hooks/_lib-tracker.sh" ] && { echo "$r/.claude/hooks/_lib-tracker.sh"; break; }; \
r="${r%/*}"; done)"
# shellcheck source=/dev/null
. "$tracker_lib"
# Ensure the `investigation` trigger label exists on the target tracker.
# Best-effort (tracker_label_ensure always exits 0).
tracker_label_ensure "{owner/repo}" "investigation" "5319E7" "Sustained root-cause work — closes when Follow-up actions land, not on PR merge"
# Pass the body via a file (arbitrary markdown — never inline-interpolated).
body_file="$(mktemp)"
cat > "$body_file" <<'BODY'
{rendered template body, with the Metadata block pointing at the live-doc path}
BODY
# tracker_create <owner/repo> <title> <body_file> [<labels_csv>] → {"ref","url"}.
result="$(tracker_create "{owner/repo}" "[Investigation] {slug}" "$body_file" "investigation")"
rc=$?
rm -f "$body_file"
if [ "$rc" -eq 3 ]; then
echo "Tracker is 'none' (shape-only) — nothing was created in a tracker." >&2
echo "File this in your external system (e.g. Jira/Linear via MCP):" >&2
printf '%s\n' "$result"
exit 0
elif [ "$rc" -ne 0 ] || [ -z "$result" ]; then
echo "Investigation creation failed — check the tracker CLI / auth. Nothing was created." >&2
exit 1
fi
ref="$(printf '%s' "$result" | jq -r '.ref')"
url="$(printf '%s' "$result" | jq -r '.url')"
Use $ref to patch the live-doc's Metadata block — replace the #{NNN}
placeholder with the real reference.
Created: {owner/repo}#${ref} — [Investigation] {slug}
${url}
Live-doc: {livedoc_path}
Next steps:
1. Open the live-doc and update Findings as evidence comes in.
2. Each hypothesis in the tree gets evidence-for / evidence-against
bullets underneath — prune as you rule things out.
3. When you reach a conclusion, fill in the Conclusion section.
4. List Follow-up actions, each linked to a tracker ticket
(`/bug`, `/feature`, `/spike`, `/decide`) or marked `(no follow-up)`.
5. Close the GitHub issue when every Follow-up action is resolved
— NOT on PR merge.
Suggested follow-up skills depending on what the investigation surfaces:
/bug — file an immediate-fix bug
/spike — file a hypothesis-driven exploration
/decide — record a technical decision that fell out
/feature — propose a new feature the investigation revealed a need for
/bug might be the right tool. Allow the user to override.investigation label is the signal that downstream automation (if any) should treat the ticket as long-running.investigation always. Priority labels (P0 / P1 / etc.) are NOT applied by default — investigations are scoped by the question, not prioritised by P-class. If the investigation is incident-driven and the operator wants a P-label, they can add one manually./investigation-close skill). The Follow-up actions section IS the close gate. Operators close the issue when actions land. Different from /spike-close because investigations have an open-ended action list, not a binary disposition. See AgDR-0027 for the rationale.<private_repo>/custom-templates/tickets/investigation.md. The skill resolves via portfolio_resolve_template tickets/investigation.md — no skill changes needed.| Skill | Purpose | When to chain into /investigation |
|---|---|---|
/bug | Immediate-fix scenario, known broken behaviour | Rare — investigations usually file bugs as follow-up actions, not the other way around |
/spike | Forward-looking hypothesis with a budget | An investigation may conclude "we need a spike to test the fix approach" — file via /spike as a follow-up action |
/debug | Live debugging session (process helper) | A /debug session that surfaces a deeper "why did this happen" question naturally promotes to /investigation for the written artefact |
/decide | Record a technical decision (AgDR) | An investigation often concludes with a decision — record it via /decide as a follow-up action; cite the investigation from the AgDR |
/feature | Propose a new user-facing feature | An investigation that reveals a missing capability files a /feature as a follow-up action |
/migration | Migration ticket + AgDR | If the investigation's remediation is a migration, file via /migration (which itself produces a ticket + AgDR pair) |
The bidirectional summary: investigations are usually upstream of other ticket types (they reveal what needs to happen); they're rarely downstream of them.
Part of ApexYard — multi-project SDLC framework for Claude Code · MIT.