Code Sentinel
Config reference
The orchestrator block of .code-analyzer-config.json.
The Code Sentinel orchestrator reads its settings from the orchestrator block of .code-analyzer-config.json at the root of your repository. The file is committed, so every machine and every person running the orchestrator on that repository gets the same behaviour.
Every key is optional. With no file at all, the orchestrator detects what it can and uses the defaults below.
Example
{
"orchestrator": {
"base": "develop",
"maxSlots": 5,
"readyLabel": "cs:ready",
"specDir": "docs/specs",
"install": "bun install",
"checks": ["bun run lint", "bun run test", "bun run build"],
"mergeMethod": "merge",
"autoMerge": true,
"defaultModel": "sonnet",
"triageSkill": null
}
}A smaller setup, squashing into main with at most three workers:
{
"orchestrator": {
"base": "main",
"maxSlots": 3,
"checks": ["bun run lint", "bun run test", "bun run build"],
"mergeMethod": "squash"
}
}Keys
| Key | Type | Default | Meaning |
|---|---|---|---|
base | string | origin's default branch | Branch every worktree is cut from and every pull request targets |
maxSlots | number | 5 | Most workers running at once. A ceiling, never a target: the orchestrator runs fewer when fewer issues are ready |
readyLabel | string | "cs:ready" | The label that puts an issue in the queue |
specDir | string | none | Where spec files live. Unset means the issue body is the spec. On released versions, a path relative to the repository (docs/specs) |
install | string | detected | Dependency install command each worker runs in its worktree. Detected from the lockfile, package.json, Makefile, pyproject.toml, Cargo.toml or go.mod |
checks | string[] | detected | Commands every worker must pass before opening its pull request. Detected the same way |
mergeMethod | "merge" | "squash" | "rebase" | "merge" | Passed to gh pr merge --<method> |
autoMerge | boolean | true | false makes the orchestrator report green pull requests instead of merging them |
defaultModel | string | "sonnet" | Model for a slot only when the orchestrator genuinely cannot classify it. Normally each slot gets opus or sonnet by what it does |
triageSkill | string | null | none | A skill run in a subagent when the queue is dry, for example an error-tracker triage that files bug issues. What it files still needs the ready label to be dispatched |
mergeApproval | boolean | off | Green pull requests merge only after a fresh approval. Unreleased, see below |
The orchestrator writes the resolved values at the top of each round board, so you can check what it actually used.
specDir outside the repository
On the plugin's develop branch (plugin #7, not released to main at the time of writing), specDir also accepts:
- a path outside the repository, relative (
../acme-docs/specs) or absolute; github:<owner>/<repo>[/<subpath>], or thehttps://github.com/<owner>/<repo>URL of it.
Specs are then read only from the spec repository's origin/<branch> after a fetch, never from a working tree, so an unmerged spec counts as NO SPEC.
mergeApproval
mergeApproval is implemented only on the plugin's unmerged merge-approval branch (plugin #8). Released versions ignore the key and merge green pull requests as usual. To keep a person in the loop today, set autoMerge to false.
On that branch, with mergeApproval: true, a green pull request waits until an approval newer than its head commit exists. Any one of three sources counts: an approval file under <git-common-dir>/cs-orchestrator/approvals/, a GitHub review from someone other than the author, or the cs:approved label. A fresh "changes requested" review wins over the label. AgentDock's Approve button writes an approval file, but in a format that branch does not accept yet, so approve through GitHub until the two are reconciled.
How AgentDock uses this file
AgentDock reads the file and never writes it. AgentDock does not edit committed files in your repository.
- When you connect a project, the runner's inspection reads the
orchestratorblock and stores it as the project's config snapshot. An operator can refresh the snapshot through the API withPOST /api/projects/<id>/refresh. - The snapshot feeds the defaults AgentDock shows: the base branch, the ready label and whether merge approval is expected.
- Merge approval mismatch. If merge approval is on in Project → Settings but the file does not set
orchestrator.mergeApproval: true, the Approvals page shows Merge approval settings disagree, because the orchestrator would merge on its own. Fix it in the file, not in AgentDock.
Ready label precedence
AgentDock decides which label means "ready" in this order:
- Ready label override in Project → Settings, if set.
orchestrator.readyLabelfrom the config snapshot.cs:ready.
AgentDock uses that label for the Queue page and when Create issue queues a new issue. The orchestrator itself reads only the file. If you set an override that differs from readyLabel, AgentDock's queue and the orchestrator's queue will disagree, so prefer changing the file.
The same applies to Base branch override: it changes what AgentDock shows, while the orchestrator follows base in the file. When no override is set, AgentDock resolves the base from orchestrator.base, then origin/HEAD, then gh repo view, then main.
Environment for dispatch
A few environment variables in the orchestrator's session affect how workers start:
| Variable | Meaning |
|---|---|
CLAUDE_CONFIG_DIR | The Claude profile workers run under. Passed through to each worker |
CS_CLAUDE_BIN | A different claude executable (plugin develop only). A value with spaces is refused |
OTEL_EXPORTER_OTLP_ENDPOINT and related OTEL_* | Forwarded to workers, and turn telemetry on (plugin develop only) |
AGENTDOCK_PROJECT, AGENTDOCK_RUN | Added to each worker's telemetry tags with its slot and issue (plugin develop only) |