create-agent-rig 0.5.0 → 0.6.0

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 (60) hide show
  1. package/CHANGELOG.md +140 -34
  2. package/README.md +12 -6
  3. package/package.json +1 -1
  4. package/packages/cli/dist/commands/init.js +6 -3
  5. package/packages/cli/dist/commands/upgrade.js +2 -2
  6. package/packages/cli/dist/index.js +46 -8
  7. package/packages/cli/dist/lib/manifest.js +10 -0
  8. package/scripts/prepare.mjs +1 -1
  9. package/templates/agent-os/init/AGENTS.md +11 -3
  10. package/templates/agent-os/init/CLAUDE.md +11 -3
  11. package/templates/agent-os/stack/aws-cdk/.agents/skills/post-deploy-verify/SKILL.md +8 -1
  12. package/templates/agent-os/stack/aws-cdk/.claude/agents/cdk-diff-reviewer.md +8 -1
  13. package/templates/agent-os/stack/aws-cdk/.claude/skills/post-deploy-verify/SKILL.md +8 -1
  14. package/templates/agent-os/stack/aws-cdk/.codex/agents/cdk-diff-reviewer.toml +1 -1
  15. package/templates/agent-os/stack/node-ts/.claude/rules/node-ts.md +29 -0
  16. package/templates/agent-os/universal/.agents/skills/check-premises/SKILL.md +4 -1
  17. package/templates/agent-os/universal/.agents/skills/loop/SKILL.md +298 -16
  18. package/templates/agent-os/universal/.agents/skills/pr-ship/SKILL.md +64 -6
  19. package/templates/agent-os/universal/.claude/agents/code-reviewer.md +8 -1
  20. package/templates/agent-os/universal/.claude/agents/prose-reviewer.md +8 -1
  21. package/templates/agent-os/universal/.claude/agents/security-scanner.md +8 -1
  22. package/templates/agent-os/universal/.claude/hooks/gate-stop-dod.mjs +28 -3
  23. package/templates/agent-os/universal/.claude/hooks/guard-rulebook.mjs +127 -0
  24. package/templates/agent-os/universal/.claude/hooks/lib/edit-input.mjs +23 -0
  25. package/templates/agent-os/universal/.claude/rules/autonomy.md +8 -0
  26. package/templates/agent-os/universal/.claude/rules/invariants.md +33 -3
  27. package/templates/agent-os/universal/.claude/scripts/decision-router.mjs +19 -1
  28. package/templates/agent-os/universal/.claude/scripts/doctor.mjs +351 -0
  29. package/templates/agent-os/universal/.claude/scripts/lib/gate-coverage.mjs +306 -0
  30. package/templates/agent-os/universal/.claude/scripts/lib/revalidation-points.mjs +28 -0
  31. package/templates/agent-os/universal/.claude/scripts/lib/verdict.mjs +37 -8
  32. package/templates/agent-os/universal/.claude/scripts/preflight.mjs +27 -1
  33. package/templates/agent-os/universal/.claude/scripts/queue/as-of.mjs +51 -0
  34. package/templates/agent-os/universal/.claude/scripts/queue/checkout.mjs +62 -2
  35. package/templates/agent-os/universal/.claude/scripts/queue/core.mjs +479 -9
  36. package/templates/agent-os/universal/.claude/scripts/queue/github-issues.mjs +89 -15
  37. package/templates/agent-os/universal/.claude/scripts/queue/index.mjs +138 -15
  38. package/templates/agent-os/universal/.claude/scripts/queue/jira.mjs +394 -46
  39. package/templates/agent-os/universal/.claude/scripts/queue/plan-md.mjs +68 -5
  40. package/templates/agent-os/universal/.claude/scripts/revalidate.mjs +316 -0
  41. package/templates/agent-os/universal/.claude/scripts/revalidation-report.mjs +180 -0
  42. package/templates/agent-os/universal/.claude/scripts/run-state.mjs +101 -3
  43. package/templates/agent-os/universal/.claude/scripts/stop-flag.mjs +15 -8
  44. package/templates/agent-os/universal/.claude/scripts/unattended-flag.mjs +239 -0
  45. package/templates/agent-os/universal/.claude/scripts/verdict.mjs +101 -4
  46. package/templates/agent-os/universal/.claude/settings.json +5 -1
  47. package/templates/agent-os/universal/.claude/skills/check-premises/SKILL.md +4 -1
  48. package/templates/agent-os/universal/.claude/skills/loop/SKILL.md +298 -16
  49. package/templates/agent-os/universal/.claude/skills/pr-ship/SKILL.md +64 -6
  50. package/templates/agent-os/universal/.codex/agents/code-reviewer.toml +1 -1
  51. package/templates/agent-os/universal/.codex/agents/prose-reviewer.toml +1 -1
  52. package/templates/agent-os/universal/.codex/agents/security-scanner.toml +1 -1
  53. package/templates/agent-os/universal/.codex/hooks.json +6 -1
  54. package/templates/agent-os/universal/AGENTS.md +3 -1
  55. package/templates/agent-os/universal/CLAUDE.md +3 -1
  56. package/templates/agent-os/universal/docs/decisions/gate-coverage.md +83 -0
  57. package/templates/agent-os/universal/docs/decisions/two-empty-endings.md +18 -6
  58. package/templates/agent-os/universal/layers.json +9 -0
  59. package/templates/hash-history.json +309 -49
  60. package/templates/release-ledger.json +9 -0
