create-agent-rig 0.3.0 → 0.3.2

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.
Files changed (28) hide show
  1. package/CHANGELOG.md +137 -0
  2. package/README.md +11 -3
  3. package/package.json +1 -1
  4. package/packages/cli/dist/commands/create.js +5 -3
  5. package/packages/cli/dist/commands/init.js +73 -18
  6. package/packages/cli/dist/index.js +11 -1
  7. package/packages/cli/dist/lib/git-env.js +48 -0
  8. package/packages/cli/dist/lib/init-settings.js +52 -0
  9. package/packages/cli/dist/lib/targets.js +15 -1
  10. package/packages/cli/dist/templates.js +8 -0
  11. package/scripts/prepare.mjs +54 -17
  12. package/templates/agent-os/init/CLAUDE.md +139 -0
  13. package/templates/agent-os/universal/.claude/agents/code-reviewer.md +16 -1
  14. package/templates/agent-os/universal/.claude/agents/prose-reviewer.md +104 -0
  15. package/templates/agent-os/universal/.claude/hooks/gate-stop-dod.mjs +20 -0
  16. package/templates/agent-os/universal/.claude/rules/invariants.md +12 -11
  17. package/templates/agent-os/universal/.claude/rules/workflow.md +4 -0
  18. package/templates/agent-os/universal/.claude/scripts/detect-missed-gate.mjs +32 -4
  19. package/templates/agent-os/universal/.claude/scripts/preflight.mjs +34 -1
  20. package/templates/agent-os/universal/.claude/scripts/queue/core.mjs +125 -0
  21. package/templates/agent-os/universal/.claude/scripts/queue/github-issues.mjs +6 -0
  22. package/templates/agent-os/universal/.claude/scripts/queue/jira.mjs +3 -0
  23. package/templates/agent-os/universal/.claude/scripts/queue/plan-md.mjs +6 -0
  24. package/templates/agent-os/universal/.claude/skills/check-premises/SKILL.md +125 -0
  25. package/templates/agent-os/universal/.claude/skills/loop/SKILL.md +19 -7
  26. package/templates/agent-os/universal/.claude/skills/pr-ship/SKILL.md +12 -2
  27. package/templates/agent-os/universal/CLAUDE.md +12 -3
  28. package/templates/agent-os/universal/layers.json +2 -0
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: check-premises
3
+ description: Check a queue item's claims about the code before building on them. Use immediately after taking an item and before the failing test — whenever the item asserts that something exists, is missing, is broken, or works a particular way.
4
+ context: fork
5
+ allowed-tools: Read, Grep, Glob, Bash
6
+ argument-hint: <the queue item's text>
7
+ ---
8
+
9
+ A queue item is a **claim about the code**, written by someone who was not
10
+ reading the code at the time. "The retry path swallows the error", "there is no
11
+ validation on that field", "the worker never gets the second message" — each of
12
+ those is a premise, and the work that follows is only worth doing if it is true.
13
+
14
+ This skill checks the premises. It runs **after selection, before the Red step**,
15
+ and it produces one of three verdicts. It writes nothing.
16
+
17
+ ## Why it sits here and not in review
18
+
19
+ A false premise is not caught later. Review reads the diff against the item, and
20
+ both are wrong in the same direction: the item said the validation was missing,
21
+ the diff adds validation, the reviewer sees a diff that does what the item asked.
22
+ Nobody re-reads the file that had the validation all along. The cost lands as a
23
+ duplicate implementation, a "fix" for a bug that was somewhere else entirely, or
24
+ a refactor of a path that no caller reaches — all of it green, reviewed, merged.
25
+
26
+ The check is cheap because it is narrow, and the next section is that narrowness.
27
+
28
+ ## 1. Write out the claims — as claims
29
+
30
+ List what the item asserts about the code as it exists **now**. Two to five
31
+ lines. Keep them in the item's own terms; do not repair them while transcribing
32
+ — a claim you have already improved is one you will not test.
33
+
34
+ Separate the claims from the request. "Add a `GET /notes/:id` route" asserts
35
+ nothing; "the route handler bypasses the usecase layer" does.
36
+
37
+ An item that asserts nothing is done here: verdict `PREMISES HOLD`, one line
38
+ saying there were none. That is a common and perfectly good outcome.
39
+
40
+ ## 2. Mark the load-bearing ones
41
+
42
+ 🔴 **A claim is load-bearing when its falsity changes what gets built.** Only
43
+ those get verified. **This is not an audit** of the item, the file, or the
44
+ codebase — the moment it becomes one, it stops being cheap, gets skipped under
45
+ time pressure, and the whole step is lost.
46
+
47
+ | Load-bearing | Not |
48
+ | --- | --- |
49
+ | "there is no X" — if X exists, the task is already done | a stale line number in the item's description |
50
+ | "X is called from Y" — if it is not, the fix goes in the wrong place | a misspelled symbol you can resolve at a glance |
51
+ | "X handles the empty case by Z" — the fix is designed against Z | a claim about a file this task will not touch |
52
+ | "nothing enforces X" — the whole task is the enforcement | a claim the task's own failing test would immediately expose |
53
+
54
+ That last row is the one worth internalising: a premise the Red step would
55
+ falsify in the next five minutes does not need checking here. This step exists
56
+ for the premises a passing test **would not** catch — the ones about code the
57
+ task never touches.
58
+
59
+ ## 3. Verify each, against the code, with a citation
60
+
61
+ Read the code. Not the tests, not the docs, not another queue item — those are
62
+ claims too. Each verified premise gets a `file:line` citation; a premise you
63
+ believe but cannot cite is not verified, it is remembered.
64
+
65
+ ## 4. The verdict
66
+
67
+ | Verdict | When | What happens next |
68
+ | --- | --- | --- |
69
+ | `PREMISES HOLD` | every load-bearing claim checked out, or there were none | proceed to the Red step |
70
+ | `PREMISE FALSE` | a load-bearing claim is contradicted by the code | **stop and report** |
71
+ | `UNVERIFIABLE` | a load-bearing claim could not be decided from the code | report it as unverifiable, name what would decide it, and proceed only under a **labelled assumption** |
72
+
73
+ 🔴 **On `PREMISE FALSE` the answer is stop and report — never quietly work around
74
+ the false premise by building something adjacent that seems useful.** Write what
75
+ the item claimed, what the code actually says with its citation, and what the
76
+ task might become instead. Then let a human re-aim it. The item is wrong, and an
77
+ agent that silently repairs a wrong item produces work nobody asked for, in a
78
+ branch named after a task that does not exist.
79
+
80
+ `UNVERIFIABLE` is not a soft pass. A probe that could not run tells you nothing —
81
+ so the assumption travels in the open, in the item and in the PR description,
82
+ where the next reader can see which part of the work rests on it.
83
+
84
+ ## Examples — the three shapes this actually catches
85
+
86
+ **The thing already exists.** Item: "the payload schema does not reject an empty
87
+ title". The schema does reject it, three lines into the validator; the reported
88
+ bug came from a caller that never invoked the validator. Building "the missing
89
+ check" would have added a second, divergent rule and left the real defect —
90
+ the caller — in place. Verdict `PREMISE FALSE`; the task becomes a caller fix.
91
+
92
+ **The thing is somewhere else.** Item: "the worker retries forever because the
93
+ retry budget is not applied". The budget is applied, and correctly; the message
94
+ returns to the queue from a path above it that never consumed the budget at all.
95
+ The fix designed against the item would have been written in a file that was not
96
+ the problem. Verdict `PREMISE FALSE`.
97
+
98
+ **Nothing enforces it — except something does.** Item: "nothing stops a handler
99
+ importing the storage layer directly". A hook does exactly that, and has since
100
+ before the item was filed. Two hours of building a second enforcement mechanism,
101
+ which would then have disagreed with the first. Verdict `PREMISE FALSE`.
102
+
103
+ Note what all three have in common: the resulting work would have been correct,
104
+ tested, reviewable, and useless. That is the failure mode this catches, and it
105
+ is invisible to every gate downstream.
106
+
107
+ ## Limits — stated, because a check trusted past its reach is worse than none
108
+
109
+ - **It reads the code, so it only catches what the code can contradict.** A claim
110
+ about runtime behaviour ("this times out in production"), about intent, or
111
+ about a system this repository does not contain is `UNVERIFIABLE` here, not
112
+ false — say so rather than guessing.
113
+ - **It is one pass, before the work.** A premise that becomes false while the
114
+ task runs (a merge lands, a dependency moves) is a staleness stop rule
115
+ (`.claude/rules/autonomy.md`), not this skill.
116
+ - **It has no opinion on whether the task is worth doing.** True premises and a
117
+ pointless task is a perfectly consistent state, and it belongs to whoever fills
118
+ the queue.
119
+ - 🔴 **Nothing makes this run, and the verdict is a self-report.** No hook fires
120
+ when a task starts building on an unchecked claim, and no artifact outlives the
121
+ step — so a run that skipped it and a run that passed it look identical
122
+ afterwards. That is the honest description of every rule of this shape here
123
+ (the `loop` skill says the same about its own no-hand-feeding rule), and it is
124
+ why the citation matters: a `file:line` in the report is the one part of this a
125
+ later reader can re-check.
@@ -10,9 +10,9 @@ boundaries; the **queue** holds the work; `PLAN.md` holds state, standing
10
10
  decisions and the journal. This skill is the driver in between: what gets picked,
