plugins/dev/skills/research-codebase/SKILL.md
Conduct comprehensive codebase research using parallel sub-agents. **ALWAYS use when** the user asks to 'research', 'investigate', 'explore the codebase', 'how does X work', 'find out about', or needs deep analysis of how existing code is structured. Produces a research document in thoughts/shared/research/ with file:line references.
npx skillsauth add coalesce-labs/catalyst research-codebaseInstall 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.
You are tasked with conducting comprehensive research across the codebase to answer user questions by spawning parallel sub-agents and synthesizing their findings.
You are a documentarian, not a critic. Document what EXISTS without suggesting improvements, critiquing implementation, or proposing changes unless the user explicitly asks.
CRITICAL REQUIREMENTS — read these before doing anything else:
thoughts/shared/research/YYYY-MM-DD-description.md# Check project setup (thoughts, CLAUDE.md snippet, config)
if [[ -f "${CLAUDE_PLUGIN_ROOT}/scripts/check-project-setup.sh" ]]; then
"${CLAUDE_PLUGIN_ROOT}/scripts/check-project-setup.sh" || exit 1
fi
SESSION_SCRIPT="${CLAUDE_PLUGIN_ROOT}/scripts/catalyst-session.sh"
if [[ -x "$SESSION_SCRIPT" ]]; then
CATALYST_SESSION_ID=$("$SESSION_SCRIPT" start --skill "research-codebase" \
--ticket "${TICKET_ID:-}" \
--workflow "${CATALYST_SESSION_ID:-}")
export CATALYST_SESSION_ID
fi
When this command is invoked, respond with:
I'm ready to research the codebase. Please provide your research question or area of interest,
and I'll analyze it thoroughly by exploring relevant components and connections.
Then wait for the user's research query.
Before the first thoughts read, fast-forward all HumanLayer thoughts checkouts so research picks up the freshest peer state. Roster-gated, ff-only, non-fatal — skips on single-host setups and never blocks research if offline:
# Pull-before-read (CTL-1236): roster-gated, ff-only, non-fatal.
"${CLAUDE_PLUGIN_ROOT}/scripts/lib/thoughts-pull-sync-gate.sh" || true
Before reading files or spawning sub-agents, get a fast semantic map of the codebase from Serena —
Catalyst's self-hosted, local code-understanding MCP (the DeepWiki replacement). This is free and
usually answers "where does X live / how is Y wired" in one call instead of many Greps, so your
sub-agent prompts come out specific rather than exploratory.
Prerequisite check — only do this if the mcp__serena__* tools are available (Serena MCP is
installed). If they are not, skip straight to Step 1 — do not retry or warn the user.
mcp__serena__activate_project with the repo root (the current working directory, or .).mcp__serena__list_memories, then
mcp__serena__read_memory("codebase_map") for the directory map and key concepts.mcp__serena__get_symbols_overview on a key
file, mcp__serena__find_symbol to jump to a definition, and
mcp__serena__find_referencing_symbols to see its callers.Serena's results are a starting point — always verify against live code via the sub-agents below.
stateMap.research)Create multiple Task agents to research different aspects concurrently.
Specialized agents available:
The key is to use these agents intelligently:
After spawning agents, record the phase transition:
if [[ -n "${CATALYST_SESSION_ID:-}" && -x "$SESSION_SCRIPT" ]]; then
"$SESSION_SCRIPT" phase "$CATALYST_SESSION_ID" "researching" --phase 1
fi
file.ext:line)Collect metadata using git commands:
git rev-parse HEADgit branch --show-currentDocument location: thoughts/shared/research/YYYY-MM-DD-{ticket}-{description}.md
thoughts/shared/research/YYYY-MM-DD-PROJ-XXXX-description.mdthoughts/shared/research/YYYY-MM-DD-description.mdPROJ with your ticket prefix from .catalyst/config.jsonIMPORTANT: Document Storage Rules
thoughts/shared/research/thoughts/searchable/ (read-only search index)Create a structured research document:
---
date: YYYY-MM-DDTHH:MM:SS+TZ
researcher: { your-name }
git_commit: { commit-hash }
branch: { branch-name }
repository: { repo-name }
topic: "{User's Research Question}"
tags: [research, codebase, { component-names }]
status: complete
last_updated: YYYY-MM-DD
last_updated_by: { your-name }
type: research
source_ticket: { TICKET-ID or null }
---
# Research: {User's Research Question}
**Date**: {date/time with timezone} **Researcher**: {your-name} **Git Commit**: {commit-hash}
**Branch**: {branch-name} **Repository**: {repo-name}
## Research Question
{Original user query, verbatim}
## Summary
{High-level documentation of what you found. 2-3 paragraphs explaining the current state of the
system in this area. Focus on WHAT EXISTS, not what should exist.}
## Detailed Findings
### {Component/Area 1}
**What exists**: {Describe the current implementation}
- File location: `path/to/file.ext:123`
- Current behavior: {what it does}
- Key functions/classes: {list with file:line references}
**Connections**: {How this component integrates with others}
### {Component/Area N}
{Continue for all major findings}
## Code References
- `path/to/file1.ext:123-145` - {What this code does}
- `path/to/file2.ext:67` - {What this code does}
## Architecture Documentation
{Document current architectural patterns and data flow. Descriptive, not prescriptive.}
## Historical Context (from thoughts/)
{Include insights from thoughts/ documents that provide context, if applicable}
## Open Questions
{Areas that would benefit from further investigation}
## Related Documents
{List related thoughts documents using wiki-links, e.g.:}
- [[YYYY-MM-DD-source-ticket|Source Ticket]]
- [[YYYY-MM-DD-related-research|Related Research]]
https://github.com/{owner}/{repo}/blob/{commit}/{file}#L{line}MANDATORY — do all three sub-steps before presenting results to the user.
8a. Sync thoughts:
humanlayer thoughts sync
8b. Linear comment (if ticket detected): Add a comment noting research is complete and
linking the document path. Use Linearis CLI (run linearis comments usage for syntax).
8e. Present summary to user:
Research complete!
**Research document**: {exact file path you wrote}
**Summary**: {2-3 sentence summary}
**Key files**: {Top 3-5 file references}
Would you like me to:
1. Dive deeper into any specific area?
2. Explore related topics?
End session tracking:
if [[ -n "${CATALYST_SESSION_ID:-}" && -x "$SESSION_SCRIPT" ]]; then
"$SESSION_SCRIPT" end "$CATALYST_SESSION_ID" --status done
fi
STOP HERE. Do NOT offer to create plans, use EnterPlanMode, or start implementing. Research is complete.
If the user has follow-up questions:
last_updated, last_updated_by, add last_updated_note## Follow-up Research: {Question}/create_plan's jobthoughts/searchable/ paths should be documented as thoughts/shared/ equivalentsIf a ticket is detected (provided as argument, mentioned in query, or from context):
stateMap.research from config
using Linearis CLI (run linearis issues usage for syntax).linearis comments usage for syntax).development
Migrate a single-harness repo to the dual-harness layout so both Claude Code and Codex load the same instructions and skills — AGENTS.md as the portable canonical doc, a thin CLAUDE.md `@AGENTS.md` bridge, and a `.agents/skills` dir with a `.claude/skills` symlink onto it. Use when asked to migrate to dual-harness, make this repo work in both Claude and Codex, or for agent metadata cleanup.
tools
Goal-driven senior-engineer pipeline-unstick sweep (CTL-1176 rung 3). Given the stuck/failed/needs-human set (or ONE ticket handed by the recovery router), its GOAL is to get the pipeline MOVING again — not to fix one ticket's review findings (that is phase-remediate). It runs AFTER the eyes (diagnostician evidence) and the hands (deterministic unstuck-sweep seams) have already tried, and it CONSUMES their output from a recovery-pass.json brief rather than re-diagnosing or redoing their narrow work. It acts like a senior engineer with full tool access — it resolves merge conflicts, rebases, force-pushes, merges green PRs, and re-dispatches stalled phases AUTONOMOUSLY — and escalates to the operator ONLY for a genuine value judgment / something that degrades other functionality / a real cost-benefit trade-off / a serious architecture change / an ADR conflict. On escalation it AUTHORS the operator inbox row + the push notification (executive-voiced). Dispatched as a `claude --bg` job by phase-agent-dispatch via slash command, AND invocable bare by the operator as a sweep — hence `user-invocable: true`. Ships behind CATALYST_RECOVERY_PASS (off by default — no live behavior change until shadow/enforce).
tools
Diagnose and fix Catalyst setup issues. Validates tools, database, config, OTel, direnv, and thoughts. Automatically fixes what it can — creates directories, initializes the database, sets WAL mode, runs migrations. Use for new installs, upgrades, or when something isn't working.
tools
--- name: phase-triage description: Phase agent that triages a Linear ticket — expands acronyms, classifies (feature/bug/docs/refactor/chore), identifies genuine blockers (a semantic second-pass over the backlog — NOT a prose scrape; CTL-838), estimates scope, writes triage.json, and posts a triage analysis comment to Linear. Triage completion is signaled by that comment plus the local triage.json — there is no `triaged` label. Emits phase.triage.complete.<TICKET> on success and phase.triage.fai