skip to content
coograph 17

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:

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.

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.

AgentPurposeKey constraint
PlannerInterview-driven planningOne question at a time. Never implements.
ReviewerStrict read-only code reviewEvery finding cites a verbatim quote.
DebuggerRoot-cause analysis, minimal fixesReproduce → Evidence → Fix → Verify. 3-attempt circuit breaker.
VerifierEvidence-based completion checksRuns commands itself. PASS/FAIL/INCOMPLETE verdict.
ExploreFast read-only codebase Q&AQuick / medium / thorough depth levels.
RetroTurns the signals report into an OpenSpecReads 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/:

HookWhat it does
block-generated.pyBlocks edits to files under generated/, dist/, build/, etc., and to anything with @generated / DO NOT EDIT in its first 5 lines.
log-bash.pyAppends every bash command to .coograph/session.log and .coograph/sessions/<session_id>.log (both gitignored). Audit trail.
report-graph.pyReports code-graph state at session start. Prints a rebuild hint if graph.db is missing.
warn-scope.pyIf an active OpenSpec exists, warns when editing a file not referenced in tasks.md. Surfaces scope creep without stopping work.
capture-signals.pyAt 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.pyWarns 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.pyWarns 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.pyWarns 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.pyPuts 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

These are not promises about correctness. They’re constraints designed to fail loudly when an agent is about to do something wrong.