11
11
  what keeps the loop going, what stops it, and where the report goes.
12
12
 
13
- Per-task procedure is unchanged: (worktree if another session may run) → failing
14
- test first → implement → `pr-ship` → merge on the named criterion → verify the
15
- deployed surface if one changed.
13
+ Per-task procedure is unchanged: (worktree if another session may run) →
14
+ `check-premises` → failing test first → implement → `pr-ship` → merge on the
15
+ named criterion → verify the deployed surface if one changed.
16
16
 
17
17
  ## 0. The queue is behind an adapter
18
18
 
@@ -102,11 +102,18 @@ and the work turns out to touch an elevated path (`CLAUDE.md` →
102
102
  `elevated-paths`), run the gate anyway, record the verdict on the PR, and treat it
103
103
  as this run's elevated item for spacing.
104
104
 
105
+ **Then, before the Red step: `check-premises`.** The item was written by someone
106
+ who was not reading the code at the time, and everything downstream — the failing
107
+ test, the implementation, the reviewer comparing diff to item — inherits its
108
+ claims rather than checking them. On `PREMISE FALSE` the item is escalated (§6),
109
+ not repaired in place: a run that silently re-aims its own task has authored work
110
+ for itself, which is the one thing this loop does not do (§8).
111
+
105
112
  ## 3. What keeps the loop running, and what stops it