@@ -3,7 +3,7 @@
3
3
  "hooks": {
4
4
  "PreToolUse": [
5
5
  {
6
- "matcher": "Write|Edit|apply_patch",
6
+ "matcher": "Write|Edit|MultiEdit|NotebookEdit|apply_patch",
7
7
  "hooks": [
8
8
  {
9
9
  "type": "command",
@@ -19,6 +19,11 @@
19
19
  "type": "command",
20
20
  "command": "node \"$(git rev-parse --show-toplevel)/.claude/hooks/guard-secret-file.mjs\"",
21
21
  "commandWindows": "powershell.exe -NoProfile -NonInteractive -EncodedCommand JAByAGUAcABvAFIAbwBvAHQAIAA9ACAAZwBpAHQAIAByAGUAdgAtAHAAYQByAHMAZQAgAC0ALQBzAGgAbwB3AC0AdABvAHAAbABlAHYAZQBsADsAIABpAGYAIAAoACQATABBAFMAVABFAFgASQBUAEMATwBEAEUAIAAtAG4AZQAgADAAKQAgAHsAIABlAHgAaQB0ACAAJABMAEEAUwBUAEUAWABJAFQAQwBPAEQARQAgAH0AOwAgACQAaABvAG8AawBQAGEAdABoACAAPQAgAEoAbwBpAG4ALQBQAGEAdABoACAAJAByAGUAcABvAFIAbwBvAHQAIAAnAC4AYwBsAGEAdQBkAGUALwBoAG8AbwBrAHMALwBnAHUAYQByAGQALQBzAGUAYwByAGUAdAAtAGYAaQBsAGUALgBtAGoAcwAnADsAIAAmACAAbgBvAGQAZQAgACQAaABvAG8AawBQAGEAdABoADsAIABlAHgAaQB0ACAAJABMAEEAUwBUAEUAWABJAFQAQwBPAEQARQA="
22
+ },
23
+ {
24
+ "type": "command",
25
+ "command": "node \"$(git rev-parse --show-toplevel)/.claude/hooks/guard-rulebook.mjs\"",
26
+ "commandWindows": "powershell.exe -NoProfile -NonInteractive -EncodedCommand JAByAGUAcABvAFIAbwBvAHQAIAA9ACAAZwBpAHQAIAByAGUAdgAtAHAAYQByAHMAZQAgAC0ALQBzAGgAbwB3AC0AdABvAHAAbABlAHYAZQBsADsAIABpAGYAIAAoACQATABBAFMAVABFAFgASQBUAEMATwBEAEUAIAAtAG4AZQAgADAAKQAgAHsAIABlAHgAaQB0ACAAJABMAEEAUwBUAEUAWABJAFQAQwBPAEQARQAgAH0AOwAgACQAaABvAG8AawBQAGEAdABoACAAPQAgAEoAbwBpAG4ALQBQAGEAdABoACAAJAByAGUAcABvAFIAbwBvAHQAIAAnAC4AYwBsAGEAdQBkAGUALwBoAG8AbwBrAHMALwBnAHUAYQByAGQALQByAHUAbABlAGIAbwBvAGsALgBtAGoAcwAnADsAIAAmACAAbgBvAGQAZQAgACQAaABvAG8AawBQAGEAdABoADsAIABlAHgAaQB0ACAAJABMAEEAUwBUAEUAWABJAFQAQwBPAEQARQA="
22
27
  }
23
28
  ]
24
29
  },
@@ -86,7 +86,9 @@ them all; they are one rulebook.
86
86
  difference is worth keeping straight.
87
87
  - **Enforcement is mechanical.** `guard-core-purity` catches an impure edit to
88
88
  the core the moment it lands; `guard-web-boundary` keeps the frontend off the
89
- backend; `guard-secret-file` refuses an edit that writes a credential — by the
89
+ backend; `guard-rulebook` refuses an edit to the rulebook itself from an
90
+ unattended run outside the item's allow-list (a flag file the `loop` skill
91
+ writes; attended sessions are untouched); `guard-secret-file` refuses an edit that writes a credential — by the
90
92
  file's name or by a value in its text, from the one vocabulary in
91
93
  `.claude/scripts/lib/secrets.mjs`; `block-no-verify` refuses pre-commit
92
94
  bypasses; `guard-bash` refuses
@@ -86,7 +86,9 @@ them all; they are one rulebook.
86
86
  difference is worth keeping straight.
87
87
  - **Enforcement is mechanical.** `guard-core-purity` catches an impure edit to
88
88
  the core the moment it lands; `guard-web-boundary` keeps the frontend off the
89
- backend; `guard-secret-file` refuses an edit that writes a credential — by the
89
+ backend; `guard-rulebook` refuses an edit to the rulebook itself from an
90
+ unattended run outside the item's allow-list (a flag file the `loop` skill
91
+ writes; attended sessions are untouched); `guard-secret-file` refuses an edit that writes a credential — by the
90
92
  file's name or by a value in its text, from the one vocabulary in
