Workflow
Every change in a Coograph-initialized project goes through the same five-step pipeline: Plan → Propose → Apply → Review → Archive. The only exemptions are narrow and literal — typo fixes, comment-only edits, user-dictated config-value bumps, and follow-ups on an already-approved in-progress proposal.
“Trivial,” “obvious,” “small,” and “just one tweak” are not exemptions. If in doubt, propose.
The point of the workflow isn’t ceremony. It’s that AI agents are uniquely good at confidently shipping the wrong thing, and the workflow forces an interrupt point before that happens.
A change usually starts with /coograph-new-ticket, which investigates, asks
its clarifying questions, and hands off to Propose. On the first ticket in a
project it also asks once whether to run each agent on a different model — see
Models.
Plan
/coograph-plan (Claude Code) or @Planner (VS Code Copilot).
The Planner agent investigates the codebase and asks one focused clarifying question at a time. It never writes code. Output is a clear understanding of what the change requires — files, integration points, risks.
Skip planning when:
- Review output already exists in conversation.
- The user has specified the problem, files, and fix direction.
- The fix is a one-line exempt change per the literal list above.
Propose
The coograph-propose skill creates an OpenSpec change directory at openspec/changes/<YYYY-MM-DD>-<slug>/ with:
.openspec.yaml
proposal.md ← Why, Goals, Non-Goals, Decisions, Impact, Risks
specs/<capability>/spec.md ← Requirements + Scenarios
tasks.md ← 3–8 task groups, last is Verification
The user reviews and either says “proceed” or sends edits. No code is written before approval.
See OpenSpec for what each of those files carries and why the gate is shaped this way.
Apply
The agent works through tasks.md in order, marking tasks done as it goes.
- Read every file before editing.
- Check API spec / generated types before assuming names.
- If a build error is non-obvious, run
/coograph-debug. - Mid-implementation requirement changes update the OpenSpec, then continue.
After all tasks are done, run quality gates: typecheck, lint, format, tests. Fix until clean.
Review
/coograph-review or @Reviewer.
The Reviewer is read-only. Every finding cites a verbatim quote from a fresh file read — diffs and conversation memory are not valid sources.
Findings are severity-rated: Critical (must fix before merge), Warning (should fix), Suggestion (could fix). The implementor fixes Critical/Warning findings, re-runs quality gates, and re-reviews only if fixes were substantial.
When the change is big: /coograph-ultra-review
One reviewer over the working tree is the right size for most changes. For a big one - more than about fifteen files, a stack of commits going to people for approval, or anything with queue jobs, locks, state transitions, data migrations or a contract between two services - Coograph offers a second, optional review: /coograph-ultra-review (plugin: /coograph:coograph-ultra-review). Several hostile reviewers, one question each, then independent refuters that attack every finding before it reaches the report; three modes (full, delta, plan) and a stop rule. The agent points it out when a change qualifies and never runs it unasked, because a run costs about a million tokens and twenty minutes. Claude Code only.
What a run does, the arguments, the measured cost of each mode and the stop rule: Ultra review.
Archive
Move the completed proposal:
mv openspec/changes/<slug>/ openspec/changes/archive/<slug>/
This keeps openspec/changes/ populated only with active work — agents read in-progress proposals on session start.
Agents
There is no separate @Implementer. The agent that plans also implements.
| Agent | Purpose | Key constraint |
|---|---|---|
| Planner | Interview-driven planning | One question at a time. Never implements. |
| Reviewer | Strict read-only code review | Every finding cites a verbatim quote. |
| Debugger | Root-cause analysis, minimal fixes | Reproduce → Evidence → Fix → Verify. 3-attempt circuit breaker. |
| Verifier | Evidence-based completion checks | Runs commands itself. PASS/FAIL/INCOMPLETE verdict. |
| Explore | Fast read-only codebase Q&A | Quick / medium / thorough depth levels. |
| Retro | Turns the signals report into an OpenSpec | Reads the deterministic report only. Never invents evidence. |
All agents are required to call code-graph first. Fallback to sqlite3 .code-graph/graph.db, and only then to grep, is permitted only when the graph DB is genuinely absent. Convenience is not a valid reason to skip.
Lifecycle hooks
Claude Code lifecycle hooks live in .claude/hooks/:
| Hook | What it does |
|---|---|
block-generated.py | Blocks edits to files under generated/, dist/, build/, etc., and to anything with @generated / DO NOT EDIT in its first 5 lines. |
log-bash.py | Appends every bash command to .coograph/session.log and .coograph/sessions/<session_id>.log (both gitignored). Audit trail. |
report-graph.py | Reports code-graph state at session start. Prints a rebuild hint if graph.db is missing. |
warn-scope.py | If an active OpenSpec exists, warns when editing a file not referenced in tasks.md. Surfaces scope creep without stopping work. |
capture-signals.py | At session start, at every compaction and at session end, turns the transcript into privacy-safe signals in .coograph/signals.jsonl, and prints the one-line Retro status. See Retro. |
no-new-deps-warn.py | Warns the first time a session installs a package or edits a dependency manifest. Silent for restores (npm install bare, pip install -r, pip install -e .), because it calls the same function the new-dependency detector uses. |
defect-warn.py | Warns once, at git commit, when a session edited source and no review ran, counting the Skill tool, a delegation to the reviewer agent, and a typed /coograph-review or /coograph-ultra-review. It flags the review that was skipped; it does not detect defects. |
openspec-gate-warn.py | Warns once per session when a second source file is about to be edited with no OpenSpec touched and no active change. The live form of the OPENSPEC OR STOP hard rule. |
gotcha-surface.py | Puts a matching GOTCHAS.md entry in front of the agent, once per session, when it edits a file under the entry’s paths or runs one of its commands. See Instruction layout. |
These run automatically: no agent decision, no prompt engineering required.
Warnings reach the agent through additionalContext (and the terminal through systemMessage), with exit code 0. A hook that prints to stderr and exits 1 is not enough: Claude Code records that text in the transcript, but the model never reads it. A nested-session probe proved it on 2026-10-06, and every warning hook was moved to the channel the model sees. A blocking hook still uses exit 2, which hands its reason to the model.
Reliability properties
- Anti-hallucination. Reviewer findings need verbatim quotes from a fresh read. Agents grep for every name before using it. Files are re-read after 10+ turns of conversation; agents never cite their own prior output as evidence.
- Circuit breakers. 3-retry limit on fixes, 3-cycle limit on review loops.
- Feature inventory. Before editing any file, list its existing features and verify each is preserved.
- Scope-creep detection. The Debugger reviews its own diff after every fix and reverts unrelated changes.
- Risk-based classification. Auth, security, payments, and migrations always get Complex treatment regardless of file count.
These are not promises about correctness. They’re constraints designed to fail loudly when an agent is about to do something wrong.