106
113
 
107
114
  Per-task stops (three strikes, attempt budget, invariant conflict, a blocking
108
- reviewer verdict) **do not end the run**: escalate that item (§5) and take the
109
- next one.
115
+ reviewer verdict, a false premise in the item itself) **do not end the run**:
116
+ escalate that item (§5) and take the next one.
110
117
 
111
118
  The run-level conditions are in `stopConditionOf` in `core.mjs`, checked in
112
119
  severity order: **queue unreadable** · **runtime regression** · **kill switch** ·
@@ -204,10 +211,14 @@ mechanises fully (`missed`, `.claude/rules/autonomy.md`) needs no self-report.
204
211
  ## 6. Escalation — two channels, by scope
205
212
 
206
213
  **Task-scoped — the item is the home, and the loop continues.** Three strikes, the
207
- attempt budget, an invariant conflict, or a blocking reviewer verdict:
214
+ attempt budget, an invariant conflict, a blocking reviewer verdict, or a
215
+ `PREMISE FALSE` verdict from `check-premises` — the last one is a
216
+ `documented-stall` (§5), and its diagnosis is already written: what the item
217
+ claimed, what the code says, and the citation:
208
218
 
209
219
  1. Comment the diagnosis on the queue item: what fails, what was tried, the
210
- current hypothesis, links to the PR and the failing run. **Name the outcome
220
+ current hypothesis, and links to the PR and the failing run where they exist
221
+ — a premise stop has neither, and its citation stands in for both. **Name the outcome
211
222
  state in the same comment** — `incomplete` if the diagnosis cannot say which
212
223
  stage needed what. Writing `incomplete` on your own task is uncomfortable and
213
224
  is the point: the run that produced it is the only witness.
@@ -274,6 +285,7 @@ three poisons the only channel by which this project learns.
274
285
  | Does not | Why |
275
286
  | --- | --- |
276
287
  | **Create its own work items** | The queue is human-filled. Self-authored work drifts scope, and unattended it drifts unwatched |
288
+ | **Re-aim an item whose premise turned out false** | Same rule wearing a disguise: an item silently rewritten into "what it should have said" is a work item the agent authored. Escalate it (§6) |
277
289
  | Take items needing a human decision | It cannot unblock itself; those wait in the Operator queue |
278
290
  | Take a `trigger-human` item | It would build for scale that does not exist |
279
291
  | Take two elevated items back to back | One unreviewed schema/permissions change is recoverable; a chain overnight is not |
@@ -19,10 +19,20 @@ blockers.
19
19
  (see its README / package scripts). Any failure is an instant HOLD — never
20
20
  argue with a red check, never rerun flakiness to green