91
93
  `.claude/scripts/lib/secrets.mjs`; `block-no-verify` refuses pre-commit
92
94
  bypasses; `guard-bash` refuses
@@ -0,0 +1,83 @@
1
+ # Why the fan-out is checked in `pr-ship`, and never in a hook
2
+
3
+ The check lives in the `pr-ship` skill, step 5 ("Coverage"), and its rule is one
4
+ sentence: *a merge is not gated by a fan-out whose reviewers did not all answer
5
+ for the commit being merged.* This file explains why that check sits in a skill
6
+ rather than in `guard-bash`. The hook version is the one that keeps being
7
+ proposed, and a refusal nobody wrote down gets proposed again. It is not loaded
8
+ into any session.
9
+
10
+ ## The shape that was refused
11
+
12
+ The proposal: `guard-bash` denies a merge command unless the run journal holds a
13
+ `SHIP` from every reviewer the router named, for the PR's head commit. It is the
14
+ attractive version — mechanical, at the tool layer, impossible for a hurried
15
+ session to skip.
16
+
17
+ It was refused on four costs, each of them a rule this project already paid for.
18
+
19
+ **1. It needs to recognise a merge command while the brake is off.** The kill
20
+ switch can be coarse — it denies the network clients *as a class of binaries*,
21
+ reading no merge semantics at all, while still allowing the wind-down it asks
22
+ for — because a false block is cheap when the session is already stopped. `invariants.md` states that
23
+ directly: match a rule's precision to the cost of a false positive. A merge gate
24
+ runs during ordinary work, where a false block lands on the last step of finished
25
+ work. The one attempt at enumerating merge routes was reverted, and what it cost
26
+ is recorded where the attempt was made rather than restated here:
27
+ `.claude/hooks/guard-bash.mjs`, the comment above `NETWORK_CLIENTS`.
28
+
29
+ **2. It needs the head commit, inside a hook that must stay pure.** For
30
+ `gh pr merge <number>` the head is only knowable over the network, and
31
+ `guard-bash` records what an unbounded hook costs: killed by its own timeout, and
32
+ a killed hook does not block — so **every** rule silently switched off, not just
33
+ the new one.
34
+
35
+ **3. It needs to parse the journal in a guard that fails open.** The journal
36
+ reader refuses a malformed line by throwing, which is right for a reader and
37
+ fatal for a fail-open guard: the throw resolves to *allow*, again for every rule
38
+ at once. `stop-flag.mjs` is not the precedent it resembles — that is `existsSync`
39
+ over a capped list of fixed paths, not a parse.
40
+
41
+ **4. Its sweep half cannot exist.** The natural companion — audit merged PRs from
42
+ outside — has nothing to read: the run directory is gitignored, and the sweep
43
+ sees labels and PR bodies only.
44
+
45
+ ## And the reason the four costs were not worth paying
46
+
47
+ Even fully built, the guard would read a file **the audited run wrote itself**.
48
+ For the threat model a hook actually has — drift, not an adversary — that is
49
+ tolerable, and it is why the skill-level check below is worth having at all. What
50
+ it is not is the *guarantee* the hook version promised, and the four costs above
51
+ were being paid for that word.
52
+
53
+ ## What was built instead
54
+
55
+ `.claude/scripts/lib/gate-coverage.mjs` compares the three sets the journal already holds —
56
+ routed, launched, answered — and `pr-ship` runs it through
57
+ `verdict.mjs coverage <commit>` before its own verdict. It sits in the layer that
58
+ already knows the head commit, is allowed to run git, and is allowed to throw.
59
+
60
+ Two limits, and both are stated in the skill beside the step rather than only
61
+ here:
62
+
63
+ - with no `RIG_RUN_DIR` there is no journal, so the check says it was skipped and
64
+ exits 0 — an honest nothing, never a pass;
65
+ - a session that skips `pr-ship` entirely skips this with it. That is the gap the
66
+ hook version was reaching for, and it stays open.
67
+
68
+ So `CLAUDE.md` keeps its sentence unchanged: *no hook launches the gates, so "the
69
+ gate ran" is a claim, not a guarantee.* What changed is narrower and worth
70
+ having on its own — the driver can no longer accept a fan-out that did not
71
+ answer, or one that answered about a commit two pushes ago.
72
+
73
+ ## The variant that removes self-report, and why it is not the default
74
+
75
+ Running the reviewers as CI check runs is the only shape where the evidence is
76
+ authored by something other than the audited run, and where the driver cannot
77
+ skip the gate at all. It is not refused on its merits.
78
+
79
+ It is refused **as a default for this layer**: everything under `.claude/` ships
80
+ into every project this rulebook generates, so making it the shape would require
81
+ a model credential in every generated project's CI and a per-PR cost, for
82
+ projects that never asked for either. A project that wants that guarantee should
83
+ adopt it deliberately; the check above is what every project gets.
@@ -13,9 +13,14 @@ why a parked cause outranks a holding one. It is not loaded into any session.
13
13
  by a condition that clears when _something else happens_: the elevated spacing
