create-agent-rig 0.9.0 → 0.10.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 (237) hide show
  1. package/CHANGELOG.md +466 -3
  2. package/README.md +267 -299
  3. package/package.json +8 -14
  4. package/packages/cli/dist/commands/create.js +56 -88
  5. package/packages/cli/dist/commands/doctor.js +213 -0
  6. package/packages/cli/dist/commands/init.js +151 -54
  7. package/packages/cli/dist/commands/integrations.js +468 -0
  8. package/packages/cli/dist/commands/memory.js +63 -4
  9. package/packages/cli/dist/commands/setup-wizard.js +61 -0
  10. package/packages/cli/dist/commands/uninstall.js +1223 -0
  11. package/packages/cli/dist/commands/upgrade.js +489 -89
  12. package/packages/cli/dist/index.js +657 -49
  13. package/packages/cli/dist/integrations/declaration.js +158 -0
  14. package/packages/cli/dist/integrations/doctor-guards.js +126 -0
  15. package/packages/cli/dist/integrations/doctor-workflow.js +25 -0
  16. package/packages/cli/dist/integrations/mcp-json.js +107 -0
  17. package/packages/cli/dist/integrations/memory-doctor.js +124 -0
  18. package/packages/cli/dist/integrations/registry.js +22 -0
  19. package/packages/cli/dist/integrations/spawn.js +228 -0
  20. package/packages/cli/dist/integrations/spec-kit.js +280 -0
  21. package/packages/cli/dist/integrations/verify.js +193 -0
  22. package/packages/cli/dist/integrations/windows-job.js +275 -0
  23. package/packages/cli/dist/lib/elevated-paths.js +74 -0
  24. package/packages/cli/dist/lib/install-set.js +1 -44
  25. package/packages/cli/dist/lib/manifest.js +86 -9
  26. package/packages/cli/dist/lib/prompts.js +0 -23
  27. package/packages/cli/dist/lib/safe-path.js +193 -2
  28. package/packages/cli/dist/lib/safe-text.js +78 -0
  29. package/packages/cli/dist/lib/substitute.js +1 -52
  30. package/packages/cli/dist/lib/summary.js +5 -5
  31. package/packages/cli/dist/templates.js +4 -14
  32. package/scripts/prepare.mjs +28 -12
  33. package/templates/agent-os/subagent-routing.json +4 -4
  34. package/templates/agent-os/universal/.agents/skills/check-premises/SKILL.md +13 -9
  35. package/templates/agent-os/universal/.agents/skills/loop/SKILL.md +31 -6
  36. package/templates/agent-os/universal/.agents/skills/new-invariant/SKILL.md +5 -5
  37. package/templates/agent-os/universal/.agents/skills/pr-ship/SKILL.md +1 -1
  38. package/templates/agent-os/universal/.agents/skills/worktree-task/SKILL.md +3 -3
  39. package/templates/agent-os/universal/.claude/agents/code-reviewer.md +8 -6
  40. package/templates/agent-os/universal/.claude/agents/implementation-agent.md +41 -0
  41. package/templates/agent-os/universal/.claude/agents/prose-reviewer.md +8 -4
  42. package/templates/agent-os/universal/.claude/agents/security-scanner.md +4 -2
  43. package/templates/agent-os/universal/.claude/agents/test-writer.md +2 -2
  44. package/templates/agent-os/universal/.claude/hooks/inject-rules.mjs +83 -4
  45. package/templates/agent-os/universal/.claude/rules/autonomy.md +55 -27
  46. package/templates/agent-os/universal/.claude/rules/invariants.md +9 -8
  47. package/templates/agent-os/universal/.claude/rules/workflow.md +47 -22
  48. package/templates/agent-os/universal/.claude/scripts/decision-router.mjs +1 -1
  49. package/templates/agent-os/universal/.claude/scripts/detect-missed-gate.mjs +12 -9
  50. package/templates/agent-os/universal/.claude/scripts/doctor.mjs +100 -2
  51. package/templates/agent-os/universal/.claude/scripts/lib/claim-records.mjs +236 -6
  52. package/templates/agent-os/universal/.claude/scripts/queue/core.mjs +43 -0
  53. package/templates/agent-os/universal/.claude/scripts/queue/jira.mjs +18 -1
  54. package/templates/agent-os/universal/.claude/scripts/queue/state.mjs +2 -2
  55. package/templates/agent-os/universal/.claude/scripts/reconcile-external-prs.mjs +273 -35
  56. package/templates/agent-os/universal/.claude/scripts/revalidate.mjs +16 -0
  57. package/templates/agent-os/universal/.claude/settings.json +0 -8
  58. package/templates/agent-os/universal/.claude/skills/check-premises/SKILL.md +13 -9
  59. package/templates/agent-os/universal/.claude/skills/loop/SKILL.md +31 -6
  60. package/templates/agent-os/universal/.claude/skills/new-invariant/SKILL.md +5 -5
  61. package/templates/agent-os/universal/.claude/skills/pr-ship/SKILL.md +1 -1
  62. package/templates/agent-os/universal/.claude/skills/worktree-task/SKILL.md +3 -3
  63. package/templates/agent-os/universal/.codex/agents/code-reviewer.toml +2 -2
  64. package/templates/agent-os/universal/.codex/agents/implementation-agent.toml +6 -0
  65. package/templates/agent-os/universal/.codex/agents/prose-reviewer.toml +2 -2
  66. package/templates/agent-os/universal/.codex/agents/security-scanner.toml +1 -1
  67. package/templates/agent-os/universal/.codex/agents/test-writer.toml +1 -1
  68. package/templates/agent-os/universal/.codex/hooks.json +0 -10
  69. package/templates/agent-os/universal/AGENTS.md +208 -107
  70. package/templates/agent-os/universal/CLAUDE.md +15 -162
  71. package/templates/agent-os/universal/PLAN.md +17 -10
  72. package/templates/agent-os/universal/docs/decisions/agents-md-canonical.md +313 -0
  73. package/templates/agent-os/universal/docs/decisions/codex-adapter.md +15 -10
  74. package/templates/agent-os/universal/docs/decisions/review-lanes.md +12 -8
  75. package/templates/agent-os/universal/docs/decisions/session-start-wire-format.md +206 -0
  76. package/templates/agent-os/universal/docs/decisions/subagent-routing.md +6 -3
  77. package/templates/agent-os/universal/docs/decisions/workflow-layer-split.md +235 -0
  78. package/templates/agent-os/universal/layers.json +25 -30
  79. package/templates/hash-history.json +73 -24
  80. package/templates/release-ledger.json +3 -1
  81. package/packages/cli/dist/lib/composition.js +0 -20
  82. package/packages/cli/dist/lib/targets.js +0 -28
  83. package/packages/cli/dist/policy/benchmark/corpus.js +0 -165
  84. package/packages/cli/dist/policy/core/adapter.js +0 -18
  85. package/packages/cli/dist/policy/core/coverage.js +0 -253
  86. package/packages/cli/dist/policy/core/decision-record.js +0 -287
  87. package/packages/cli/dist/policy/core/declaration.js +0 -127
  88. package/packages/cli/dist/policy/core/evidence-matrix.js +0 -94
  89. package/packages/cli/dist/policy/core/probe.js +0 -442
  90. package/packages/cli/dist/policy/core/registry.js +0 -115
  91. package/packages/cli/dist/policy/core/validation.js +0 -275
  92. package/packages/cli/dist/policy/core/vocabulary.js +0 -123
  93. package/packages/cli/dist/policy/harness/claude.js +0 -47
  94. package/packages/cli/dist/policy/harness/codex.js +0 -87
  95. package/packages/cli/dist/policy/harness/index.js +0 -15
  96. package/packages/cli/dist/policy/harness/shared-hooks.js +0 -28
  97. package/packages/cli/dist/policy/index.js +0 -17
  98. package/templates/agent-os/init/AGENTS.md +0 -201
  99. package/templates/agent-os/init/CLAUDE.md +0 -201
  100. package/templates/agent-os/stack/aws-cdk/.agents/skills/post-deploy-verify/SKILL.md +0 -105
  101. package/templates/agent-os/stack/aws-cdk/.agents/skills/ro-debug/SKILL.md +0 -117
  102. package/templates/agent-os/stack/aws-cdk/.claude/agents/cdk-diff-reviewer.md +0 -89
  103. package/templates/agent-os/stack/aws-cdk/.claude/rules/aws-cdk.md +0 -105
  104. package/templates/agent-os/stack/aws-cdk/.claude/skills/post-deploy-verify/SKILL.md +0 -105
  105. package/templates/agent-os/stack/aws-cdk/.claude/skills/ro-debug/SKILL.md +0 -117
  106. package/templates/agent-os/stack/aws-cdk/.codex/agents/cdk-diff-reviewer.toml +0 -6
  107. package/templates/agent-os/stack/node-ts/.claude/hooks/dod-checks.json +0 -1
  108. package/templates/agent-os/stack/node-ts/.claude/rules/node-ts.md +0 -85
  109. package/templates/agent-os/universal/.claude/hooks/guard-core-purity.mjs +0 -89
  110. package/templates/agent-os/universal/.claude/hooks/guard-web-boundary.mjs +0 -68
  111. package/templates/agent-os/universal/.claude/rules/architecture.md +0 -81
  112. package/templates/skeleton/aws-serverless/.github/workflows/ci.yml +0 -28
  113. package/templates/skeleton/aws-serverless/.github/workflows/deploy.yml +0 -90
  114. package/templates/skeleton/aws-serverless/README.md +0 -181
  115. package/templates/skeleton/aws-serverless/apps/web/next.config.mjs +0 -17
  116. package/templates/skeleton/aws-serverless/apps/web/package.json +0 -19
  117. package/templates/skeleton/aws-serverless/apps/web/src/app/layout.tsx +0 -17
  118. package/templates/skeleton/aws-serverless/apps/web/src/app/page.tsx +0 -96
  119. package/templates/skeleton/aws-serverless/apps/web/src/lib/api.ts +0 -36
  120. package/templates/skeleton/aws-serverless/apps/web/src/lib/validate.ts +0 -23
  121. package/templates/skeleton/aws-serverless/apps/web/test/shared-validation.test.ts +0 -38
  122. package/templates/skeleton/aws-serverless/apps/web/tsconfig.json +0 -14
  123. package/templates/skeleton/aws-serverless/eslint.config.mjs +0 -20
  124. package/templates/skeleton/aws-serverless/gitignore +0 -56
  125. package/templates/skeleton/aws-serverless/infra/bin/app.ts +0 -79
  126. package/templates/skeleton/aws-serverless/infra/cdk.json +0 -3
  127. package/templates/skeleton/aws-serverless/infra/lib/app-stack.ts +0 -248
  128. package/templates/skeleton/aws-serverless/infra/lib/web-stack.ts +0 -45
  129. package/templates/skeleton/aws-serverless/infra/package.json +0 -18
  130. package/templates/skeleton/aws-serverless/infra/test/allowed-origins.test.ts +0 -301
  131. package/templates/skeleton/aws-serverless/infra/test/app-composition.test.ts +0 -137
  132. package/templates/skeleton/aws-serverless/infra/test/app-stack.test.ts +0 -120
  133. package/templates/skeleton/aws-serverless/infra/test/web-stack.test.ts +0 -44
  134. package/templates/skeleton/aws-serverless/package.json +0 -30
  135. package/templates/skeleton/aws-serverless/packages/core/package.json +0 -11
  136. package/templates/skeleton/aws-serverless/packages/core/src/events.ts +0 -14
  137. package/templates/skeleton/aws-serverless/packages/core/src/index.ts +0 -15
  138. package/templates/skeleton/aws-serverless/packages/core/src/note.ts +0 -69
  139. package/templates/skeleton/aws-serverless/packages/core/test/events.test.ts +0 -23
  140. package/templates/skeleton/aws-serverless/packages/core/test/note.test.ts +0 -101
  141. package/templates/skeleton/aws-serverless/packages/db/package.json +0 -14
  142. package/templates/skeleton/aws-serverless/packages/db/src/client.ts +0 -17
  143. package/templates/skeleton/aws-serverless/packages/db/src/index.ts +0 -2
  144. package/templates/skeleton/aws-serverless/packages/db/src/note-model.ts +0 -52
  145. package/templates/skeleton/aws-serverless/packages/db/test/note-model.test.ts +0 -91
  146. package/templates/skeleton/aws-serverless/packages/shared/package.json +0 -11
  147. package/templates/skeleton/aws-serverless/packages/shared/src/env.ts +0 -17
  148. package/templates/skeleton/aws-serverless/packages/shared/src/errors.ts +0 -33
  149. package/templates/skeleton/aws-serverless/packages/shared/src/index.ts +0 -3
  150. package/templates/skeleton/aws-serverless/packages/shared/src/logger.ts +0 -20
  151. package/templates/skeleton/aws-serverless/packages/shared/test/env.test.ts +0 -26
  152. package/templates/skeleton/aws-serverless/packages/shared/test/errors.test.ts +0 -28
  153. package/templates/skeleton/aws-serverless/packages/shared/test/logger.test.ts +0 -19
  154. package/templates/skeleton/aws-serverless/pnpm-lock.yaml +0 -2855
  155. package/templates/skeleton/aws-serverless/pnpm-workspace.yaml +0 -14
  156. package/templates/skeleton/aws-serverless/services/api/package.json +0 -15
  157. package/templates/skeleton/aws-serverless/services/api/src/adapters/sqs-publisher.ts +0 -26
  158. package/templates/skeleton/aws-serverless/services/api/src/handlers/create-note.ts +0 -69
  159. package/templates/skeleton/aws-serverless/services/api/src/handlers/list-notes.ts +0 -37
  160. package/templates/skeleton/aws-serverless/services/api/src/list-main.ts +0 -12
  161. package/templates/skeleton/aws-serverless/services/api/src/main.ts +0 -21
  162. package/templates/skeleton/aws-serverless/services/api/src/usecases/create-note.ts +0 -41
  163. package/templates/skeleton/aws-serverless/services/api/src/usecases/list-notes.ts +0 -14
  164. package/templates/skeleton/aws-serverless/services/api/test/create-note.handler.test.ts +0 -211
  165. package/templates/skeleton/aws-serverless/services/api/test/create-note.usecase.test.ts +0 -45
  166. package/templates/skeleton/aws-serverless/services/api/test/list-notes.test.ts +0 -122
  167. package/templates/skeleton/aws-serverless/services/api/test/sqs-publisher.test.ts +0 -22
  168. package/templates/skeleton/aws-serverless/services/worker/package.json +0 -12
  169. package/templates/skeleton/aws-serverless/services/worker/src/handlers/note-created.ts +0 -15
  170. package/templates/skeleton/aws-serverless/services/worker/src/main.ts +0 -7
  171. package/templates/skeleton/aws-serverless/services/worker/src/usecases/process-note-created.ts +0 -37
  172. package/templates/skeleton/aws-serverless/services/worker/test/note-created.test.ts +0 -61
  173. package/templates/skeleton/aws-serverless/tsconfig.base.json +0 -15
  174. package/templates/skeleton/aws-serverless/tsconfig.json +0 -16
  175. package/templates/skeleton/aws-serverless/vitest.config.ts +0 -14
  176. package/templates/skeleton/node-service/.github/workflows/ci.yml +0 -27
  177. package/templates/skeleton/node-service/.github/workflows/deploy.yml +0 -29
  178. package/templates/skeleton/node-service/README.md +0 -104
  179. package/templates/skeleton/node-service/apps/web/next.config.mjs +0 -17
  180. package/templates/skeleton/node-service/apps/web/package.json +0 -19
  181. package/templates/skeleton/node-service/apps/web/src/app/layout.tsx +0 -17
  182. package/templates/skeleton/node-service/apps/web/src/app/page.tsx +0 -96
  183. package/templates/skeleton/node-service/apps/web/src/lib/api.ts +0 -29
  184. package/templates/skeleton/node-service/apps/web/src/lib/validate.ts +0 -23
  185. package/templates/skeleton/node-service/apps/web/test/shared-validation.test.ts +0 -38
  186. package/templates/skeleton/node-service/apps/web/tsconfig.json +0 -14
  187. package/templates/skeleton/node-service/eslint.config.mjs +0 -20
  188. package/templates/skeleton/node-service/gitignore +0 -54
  189. package/templates/skeleton/node-service/package.json +0 -30
  190. package/templates/skeleton/node-service/packages/core/package.json +0 -11
  191. package/templates/skeleton/node-service/packages/core/src/events.ts +0 -14
  192. package/templates/skeleton/node-service/packages/core/src/index.ts +0 -15
  193. package/templates/skeleton/node-service/packages/core/src/note.ts +0 -69
  194. package/templates/skeleton/node-service/packages/core/test/events.test.ts +0 -23
  195. package/templates/skeleton/node-service/packages/core/test/note.test.ts +0 -101
  196. package/templates/skeleton/node-service/packages/db/package.json +0 -12
  197. package/templates/skeleton/node-service/packages/db/src/index.ts +0 -1
  198. package/templates/skeleton/node-service/packages/db/src/note-store.ts +0 -100
  199. package/templates/skeleton/node-service/packages/db/test/note-store.test.ts +0 -100
  200. package/templates/skeleton/node-service/packages/shared/package.json +0 -11
  201. package/templates/skeleton/node-service/packages/shared/src/env.ts +0 -17
  202. package/templates/skeleton/node-service/packages/shared/src/errors.ts +0 -33
  203. package/templates/skeleton/node-service/packages/shared/src/index.ts +0 -3
  204. package/templates/skeleton/node-service/packages/shared/src/logger.ts +0 -20
  205. package/templates/skeleton/node-service/packages/shared/test/env.test.ts +0 -26
  206. package/templates/skeleton/node-service/packages/shared/test/errors.test.ts +0 -28
  207. package/templates/skeleton/node-service/packages/shared/test/logger.test.ts +0 -19
  208. package/templates/skeleton/node-service/pnpm-lock.yaml +0 -2402
  209. package/templates/skeleton/node-service/pnpm-workspace.yaml +0 -13
  210. package/templates/skeleton/node-service/scripts/build-artifact.mjs +0 -34
  211. package/templates/skeleton/node-service/services/api/package.json +0 -17
  212. package/templates/skeleton/node-service/services/api/src/adapters/spool-publisher.ts +0 -23
  213. package/templates/skeleton/node-service/services/api/src/handlers/create-note.ts +0 -40
  214. package/templates/skeleton/node-service/services/api/src/handlers/list-notes.ts +0 -23
  215. package/templates/skeleton/node-service/services/api/src/main.ts +0 -40
  216. package/templates/skeleton/node-service/services/api/src/server.ts +0 -172
  217. package/templates/skeleton/node-service/services/api/src/static-dir.ts +0 -20
  218. package/templates/skeleton/node-service/services/api/src/usecases/create-note.ts +0 -30
  219. package/templates/skeleton/node-service/services/api/src/usecases/list-notes.ts +0 -14
  220. package/templates/skeleton/node-service/services/api/test/artifact.test.ts +0 -92
  221. package/templates/skeleton/node-service/services/api/test/create-note.handler.test.ts +0 -64
  222. package/templates/skeleton/node-service/services/api/test/create-note.usecase.test.ts +0 -43
  223. package/templates/skeleton/node-service/services/api/test/list-notes.test.ts +0 -48
  224. package/templates/skeleton/node-service/services/api/test/package-manager.test.ts +0 -40
  225. package/templates/skeleton/node-service/services/api/test/package-manager.ts +0 -51
  226. package/templates/skeleton/node-service/services/api/test/server.test.ts +0 -208
  227. package/templates/skeleton/node-service/services/api/test/spool-publisher.test.ts +0 -32
  228. package/templates/skeleton/node-service/services/api/test/static-dir.test.ts +0 -29
  229. package/templates/skeleton/node-service/services/worker/package.json +0 -16
  230. package/templates/skeleton/node-service/services/worker/src/main.ts +0 -28
  231. package/templates/skeleton/node-service/services/worker/src/spool.ts +0 -60
  232. package/templates/skeleton/node-service/services/worker/src/usecases/process-note-created.ts +0 -38
  233. package/templates/skeleton/node-service/services/worker/test/process-note-created.test.ts +0 -34
  234. package/templates/skeleton/node-service/services/worker/test/spool.test.ts +0 -76
  235. package/templates/skeleton/node-service/tsconfig.base.json +0 -15
  236. package/templates/skeleton/node-service/tsconfig.json +0 -13
  237. package/templates/skeleton/node-service/vitest.config.ts +0 -12
