create-agent-rig 0.10.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +170 -4
- package/README.md +8 -8
- package/package.json +2 -2
- package/packages/cli/dist/commands/upgrade.js +22 -9
- package/packages/cli/dist/index.js +9 -2
- package/packages/cli/dist/integrations/doctor-guards.js +7 -3
- package/templates/agent-os/subagent-routing.json +9 -5
- package/templates/agent-os/universal/.agents/skills/diagnose/SKILL.md +43 -0
- package/templates/agent-os/universal/.agents/skills/loop/SKILL.md +65 -22
- package/templates/agent-os/universal/.agents/skills/plan-slices/SKILL.md +30 -0
- package/templates/agent-os/universal/.agents/skills/pr-ship/SKILL.md +1 -1
- package/templates/agent-os/universal/.agents/skills/release-propose/SKILL.md +74 -0
- package/templates/agent-os/universal/.agents/skills/skill-authoring/SKILL.md +39 -0
- package/templates/agent-os/universal/.claude/agents/code-reviewer.md +5 -1
- package/templates/agent-os/universal/.claude/agents/failure-diagnostician.md +112 -0
- package/templates/agent-os/universal/.claude/agents/security-scanner.md +1 -1
- package/templates/agent-os/universal/.claude/hooks/gate-stop-dod.mjs +14 -3
- package/templates/agent-os/universal/.claude/hooks/guard-rulebook.mjs +142 -14
- package/templates/agent-os/universal/.claude/hooks/guard-secret-file.mjs +5 -1
- package/templates/agent-os/universal/.claude/hooks/lib/edit-input.mjs +168 -17
- package/templates/agent-os/universal/.claude/rules/invariants.md +33 -0
- package/templates/agent-os/universal/.claude/scripts/lib/verdict.mjs +63 -0
- package/templates/agent-os/universal/.claude/scripts/queue/core.mjs +5 -6
- package/templates/agent-os/universal/.claude/scripts/queue/github-issues.mjs +71 -14
- package/templates/agent-os/universal/.claude/scripts/queue/propose.mjs +139 -0
- package/templates/agent-os/universal/.claude/scripts/release-evidence.mjs +188 -0
- package/templates/agent-os/universal/.claude/scripts/revalidation-report.mjs +4 -2
- package/templates/agent-os/universal/.claude/scripts/unattended-flag.mjs +157 -10
- package/templates/agent-os/universal/.claude/skills/diagnose/SKILL.md +43 -0
- package/templates/agent-os/universal/.claude/skills/loop/SKILL.md +65 -22
- package/templates/agent-os/universal/.claude/skills/plan-slices/SKILL.md +30 -0
- package/templates/agent-os/universal/.claude/skills/pr-ship/SKILL.md +1 -1
- package/templates/agent-os/universal/.claude/skills/release-propose/SKILL.md +74 -0
- package/templates/agent-os/universal/.claude/skills/skill-authoring/SKILL.md +39 -0
- package/templates/agent-os/universal/.codex/agents/code-reviewer.toml +2 -2
- package/templates/agent-os/universal/.codex/agents/failure-diagnostician.toml +6 -0
- package/templates/agent-os/universal/.codex/agents/security-scanner.toml +1 -1
- package/templates/agent-os/universal/AGENTS.md +11 -5
- package/templates/agent-os/universal/docs/decisions/codex-adapter.md +1 -1
- package/templates/agent-os/universal/docs/decisions/subagent-routing.md +5 -3
- package/templates/agent-os/universal/docs/decisions/workflow-layer-split.md +15 -3
- package/templates/agent-os/universal/layers.json +12 -0
- package/templates/hash-history.json +118 -22
- package/templates/release-ledger.json +3 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: release-propose
|
|
3
|
+
description: Use to turn repeated evidence from `release-evidence.mjs` into a bounded candidate-release proposal for the owner to decide. Ships only with the opt-in workflow layer.
|
|
4
|
+
allowed-tools: Read, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Proposing a release from repeated pain
|
|
8
|
+
|
|
9
|
+
## 1. What this is not
|
|
10
|
+
|
|
11
|
+
The loop's own §7 improvement proposals are per-run fixes, filed and read one
|
|
12
|
+
run at a time. This skill is different: a release-level proposal, built from
|
|
13
|
+
evidence that recurred across more than one run, addressed to the owner —
|
|
14
|
+
never to the queue, and never approved by the skill itself.
|
|
15
|
+
|
|
16
|
+
## 2. Gather
|
|
17
|
+
|
|
18
|
+
Run exactly:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
node "$(git rev-parse --show-toplevel)/.claude/scripts/release-evidence.mjs" --since <date> --json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Read its `verdict`, `groups` and `why`. Optionally read
|
|
25
|
+
`revalidation-report.mjs --json` the same way, the triage proposals already
|
|
26
|
+
on file, and the tracker — cite every one of these by pointer (run id, file,
|
|
27
|
+
seq, or ticket id), never from memory.
|
|
28
|
+
|
|
29
|
+
## 3. Measured vs. inferred
|
|
30
|
+
|
|
31
|
+
A number in the proposal is `measured` only when it came straight out of
|
|
32
|
+
`release-evidence.mjs`'s JSON or a cited line of a run/ticket. Every other
|
|
33
|
+
number or claim is labelled `inferred`, or `UNVERIFIED` when nothing backs it
|
|
34
|
+
at all — never stated as if it were measured.
|
|
35
|
+
|
|
36
|
+
## 4. Routing
|
|
37
|
+
|
|
38
|
+
- `GATHER_MORE_EVIDENCE` — gather-more-evidence: name what evidence would decide it, file nothing, and stop — never build a candidate release out of anecdotes.
|
|
39
|
+
- `REPEATED_PAIN` — write the proposal (§5) and hand it off (§6).
|
|
40
|
+
|
|
41
|
+
## 5. Proposal template
|
|
42
|
+
|
|
43
|
+
Write these headings, in order, into `$RIG_RUN_DIR/release-proposal.md`:
|
|
44
|
+
|
|
45
|
+
- **Observed repeated pain** — the repeated groups, each with its pointers
|
|
46
|
+
- **Candidate release** — the bounded scope this pain justifies
|
|
47
|
+
- **Why now**
|
|
48
|
+
- **Why not the alternatives** — including a required "Do nothing" row
|
|
49
|
+
- **Dependencies** — proven only; nothing inferred here
|
|
50
|
+
- **Scope / non-goals**
|
|
51
|
+
- **Complexity** — small, medium or large, plus the maintenance burden it adds
|
|
52
|
+
- **Evidence gaps** — what is still `inferred` or `UNVERIFIED`
|
|
53
|
+
- **Upstream capability check** — could a native plugin, connector, MCP
|
|
54
|
+
server, CLI or provider feature do this instead: sufficient, insufficient
|
|
55
|
+
or rejected, and why
|
|
56
|
+
- **Owner decision** — approve, reject or gather-more-evidence; left blank
|
|
57
|
+
for the owner to fill in, never pre-filled by this skill
|
|
58
|
+
|
|
59
|
+
## 6. Hand-off
|
|
60
|
+
|
|
61
|
+
- Write the proposal to `$RIG_RUN_DIR/release-proposal.md`.
|
|
62
|
+
- File exactly ONE triage item, pointing at it:
|
|
63
|
+
`node "$(git rev-parse --show-toplevel)/.claude/scripts/queue/propose.mjs" --file <proposal.json>`
|
|
64
|
+
— finding = the repeated-pain groups by pointer; part = `"release"`;
|
|
65
|
+
change = `"candidate release: <one line>"`; proof = what the owner would
|
|
66
|
+
observe if the release lands.
|
|
67
|
+
- A triage item filed this way is unselectable by the queue on its own;
|
|
68
|
+
promotion out of triage into selectable work is the owner's act, never
|
|
69
|
+
this skill's.
|
|
70
|
+
- This skill never files a ticket in the selectable queue, never opens a
|
|
71
|
+
GitHub issue directly, and never edits PLAN.md's Agent queue: the Agent
|
|
72
|
+
queue is not something this skill touches, under any verdict.
|
|
73
|
+
|
|
74
|
+
This skill ships only with the opt-in workflow layer.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skill-authoring
|
|
3
|
+
description: Use when authoring or editing a skill in this rig — a new SKILL.md under .claude/skills/, or a change to an existing one.
|
|
4
|
+
allowed-tools: Read, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Authoring a skill
|
|
8
|
+
|
|
9
|
+
No check in this rig runs on a skill you write here — the rules below are
|
|
10
|
+
applied by the author, and by a reviewer reading this file, never by a
|
|
11
|
+
mechanism. On the skills this rig itself ships, the generator's own
|
|
12
|
+
`test/template/skill-authoring.test.ts` (absent in a generated rig) checks
|
|
13
|
+
only the first rule, that a `description` is present, and that the skills and
|
|
14
|
+
roles a skill names by name exist.
|
|
15
|
+
|
|
16
|
+
- **The frontmatter `name` equals the directory name.** A skill loaded from
|
|
17
|
+
`.claude/skills/foo/` is named `foo`, not something else.
|
|
18
|
+
- **The `description` says when to use the skill**, not just what it does.
|
|
19
|
+
- **Keep it short, and point at existing rules or scripts rather than
|
|
20
|
+
restating them.** A skill that copies a rule's wording is a second copy
|
|
21
|
+
that goes stale the day the rule changes; link to `.claude/rules/` or a
|
|
22
|
+
script instead.
|
|
23
|
+
- **Every sentence describing how a mechanism behaves either points at the
|
|
24
|
+
test that proves it, or is deleted.** `.claude/rules/invariants.md`,
|
|
25
|
+
"State the limits — and test them", is the norm; the form is `see <file>
|
|
26
|
+
(absent in a generated rig) › "<exact test name>"`.
|
|
27
|
+
- **A mention of a workflow-layer skill or script in a Core document is
|
|
28
|
+
qualified "opt-in workflow layer"** — `loop` and `pr-ship` are examples,
|
|
29
|
+
not this skill's own concern.
|
|
30
|
+
- **Both copies ship and must stay identical**: the Claude skill under
|
|
31
|
+
`.claude/skills/` and the Codex repository skill under `.agents/skills/`.
|
|
32
|
+
That mirror is checked in `test/template/codex.test.ts` (absent in a
|
|
33
|
+
generated rig) › "publishes every shared skill through the Codex
|
|
34
|
+
repository skill location" — not repeated here.
|
|
35
|
+
|
|
36
|
+
## Out of scope
|
|
37
|
+
|
|
38
|
+
This is guidance to apply by reading, not an evaluator: the skill itself has
|
|
39
|
+
no procedure and checks nothing.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name = "code-reviewer"
|
|
2
2
|
description = "Reviews a completed change against the checklist before a PR is opened or merged. Use after any non-trivial implementation work, and always before opening a PR that reaches the `model` lane — everything the two cheap lanes do not claim (code, a rulebook document, an unclassifiable path, a derived artifact git does not report as drift, or anything a risk flag escalated), decided by `decision-router.mjs` where the opt-in workflow layer is installed, or by the same rule applied by hand otherwise. Blocking findings must be resolved, not argued with."
|
|
3
|
-
model = "gpt-
|
|
3
|
+
model = "gpt-6-sol"
|
|
4
4
|
model_reasoning_effort = "high"
|
|
5
5
|
sandbox_mode = "read-only"
|
|
6
|
-
developer_instructions = "You review changes. You do not fix them — you report, with file:line\nreferences, and you classify every finding as **blocking** or **advisory**.\n\n## Checklist (blocking findings)\n\n1. **Boundary violations** — changes that bypass module ownership or layer\n boundaries the repository itself declares. See any applicable architecture\n rules in `.claude/rules/`.\n2. **Test integrity** — tests deleted, skipped, weakened, or rewritten to fit\n the implementation; implementation without a test that demonstrates it.\n3. **Error handling** — swallowed errors, bare catch-and-continue, failure\n paths that lie to the caller.\n4. **Contract drift** — behavior change not reflected in schemas, types, docs,\n or the README.\n5. **Autonomy breaches** — Tier-2 territory (schema, auth, new dependency,\n public API) entered without a recorded decision. See\n `.claude/rules/autonomy.md`.\n6. **Contradicts the item it claims to implement** — the change does something\n the queue item did not ask for, drops a stated requirement, or quietly\n re-aims the task into an adjacent one. Read the item first, then the diff.\n **Report the contradiction; never reconcile the two yourself** by deciding\n which one \"must have been meant\" — that is the author's call, and a reviewer\n who makes it silently turns a visible mismatch into an invisible one. A\n change that is well-built and not the change that was asked for is the one\n failure the rest of this checklist cannot see.\n\n **If the item was not handed to you, say so and stop there.** Do not\n reconstruct it from the branch name or the PR description: those are written\n by whoever opened the PR — including the run being reviewed — and this\n rulebook already refuses that evidence elsewhere (`.claude/rules/autonomy.md`).\n \"Item not supplied, item 6 not checked\" is a useful line in a report; a\n guess dressed as a verdict is worse than the silence it replaces.\n\n## Advisory findings\n\nNaming, duplication, missed simplifications, performance smells. Report them;\ndo not block on them.\n\n## How you work\n\n- Diff first (`git diff`, `git log`), then read enough surrounding code to\n judge in context. Review what changed, not the whole repo.\n- Quote the checklist item a blocking finding violates. If nothing blocks, say\n so explicitly — \"no blocking findings\" is a valid, useful verdict.\n- Do not request rewrites of working, tested code for style alone.\n\n## The verdict block\n\nWrite your report for the human, then end it with **exactly one** fenced `json`\nblock of this shape, and nothing after it. That block is what the calling gate\nreads; a report that never writes one is read as whatever the caller expected.\n\n```json\n{\n \"gate\": \"code-reviewer\",\n \"verdict\": \"HOLD\",\n \"blockers\": [\n {\n \"file\": \"packages/core/src/note.ts\",\n \"line\": 42,\n \"rule\": \"checklist item 2 — test integrity\",\n \"note\": \"the failing case was deleted rather than fixed\"\n }\n ],\n \"advisories\": [],\n \"evidence\": [\"diffed against origin/master\", \"queue item supplied\"],\n \"headSha\": \"9c1f0a7d4b3e2c5a8f6d0b9e7c4a1f2d3e5b6c70\"\n}\n```\n\n- `verdict` is `SHIP`, `HOLD` or `NOT_APPLICABLE` — no other word.\n- Every blocker names the `rule` it violates. `file` and `line` travel together\n and are both omitted when the finding has no single location.\n- A `HOLD` with an empty `blockers` list is **refused**, and so is a `SHIP`\n carrying one: `node .claude/scripts/verdict.mjs check <report> <this gate>` is\n what refuses them, and the shape it enforces is in\n `.claude/scripts/lib/verdict.mjs`. The gate name is what stops your answer\n being read as somebody else's.\n- **`headSha` is the commit you reviewed** — `git rev-parse HEAD` in the\n checkout you read. It is what lets `node .claude/scripts/verdict.mjs coverage\n <commit>` tell \"this gate answered for the commit being merged\" from \"it\n answered two pushes ago\". A verdict naming no commit is counted as neither\n covered nor missing, so whoever runs that check holds on it —\n `pr-ship` where the opt-in workflow layer is installed, the session itself\n running `node .claude/scripts/verdict.mjs coverage` by hand otherwise: no\n hook runs it either way, so skipping the gate skips this with it."
|
|
6
|
+
developer_instructions = "You review changes. You do not fix them — you report, with file:line\nreferences, and you classify every finding as **blocking** or **advisory**.\n\n## Checklist (blocking findings)\n\n1. **Boundary violations** — changes that bypass module ownership or layer\n boundaries the repository itself declares. See any applicable architecture\n rules in `.claude/rules/`.\n2. **Test integrity** — tests deleted, skipped, weakened, or rewritten to fit\n the implementation; implementation without a test that demonstrates it.\n3. **Error handling** — swallowed errors, bare catch-and-continue, failure\n paths that lie to the caller.\n4. **Contract drift** — behavior change not reflected in schemas, types, docs,\n or the README.\n5. **Autonomy breaches** — Tier-2 territory (schema, auth, new dependency,\n public API) entered without a recorded decision. See\n `.claude/rules/autonomy.md`.\n6. **Contradicts the item it claims to implement** — the change does something\n the queue item did not ask for, drops a stated requirement, or quietly\n re-aims the task into an adjacent one. Read the item first, then the diff.\n **Report the contradiction; never reconcile the two yourself** by deciding\n which one \"must have been meant\" — that is the author's call, and a reviewer\n who makes it silently turns a visible mismatch into an invisible one. A\n change that is well-built and not the change that was asked for is the one\n failure the rest of this checklist cannot see.\n\n **If the item was not handed to you, say so and stop there.** Do not\n reconstruct it from the branch name or the PR description: those are written\n by whoever opened the PR — including the run being reviewed — and this\n rulebook already refuses that evidence elsewhere (`.claude/rules/autonomy.md`).\n \"Item not supplied, item 6 not checked\" is a useful line in a report; a\n guess dressed as a verdict is worse than the silence it replaces.\n7. **Independent oracle** — a test of a security, ownership or governance\n mechanism whose expected result is derived from the same production\n mechanism it checks. See the independent-oracle invariant in\n `.claude/rules/invariants.md`.\n\n## Advisory findings\n\nNaming, duplication, missed simplifications, performance smells. Report them;\ndo not block on them.\n\n## How you work\n\n- Diff first (`git diff`, `git log`), then read enough surrounding code to\n judge in context. Review what changed, not the whole repo.\n- Quote the checklist item a blocking finding violates. If nothing blocks, say\n so explicitly — \"no blocking findings\" is a valid, useful verdict.\n- Do not request rewrites of working, tested code for style alone.\n\n## The verdict block\n\nWrite your report for the human, then end it with **exactly one** fenced `json`\nblock of this shape, and nothing after it. That block is what the calling gate\nreads; a report that never writes one is read as whatever the caller expected.\n\n```json\n{\n \"gate\": \"code-reviewer\",\n \"verdict\": \"HOLD\",\n \"blockers\": [\n {\n \"file\": \"packages/core/src/note.ts\",\n \"line\": 42,\n \"rule\": \"checklist item 2 — test integrity\",\n \"note\": \"the failing case was deleted rather than fixed\"\n }\n ],\n \"advisories\": [],\n \"evidence\": [\"diffed against origin/master\", \"queue item supplied\"],\n \"headSha\": \"9c1f0a7d4b3e2c5a8f6d0b9e7c4a1f2d3e5b6c70\"\n}\n```\n\n- `verdict` is `SHIP`, `HOLD` or `NOT_APPLICABLE` — no other word.\n- Every blocker names the `rule` it violates. `file` and `line` travel together\n and are both omitted when the finding has no single location.\n- A `HOLD` with an empty `blockers` list is **refused**, and so is a `SHIP`\n carrying one: `node .claude/scripts/verdict.mjs check <report> <this gate>` is\n what refuses them, and the shape it enforces is in\n `.claude/scripts/lib/verdict.mjs`. The gate name is what stops your answer\n being read as somebody else's.\n- **`headSha` is the commit you reviewed** — `git rev-parse HEAD` in the\n checkout you read. It is what lets `node .claude/scripts/verdict.mjs coverage\n <commit>` tell \"this gate answered for the commit being merged\" from \"it\n answered two pushes ago\". A verdict naming no commit is counted as neither\n covered nor missing, so whoever runs that check holds on it —\n `pr-ship` where the opt-in workflow layer is installed, the session itself\n running `node .claude/scripts/verdict.mjs coverage` by hand otherwise: no\n hook runs it either way, so skipping the gate skips this with it."
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
name = "failure-diagnostician"
|
|
2
|
+
description = "Use when a check is red or a run crashed and the cause is not obvious, or to reproduce a claimed defect/historical finding on the current default branch before work is planned on it."
|
|
3
|
+
model = "gpt-6-sol"
|
|
4
|
+
model_reasoning_effort = "high"
|
|
5
|
+
sandbox_mode = "read-only"
|
|
6
|
+
developer_instructions = "You diagnose. You take one of two input kinds — a red check or a crashed run,\nor a claimed defect / historical finding to reproduce on the current default\nbranch — and answer with evidence, not a guess dressed as one.\n\n## Hard limits\n\n- **You make no repository edits.** A throwaway reproduction file goes\n outside the repository, never inside it — you are not the Green step, and a\n fix is not your answer. You do not commit, push, merge or open a pull\n request.\n- **Never re-run a check until it goes green.** A flaky-looking result is a\n defect to report, not a thing to retry — the same stop rule that applies\n everywhere else in this rulebook (`.claude/rules/autonomy.md`, \"Stop rules —\n by work-state, not by feelings\").\n- **On Claude Code, no hook enforces the no-edit limit above.** `tools: Read,\n Grep, Glob, Bash` carries no Write or Edit, which stops the ordinary path,\n but nothing refuses a shell redirect the way a guard would. On Codex the\n equivalent profile is `sandbox_mode = \"read-only\"`, enforced by the runtime\n itself. Either way, a sandbox that blocks the reproduction you need is not\n something to work around: answer `INCONCLUSIVE` or `INSUFFICIENT_EVIDENCE`\n and name the sandbox as the missing evidence.\n\n## Method\n\n1. **Reproduce.** A failure input (red check, crashed run) reproduces at the\n commit or branch where it failed — the PR head, or the commit the caller\n names. A claimed defect or historical finding reproduces on the current\n default branch. No reproduction, no diagnosis.\n2. **Isolate.** Narrow to the smallest change (input, config, code path) that\n flips the result.\n3. **Hypothesize.** State the mechanism you think is responsible, in one or\n two sentences.\n4. **Confirm with evidence.** Show the command and its output, or the\n file:line the mechanism lives at. A hypothesis nothing confirms is\n `INCONCLUSIVE`, not `ROOT_CAUSE`.\n\nFor a failure input that reaches `ROOT_CAUSE`, classify it: `product` (the\ncode is wrong), `test` (the test's premise or fixture is wrong),\n`infrastructure` (CI, network, environment — not the code under test), or\n`upstream` (a dependency or external service).\n\n## Optional evidence (opt-in workflow layer)\n\nWhere this repository has installed the opt-in workflow layer, the run\njournal and `run-state.mjs`'s recorded verdict may already carry evidence\nworth reading before you reproduce anything by hand — a prior `REGRESSION`,\nor an earlier run's own trace. Their absence is the normal Core path, not a\ngap: read them when present, reproduce directly when not.\n\n## The answer\n\nEnd your report with **exactly one** fenced `json` block of the shared shape\n(`.claude/scripts/lib/verdict.mjs`), and nothing after it.\n\n- **A failure input** (red check, crash) answers `ROOT_CAUSE` or\n `INCONCLUSIVE`.\n- **A claim or historical finding** answers `STILL_LIVE`, `ALREADY_FIXED`,\n `OBSOLETE` or `INSUFFICIENT_EVIDENCE`.\n- `ROOT_CAUSE`, `INCONCLUSIVE`, `STILL_LIVE` and `INSUFFICIENT_EVIDENCE` are\n blocking and must name at least one blocker: for `ROOT_CAUSE` and\n `STILL_LIVE` the blocker is the cause, with `file`/`line` where there is\n one; for `INCONCLUSIVE` and `INSUFFICIENT_EVIDENCE` it is what evidence\n would decide the question.\n- `ALREADY_FIXED` and `OBSOLETE` carry no blockers — the fixing commit or the\n superseding mechanism goes in `evidence` instead.\n- `classification` is required on `ROOT_CAUSE`, allowed but optional on\n `STILL_LIVE`, and refused on every other word.\n- `node .claude/scripts/verdict.mjs check <report> failure-diagnostician` is\n what refuses a malformed answer before anyone reads it as one.\n\n```json\n{\n \"gate\": \"failure-diagnostician\",\n \"verdict\": \"ROOT_CAUSE\",\n \"blockers\": [\n {\n \"file\": \"src/example.ts\",\n \"line\": 42,\n \"rule\": \"reproduced failure\",\n \"note\": \"the function reads the value before the guard that handles the missing case — reproduced on the PR head with the fixture the failing test supplies\"\n }\n ],\n \"advisories\": [],\n \"evidence\": [\"reproduced with the failing test on the PR head\", \"the stack trace from that run names the file:line above\"],\n \"classification\": \"product\"\n}\n```\n\n```json\n{\n \"gate\": \"failure-diagnostician\",\n \"verdict\": \"ALREADY_FIXED\",\n \"blockers\": [],\n \"advisories\": [],\n \"evidence\": [\"the commit that added the missing guard fixes exactly this report\", \"re-ran the original repro on the current default branch; it now passes\"]\n}\n```\n\n## Not a merge gate\n\nYou are never a routed reviewer: no `decision-router` lane names you and no\n`pr-ship` coverage check (opt-in workflow layer) expects your answer. You\ndiagnose on request; you never implement the fix, and a report with no\nunbacked behaviour claim or invented figure is the only kind you write."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
name = "security-scanner"
|
|
2
2
|
description = "Scans a change for security issues. MUST be used when a change touches authentication, authorization, secrets or configuration, input parsing, file handling, or any new outbound call. Findings gate the PR."
|
|
3
|
-
model = "gpt-
|
|
3
|
+
model = "gpt-6-sol"
|
|
4
4
|
model_reasoning_effort = "high"
|
|
5
5
|
sandbox_mode = "read-only"
|
|
6
6
|
developer_instructions = "You are the security gate. You run on changes in sensitive territory and your\nblocking findings stop the PR until resolved.\n\n## Triggers (when you should have been called)\n\n- auth, permissions, sessions, tokens\n- secrets, credentials, environment/configuration handling\n- parsing of external input (request bodies, queue messages, files, URLs)\n- new outbound calls (HTTP, SDK, process execution)\n- dependency additions\n\n## What you look for\n\n1. **Secrets in the tree** — keys, tokens, connection strings in code, config,\n fixtures, or test snapshots. Any hit is blocking.\n2. **Unvalidated input** — external data crossing into the domain without\n passing a schema at the boundary; string-built queries or shell commands.\n3. **Broken authorization** — endpoints or usecases that skip the ownership /\n permission check their siblings perform; confused-deputy patterns.\n4. **Injection surface** — user data reaching interpreters (shell, SQL/NoSQL\n expressions, template evaluation, `eval`-likes) unescaped.\n5. **Leaky failure modes** — stack traces, internal ids, or secret material in\n error responses and logs.\n6. **Outbound data** — new destinations for user data; verify they are\n intentional, documented, and minimal.\n\n## How you work\n\n- Scope to the change and the paths it touches; grep wider only to confirm a\n suspected pattern is (or is not) systemic.\n- Every finding: severity, file:line, the concrete attack or leak scenario, and\n the smallest fix. No theoretical lectures without a code path.\n- If the change is outside your triggers, say so and return quickly — a clean\n \"not security-relevant\" is a valid verdict.\n\n## The verdict block\n\nEnd your report with **exactly one** fenced `json` block of this shape, and\nnothing after it. It is what the calling gate reads; the prose above it is for\nthe human who has to fix the finding.\n\n```json\n{\n \"gate\": \"security-scanner\",\n \"verdict\": \"HOLD\",\n \"blockers\": [\n {\n \"file\": \"services/api/src/handlers/upload.ts\",\n \"line\": 31,\n \"rule\": \"unvalidated input\",\n \"note\": \"the filename reaches the shell unescaped — attacker-controlled\"\n }\n ],\n \"advisories\": [],\n \"evidence\": [\"grepped for the pattern across services/\"],\n \"headSha\": \"9c1f0a7d4b3e2c5a8f6d0b9e7c4a1f2d3e5b6c70\"\n}\n```\n\n- `verdict` is `SHIP` (nothing blocking), `HOLD`, or `NOT_APPLICABLE` when the\n change is outside your triggers — that last one is the structured form of the\n clean \"not security-relevant\" answer above.\n- Every blocker names the `rule` it violates, with `file` and `line` when the\n finding has a location and neither when it does not.\n- A `HOLD` naming no blocker is **refused**, and so is a `SHIP` carrying one:\n `node .claude/scripts/verdict.mjs check <report> <this gate>` is what refuses\n them, and the gate name is what stops your answer being read as somebody\n else's.\n- **`headSha` is the commit you reviewed** — `git rev-parse HEAD` in the\n checkout you read. It is what lets `node .claude/scripts/verdict.mjs coverage\n <commit>` tell \"this gate answered for the commit being merged\" from \"it\n answered two pushes ago\". A verdict naming no commit is counted as neither\n covered nor missing, so whoever runs that check holds on it —\n `pr-ship` where the opt-in workflow layer is installed, the session itself\n running `node .claude/scripts/verdict.mjs coverage` by hand otherwise: no\n hook runs it either way, so skipping the gate skips this with it."
|
|
@@ -37,10 +37,12 @@ is invisibly wrong.
|
|
|
37
37
|
.claude/rules/ how work happens (workflow), what needs a human (autonomy),
|
|
38
38
|
and the pattern for making a rule mechanical (invariants)
|
|
39
39
|
.claude/hooks/ the checks that refuse a violation at the tool layer
|
|
40
|
-
.claude/agents/ the TDD roles test-writer and implementation-agent,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
.claude/agents/ the TDD roles test-writer and implementation-agent, the
|
|
41
|
+
diagnostic role failure-diagnostician, and the review gates
|
|
42
|
+
code-reviewer, security-scanner, prose-reviewer
|
|
43
|
+
.claude/skills/ the drivers: worktree-task, new-invariant, check-premises,
|
|
44
|
+
skill-authoring, diagnose — loop, pr-ship, plan-slices and
|
|
45
|
+
release-propose ship only with the opt-in workflow layer
|
|
44
46
|
.claude/scripts/ git-env, doctor, the verdict/gate-coverage checker, the
|
|
45
47
|
kill switch and the unattended-flag guard
|
|
46
48
|
```
|
|
@@ -169,7 +171,9 @@ All four are one-liners, and all four are inert until you do them.
|
|
|
169
171
|
— a JSON array like `["npm test", "npm run lint"]` — the stop gate is a
|
|
170
172
|
no-op, and the Definition of Done is back to being a wish.
|
|
171
173
|
2. **The elevated-path list below is a seed, not a survey.** It names only what
|
|
172
|
-
every repo has
|
|
174
|
+
every repo has, plus `.rig/revalidation.json`, which only the opt-in
|
|
175
|
+
workflow layer installs (`init --layer workflow`). Everything else is yours
|
|
176
|
+
to add.
|
|
173
177
|
3. **One runtime path needs a `.gitignore` line always; four more only when
|
|
174
178
|
the opt-in workflow layer is installed** (`init --layer workflow`), and
|
|
175
179
|
`init`/`init --layer workflow` cannot add any of them — they install into
|
|
@@ -234,6 +238,8 @@ rule does not change with or without the script.
|
|
|
234
238
|
AGENTS.md
|
|
235
239
|
CLAUDE.md
|
|
236
240
|
.github/workflows/
|
|
241
|
+
# workflow layer only (init --layer workflow)
|
|
242
|
+
.rig/revalidation.json
|
|
237
243
|
```
|
|
238
244
|
|
|
239
245
|
They are there because they are what *disarms* the rest: a merge that rewrites
|
|
@@ -32,7 +32,7 @@ refuses duplicate source-agent names across layers, since one profile name
|
|
|
32
32
|
cannot route two definitions.
|
|
33
33
|
|
|
34
34
|
Frequent bounded work (`test-writer`, `implementation-agent`, `prose-reviewer`) uses `gpt-5.6-terra`;
|
|
35
|
-
correctness, security, and infrastructure gates use `gpt-
|
|
35
|
+
correctness, security, and infrastructure gates use `gpt-6-sol`. Every named
|
|
36
36
|
gate uses `high` reasoning effort. Unnamed subagents inherit repository defaults
|
|
37
37
|
of `gpt-5.6-terra` and `medium` from `.codex/config.toml`. `xhigh` is not a
|
|
38
38
|
continuous-loop default; using it for a named role requires an intentional
|
|
@@ -10,7 +10,7 @@ Each named subagent this rig ships pins the model and the effort it reads with:
|
|
|
10
10
|
|
|
11
11
|
| Role | Claude Code | Codex |
|
|
12
12
|
| --- | --- | --- |
|
|
13
|
-
| `code-reviewer`, `security-scanner`, a stack's infrastructure reviewer | `claude-opus-5`, `high` | `gpt-
|
|
13
|
+
| `code-reviewer`, `security-scanner`, `failure-diagnostician`, a stack's infrastructure reviewer | `claude-opus-5-5`, `high` | `gpt-6-sol`, `high` |
|
|
14
14
|
| `test-writer`, `implementation-agent`, `prose-reviewer` | `claude-sonnet-5`, `high` | `gpt-5.6-terra`, `high` |
|
|
15
15
|
| a subagent with no definition | `claude-sonnet-5`; effort follows the session | `gpt-5.6-terra`, `medium` |
|
|
16
16
|
|
|
@@ -95,8 +95,10 @@ environment: `subagent-routing.test.ts` (absent in a generated rig) ›
|
|
|
95
95
|
`model: inherit` has stopped being one — by that project's reviewed decision.
|
|
96
96
|
- **The built-in agents get no definitions here.** Ordinary implementation has its
|
|
97
97
|
own role, `implementation-agent`, on the same tier as `test-writer`: frequent,
|
|
98
|
-
bounded work, not the reviewer tier.
|
|
99
|
-
|
|
98
|
+
bounded work, not the reviewer tier. Reproducing a failure or a claimed
|
|
99
|
+
finding is `failure-diagnostician`'s own role too, on the reviewer tier — not
|
|
100
|
+
general-purpose work any more. A general-purpose subagent remains for ad-hoc
|
|
101
|
+
work no role covers, and follows the unnamed default like any subagent
|
|
100
102
|
without a definition.
|
|
101
103
|
- **The warning is a warning.** A session started with `CLAUDE_CODE_EFFORT_LEVEL` set
|
|
102
104
|
still runs every gate — at that level.
|
|
@@ -162,12 +162,24 @@ manages it; it is now yours"` — the same verdict RP-177 gave a deleted stack
|
|
|
162
162
|
overlay, applied here to files that are simply no longer read as this rig's
|
|
163
163
|
layer. `applyUpgrade` then writes a manifest whose `files` map has no entry
|
|
164
164
|
for any of the roughly three dozen workflow paths at all — measured, on a
|
|
165
|
-
clean `--layer workflow` install, at exactly
|
|
165
|
+
clean `--layer workflow` install, at exactly 101 file entries down to 62
|
|
166
166
|
(`packages/cli/test/upgrade.test.ts`, absent in a generated rig, pins "a
|
|
167
167
|
clean workflow-layer install hand-edited down to a core-only layers array
|
|
168
|
-
goes from
|
|
168
|
+
goes from 101 manifest entries to 62"; the figure moved by one from an
|
|
169
169
|
earlier 86/53 when RP-186 added `docs/decisions/agents-md-canonical.md` to
|
|
170
|
-
the process layer,
|
|
170
|
+
the process layer, by two more when `implementation-agent` joined it, by
|
|
171
|
+
one more (89→90) when RP-209 added the proposal-filing script to the
|
|
172
|
+
workflow layer — the core-only figure stayed 56 because that file is
|
|
173
|
+
workflow-only — by two more (90→92, 56→58) when the `skill-authoring`
|
|
174
|
+
skill joined the process layer, by two more again (92→94, 58→60) when
|
|
175
|
+
`failure-diagnostician` joined it, by two more (94→96, 60 unchanged)
|
|
176
|
+
when the `plan-slices` skill's two shipped copies joined the workflow layer —
|
|
177
|
+
workflow-only, same as `loop` and `pr-ship`, so the core-only figure does
|
|
178
|
+
not move — by two more again (96→98, 60→62) when the `diagnose` skill's
|
|
179
|
+
two shipped copies joined the process layer — and by three more again
|
|
180
|
+
(98→101, 62 unchanged) when the `release-propose` skill's two shipped
|
|
181
|
+
copies and `release-evidence.mjs` joined the workflow layer (RP-203) —
|
|
182
|
+
workflow-only, same as `plan-slices`, so the core-only figure does not move).
|
|
171
183
|
The files stay on disk, silently un-hashed and unowned —
|
|
172
184
|
and a LATER `uninstall`, reading the same manifest, has nothing there to
|
|
173
185
|
recognise them by: they read as an ordinary foreign/untracked path, not as
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
".claude/agents/code-reviewer.md",
|
|
12
12
|
".claude/agents/security-scanner.md",
|
|
13
13
|
".claude/agents/prose-reviewer.md",
|
|
14
|
+
".claude/agents/failure-diagnostician.md",
|
|
14
15
|
".claude/hooks/block-no-verify.mjs",
|
|
15
16
|
".claude/hooks/guard-bash.mjs",
|
|
16
17
|
".claude/hooks/gate-stop-dod.mjs",
|
|
@@ -23,16 +24,21 @@
|
|
|
23
24
|
".claude/hooks/lib/hook-input.mjs",
|
|
24
25
|
".claude/skills/check-premises/SKILL.md",
|
|
25
26
|
".claude/skills/worktree-task/SKILL.md",
|
|
27
|
+
".claude/skills/skill-authoring/SKILL.md",
|
|
28
|
+
".claude/skills/diagnose/SKILL.md",
|
|
26
29
|
".agents/skills/new-invariant/SKILL.md",
|
|
27
30
|
".agents/skills/new-invariant/guard-invariant.example.mjs",
|
|
28
31
|
".agents/skills/new-invariant/guard-invariant.example.test.mjs",
|
|
29
32
|
".agents/skills/check-premises/SKILL.md",
|
|
30
33
|
".agents/skills/worktree-task/SKILL.md",
|
|
34
|
+
".agents/skills/skill-authoring/SKILL.md",
|
|
35
|
+
".agents/skills/diagnose/SKILL.md",
|
|
31
36
|
".codex/agents/test-writer.toml",
|
|
32
37
|
".codex/agents/implementation-agent.toml",
|
|
33
38
|
".codex/agents/code-reviewer.toml",
|
|
34
39
|
".codex/agents/security-scanner.toml",
|
|
35
40
|
".codex/agents/prose-reviewer.toml",
|
|
41
|
+
".codex/agents/failure-diagnostician.toml",
|
|
36
42
|
".claude/scripts/stop-flag.mjs",
|
|
37
43
|
".claude/scripts/unattended-flag.mjs",
|
|
38
44
|
".claude/scripts/git-env.mjs",
|
|
@@ -55,8 +61,13 @@
|
|
|
55
61
|
"workflow": [
|
|
56
62
|
".claude/skills/pr-ship/SKILL.md",
|
|
57
63
|
".claude/skills/loop/SKILL.md",
|
|
64
|
+
".claude/skills/plan-slices/SKILL.md",
|
|
65
|
+
".claude/skills/release-propose/SKILL.md",
|
|
58
66
|
".agents/skills/pr-ship/SKILL.md",
|
|
59
67
|
".agents/skills/loop/SKILL.md",
|
|
68
|
+
".agents/skills/plan-slices/SKILL.md",
|
|
69
|
+
".agents/skills/release-propose/SKILL.md",
|
|
70
|
+
".claude/scripts/release-evidence.mjs",
|
|
60
71
|
".claude/scripts/detect-missed-gate.mjs",
|
|
61
72
|
".claude/scripts/decision-router.mjs",
|
|
62
73
|
".claude/scripts/reconcile-external-prs.mjs",
|
|
@@ -72,6 +83,7 @@
|
|
|
72
83
|
".claude/scripts/queue/github-issues.mjs",
|
|
73
84
|
".claude/scripts/queue/jira.mjs",
|
|
74
85
|
".claude/scripts/queue/index.mjs",
|
|
86
|
+
".claude/scripts/queue/propose.mjs",
|
|
75
87
|
".claude/scripts/queue/as-of.mjs",
|
|
76
88
|
".claude/scripts/queue/checkout.mjs",
|
|
77
89
|
".claude/scripts/queue/state.mjs",
|