14
14
  (a normal item lands — or an elevated one whose paths were all documents, see
15
15
  `spacing-rations-mechanisms.md`), a blocker (its item closes), `in-progress`
16
- (the other session finishes), a trigger (a human declares it).
17
-
18
- An empty queue wants refilling. A held one wants interleaving, or simply time.
16
+ (the other session finishes), a trigger (a human declares it), an owner (the
17
+ item is marked for another repository and a human moves or re-marks it —
18
+ AR-132), a `re-scope` item (a human rewrites it against the current code and
19
+ removes the label — AR-144), and a `deferred` item (it carries the `parked`
20
+ label and a human un-parks it — AR-144).
21
+
22
+ An empty queue wants refilling. A held one wants interleaving, time, or — for a
23
+ trigger or an owner — the human act the stop line names.
19
24
  Reporting the second as the first sends the owner to write tickets that already
20
25
  exist; reporting the first as the second tells them to wait for nothing.
21
26
 
@@ -23,14 +28,21 @@ exist; reporting the first as the second tells them to wait for nothing.
23
28
 
24
29
  Parked items are out of play and waiting on a human. They are not work this run
25
30
  can take, and they are not why the queue is empty — so they are named separately,
26
- by cause and count.
31
+ by cause and count. An `obsolete` item (AR-144) is one of them: it waits on a
32
+ human close with a comment naming the evidence, which the loop never writes.
33
+
34
+ ⚠ "Parked" here is the pile, not the `parked` **label**. The label (AR-144) means
35
+ "valid work, deliberately not now" — takeable, held, freed by an un-park — so its
36
+ cause is spelled `deferred`, and it is never in this pile. The two were named
37
+ before each other existed; this note is the reconciliation rather than a rename,
38
+ because the pile word runs through the stop line, the tests and this record.
27
39
 