package/CHANGELOG.md CHANGED
@@ -14,6 +14,470 @@ second recorded departure; its own entry states the direction and the reason,
14
14
  and this paragraph deliberately does not restate them — a numbering rule with
15
15
  two copies of its exceptions is the shape 0.8.0 exists to remove.
16
16
 
17
+ ## 0.10.0
18
+
19
+ Platforms: the packed release candidate is accepted on Linux, Windows and
20
+ macOS on Apple silicon (`scripts/release-acceptance.mjs`, dispatched on the
21
+ exact release commit; `e2e.yml` gains a `macos-e2e` job for it). Every CI job
22
+ now runs on a GitHub-hosted image; `e2e.yml` no longer has a runner switch.
23
+ On Windows, Spec Kit 1.0.8 rewrites `.claude/settings.json` and `.codex/config.toml` with CRLF line endings, so
24
+ `doctor` reports `rig-owned-files` as `warn` after Spec Kit setup there.
25
+ Ownership hashes cover exact bytes (`docs/decisions/raw-byte-ownership.md`), so
26
+ where a Codex MCP provider is also wired, `doctor` reports that wiring as
27
+ `drift` and a later `setup` change to a Codex MCP provider refuses with the
28
+ managed fragment for a manual merge instead of overwriting the file.
29
+
30
+ `doctor [--json]` aggregates Rig file integrity, installed guards, optional
31
+ workflow mechanisms, MCP wiring, pinned offline Spec Kit status and the
32
+ machine's custom Memory diagnosis. It preserves the existing versioned
33
+ `ok`/`warn`/`fail` contract and keeps connectivity and trust unobserved.
34
+
35
+ A new project gets an `implementation-agent` for the Green step of TDD, pinned
36
+ like the other roles (`claude-sonnet-5` / `gpt-5.6-terra`, `high`) in
37
+ `.claude/agents/` and `.codex/agents/`. Ordinary implementation no longer falls
38
+ to the unnamed general-purpose subagent, which remains for ad-hoc work.
39
+
40
+ Basic Memory is available as an optional, wiring-only MCP preview for Claude Code
41
+ and Codex. Rig records only its project MCP wiring; it never installs, updates,
42
+ inspects, synchronizes, or removes Basic Memory data. `uvx` remains a launcher
43
+ observation rather than a runtime, connectivity, or trust verification.
44
+
45
+ `setup` now offers a provider/harness wizard and delegates Spec Kit setup to
46
+ the pinned official CLI after an explicit plan and consent. Existing external
47
+ installations use `setup add spec-kit --adopt`; updates and removal use the
48
+ official integration lifecycle without destructive force. Spec Kit retains
49
+ its files and manifests; Rig records intent after authoritative status succeeds.
50
+
51
+ `setup apply` and `setup remove` manage explicitly selected Figma and Atlassian
52
+ MCP configuration through Claude Code's documented project config. Dry-run and
53
+ consent apply before changes; existing user entries are preserved. Ownership
54
+ hashes live alongside provider selection in `.rig/integrations.json`.
55
+ Authorization stays with the provider and harness. Codex uses whole-file
56
+ rendering from the installed release baseline and a rolling intent hash; a
57
+ manual edit refuses rather than being merged or overwritten.
58
+
59
+ **`AGENTS.md` is now the canonical rulebook; `CLAUDE.md` is a short
60
+ compatibility shim.** A new project gets the full rulebook text in
61
+ `AGENTS.md` and a `CLAUDE.md` that is just an `@AGENTS.md` import (Claude
62
+ Code's own import syntax) plus Claude-Code-specific notes — never a second
63
+ copy of the rulebook. This is not a claim that Claude Code always reads
64
+ `AGENTS.md` on its own: that support is version- and configuration-dependent,
65
+ and the shim exists precisely for the sessions where it is not active (see
66
+ `docs/decisions/agents-md-canonical.md` for what is verified and what is
67
+ not). Provider-specific wiring (`.claude/settings.json`, `.claude/agents/`,
68
+ `.codex/hooks.json`, `.codex/config.toml`) is unaffected.
69
+
70
+ Migrating an existing rig: `upgrade` treats both files as the ordinary
71
+ manifest-tracked paths they always were, with one deliberate coupling. An
72
+ untouched pair is replaced with the new shim/canonical split. A `CLAUDE.md`
73
+ or `AGENTS.md` the user edited is reported as a conflict and kept exactly as
74
+ edited, never force-shimmed or overwritten — and if the kept CLAUDE.md is not
75
+ already the `@AGENTS.md` shim, the reason also says it **shadows AGENTS.md**
76
+ (by Claude Code's own default, a `CLAUDE.md` is read _instead of_ `AGENTS.md`,
77
+ not alongside it) and names the fix. A file the user deleted stays deleted.
78
+ **Security fix, content-based since round 5:** CLAUDE.md is held back —
79
+ kept as its old, still-readable content, never replaced with the shim —
80
+ only when the on-disk AGENTS.md genuinely cannot serve as the rulebook:
81
+ absent, or present but carrying no non-empty `elevated-paths` block. A
82
+ CUSTOMISED AGENTS.md that still carries a readable block lets the shim
83
+ through — the shim then imports the user's own rulebook, which is the whole
84
+ point of it — and AGENTS.md itself stays a perfectly ordinary, quiet
85
+ conflict, because a customised `elevated-paths` block is this project's own
86
+ designed steady state, not a broken rulebook (an earlier version of this
87
+ rule keyed on AGENTS.md's verdict alone, which could not tell the two
88
+ apart). Without the hold at all, an unreadable AGENTS.md combined with an
89
+ untouched CLAUDE.md would silently install a shim over a rulebook that may
90
+ carry no `elevated-paths` declaration at all. Holding CLAUDE.md back
91
+ re-vouches it for its own current bytes — the same mechanism that lets a
92
+ later `upgrade` resolve cleanly — which means a later `uninstall` reads it
93
+ as rig-owned and unedited and **removes it**, not "leaves it in place" the
94
+ way an ordinary, never-vouched conflict does; the decision record's
95
+ uninstall column and a dedicated test cover this.
96
+
97
+ The one always-reachable remedy for a genuinely unreadable AGENTS.md:
98
+ `upgrade` WRITES the already-rendered content to a real sibling file,
99
+ `AGENTS.md.rig-new` (never recorded in the manifest, and appearing ONLY in
100
+ the genuinely held-back state — never for an ordinary, readable conflict),
101
+ instead of printing it to stdout for a verbatim paste — measured (gate cycle
102
+ 3, round 3's own remedy) not to survive a real copy-paste byte-for-byte. Its
103
+ status (`would-write` / `identical` / `differs` / `unsafe`) is decided
104
+ entirely at plan time, so a dry run and a real run agree, and a symlink or
105
+ directory at the path is refused BEFORE anything else is written. `mv
106
+ AGENTS.md.rig-new AGENTS.md` is printed only for bytes this run wrote or
107
+ verified — for a pre-existing, differing rescue file the remedy is `rm` (or
108
+ restoring AGENTS.md some other way), never `mv`, since that file is not this
109
+ run's bytes. The instruction is the short, delimited, LAST thing the run
110
+ prints, not buried between the plan and the consent prompt. Once AGENTS.md
111
+ resolves and the rig is no longer held back, a leftover matching rescue file
112
+ is cleaned up and the run says so; unrelated clutter at the path (a stray
113
+ directory or symlink) on an otherwise healthy rig is never touched and never
114
+ mentioned. **Round 4, security disclosure:** `uninstall` removing CLAUDE.md
115
+ or AGENTS.md while the other of the pair is not a clean removal now says so,
116
+ naming which file stays and as what — a bare `- CLAUDE.md` line previously
117
+ did not. See `docs/decisions/agents-md-canonical.md`, "The remedy that
118
+ actually works", for what was measured and what did not work.
119
+
120
+ Pinned by `packages/cli/test/upgrade.test.ts`'s describe block "RP-186:
121
+ AGENTS.md becomes canonical, CLAUDE.md becomes its shim" (untouched pair,
122
+ edited/deleted each side, the shadow-note cases, the held-back cases, the
123
+ rescue-file state machine, the held-back uninstall case, and the re-derived
124
+ 4×3 pristine/edited-with-block/edited-without-block/deleted grid across both
125
+ files), `packages/cli/test/uninstall.test.ts`'s pair-disclosure and
126
+ rescue-file tests, `packages/cli/test/cli-report.test.ts`'s CLI-boundary
127
+ tests for the rescue file (an independent oracle, never `plan.contents`) and
128
+ for the quiet, customised-AGENTS.md conflict, and
129
+ `test/e2e/agents-md-migration.test.ts` (the same migration, including the
130
+ rescue-file remedy end to end and the customised-rulebook case, against a
131
+ rig built from the actual pre-RP-186 payload).
132
+
133
+ **Breaking: the application skeletons are removed, exactly as 0.9.0
134
+ announced.** `create <dir>` no longer takes `--target` and no longer
135
+ scaffolds `aws-serverless` or `node-service` — there is one payload, the same
136
+ one `init` installs, and `create` is now a thin wrapper: `mkdir` → `git init`
137
+ → that install → the pristine baseline commit. The product is a package
138
+ manager for repository-scoped Claude Code and Codex configuration, never an
139
+ application generator (owner ruling, 2026-09-13). The universal layer's
140
+ create-only "architecture group" (`.claude/rules/architecture.md`,
141
+ `guard-core-purity`, `guard-web-boundary`, and the monorepo-shaped
142
+ `CLAUDE.md`/`AGENTS.md` map) is retired along with it — it was an
143
+ application-shape promise a harness configurator has no business making.
144
+ `templates/agent-os/stack/*` (the node-ts and aws-cdk overlays) and
145
+ `templates/agent-os/init/*` (the override layer `init` used to shadow
146
+ `universal` with) are deleted; the init flavour's map and process-only scope
147
+ _is_ the universal layer now.
148
+
149
+ Migration for a repository this tool already generated: nothing breaks.
150
+ `upgrade` still recognises your rig, still refreshes the files it installed
151
+ and you did not touch, and still leaves your application code alone — it was
152
+ never part of any install set, before or after this release. A path from a
153
+ retired layer (an aws-cdk or node-ts rule, an architecture hook) gets a new
154
+ verdict, `retired`: never written, never deleted, dropped from the manifest,
155
+ and reported as no longer shipped — it is yours now. `upgrade`'s `--dry-run`
156
+ output and its summary line both show a `retired` count when there is one.
157
+ The full pre-0.10 migration path is pinned in `test/e2e/upgrade.test.ts` ›
158
+ "retires the deleted stack overlay, and preserves the application and the
159
+ process layer".
160
+
161
+ **Fixed: Codex rejected the `SessionStart` rules refresh.** `inject-rules`
162
+ printed plain text opening with `[agent-os]`, and Codex 0.154.0 was measured
163
+ failing the hook with `hook returned invalid session start JSON output`, so
164
+ that session started without the autonomy rules. The hook now prints one JSON object —
165
+ `hookSpecificOutput.additionalContext`, the shape both harnesses document —
166
+ carrying the same text, character for character, that Claude Code received
167
+ before. It also waits for that write to finish instead of exiting over it,
168
+ and a stdout failure other than an abandoned reader is reported on stderr
169
+ with a non-zero exit rather than looking like a healthy session
170
+ (`docs/decisions/session-start-wire-format.md`). That decision record now
171
+ ships with the hook that cites it — the process layer's manifest
172
+ (`layers.json`) had omitted it, so a generated rig received the hook's
173
+ citation but not the file it pointed at.
174
+
175
+ **Breaking: the workflow layer (queue/loop/pr-ship/run-state/journal/
176
+ revalidation/claim-records/PR-lifecycle helpers) is now an experimental,
177
+ opt-in install (RP-180).** A default `init`/`create` installs Lean Core only
178
+ — rules, gates, stop rules, the review-gate agents and their hooks — and
179
+ never the autonomous, cooperative multi-session machinery on top of it. Pass
180
+ `--layer workflow` to `init` or to `create-agent-rig <dir>` to install it too;
181
+ a rig that already has it keeps it on a plain re-run of `init` with no flag.
182
+ `RigManifest` gains a `layers` field recording the choice, and `upgrade`
183
+ refreshes only the layer(s) a rig recorded. Migration for an existing rig:
184
+ nothing breaks and nothing is deleted — a manifest written before this field
185
+ existed carries no `layers` key, and that absence is read as "every layer,"
186
+ exactly what every release before this one installed, so `upgrade` keeps
187
+ managing the workflow files a rig already has. Revalidation and claim-records
188
+ keep their existing behavior unchanged (RP-53's freeze through the RP-26 gate
189
+ on 2026-10-27) — this release only relocates their install-time layer.
190
+ `uninstall` (RP-181) needs no layer awareness of its own: it walks
191
+ `manifest.files` and `manifest.kept` directly, and those two records already
192
+ reflect exactly what a given install wrote, by construction — a Core-only
193
+ rig's manifest simply has no workflow-layer entries in `files` for
194
+ `uninstall` to find, and an inherited pre-0.10 rig's workflow files are
195
+ recorded in `files` exactly as every other installed path is (its manifest
196
+ carries no `layers` key, read as "every layer" the same way `upgrade` reads
197
+ it), so `uninstall` removes them under the same byte-hash check as anything
198
+ else it owns. Nothing about the layer split widens or narrows what
199
+ `uninstall` was already willing to remove.
200
+
201
+ **This repository's own node-ts conventions move out of the shipped
202
+ package**, into `scripts/dogfood/` — a repo-local overlay `sync-agent-os.mjs`
203
+ composes into this repository's own rulebook, same as before, just no longer
204
+ a template any generated rig receives.
205
+
206
+ ### Added
207
+
208
+ - **Setup MCP ownership (RP-22)** uses one schema-v1
209
+ `.rig/integrations.json` for intent and Claude entry hashes. The
210
+ `list | add | apply | remove` commands replace the intermediate receipt
211
+ and `setup verify` surface. See `docs/command-contract.md`,
212
+ "setup integrations", and the command-level regressions in
213
+ `packages/cli/test/integrations-intent.test.ts`. The published
214
+ `setup --memory-root` interface remains compatible.
215
+ - **`uninstall [dir] [--dry-run] [--yes] [--json]`** removes what a rig
216
+ installed, file by file, against the evidence `.claude/.rig-manifest.json`
217
+ carries and nothing else: a path is removed only when its bytes on disk
218
+ still match the recorded hash exactly (compared as raw bytes, never a
219
+ UTF-8-decoded string — ADR-RP-003), the path is a plain file the whole way
220
+ down from the repository root (never a symlinked ancestor or a symlink
221
+ itself), and the path is itself one of the EXACT paths this release
222
+ actually installs — a boundary drawn at a top-level directory would let a
223
+ manifest pair almost any path under `.claude/`, `.rig/`, `docs/` or
224
+ `journal/` with its true hash and have it removed. Anything under `.git` is
225
+ refused outright, for the whole run, for any segment that NORMALISES to
226
+ `.git` (case folded, a Windows alternate-data-stream suffix stripped,
227
+ trailing dots and spaces stripped) at any depth — not only a literal
228
+ top-level `.git` — regardless of the hash a manifest pairs it with; the same
229
+ refusal covers a manifest that lists one path under both `files` and
230
+ `kept`, which this tool's own writer never produces. An edited,
231
+ already-deleted, foreign, `init`-kept, or otherwise unrecognised file is
232
+ reported and left in place, and so is modified hook wiring
233
+ (`.claude/settings.json`, `.codex/hooks.json`), which names the hooks still
234
+ referenced — and so is a hook file such wiring still calls, even when that
235
+ hook file's own bytes are pristine, naming the wiring file that holds it, so
236
+ a kept settings file is never left pointing at a hook `uninstall` just
237
+ deleted. The manifest itself is read, and later removed, through the same
238
+ symlink-safe per-segment check every other manifest-owned path gets, never
239
+ a plain lexical one. It prints the plan, then asks before removing anything
240
+ — `--yes` up front, a prompt on a terminal, an outright refusal off one, and
241
+ always required with `--json`, which never prompts, never deletes
242
+ unattended, and reports an unplanned filesystem error (not only its own
243
+ refusals) as the same one JSON object rather than a bare stack trace. The
244
+ manifest is deleted last, and only once nothing was preserved: a CRLF
245
+ checkout, an edit, or any other conflict keeps the manifest even after
246
+ every removal that WAS planned succeeded, because the rig still owns bytes
247
+ it did not remove and the manifest is the only record naming them. A run
248
+ interrupted partway also keeps it and reports what finished and what a
249
+ re-run still owes — including the manifest itself, whenever a clean re-run
250
+ really would go on to delete it — so a repeat run is safe, and a repeat run
251
+ that finds no manifest at all is a no-op, exit 0. `.rig/` itself is never
252
+ removed, empty or not; the one manifest-owned file the rig installs
253
+ directly inside it is removed like any other file when it is pristine.
254
+ `--json` prints one JSON object and nothing else on stdout — `removed` is
255
+ always what was actually deleted, and `planned` carries the plan's own
256
+ answer regardless of outcome — documented next to the other command
257
+ contracts in `docs/command-contract.md` ("## uninstall (RP-181)"). A
258
+ successful removal names its own next step (`git add -A` and a commit) —
259
+ `uninstall` never touches git history itself. Selected MCP wiring and
260
+ delegated Spec Kit removal have their own lifecycle, `setup remove`;
261
+ `uninstall` touches only files the Rig manifest names (RP-181).
262
+ - **`uninstall` re-verifies bytes twice more, and gains `--detach`.** A plan
263
+ can go stale in the window a confirmation prompt sits in: each `remove`
264
+ action now carries the plan's own recorded hash, re-read and compared
265
+ immediately before that one file's removal — a mismatch skips that file
266
+ (reported `preserved`, reason "changed since planning"), never aborts the
267
+ run, and never deletes it. The manifest's own bytes are checked the same
268
+ way at two points: once before the first removal (a mismatch refuses the
269
+ whole apply, nothing removed) and once immediately before the manifest's
270
+ own deletion (a mismatch keeps the manifest and reports an honest partial
271
+ result — what finished, and that the manifest is what a re-run still owes).
272
+ `--json`'s payload now names which of three outcomes a completed,
273
+ non-dry-run reached — `uninstalled`, `partial`, `detached`; a `--dry-run`
274
+ preview names none of them, since it has no end state to name — and folds
275
+ any
276
+ changed-since-planning path into `preserved` rather than a separate,
277
+ easy-to-miss list. **`--detach`** performs the identical safe cleanup and
278
+ then removes the manifest anyway, leaving every preserved (or
279
+ changed-since-planning) path for the user and printing the complete
280
+ handover list — it never forces away a conflicting or modified file, and
281
+ there is no `--force`. A hook file a wiring file still calls survives even
282
+ when that protection is only discoverable at apply time — a symlinked
283
+ wiring file (whose referenced hooks cannot be safely read, so every owned
284
+ hook is protected instead of a guessed subset) or one edited inside the
285
+ confirmation-prompt window, re-checked immediately before the first hook
286
+ removal, since hook files sort ahead of the wiring that references them.
287
+ **Protection also now follows a hook's own imports to a fixed point**: a
288
+ wired hook is not self-contained (`guard-bash.mjs` imports
289
+ `.claude/hooks/lib/hook-input.mjs`, `.claude/scripts/stop-flag.mjs`,
290
+ `.claude/scripts/lib/shell-tools.mjs`, …), and protecting only the
291
+ directly-named hook while deleting what it imports left every one of
292
+ those dying at module resolution with exit 1 — silently inert, since a
293
+ `PreToolUse` hook that exits non-2 is non-blocking. Every REAL read this
294
+ walk performs is gated by the same symlink-safe check every other read in
295
+ this command gets, not the purely lexical containment alone: a hook file
296
+ swapped for a symlink to an unbounded or blocking special file — reachable
297
+ from nothing worse than `git clone`ing a hostile branch, before consent —
298
+ no longer makes the walk's own read hang or exhaust the heap; the file
299
+ stays protected regardless, since that is recorded before the read is
300
+ attempted. A `kept` wiring file (a pre-existing `.claude/settings.json`
301
+ `init` never took ownership of — the ordinary "starts from an existing
302
+ repository" path) now protects its hooks too: it used to protect NONE of
303
+ them, silently, because the pass that decides this read only `files`'
304
+ hashes and a `kept` path has none. **The reason a protected hook reports
305
+ now names WHY its wiring file survives, not only THAT it does** — a `kept`
306
+ wiring file's hook used to say "which was preserved as edited" too, which
307
+ is false (nobody edited it; the rig never wrote it), and told a
308
+ contradictory story two lines apart from `.claude/settings.json`'s own
309
+ "user-owned (kept by init)" verdict in the same report. It now reads
310
+ "which init found already in place and never took ownership of"; a hook
311
+ whose wiring file could not be safely read at all (itself a symlink) now
312
+ says so ("which could not be safely read…") instead of "edited" too. A
313
+ file reached only through another protected file's own import, rather
314
+ than named by the wiring file directly, now gets its own reason wording
315
+ naming the immediate importer, since the wiring file itself may never
316
+ mention it at all. **A hook file that cannot itself be safely read (a
317
+ symlink) now protects the conservative superset of every owned `.mjs`
318
+ path, not only itself.** Two dependencies in the shipped tree have exactly
319
+ ONE hook that imports them — `.claude/scripts/lib/secrets.mjs` (only
320
+ `guard-secret-file.mjs`) and `.claude/scripts/unattended-flag.mjs` (only
321
+ `guard-rulebook.mjs`) — so symlinking that one seeder used to drop the
322
+ dependency's protection entirely: measured end to end through a real
323
+ `git commit` and a fresh `git clone`, the credential guard went from
324
+ blocking a credential write (exit 2) to dying at module resolution (exit 1,
325
+ non-blocking for `PreToolUse`) once its own import was gone, wiring still
326
+ in place and still claiming to enforce it. **The sweep that protects a
327
+ dependency it could not trace now says so, instead of claiming it as a
328
+ confirmed reference.** Reusing the "still referenced by … which was
329
+ preserved as edited" wording for a swept-in path made the sentence that
330
+ sounds most certain describe the files the command was least sure about:
331
+ in one reproduced run, of 84 owned paths under one preserved wiring file,
332
+ only ~7 were genuinely referenced by it, and ~30 were swept in by caution
333
+ alone — including a test fixture no hook could ever import — all reported
334
+ with the identical, fully-confident wording. A fifth reason string now
335
+ names the file whose own unreadability triggered the sweep instead
336
+ ("protected because `<file>` could not be read…"), and the plain-text
337
+ summary adds a one-line roll-up — how many `preserved` paths were
338
+ genuinely traced versus kept only as a precaution — once any are.
339
+ Which wording a hook gets does not depend on where the unreadable file
340
+ sits in the wiring file's own order: a hook the wiring names, or one a
341
+ readable file imports, is reported as referenced or imported whether the
342
+ precaution sweep ran before or after the command reached it. The sweep
343
+ itself is also
344
+ now narrower: it fires on a file that could not be SAFELY READ, never on one that is simply gone. Sweeping on absence bought
345
+ nothing (an absent file has no imports that can fail to resolve, because
346
+ the module that would make them is itself gone) and cost a real one: an
347
+ ordinary "I turned this hook off by hand" deletion, with the wiring still
348
+ naming it, used to turn 83 planned removals into 40 planned / 43
349
+ preserved on a repository that had done nothing hostile at all. Two other
350
+ apply-time-only fixes in the same area: the removal loop now re-reads a
351
+ wiring file's bytes fresh, immediately before that file's own removal,
352
+ instead of reusing a copy `protectedHooksFor` read before the loop even
353
+ started (an edit landing in that window was previously missed); and a
354
+ filesystem error surfacing from the new apply-time hook-protection re-check
355
+ itself is now caught the same way `planUninstall`'s own errors are, so
356
+ `--json` still gets its one promised object rather than a bare stack trace.
357
+ A manifest key with more path segments than any real path this release ever
358
+ installs no longer reaches the native path-join call that segment count
359
+ could otherwise overflow — reported the same honest, per-path `preserved`
360
+ way any other unowned path is (deeper than any path this release could ever
361
+ own), rather than aborting the whole run, `--dry-run` included, through a
362
+ message that used to claim the path "resolves outside" the repository,
363
+ which was simply false for one that never left it lexically at all; the
364
+ genuine `..`/absolute escape check is unweakened and still aborts the whole
365
+ run exactly as before.
366
+ Every ancestor check now makes two independent tests per segment, not one:
367
+ the existing symlink/type classification, and a separate `realpath`
368
+ containment check that does not read that classification at all — the
369
+ second is what makes the containment guarantee hold for a Windows
370
+ directory junction (or any future reparse-point kind) by construction,
371
+ rather than resting on `isSymbolicLink()` reporting it correctly, which is
372
+ the one part of this that a Windows-only test in the `windows-e2e` lane
373
+ (`packages/cli/test/uninstall.test.ts`, gated by `onlyOnWindows`) actually
374
+ measures — this repository's own development environment cannot build a
375
+ junction to verify it directly. Also: a manifest segment with a very long
376
+ run of trailing dots or spaces no longer costs quadratic time to
377
+ normalise (a hostile committed manifest could otherwise hang
378
+ `uninstall --dry-run`); `rigOwnedPaths` reads the bare install-manifest
379
+ list rather than rendering every template's content just to learn which
380
+ paths exist.
381
+
382
+ ### Generator (not a rig-facing change)
383
+
384
+ **Generator-only (RP-178): nothing a newly scaffolded project receives changes.**
385
+ No file under `templates/` moved. This entry records what changed inside the
386
+ generator's own repository, ahead of 0.10.0.
387
+
388
+ - **The speculative policy-declaration library and its benchmark are gone.**
389
+ `packages/cli/src/policy/` (a declaration schema, registry, decision-record
390
+ format and per-harness adapters, RP-36/RP-76) and
391
+ `scripts/policy-benchmark*.mjs` (the child-process benchmark that measured
392
+ it) shipped nothing a CLI command, an installed hook, or the sync scripts
393
+ ever called — its own module header said so. Removed as dead code, along
394
+ with `contracts/session-messaging/` (its sole remaining consumer) and the
395
+ vitest `benchmark` project. RP-157, RP-160 and RP-161 are closed by
396
+ deletion rather than by fix, since all three findings were against this
397
+ unreachable surface; the consumer graph behind each deletion is on pull
398
+ request #227.
399
+ - **`docs/compatibility.md`** replaces the removed framework's claim to be a
400
+ compatibility check: a Claude Code × Codex × capability matrix — every
401
+ wired hook, the Windows command strings, skills/agents delivery, and the
402
+ optional external-subsystem contract — with one status vocabulary for the
403
+ matrix (SUPPORTED, DEGRADED, UNSUPPORTED, NOT-APPLICABLE, UNVERIFIED).
404
+ `test/template/compatibility-matrix.test.ts` refuses a status outside it,
405
+ a measured status without a test pointer, and a pointer whose test file is
406
+ gone or no longer contains the quoted test name. Windows is stated as
407
+ measured: the Claude Code wiring and most Codex `commandWindows` scripts
408
+ are UNVERIFIED there.
409
+ - **`test/template/guard-acceptance.test.ts`** invokes the retained
410
+ `PreToolUse` guards through the real `.claude/settings.json` /
411
+ `.codex/hooks.json` wiring strings on POSIX, with one allowed and one
412
+ denied fixture per guard for each harness that wires it, in the payload
413
+ shape that harness sends (Codex edits arrive as `apply_patch`); the denied
414
+ one must exit exactly 2 and name its reason. It is the wiring a generated
415
+ project actually runs, not a parallel path. The guard list is derived from
416
+ the two wiring files, so a newly wired guard with no fixture and no
417
+ reasoned exception fails the suite, and so does one without a
418
+ `docs/compatibility.md` row. `guard-subagent-model` is Claude-only and
419
+ runs through the Claude Code wiring alone.
420
+ - **Meta-tests that pinned shape instead of behaviour were removed or cut
421
+ down to the assertion that survives review as real**, each with its own
422
+ reason recorded in the pull request: a citation count nothing rereads
423
+ (RP-82, `generator-neutrality.test.ts`), an exact skip-site count that
424
+ named the deleted benchmark files, and the project-count/ordering
425
+ assertions that named the deleted `benchmark` vitest project.
426
+ - **RP-110: the CI spawn-baseline diagnostic is removed** from the
427
+ `windows-smoke` job. It measured bare `node` startup, which stayed flat
428
+ across a red run and its green rerun while their wall clocks differed by
429
+ roughly half, so it read "healthy" on the run it was built to diagnose — a
430
+ diagnostic that argues against the correct conclusion is worse than none.
431
+ No replacement baseline was added, per the ticket's own accepted
432
+ resolution.
433
+
434
+ ## 0.9.1
435
+
436
+ **A patch, numbered by the owner.** Every entry corrects existing behaviour;
437
+ two of them (RP-182, RP-59) do it by recording or reporting something new.
438
+ Nothing is added to what `create`, `init` or `upgrade` install beyond the
439
+ corrected files, the contract version stays `1.0`, and the application
440
+ skeletons remain deprecated and scheduled for removal in 0.10.0 exactly as
441
+ 0.9.0 announced.
442
+
443
+ ### Fixed
444
+
445
+ - **`init` records the files it kept.** When `init` finds a payload path
446
+ already present and leaves it alone, the manifest now records that file's
447
+ hash under `kept`, so a later `upgrade` can say whether the file is
448
+ unchanged or edited since `init` found it instead of reporting it with no
449
+ history (RP-182). A manifest with nothing kept is written exactly as
450
+ before.
451
+ - **`memory load` passes Memory a deadline of its own.** A `load` that names
452
+ no `--timeout-ms` gets `--timeout-ms 45000` appended, below the rig's 60 s
453
+ kill. A well-formed `--timeout-ms <value>` pair raises that kill to the
454
+ value plus 15 s when that is above 60 s, capped at Node's timer limit of
455
+ 2 147 483 647 ms; any other spelling passes through unchanged. `doctor`'s
456
+ arguments are untouched. The README example adds `--cwd .`, which the Memory
457
+ owner names as part of Memory's own contract (RP-183).
458
+ - **`reconcile-external-prs.mjs` works on a `gh` that does not serve
459
+ `authorAssociation`** from `gh pr list`: the association is fetched
460
+ separately and kept only when it answers for the same pull request, and a
461
+ failed lookup leaves those pull requests untrusted rather than failing the
462
+ sweep. A failure now names the one cause the evidence shows, with terminal
463
+ control sequences and credential shapes removed from the detail (RP-99).
464
+ - **The queue reports a Blocks link the ticket body says was removed but the
465
+ tracker still carries** — a body line of the form
466
+ `The Blocks link A -> B is removed` — as a `link-contradicted-by-body`
467
+ hygiene finding (RP-59).
468
+ - **A Jira triage proposal with a long `change` is filed, not refused by the
469
+ tracker.** Jira rejects a summary over 255 characters; the summary is now
470
+ cut to fit and the full text stays in the description (RP-121).
471
+
472
+ ### Generator CI (not a rig-facing change)
473
+
474
+ Test-fixture cleanup goes through one bounded-retry helper, and an audit holds
475
+ every other recursive removal and every in-repository fixture to a written
476
+ reason. The four child-process time bounds are measured inside the child, and
477
+ the package-manager CLI-start cases carry their own measured budget. The e2e
478
+ installs run in a vitest group of their own, so they no longer compete with
479
+ the template tests on the Windows full-suite runner (RP-158).
480
+
17
481
  ## 0.9.0
18
482
 
19
483
  **The harness ↔ Memory boundary is executable, and the rig is a consumer of
@@ -103,9 +567,8 @@ and the two template checks on Linux and `windows-smoke` (the CLI's unit
103
567
  project) on Windows; in `e2e.yml`, the Linux `e2e` job — the full suite with
104
568
  the e2e installs and the benchmark — when the pull request touches the CLI,
105
569
  the templates, the e2e harness or that workflow. The full suite on Windows
106
- runs in `e2e.yml` on master, nightly and by dispatch only, and a
107
- `runner_mode` switch there selects a self-hosted fallback that no pull
108
- request can reach (`docs/runners.md`).
570
+ runs in `e2e.yml` on master, nightly and by dispatch only
571
+ (`docs/runners.md`).
109
572
 
110
573
  ## 0.8.0
111
574