Skip to content
AgentDock

Code Sentinel

Specs and grilling

Turn an idea into an issue the fleet can build, through an interview.

/code-sentinel:spec turns an idea into a GitHub issue the orchestrator can dispatch. It interviews you in rounds, checks the answers against your project's decisions, splits the work into slots that parallel agents can build without colliding, and only then writes anything.

It writes documents, never product code, and it never dispatches agents. Dispatching is the orchestrator's job.

Two ways in

Claude Code
/code-sentinel:spec "Users can export their orders as CSV"
/code-sentinel:spec #42
/code-sentinel:spec
  • With an idea or an issue number, it starts the interview straight away.
  • With no argument, it starts with discovery. It proposes at most five candidates, each citing where it came from: open issues without the ready label, roadmap items whose dependencies have landed, documented deferrals, TODO and FIXME in the code, and follow-ups promised in pull requests. You pick one. "There is nothing to specify" is a valid outcome.

It reads before it asks

Before the first question, the skill reads CLAUDE.md, AGENTS.md and CONTRIBUTING.md, your decision records (docs/adr/ and similar), architecture and roadmap docs, open issues and the code. It never asks something the repository already answers, and it says what it checked. Broad lookups run in a background agent, and only the questions that depend on them wait.

The grilling

The interview is a "grilling": a design tree worked in rounds. Every decision branches into the decisions that hang off it. "Exports run in the background" opens how you get the file, how long it is kept and what happens on failure, none of which can be asked before the first answer.

  • Rounds. Each round asks the whole frontier: every question whose prerequisites are already settled. A question that depends on another open question waits for a later round.
  • Numbered questions, one decision each. Every question is numbered and covers a single decision, so you can answer "Q2: no" without restating the rest.
  • A recommended answer for each. Every question comes with the skill's recommendation and a one-line reason, citing an existing decision record where one applies. Answer only the questions you disagree with; the recommendation is what happens if nobody answers.
  • Only questions that matter. A question is asked only if the repository cannot answer it, the two answers would lead to different documents (not just different wording), and there is a stated default.
  • Assumptions are challenged. Claims in the spec are marked [Confirmed] (read in code or docs) or [Unknown]. A slot that depends on an [Unknown] gets the stronger model and a line in the risks.
  • Nothing is written until you confirm. When the frontier is empty, the skill reads all your answers back in one block and asks: Confirm, Change an answer or Stop.

The decisions stay yours. The skill recommends; it never merges two options into one because it prefers one. It talks to you in your language, and writes every repository document in English unless CLAUDE.md says otherwise.

An example round

The excerpt below is an illustrative example, not output copied from a real session. It shows the shape of a first round for a CSV export.

Example: round 1 (illustrative)
I checked docs/adr/ (12 records), the orders module and open issues.
Orders are already paginated server-side (src/api/orders/list.ts); there is
no background job runner yet.
 
❓ **Q1** **Where does the export run**: in the request, or as a background job?
 
➡️ In the request, capped at 10 000 rows. There is no job runner, and adding one
is a separate decision.
 
---
 
❓ **Q2** **Which columns**: the table as shown, or every order field?
 
➡️ The table as shown. It is what users asked for in #42.
 
---
 
❓ **Q3** **Who may export**: every role that can see orders, or admins only?
 
➡️ Every role that can see orders, filtered by the same tenant rule (ADR-0004).

You answer, for example, "Q1: 50 000 rows. Rest fine." The next round asks only what your answers opened (what happens above the cap, the file name) and stops when nothing is left.

Checked against your decisions

The finished answers are checked against your decision records and the rules in CLAUDE.md and AGENTS.md: tenancy and authorization boundaries, module dependencies, data ownership. If the work contradicts a decision, there are two honest outcomes: the decision is amended in the same change with its cost stated, or the work is wrong. The spec says which.

Slots for parallel agents

This step is what lets several agents work on one feature at once. The skill lists every file the work touches and marks the serialized resources: schema files, migrations, generated code, lockfiles, CI and compose files, CLAUDE.md, route and module registries, barrel files. Then it writes a plan under fixed rules:

  • One writer per file across the whole wave.
  • Serialize by table, not by file. Two slots adding distinct new tables may share the schema file; two altering the same table may not.
  • At most maxSlots slots, and fewer is usually better.
  • Every slot is independently reviewable and mergeable.
  • A model per slot: opus when the slot still decides something, sonnet when it executes a written decision.

The orchestrator reads these tables without interpretation:

Issue body (excerpt)
## Parallel plan
 
| Slot | Owns | Touches | Depends on | Lead | Model |
|---|---|---|---|---|---|
| i42-api | the export endpoint | src/api/orders/export/** | none | yes | opus |
| i42-web | the export button   | web/app/orders/**        | i42-api | no | sonnet |
 
## Contention
 
| Resource | Owner | Everyone else |
|---|---|---|
| src/api/routes.ts | i42-api | do not open it |

Each slot's Touches globs become its owns: fence when the orchestrator dispatches it.

What it produces

The spec has a fixed shape: Summary, Scope (in and out), Decisions, Data and schema, API, UI, Configuration, Acceptance criteria as checkboxes, Parallel plan, Contention, Risks, and Open questions each with its default. Trailing lines carry Depends on #N and, if a person must clear something before merge, Gate: …. Any new read path to multi-user data gets an authorization test as a named acceptance criterion.

Before publishing, it shows you the full spec and asks: Publish, Publish and queue for the orchestrator, Edit or Stop.

  • The issue. It creates the issue (feat: …, label enhancement) or updates the one you named. One piece of work is one issue; a wave is one issue with a parallel plan, not one issue per slot.
  • The spec file, if you keep them. When specDir is set in the config, the spec goes to <specDir>/<issue>-<slug>.md on a docs/<issue>-<slug> branch with a pull request, and the issue body summarizes and links it. Documentation lands first.
  • The ready label. Only Publish and queue adds it. With a spec file, the label is added only after the docs pull request has merged, so the spec exists on the base branch before any worker reads it.

It ends by naming /code-sentinel:orchestrator as the next step, and for a wave it offers /code-sentinel:estimate #<n> --post.

Other ways into the queue

/code-sentinel:estimate sizes work from evidence in your code and repository history. It first asks who executes it (the agent fleet, a team, or both compared) and, for a parallel plan, gives the critical path with N workers. --post posts the estimate as a comment and sets a size: label. If the fleet is the executor and every readiness check passes, it offers Queue it for the orchestrator. It never starts the orchestrator itself.

Claude Code
/code-sentinel:estimate #42 --fleet --post
/code-sentinel:estimate --queue

/code-sentinel:issue files an issue directly. --ready adds the ready label only when the body has acceptance criteria (feature) or a reproduction (bug); otherwise the issue is created without it and says why. --depends-on writes the Depends on lines.

Claude Code
/code-sentinel:issue "Rate-limit the login endpoint" --auto --ready
/code-sentinel:issue "Add audit export" --auto --ready --depends-on 41

In AgentDock, Project → Queue → Create issue with queueing turned on applies the same rule: no acceptance criteria, no ready label.

Next steps