28
40
  How that pile grows is the adapter's business, and the stop line does not guess:
29
41
 
30
42
  | adapter | what lands in the parked pile |
31
43
  | ---------------------------------------- | ----------------------------------------------------- |
32
- | tracker-backed (`github-issues`, `jira`) | an escalated item and a filed proposal both stay open |
33
- | `plan-md` | only a `[triage]` line sitting in the Agent queue |
44
+ | tracker-backed (`github-issues`, `jira`) | an escalated item, a filed proposal (both stay open), and an item labelled `obsolete` (AR-144) |
45
+ | `plan-md` | a `[triage]` or an `[obsolete]` line sitting in the Agent queue — nothing else, because a flat list has no per-item state |
34
46
 
35
47
  Under `plan-md` a filed proposal goes to the Operator queue, where selection
36
48
  never looks, and an escalation leaves **no mark on the queue at all** — a flat
@@ -15,6 +15,7 @@
15
15
  ".claude/hooks/gate-stop-dod.mjs",
16
16
  ".claude/hooks/inject-rules.mjs",
17
17
  ".claude/hooks/guard-secret-file.mjs",
18
+ ".claude/hooks/guard-rulebook.mjs",
18
19
  ".claude/hooks/lib/edit-input.mjs",
19
20
  ".claude/skills/pr-ship/SKILL.md",
20
21
  ".claude/skills/loop/SKILL.md",
@@ -35,11 +36,17 @@
35
36
  ".claude/scripts/decision-router.mjs",
36
37
  ".claude/scripts/reconcile-external-prs.mjs",
37
38
  ".claude/scripts/stop-flag.mjs",
39
+ ".claude/scripts/unattended-flag.mjs",
38
40
  ".claude/scripts/git-env.mjs",
39
41
  ".claude/scripts/preflight.mjs",
42
+ ".claude/scripts/doctor.mjs",
40
43
  ".claude/scripts/run-journal.mjs",
41
44
  ".claude/scripts/run-state.mjs",
42
45
  ".claude/scripts/verdict.mjs",
46
+ ".claude/scripts/revalidate.mjs",
47
+ ".claude/scripts/revalidation-report.mjs",
48
+ ".claude/scripts/lib/gate-coverage.mjs",
49
+ ".claude/scripts/lib/revalidation-points.mjs",
43
50
  ".claude/scripts/lib/verdict.mjs",
44
51
  ".claude/scripts/lib/secrets.mjs",
45
52
  ".claude/scripts/queue/core.mjs",
@@ -47,12 +54,14 @@
47
54
  ".claude/scripts/queue/github-issues.mjs",
48
55
  ".claude/scripts/queue/jira.mjs",
49
56
  ".claude/scripts/queue/index.mjs",
57
+ ".claude/scripts/queue/as-of.mjs",
50
58
  ".claude/scripts/queue/checkout.mjs",
51
59
  ".claude/scripts/queue/state.mjs",
52
60
  ".claude/scripts/queue/gate-rounds.mjs",
53
61
  ".claude/queue.json",
54
62
  "PLAN.md",
55
63
  "journal/README.md",
64
+ "docs/decisions/gate-coverage.md",
56
65
  "docs/decisions/fail-open-guards.md",
57
66
  "docs/decisions/codex-adapter.md",
58
67
  "docs/decisions/closing-a-task.md",