21
21
  (`.claude/rules/workflow.md`).
22
- 3. **Reviewer fan-out.** Launch the `code-reviewer` agent on the diff — always.
22
+ 3. **Reviewer fan-out.** Launch the `code-reviewer` agent on the diff — always,
23
+ and **pass it the text of the queue item this branch implements**. Its
24
+ checklist blocks on a change that contradicts its item, and a reviewer given
25
+ only a diff cannot run that check: a cold context has no way to know what was
26
+ asked, and reconstructing it from the PR description would mean trusting the
27
+ run under review. If there is no item — owner-directed work, a hotfix — say
28
+ so when launching, and the reviewer skips that item openly instead of
29
+ guessing at it.
23
30
  Launch `security-scanner` as well when the diff touches its triggers: auth,
24
31
  secrets or configuration, input parsing, file handling, new outbound calls,
25
- dependency changes. Run them as subagents, in parallel — a fresh context
32
+ dependency changes. Launch `prose-reviewer` when the diff touches a rule
33
+ file, a skill, an agent spec, `CLAUDE.md` or the README — a rulebook that
34
+ overstates its own enforcement fails silently and in the direction of false
35
+ confidence. Run them as subagents, in parallel — a fresh context
26
36
  reviews better than the session that wrote the code (see
27
37
  `.claude/rules/workflow.md`, "Review-context isolation").
28
38
  4. **DoD walk.** Check the Definition of Done list in
@@ -42,6 +42,10 @@ them all; they are one rulebook.
42
42
 
43
43
  - **TDD, without exception.** The failing test comes first — use the
44
44
  `test-writer` agent for it. See `.claude/rules/workflow.md`.
45
+ - **Check the task's premises before the test.** A queue item is a claim about
46
+ the code, and nothing downstream re-reads the file it was wrong about — the
47
+ `check-premises` skill runs between taking the item and the failing test, and
48
+ a false load-bearing claim stops the task instead of quietly re-aiming it.
45
49
  - **One task, one branch — and merge via PR.** Every unit of work gets its own
46
50
  short-lived branch; the default branch is never committed to directly. Once
47
51
  the project has a remote and CI, changes reach it through the PR flow (local
@@ -49,9 +53,14 @@ them all; they are one rulebook.
49
53
  `.claude/rules/workflow.md` ("Branches and commits", "PR flow"). When another
50
54
  session may touch this repo at the same time, the branch lives in its own
51
55
  worktree — the `worktree-task` skill has the lifecycle and the cleanup.
52
- - **Gates.** `code-reviewer` runs before every PR; `security-scanner` runs when
53
- a change touches auth, secrets, parsing, or outbound calls. Blocking findings
54
- are resolved, not argued with. The `pr-ship` skill drives the gate.
56
+ - **Gates.** `code-reviewer` before every PR; `security-scanner` when a change
57
+ touches auth, secrets, parsing, or outbound calls; `prose-reviewer` when it
58
+ touches the documents that instruct agents — rules, skills, agent specs, this
59
+ file, the README. Blocking findings are resolved, not argued with, and the
60
+ `pr-ship` skill drives the fan-out. **No hook launches them** — a gate here is
61
+ a session following a written rule, so "the gate ran" is a claim, not a
62
+ guarantee. The mechanical enforcement below is a different thing, and the
63
+ difference is worth keeping straight.
55
64
  - **Enforcement is mechanical.** `guard-core-purity` catches an impure edit to
56
65
  the core the moment it lands; `guard-web-boundary` keeps the frontend off the
57
66
  backend; `block-no-verify` refuses pre-commit bypasses; `guard-bash` refuses
@@ -9,12 +9,14 @@
9
9
  ".claude/agents/test-writer.md",
10
10
  ".claude/agents/code-reviewer.md",
11
11
  ".claude/agents/security-scanner.md",
12
+ ".claude/agents/prose-reviewer.md",
12
13
  ".claude/hooks/block-no-verify.mjs",
13
14
  ".claude/hooks/guard-bash.mjs",
14
15
  ".claude/hooks/gate-stop-dod.mjs",
15
16
  ".claude/hooks/inject-rules.mjs",
16
17
  ".claude/skills/pr-ship/SKILL.md",
17
18
  ".claude/skills/loop/SKILL.md",
19
+ ".claude/skills/check-premises/SKILL.md",
18
20
  ".claude/skills/worktree-task/SKILL.md",
19
21
  ".claude/scripts/detect-missed-gate.mjs",
20
22
  ".claude/scripts/reconcile-external-prs.mjs",