riskrails 3.0.0 → 3.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/README.md +246 -812
- package/agents/ai-reviewer.md.tmpl +6 -4
- package/ai/policies/review-economy.md +7 -2
- package/ai/using-riskrails.md +15 -0
- package/bin/claude-1m +15 -14
- package/bin/riskrails.js +108 -32
- package/codex/hooks.json +25 -2
- package/hooks/AGENTS.md +2 -2
- package/hooks/CLAUDE.md +2 -2
- package/hooks/ai-guard.py +29 -8
- package/hooks/ai-path-guard-defaults.json +3 -1
- package/hooks/codex-hooks.json +25 -2
- package/hooks/context-guard.py +251 -35
- package/hooks/dialog-gate.py +105 -0
- package/hooks/guard/common.py +5 -0
- package/hooks/guard/decision.py +123 -0
- package/hooks/guard/dialog.py +598 -0
- package/hooks/guard/git.py +49 -3
- package/hooks/guard/paths.py +62 -3
- package/hooks/hooks.json +37 -2
- package/hooks/memory-pre-push.py +28 -0
- package/hooks/runtime-gate.py +59 -12
- package/hooks/update_notice.py +135 -0
- package/instructions/routing.md +4 -4
- package/instructions/stub.md +2 -2
- package/package.json +1 -1
- package/profiles/max.json +3 -1
- package/profiles/pro.json +3 -1
- package/scripts/merge-codex-config.py +134 -0
- package/scripts/resolve-profile.py +15 -3
- package/settings.common.json +39 -2
- package/skills/AGENTS.md +2 -2
- package/skills/CLAUDE.md +2 -2
- package/skills/ai-init/templates/.ai/AGENTS.md +2 -2
- package/skills/ai-init/templates/.ai/VERSION +1 -1
- package/skills/ai-init/templates/.ai/policies/dialog.json +1 -0
- package/skills/ai-init/templates/.ai/policies/safety.md +22 -2
- package/skills/ai-init/templates/.ai/policies/weight.json +1 -0
- package/skills/ai-init/templates/.ai/policies/weight.md +2 -2
- package/skills/ai-init/templates/.ai/state/README.md +9 -6
- package/skills/ai-init/templates/AGENTS.block.md +1 -1
- package/skills/ai-init/templates/CLAUDE.block.md +1 -1
- package/skills/ai-init/templates/GEMINI.block.md +1 -1
- package/skills/ai-init/templates/junie-guidelines.block.md +1 -1
- package/skills/ai-task/memory_compact.py +968 -0
- package/skills/ai-task/memory_format.py +775 -0
- package/skills/ai-task/memory_store.py +528 -0
- package/skills/ai-task/memory_sync.py +1571 -0
- package/skills/ai-task/sensors.py +2 -2
- package/skills/ai-task/state.py +967 -70
- package/skills/ai-task/weight.py +3 -3
- package/skills/project-init/templates/constitution.md +1 -1
- package/skills/project-update/history/blobs/164cd34c182de88c33de7df35beb29200d792419e1c13a5f0b2104f944e57be7 +1 -0
- package/skills/project-update/history/blobs/1d1d907449ec74594d0ee923ac142ae746b9aedf0a1eda9469f075a44d23e3d7 +13 -0
- package/skills/project-update/history/blobs/23a42febbacaa7b52a802d428033a99c0694391c81d51fe3b6e1dff608a641d5 +67 -0
- package/skills/project-update/history/blobs/5353ca529c46f2443e12947ec205a6887fb594a4de1f87f0eb1c0e6c0f826133 +49 -0
- package/skills/project-update/history/blobs/5f65bc7ab3fc3c4e75ae05d49eaf4331fafc398c661abe33c69f7380a720344c +32 -0
- package/skills/project-update/history/blobs/7be527cd648b27cca6e267de30f8e33a2ce17d5631a82694f23ae5c0623efe1f +15 -0
- package/skills/project-update/history/blobs/7ee99edafe7cec45ff577376c0d0178fdb2690134d4656488f46e129aba3cc5a +67 -0
- package/skills/project-update/history/blobs/8b3ef9586491a426767c01da5d01bdd6b0655c576c68c4cc6dfb093367817dc0 +67 -0
- package/skills/project-update/history/blobs/917df3320d778ddbaa5c5c7742bc4046bf803c36ed2b050f30844ed206783469 +1 -0
- package/skills/project-update/history/blobs/935af1019931058ec3a0b834fe230e127ec914f75edcc4a6c589cfe733b0b979 +13 -0
- package/skills/project-update/history/blobs/ae5ce131d6bae401199ff32d8c3dc4d8aec188010a9111624ac64506e2116ff4 +84 -0
- package/skills/project-update/history/blobs/ca4499d829268c8766fb3b825a515e88dc55c237e9d202816b50959b4dac031f +13 -0
- package/skills/project-update/history/blobs/e9adb7a9905eb719ac78ab96671f055da53e5001810f5ad6d6c94306b0323fe7 +74 -0
- package/skills/project-update/history/blobs/fae3064e648cdc55be4aeb1177525b302a5e34ebd752e4a904f47dc0f4557b96 +71 -0
- package/skills/project-update/history/index.json +32 -13
- package/skills/project-update/migrations/0009_state_file.py +25 -0
- package/skills/project-update/migrations/0010_dialog_switch.py +30 -0
- package/skills/project-update/migrations/README.md +2 -1
- package/skills/project-update/update.py +12 -3
- package/skills/rr-build/SKILL.md +14 -5
- package/skills/rr-build-all/SKILL.md +190 -0
- package/skills/rr-plan/SKILL.md +13 -3
- package/skills/rr-review/SKILL.md +18 -8
- package/skills/rr-ship/SKILL.md +16 -8
- package/skills/rr-status/SKILL.md +2 -2
- package/skills/usage-report/usage-report.py +41 -8
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"31bb922076c8dadb4a84bb6a03d331dafc7157893aaf2f92b13792270fbece9b",
|
|
10
10
|
"a13cb0db5372c3ce3e71470165c17a2db76e7a2415717ba27fccd1b0593c61c4",
|
|
11
11
|
"54eefe3d8cd6cd1ed56764e7bd412a4c919a28fc64b56b69dcafeecd7a921678",
|
|
12
|
-
"fe513647c66e8883b326ea884a7e9cb045ce54c49b03d2e75a0b73c4756c423e"
|
|
12
|
+
"fe513647c66e8883b326ea884a7e9cb045ce54c49b03d2e75a0b73c4756c423e",
|
|
13
|
+
"8b3ef9586491a426767c01da5d01bdd6b0655c576c68c4cc6dfb093367817dc0"
|
|
13
14
|
],
|
|
14
15
|
"ai-init/.ai/VERSION": [
|
|
15
16
|
"4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865",
|
|
@@ -19,7 +20,8 @@
|
|
|
19
20
|
"f0b5c2c2211c8d67ed15e75e656c7862d086e9245420892a7de62cd9ec582a06",
|
|
20
21
|
"06e9d52c1720fca412803e3b07c4b228ff113e303f4c7ab94665319d832bbfb7",
|
|
21
22
|
"10159baf262b43a92d95db59dae1f72c645127301661e0a3ce4e38b295a97c58",
|
|
22
|
-
"aa67a169b0bba217aa0aa88a65346920c84c42447c36ba5f7ea65f422c1fe5d8"
|
|
23
|
+
"aa67a169b0bba217aa0aa88a65346920c84c42447c36ba5f7ea65f422c1fe5d8",
|
|
24
|
+
"917df3320d778ddbaa5c5c7742bc4046bf803c36ed2b050f30844ed206783469"
|
|
23
25
|
],
|
|
24
26
|
"ai-init/.ai/agents/context.md": [
|
|
25
27
|
"a213099429aff491b00e885c8d556465be2405072efbb9a3a297890a15a5b4ca",
|
|
@@ -87,6 +89,9 @@
|
|
|
87
89
|
"ai-init/.ai/policies/database.md": [
|
|
88
90
|
"894a37936b769203bbb880ff842cc0a04e62d53e01deb07af83179f6b1359cf4"
|
|
89
91
|
],
|
|
92
|
+
"ai-init/.ai/policies/dialog.json": [
|
|
93
|
+
"164cd34c182de88c33de7df35beb29200d792419e1c13a5f0b2104f944e57be7"
|
|
94
|
+
],
|
|
90
95
|
"ai-init/.ai/policies/git.md": [
|
|
91
96
|
"6bbcb8ea55726cdd49e0544725d224ac6d728cd1db757a269399342da92677ca"
|
|
92
97
|
],
|
|
@@ -119,7 +124,8 @@
|
|
|
119
124
|
"9984ac1e1b1edb7217df58e256002ae09913fdc598da6f7773f1c01e5a3e55e2",
|
|
120
125
|
"c392fd585241389355958099a95bd85358a80d9a10310301a430219f83c8962e",
|
|
121
126
|
"edecd502e22395300781a3c653b56c3587b1b894ce4b96f60e19c601a5cdae46",
|
|
122
|
-
"91e924527f51c8c36fa1156a8f30af4c07adab2d324b8c5a879145a1641c413a"
|
|
127
|
+
"91e924527f51c8c36fa1156a8f30af4c07adab2d324b8c5a879145a1641c413a",
|
|
128
|
+
"6a3f34706c31fc91fdace8ea8729bd7a74065f983032204f5aad3ec80cf13ce0"
|
|
123
129
|
],
|
|
124
130
|
"ai-init/.ai/policies/risk-tiers.json": [
|
|
125
131
|
"01c32f8ff038787e49070b8b0eb160eb4b4704a020b050678292051fc73a4fc6",
|
|
@@ -154,7 +160,10 @@
|
|
|
154
160
|
],
|
|
155
161
|
"ai-init/.ai/policies/safety.md": [
|
|
156
162
|
"0f00cbb216a20c7f67749ffb88835bcaaa29cc1a4c15d468edb3c6039bd291d3",
|
|
157
|
-
"ae9a22907ba9acbb7e80fac1ba4e3d1ff09e5f1df5c4456afb9099d7090fcaa6"
|
|
163
|
+
"ae9a22907ba9acbb7e80fac1ba4e3d1ff09e5f1df5c4456afb9099d7090fcaa6",
|
|
164
|
+
"fae3064e648cdc55be4aeb1177525b302a5e34ebd752e4a904f47dc0f4557b96",
|
|
165
|
+
"e9adb7a9905eb719ac78ab96671f055da53e5001810f5ad6d6c94306b0323fe7",
|
|
166
|
+
"ae5ce131d6bae401199ff32d8c3dc4d8aec188010a9111624ac64506e2116ff4"
|
|
158
167
|
],
|
|
159
168
|
"ai-init/.ai/policies/security.md": [
|
|
160
169
|
"cc808d5b940109f1703abfb3ca0334a3fcfd34267feefb2323627d0decc8b89a",
|
|
@@ -175,10 +184,12 @@
|
|
|
175
184
|
"2c6afb3518714d35eaf0119bf2ae2154782bbece632dfdbd68988351abde61f5"
|
|
176
185
|
],
|
|
177
186
|
"ai-init/.ai/policies/weight.json": [
|
|
178
|
-
"7f3859c34035fe32abf937eebdd7240ac72ab32d254286cff7d939cf0cf6eaef"
|
|
187
|
+
"7f3859c34035fe32abf937eebdd7240ac72ab32d254286cff7d939cf0cf6eaef",
|
|
188
|
+
"5353ca529c46f2443e12947ec205a6887fb594a4de1f87f0eb1c0e6c0f826133"
|
|
179
189
|
],
|
|
180
190
|
"ai-init/.ai/policies/weight.md": [
|
|
181
|
-
"e639e99d3f59015dc21472de081ca7766231135399ac3a6f439e841e458251f4"
|
|
191
|
+
"e639e99d3f59015dc21472de081ca7766231135399ac3a6f439e841e458251f4",
|
|
192
|
+
"5f65bc7ab3fc3c4e75ae05d49eaf4331fafc398c661abe33c69f7380a720344c"
|
|
182
193
|
],
|
|
183
194
|
"ai-init/.ai/project/architecture.md": [
|
|
184
195
|
"5cbaaabe2c8d0e24582877aab05eeaaf4d53cb5e9515e81cd18368d13d2fe79e"
|
|
@@ -222,7 +233,9 @@
|
|
|
222
233
|
"962fd396da83337c3fadcc642d45e98429b18e79bb81f58915baaf2b9bffd3c5",
|
|
223
234
|
"d7b96902bf9d2078df1e09901327b02f565b174777af34a2b24be660cad81d01",
|
|
224
235
|
"ad4c4f81855725f7fe6e0e3d8f557df0de5fc063465d428546f69c54020c69d9",
|
|
225
|
-
"19b1a6390e96136619d23bc2ef9afed8f15e62107de7c1052bc5ea23e5bb5692"
|
|
236
|
+
"19b1a6390e96136619d23bc2ef9afed8f15e62107de7c1052bc5ea23e5bb5692",
|
|
237
|
+
"23a42febbacaa7b52a802d428033a99c0694391c81d51fe3b6e1dff608a641d5",
|
|
238
|
+
"7ee99edafe7cec45ff577376c0d0178fdb2690134d4656488f46e129aba3cc5a"
|
|
226
239
|
],
|
|
227
240
|
"ai-init/.ai/templates/architecture-decision.md": [
|
|
228
241
|
"78619b522826ba8f5f0422e9deb7359c8002553d1aeb29a3719da5ab11ff13a1"
|
|
@@ -246,7 +259,8 @@
|
|
|
246
259
|
"515df0eab178b5f53b50f95bec2671e861efef35b487a6e65d80e80de42c4d0d"
|
|
247
260
|
],
|
|
248
261
|
"ai-init/.ai/using-riskrails.md": [
|
|
249
|
-
"03282999978b2bfb5f65135e1884f9447f8a71021a88895d5436d377797b9acb"
|
|
262
|
+
"03282999978b2bfb5f65135e1884f9447f8a71021a88895d5436d377797b9acb",
|
|
263
|
+
"25d08ff01a4ab2069b0dd4e5ec52e888d33e00091dc467dd10d63f10223b6f80"
|
|
250
264
|
],
|
|
251
265
|
"ai-init/.ai/workflows.md": [
|
|
252
266
|
"500d93714106b1c4e21b13f248f7175c86073a9bcb6e0a849845f61f49b5a66d"
|
|
@@ -310,7 +324,8 @@
|
|
|
310
324
|
"815d78ce95d18454cf0842335f81755bf3aceb87ee9d2197e121d3ff734cd2b5",
|
|
311
325
|
"de0685f9bc2ac22c1b0178d6a1fc8d07fa23451f29d0c36571cbf85c69716fc2",
|
|
312
326
|
"c735911eb1a744f78213a9f7577b425c1605843f6d05fed798d7f41b47fa1e0c",
|
|
313
|
-
"7eee4ea9f6e778ff691c263621e717c021505b86386034cc64f8ebbfc9d8fe65"
|
|
327
|
+
"7eee4ea9f6e778ff691c263621e717c021505b86386034cc64f8ebbfc9d8fe65",
|
|
328
|
+
"ca4499d829268c8766fb3b825a515e88dc55c237e9d202816b50959b4dac031f"
|
|
314
329
|
],
|
|
315
330
|
"ai-init/AGENTS.minimal.md": [
|
|
316
331
|
"b7b697fc987617449ba10634f12f70326281cc182f8b7f20f9e047a75f3f182b",
|
|
@@ -324,7 +339,8 @@
|
|
|
324
339
|
"3775eed295a794dda73b14f88af70bc2c99b5590f81da53f165423e4337dceed",
|
|
325
340
|
"ee7c8321fff228d967c5d200c316967195d93a26196383f57f474e837b1b3d33",
|
|
326
341
|
"da848b831443484c831fa630666c004e07c1c9669dd247e8e4066979c8599080",
|
|
327
|
-
"c076d603cffc731823d2acf096bcc17cca1d99eee24b0aa313776d7d01571b4f"
|
|
342
|
+
"c076d603cffc731823d2acf096bcc17cca1d99eee24b0aa313776d7d01571b4f",
|
|
343
|
+
"1d1d907449ec74594d0ee923ac142ae746b9aedf0a1eda9469f075a44d23e3d7"
|
|
328
344
|
],
|
|
329
345
|
"ai-init/CLAUDE.minimal.md": [
|
|
330
346
|
"7578025c0ce0a64dd37fe4c999541db5681199763df8b373ed0bfba11e2f581e",
|
|
@@ -335,7 +351,8 @@
|
|
|
335
351
|
"e8df28f07cb784d768bcafbced70fd15771afa61dbec7dc4c1c3f858f9002fec",
|
|
336
352
|
"c9ddacab2a6943af94c927799ba314877c1f19d40949e927c2d3825689005288",
|
|
337
353
|
"4d1f9073276936834747199393159f1badc0277b5bb394f78f408d52c36c4e35",
|
|
338
|
-
"65acd4be95c695d0cc20cb5f4faffe0f44e0873b385c124140b223c41328cb56"
|
|
354
|
+
"65acd4be95c695d0cc20cb5f4faffe0f44e0873b385c124140b223c41328cb56",
|
|
355
|
+
"935af1019931058ec3a0b834fe230e127ec914f75edcc4a6c589cfe733b0b979"
|
|
339
356
|
],
|
|
340
357
|
"ai-init/GEMINI.minimal.md": [
|
|
341
358
|
"933629cd5c872a11837046b13051a9b02bbc1033e3ba74f41966af2ed4edee5d"
|
|
@@ -348,7 +365,8 @@
|
|
|
348
365
|
"e8df28f07cb784d768bcafbced70fd15771afa61dbec7dc4c1c3f858f9002fec",
|
|
349
366
|
"c9ddacab2a6943af94c927799ba314877c1f19d40949e927c2d3825689005288",
|
|
350
367
|
"4d1f9073276936834747199393159f1badc0277b5bb394f78f408d52c36c4e35",
|
|
351
|
-
"65acd4be95c695d0cc20cb5f4faffe0f44e0873b385c124140b223c41328cb56"
|
|
368
|
+
"65acd4be95c695d0cc20cb5f4faffe0f44e0873b385c124140b223c41328cb56",
|
|
369
|
+
"935af1019931058ec3a0b834fe230e127ec914f75edcc4a6c589cfe733b0b979"
|
|
352
370
|
],
|
|
353
371
|
"ai-init/junie-guidelines.minimal.md": [
|
|
354
372
|
"5551499579a0bceb74a79731d30213b1ddf9168b92f6d3dd0aecad91d8aff464"
|
|
@@ -371,7 +389,8 @@
|
|
|
371
389
|
"a349aaad234825ea429df33cafb7928579c0cb5b1801f0a237e103aa8d159642"
|
|
372
390
|
],
|
|
373
391
|
"project-init/constitution.md": [
|
|
374
|
-
"5e38d93c4f82300cc5d331f4ce3022d2872db15d108ae23bf33e2169a19b42f2"
|
|
392
|
+
"5e38d93c4f82300cc5d331f4ce3022d2872db15d108ae23bf33e2169a19b42f2",
|
|
393
|
+
"7be527cd648b27cca6e267de30f8e33a2ce17d5631a82694f23ae5c0623efe1f"
|
|
375
394
|
],
|
|
376
395
|
"project-init/gitignore.snippet": [
|
|
377
396
|
"965a03be82000866cb5275acda18ebb2172c9a50f0011df2fa475f74a1124c35",
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""0009: the task's state file is `.ai/state/state.json`.
|
|
2
|
+
|
|
3
|
+
R34's contract half. 0008 shipped the expand half: the guards and state.py of
|
|
4
|
+
3.4b read `.ai/state/state.json` first and `current.json` otherwise, and write
|
|
5
|
+
the file where it is. This migration, run once such a version is installed,
|
|
6
|
+
moves a task in flight from `current.json` to `state.json`, and `state.py start`
|
|
7
|
+
opens every new task in `state.json`.
|
|
8
|
+
|
|
9
|
+
* The move goes through MOVES like any other: no task in flight means no
|
|
10
|
+
file, and nothing happens; a project that already holds `state.json` keeps
|
|
11
|
+
it (a `current.json` beside it is a conflict for a human, not overwritten).
|
|
12
|
+
* The file's bytes are not touched: every field of the task survives.
|
|
13
|
+
* Reverting to 3.4b after the move still guards the task, because that
|
|
14
|
+
version reads `state.json`.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
VERSION = 9
|
|
18
|
+
TITLE = "the task's state file is state.json"
|
|
19
|
+
STATE_LEGACY = ".ai/state/current.json"
|
|
20
|
+
STATE_NEW = ".ai/state/state.json"
|
|
21
|
+
MOVES = [(STATE_LEGACY, STATE_NEW)]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def plan(ctx):
|
|
25
|
+
ctx.move(STATE_LEGACY, STATE_NEW)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""0010: the command-choice dialog is on (R36.1).
|
|
2
|
+
|
|
3
|
+
`.ai/policies/dialog.json` is the project's switch for the dialog: the human
|
|
4
|
+
picks a commit, push or approval command in the runtime's dialog and the agent
|
|
5
|
+
runs that command, verbatim and once. This migration writes the switch, on, as
|
|
6
|
+
the scaffold does for a new project.
|
|
7
|
+
|
|
8
|
+
* A project that already has the file keeps it, whatever it says: `create`
|
|
9
|
+
does not overwrite, and a human's `"enabled": false` stays off.
|
|
10
|
+
* A second run finds the file and does nothing, and prints nothing.
|
|
11
|
+
* The task's state is not touched: a task in flight survives.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
VERSION = 10
|
|
15
|
+
TITLE = "the command-choice dialog switch"
|
|
16
|
+
SWITCH = ".ai/policies/dialog.json"
|
|
17
|
+
MOVES = []
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def plan(ctx):
|
|
21
|
+
if ctx.exists(SWITCH):
|
|
22
|
+
return
|
|
23
|
+
ctx.create(SWITCH, ctx.template(SWITCH))
|
|
24
|
+
ctx.hint("%s is new and the command-choice dialog is on; set \"enabled\": false in it to turn the dialog off"
|
|
25
|
+
% SWITCH)
|
|
26
|
+
ctx.hint("docs/sdlc/constitution.md C5 still says no agent commits, merges or deploys: if you keep the dialog "
|
|
27
|
+
"on, amend C5 to the new sentence (skills/project-init/templates/constitution.md, C5)")
|
|
28
|
+
if ctx.state is not None:
|
|
29
|
+
ctx.hint("a task is in flight: the dialog switch takes effect for it too; set \"enabled\": false in %s "
|
|
30
|
+
"to turn it off" % SWITCH)
|
|
@@ -16,7 +16,8 @@ this directory, named `NNNN_slug.py`, numbered contiguously from `0001`, with
|
|
|
16
16
|
- A migration that deletes must retire the template in the same release,
|
|
17
17
|
otherwise the next run re-creates the file.
|
|
18
18
|
- `ctx.patch_state` is the only way to change a task in flight, and the only
|
|
19
|
-
writer of `.ai/state/
|
|
19
|
+
writer of the task's state file (`.ai/state/state.json`, `current.json` in a
|
|
20
|
+
project not yet at schema 9) other than `state.py`. A migration that
|
|
20
21
|
moves a path a task's step may touch must patch it, or the scope guard will
|
|
21
22
|
stop that task on a file that no longer exists.
|
|
22
23
|
- Operations are planned, never written: the dry run must list everything.
|
|
@@ -81,12 +81,18 @@ ROUTER_FILE = ".ai/AGENTS.md"
|
|
|
81
81
|
SHARED_SECTION_RE = re.compile(rb"(?m)^## Shared files[ \t]*\r?$")
|
|
82
82
|
SHARED_SCHEMA = 6 # the schema from which shared copies are overrides (0006)
|
|
83
83
|
STATE_FILE = ".ai/state/state.json"
|
|
84
|
-
LEGACY_STATE_FILE = ".ai/state/current.json" # R34: the name until migration
|
|
84
|
+
LEGACY_STATE_FILE = ".ai/state/current.json" # R34: the name until migration 0009 moves it
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
# Templates a migration creates exactly once, on the step to the given schema.
|
|
88
|
+
# From that schema on, a missing file is the human's choice (dialog.json missing
|
|
89
|
+
# means the dialog is off), so the template walk must not re-create it.
|
|
90
|
+
CREATE_ONCE = {".ai/policies/dialog.json": 10}
|
|
85
91
|
|
|
86
92
|
|
|
87
93
|
def state_file(plan):
|
|
88
94
|
"""The task state's path as this run leaves the project: state.json once it
|
|
89
|
-
exists there (migration
|
|
95
|
+
exists there (migration 0009 moved it, or the task started under it), else
|
|
90
96
|
the legacy current.json."""
|
|
91
97
|
if not plan.exists(STATE_FILE) and plan.exists(LEGACY_STATE_FILE):
|
|
92
98
|
return LEGACY_STATE_FILE
|
|
@@ -1263,6 +1269,8 @@ def build_plan(root, confirm_delete=None, confirm_via=None):
|
|
|
1263
1269
|
continue
|
|
1264
1270
|
if rel in plan.removed: # a migration moved it away in this run
|
|
1265
1271
|
continue
|
|
1272
|
+
if rel in CREATE_ONCE and version >= CREATE_ONCE[rel] and not plan.exists(rel):
|
|
1273
|
+
continue # past the step that created it: its absence is the human's choice
|
|
1266
1274
|
content = read(os.path.join(tpl, rel))
|
|
1267
1275
|
if rel.startswith(".ai/project/") or rel.startswith(".ai/reports/"):
|
|
1268
1276
|
if not plan.exists(rel):
|
|
@@ -1433,7 +1441,8 @@ def apply_item(plan, item, written, recorded):
|
|
|
1433
1441
|
if action == "move":
|
|
1434
1442
|
check(plan, item, target, item["expect"], written)
|
|
1435
1443
|
mode = os.stat(os.path.join(plan.root, source)).st_mode & 0o7777
|
|
1436
|
-
|
|
1444
|
+
if not source.startswith(".ai/state/"): # git-ignored task state: a move is byte-identical
|
|
1445
|
+
keep_original(plan, source)
|
|
1437
1446
|
recorded.append(target)
|
|
1438
1447
|
# Recorded before the file is gone: an abort later must not lose the note
|
|
1439
1448
|
# of what was taken away, or of who approved a deletion.
|
package/skills/rr-build/SKILL.md
CHANGED
|
@@ -38,6 +38,8 @@ $STATE handoff --print
|
|
|
38
38
|
Trust it over a compaction summary; it is rendered from the state. If
|
|
39
39
|
`$ARGUMENTS` asks for something else, say what is in flight and ask whether to
|
|
40
40
|
finish it, or drop it with `$STATE close --abandon`. Never discard it silently.
|
|
41
|
+
A handoff line `Batch: on` means the task runs the loop of `/rr-build-all` —
|
|
42
|
+
parallel implementers and fixers, its own budgets — continue there.
|
|
41
43
|
- **`Handed to <the other runtime>`:** every state change exits 7 until that
|
|
42
44
|
runtime resumes it. Say where to resume; take it back with
|
|
43
45
|
`$STATE handoff --to <this runtime>` only when asked. `Handed to <this
|
|
@@ -47,6 +49,11 @@ $STATE handoff --print
|
|
|
47
49
|
|
|
48
50
|
## 2. Edit, inside the task
|
|
49
51
|
|
|
52
|
+
Before the first edit, recall what the record already holds about the task's
|
|
53
|
+
files — open risks, residual findings, decisions and why, within a token budget,
|
|
54
|
+
read-only: `$STATE recall --files "<the task's files>"` (`memory show <id>` for
|
|
55
|
+
one task in full).
|
|
56
|
+
|
|
50
57
|
Implement it yourself. The scope guard refuses an edit to a file the task does
|
|
51
58
|
not name. That refusal is the plan being enforced, not an obstacle:
|
|
52
59
|
|
|
@@ -56,8 +63,9 @@ $STATE start --amend --files "+<path>" --why "<why the task needs it>"
|
|
|
56
63
|
```
|
|
57
64
|
|
|
58
65
|
The amendment is journaled; the task is not re-planned. A file that belongs to
|
|
59
|
-
a different change is not amended in — it is
|
|
60
|
-
|
|
66
|
+
a different change is not amended in — it is recorded with `$STATE memory risk
|
|
67
|
+
add --title … --where "file:line" --label RISK --what …` (in files mode that
|
|
68
|
+
writes `.ai/project/known-risks.md`) and left for its own task.
|
|
61
69
|
|
|
62
70
|
Production behaviour is the source of truth: code that looks wrong may be
|
|
63
71
|
load-bearing. Change only what the task asked for; a refactoring never rides
|
|
@@ -94,7 +102,7 @@ at `close` is finished by `close`.
|
|
|
94
102
|
|
|
95
103
|
## 4. Verify once, to the end
|
|
96
104
|
|
|
97
|
-
After the last edit:
|
|
105
|
+
After the last edit (after the last step: `$STATE step-done <id> && $STATE verify --scope all`):
|
|
98
106
|
|
|
99
107
|
```bash
|
|
100
108
|
$STATE verify --scope all
|
|
@@ -118,10 +126,11 @@ fixed:
|
|
|
118
126
|
$STATE verify --scope all --after-fix "<n> regressions: <one line each>"
|
|
119
127
|
```
|
|
120
128
|
|
|
121
|
-
- An existing failure is recorded
|
|
129
|
+
- An existing failure is recorded with `$STATE memory risk add`, not fixed.
|
|
122
130
|
- An environment failure gets one more run, not a code change.
|
|
123
131
|
- Never edit a test to make it pass.
|
|
124
|
-
- Two whole-suite runs are the budget (`tests.max_suite_runs
|
|
132
|
+
- Two whole-suite runs are the budget (`tests.max_suite_runs`; in a batch task
|
|
133
|
+
`batch.max_suite_runs`). The third
|
|
125
134
|
exits 6 `SUITE_BUDGET`: running it again is the human's decision, from their
|
|
126
135
|
own terminal, with the command it prints — or the pick: with the dialog on it
|
|
127
136
|
also prints `DIALOG_PENDING`, and you run the command the human picks,
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rr-build-all
|
|
3
|
+
description: Run a whole programme plan as one task in a repository that has .ai/ — every row of docs/sdlc/plans/<slug>.md becomes a step with its files, tests and dependencies; the ready steps go to parallel implementer subagents on the BALANCED tier, serialized where one depends on another; after the last step the suite runs once to the end, every failure is recorded and fixed by parallel fixers as one batch, then one review at the mode's tier, its findings fixed by parallel fixers as one batch, then tests and the review again until it passes; the pass past the batch budget (three failed reviews) is the human's. Use on "/rr-build-all", "run the whole plan", "all points in one task", "sdlc-lite", "batch build".
|
|
4
|
+
argument-hint: [<path to docs/sdlc/plans/<slug>.md>] | --resume
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# /rr-build-all $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
One task for the whole plan — the loop a developer otherwise runs by hand: implement every
|
|
10
|
+
row, test once, fix everything, review, fix everything, again, until the review passes. The
|
|
11
|
+
mode (light, guarded, full) is still the weight's; batch only changes who implements, how
|
|
12
|
+
failures are fixed, and how many rounds run before the human. Resolve the install root once:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
for AI_HOME in "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "${CODEX_HOME:-$HOME/.codex}"; do
|
|
16
|
+
[ -d "$AI_HOME/skills/rr-build-all" ] && break
|
|
17
|
+
done
|
|
18
|
+
STATE="python3 $AI_HOME/skills/ai-task/state.py"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Shared files resolve through `"$AI_HOME/riskrails/ai-path" <path>`. Read `policies/safety.md`
|
|
22
|
+
and `using-riskrails.md` once per session. Every rule of `/rr-build` holds here: nothing outside
|
|
23
|
+
the task's files, no commit, a refusal names the way out and is never reworded around.
|
|
24
|
+
|
|
25
|
+
## 1. Resume or start
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
$STATE handoff --print
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- **A task in flight whose handoff says `Batch: on`:** continue at its stage — §3 while
|
|
32
|
+
`steps --ready` prints a step, §4 after the last `step-done`, §5 after a green verify.
|
|
33
|
+
- **A task in flight without that line:** it runs the standard way — say so and hand over to
|
|
34
|
+
`/rr-build`. Only the human turns the loop on mid-task (`batch on`, §Switching).
|
|
35
|
+
- **No task in flight:** §2.
|
|
36
|
+
|
|
37
|
+
## 2. The plan → one task
|
|
38
|
+
|
|
39
|
+
`$ARGUMENTS` is a programme plan (default: the newest `docs/sdlc/plans/*.md`). Its spec's
|
|
40
|
+
**Flagged concerns** are resolved or accepted, as `/rr-plan` demands; a plan with an open
|
|
41
|
+
blocking question is not started.
|
|
42
|
+
|
|
43
|
+
1. **Rows → steps.** Every row of **Order of work** that an agent does becomes one step
|
|
44
|
+
`{"id", "files", "tests", "after"}`: the row's files, the tests it names, and in `after` the
|
|
45
|
+
rows it depends on — its *Consumes* line, a stated dependency, or an earlier row it builds
|
|
46
|
+
on. A refactoring row stays its own task (C3): leave it out and say so. A human row (G1, …)
|
|
47
|
+
is not a step: every row after it names in `after` every step before it, so nothing past
|
|
48
|
+
the human row is ready until the rows before it are done — and its question (3.) answered.
|
|
49
|
+
2. **Weigh and start** — `/rr-plan`'s "A task" section, on the union of the steps' files, then:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
$STATE start --goal "<the plan's title>" --workflow feature --files "<every file of every step>" \
|
|
53
|
+
--tests "<every test>" [--declare …] --plan-file /path/steps.json \
|
|
54
|
+
--batch --by "<the human's name>" --why "/rr-build-all docs/sdlc/plans/<slug>.md" \
|
|
55
|
+
[--mode <higher> --by "<name>"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
An `after` id must exist and form no cycle; two steps that name one file are ordered by
|
|
59
|
+
`start` itself (`ordered: s4 after s1 (shares …)`), so two implementers never hold one file.
|
|
60
|
+
In full mode the written plan is the programme plan the human already accepted. With
|
|
61
|
+
`batch.default` true in `.ai/policies/weight.json` the flag is implied; `--no-batch` opts out.
|
|
62
|
+
3. **A human row** becomes a question the moment every step before it is done — asked
|
|
63
|
+
**before** the next wave is dispatched:
|
|
64
|
+
`$STATE ask "G1 is yours: <what>" --option "A: done" --option "B: not yet" --recommend A`,
|
|
65
|
+
then **stop**. Never dispatch while a question is pending (`step-done` and `close` exit 4;
|
|
66
|
+
`steps --ready` still answers); `/rr-build-all --resume` goes on once the human answered.
|
|
67
|
+
|
|
68
|
+
## 3. Implement, by waves
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
$STATE steps --ready # the next wave: the steps whose dependencies are done, one id per line
|
|
72
|
+
$STATE steps --json # batch_policy.tier and .parallel: the implementers' tier, how many at once
|
|
73
|
+
$STATE profile --tier <that tier> # the tier's model in this runtime (BALANCED as shipped)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Resuming mid-wave** (after a compaction or a stop): before dispatching, compare
|
|
77
|
+
`git status --short` with each ready step's files. A ready step whose files already changed
|
|
78
|
+
was dispatched before and never recorded — do not send it again blind: brief its implementer
|
|
79
|
+
with that partial diff to finish, or `step-done` it if its tests pass.
|
|
80
|
+
|
|
81
|
+
Dispatch one subagent per ready step, at most `batch.parallel` (shipped 3) at once — under
|
|
82
|
+
Claude Code a `general-purpose` agent with `model:` set to that tier's model; under Codex a
|
|
83
|
+
spawn with no agent named, on that model. Its brief is the implementer contract,
|
|
84
|
+
`agents/implementer.md` in the shared tree, filled in:
|
|
85
|
+
|
|
86
|
+
- **Goal** — the row's text from the plan. **Allowed files** — the step's files, nothing else.
|
|
87
|
+
**Forbidden files** — every other step's files, "another implementer holds them".
|
|
88
|
+
**Required behaviour / behaviour that must not change** — from the row and the spec.
|
|
89
|
+
**Required tests** — the step's tests.
|
|
90
|
+
- Its own tests, run directly: `step_test_command` from `.ai/policies/testing.md` with the
|
|
91
|
+
step's tests in place of `{files}`. **A subagent never calls `state.py`** — one state file,
|
|
92
|
+
one writer, this session.
|
|
93
|
+
- It returns `## RESULT`, or `## SCOPE_CHANGE_REQUIRED`, or `## QUESTIONS_NEEDED`.
|
|
94
|
+
|
|
95
|
+
After the wave, in this session:
|
|
96
|
+
|
|
97
|
+
- `RESULT` → `$STATE step-done <id>` for each step. Exit 6 names a file outside the task:
|
|
98
|
+
`$STATE start --amend --files "+<path>" --why "…"`, then `step-done` again.
|
|
99
|
+
- `SCOPE_CHANGE_REQUIRED` → amend as above and send the same step again. A file that belongs
|
|
100
|
+
to another change goes into `.ai/project/known-risks.md`, not into the task.
|
|
101
|
+
- `QUESTIONS_NEEDED` → `$STATE ask --batch /path/questions.json`, show the questions, **stop**;
|
|
102
|
+
the human answers, and `/rr-build-all --resume` goes on from the handoff.
|
|
103
|
+
|
|
104
|
+
Then `steps --ready` again. Nothing ready and nothing pending: §4. Keep this session small:
|
|
105
|
+
read `## RESULT` blocks, never a subagent's diff; `git status --short` is the only view of the
|
|
106
|
+
tree you need between waves.
|
|
107
|
+
|
|
108
|
+
## 4. Tests once, failures fixed as one parallel batch
|
|
109
|
+
|
|
110
|
+
After the last wave, `$STATE step-done <id> && $STATE verify --scope all`:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
$STATE verify --scope all
|
|
114
|
+
$STATE verify --scope all --e2e not-applicable "<why the change reaches no e2e flow>"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Green: §5. **Red:** a FAST `log-reader` reads the log by path and returns every failure
|
|
118
|
+
classified — new regression, existing failure, environment, unknown (`testing.md`, "Reading a
|
|
119
|
+
failure") — each with `file:line`. Then:
|
|
120
|
+
|
|
121
|
+
- an existing failure → one entry in `.ai/project/known-risks.md`; an environment failure →
|
|
122
|
+
one more run, no code change;
|
|
123
|
+
- the new regressions, grouped by the file they point at → one fixer subagent per group, in
|
|
124
|
+
parallel, at most `batch.parallel`, on the batch tier, briefed with the failures' excerpts
|
|
125
|
+
and the files it may touch (that group's files, inside the task's). Fix the code, never the
|
|
126
|
+
test; report `files_changed` and what stayed unfixed;
|
|
127
|
+
- one run: `$STATE verify --scope all --after-fix "<n> regressions: <one line each>"`.
|
|
128
|
+
|
|
129
|
+
Red again → the same once more. Exit 6 `SUITE_BUDGET` — past `batch.max_suite_runs`
|
|
130
|
+
(shipped 8) — is the human's run: the pick in the dialog, or the command it prints, in their
|
|
131
|
+
own terminal. **Stop.**
|
|
132
|
+
|
|
133
|
+
## 5. Review, findings fixed as one parallel batch, again until it passes
|
|
134
|
+
|
|
135
|
+
One `ai-reviewer` at the mode's tier, briefed as `/rr-review` §2 says: the whole diff since the
|
|
136
|
+
task's base, the task's files, the tests, the last verify log; unbounded "look for" in full
|
|
137
|
+
mode, the security focus when the domain axis is 2. Record it verbatim:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
$STATE review --verdict <pass|pass_with_findings|blockers_open> --tier <BALANCED|STRONG> \
|
|
141
|
+
[--focus security] --report - <<'EOF'
|
|
142
|
+
<the reviewer's FINDINGS and VERDICT, unchanged>
|
|
143
|
+
EOF
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
- **pass** → §6.
|
|
147
|
+
- **pass_with_findings** → the in-scope HIGHs, grouped by file, one fixer per group in
|
|
148
|
+
parallel; `$STATE verify --scope all --after-fix "H1,H2: …"`; `$STATE review --closes "H1,H2"`
|
|
149
|
+
→ §6. Each MEDIUM and LOW is one `$STATE memory risk add`, not a fix; only a BLOCKER, a HIGH
|
|
150
|
+
or a regression buys an `--after-fix` run.
|
|
151
|
+
- **blockers_open** → every in-scope BLOCKER and HIGH, grouped by file, one fixer per group in
|
|
152
|
+
parallel; `$STATE verify --scope all --after-fix "B1,H1: …"` (red: §4's batch); then
|
|
153
|
+
**§5 again, a full pass** — a fix batch across many files is a new change, not a scoped one.
|
|
154
|
+
|
|
155
|
+
Exit 6 `REVIEW_BUDGET` after `batch.review_rounds_max` passes (shipped 3 — three failed
|
|
156
|
+
reviews) — the next verdict is the human's: the pick in the dialog, or the command it prints,
|
|
157
|
+
in their own terminal. Show the open findings and **stop**. A `verify` past its budget inside
|
|
158
|
+
this loop is `SUITE_BUDGET`, handled the same way.
|
|
159
|
+
|
|
160
|
+
## 6. Ship
|
|
161
|
+
|
|
162
|
+
`/rr-ship` — `close` measures the two facts and, in full mode, asks the human to approve,
|
|
163
|
+
exactly as for any task; for a documents-only change since the green suite it is
|
|
164
|
+
`$STATE verify --scope step --files "<doc_tests>" && $STATE verify --scope e2e && $STATE close`. Suggest `/clear` after it.
|
|
165
|
+
|
|
166
|
+
## Switching
|
|
167
|
+
|
|
168
|
+
- **To the standard loop ("full" from here):** `$STATE batch off --by "<name>" --why "<why>"`.
|
|
169
|
+
The standard budgets apply from now, counting what was spent — with two passes behind you,
|
|
170
|
+
the next verdict is already the human's. The session implements the remaining steps itself;
|
|
171
|
+
continue with `/rr-build`, `/rr-review`, `/rr-ship`. Anyone may do this: it raises the rigor.
|
|
172
|
+
- **To batch, mid-task:** lowers the rigor — the human's, in their own terminal:
|
|
173
|
+
`python3 <AI_HOME>/skills/ai-task/state.py --root <project> batch on --by "<name>"`. Never
|
|
174
|
+
from a tool call; the refusal (`APPROVAL_REFUSED`) prints that command.
|
|
175
|
+
- **The project's default:** `batch.default` in `.ai/policies/weight.json`, beside
|
|
176
|
+
`batch.review_rounds_max`, `batch.max_suite_runs`, `batch.parallel` and `batch.tier`
|
|
177
|
+
(`/rr-setup --update` adds the section). A policy is the human's and is frozen during a task.
|
|
178
|
+
|
|
179
|
+
## Rules
|
|
180
|
+
|
|
181
|
+
- The mode is the weight's and only rises; the scope guard, the two facts, the gate and the
|
|
182
|
+
three nevers are untouched by batch.
|
|
183
|
+
- Three or more parallel agents run at BALANCED, never above — `start` refuses `batch.tier`
|
|
184
|
+
above it when `batch.parallel` is three or more; one reviewer per pass, at the mode's tier;
|
|
185
|
+
the session writes every conclusion (`model-routing.md`).
|
|
186
|
+
- One writer of the state: a subagent never calls `state.py`; this session records every step,
|
|
187
|
+
run and verdict.
|
|
188
|
+
- Failures and findings are fixed as batches, never one at a time; a test is never edited to
|
|
189
|
+
make it pass; what is outside the task is written down, not fixed.
|
|
190
|
+
- No commit, push, merge or deploy. The task ends at `/rr-ship`; approval is the human's.
|
package/skills/rr-plan/SKILL.md
CHANGED
|
@@ -38,7 +38,11 @@ When `$ARGUMENTS` is a spec (default: the newest `docs/sdlc/specs/*.md`):
|
|
|
38
38
|
4. Copy the template to `docs/sdlc/plans/<slug>.md`, fill **Files that change /
|
|
39
39
|
Order of work / Risks / Proof / Rollback**; Proof maps every requirement R<n>
|
|
40
40
|
to a test or command. One round of corrections; suggest the commit
|
|
41
|
-
`plan: <title>`. Each row of the plan is later one task, planned below
|
|
41
|
+
`plan: <title>`. Each row of the plan is later one task, planned below —
|
|
42
|
+
unless the whole plan runs as one task through `/rr-build-all` (the project's
|
|
43
|
+
`batch.default` in `weight.json`, or the developer's call): then every row
|
|
44
|
+
becomes one step of that task, so give each row its files and its *Consumes*
|
|
45
|
+
line (the rows it depends on) — that is what `/rr-build-all` reads.
|
|
42
46
|
|
|
43
47
|
## A task → weight, mode, plan, start
|
|
44
48
|
|
|
@@ -48,7 +52,10 @@ investigation — say which and why. `using-riskrails.md` in the shared tree
|
|
|
48
52
|
`workflows.md#<kind>` say what each kind requires. A refactoring and a feature
|
|
49
53
|
are never one task.
|
|
50
54
|
|
|
51
|
-
**2. Name the files** from the request, confirmed with `grep -n`.
|
|
55
|
+
**2. Name the files** from the request, confirmed with `grep -n`. Recall what
|
|
56
|
+
the record holds about them — `$STATE recall --files "<a>,<b>"`: open risks,
|
|
57
|
+
residual findings and earlier decisions are evidence for the weight and the
|
|
58
|
+
plan. Then weigh:
|
|
52
59
|
|
|
53
60
|
```bash
|
|
54
61
|
$STATE weight --files "<a>,<b>" --goal "<one sentence>" \
|
|
@@ -64,7 +71,7 @@ The table is `.ai/policies/weight.json` (`weight.md` mirrors it).
|
|
|
64
71
|
|
|
65
72
|
**3. The mode is the weight's**, not yours: raising it is free
|
|
66
73
|
(`--mode <m> --by "<name>"` on `start`); lowering it is the human's, from their
|
|
67
|
-
own terminal. Shape the plan by it:
|
|
74
|
+
own terminal, or the command they picked in the dialog. Shape the plan by it:
|
|
68
75
|
|
|
69
76
|
| Mode | Plan | Who sees it before the first edit |
|
|
70
77
|
|---|---|---|
|
|
@@ -92,6 +99,9 @@ $STATE start --goal "<one sentence>" --workflow <kind> --files "<a>,<b>" \
|
|
|
92
99
|
|
|
93
100
|
`--plan-file` is a JSON list `[{"id": "s1", "files": [...], "tests": [...]}]`
|
|
94
101
|
for a guarded or full plan with steps; a light task is one scope and needs none.
|
|
102
|
+
A step may add `"after": ["s0"]`, the steps it waits for — `/rr-build-all` runs
|
|
103
|
+
the rest in parallel — and `--batch --by "<name>"` (or `--no-batch`) sets that
|
|
104
|
+
loop for the task; the default is `batch.default` in `weight.json`.
|
|
95
105
|
`--files` lists every file of every step — the guard refuses an edit outside
|
|
96
106
|
them. `--tests` names the task's own tests; a bugfix names its failing test. At
|
|
97
107
|
guarded and full, run `start` only after the human accepted the plan.
|
|
@@ -30,7 +30,10 @@ STATE="python3 $AI_HOME/skills/ai-task/state.py"
|
|
|
30
30
|
(`review_rounds_max`): one full review and one scoped re-review. The pass past
|
|
31
31
|
it exits 6 `REVIEW_BUDGET` — the next verdict is the human's, from their own
|
|
32
32
|
terminal, with the command it prints, or the pick in the dialog (`DIALOG_PENDING`,
|
|
33
|
-
then the picked command verbatim, once). Never a third pass.
|
|
33
|
+
then the picked command verbatim, once). Never a third pass. A batch task
|
|
34
|
+
(`/rr-build-all`) has its own budget, `batch.review_rounds_max` full passes
|
|
35
|
+
(shipped three): after a `blockers_open` fix batch the next pass is a full one,
|
|
36
|
+
and the pass past the budget is the human's the same way.
|
|
34
37
|
|
|
35
38
|
## 2. Brief one `ai-reviewer`
|
|
36
39
|
|
|
@@ -49,10 +52,11 @@ the tier, so name the tier in the brief. Give it paths, not pasted text:
|
|
|
49
52
|
**Bounded inputs in light and guarded:** the goal, the diff, the named tests,
|
|
50
53
|
and the project's own threat model (`.ai/policies/safety.md`, the guards'
|
|
51
54
|
defaults, the test fixtures). A finding that needs anything outside them comes
|
|
52
|
-
back `[INFO]` with `in_scope: no`;
|
|
55
|
+
back `[INFO]` with `in_scope: no`; record it with `$STATE memory risk add`
|
|
53
56
|
as one entry — it never opens a fix. You may move a finding to
|
|
54
57
|
`in_scope: yes`, never the other way. **In full mode** the reviewer's own "look
|
|
55
|
-
for" list applies unbounded.
|
|
58
|
+
for" list applies unbounded. Tell it the cap: about 40 tool calls in light and
|
|
59
|
+
guarded, about 80 in full, then FINDINGS and VERDICT.
|
|
56
60
|
|
|
57
61
|
Before you delegate, probe the change yourself for a minute: the few inputs its
|
|
58
62
|
own threat model makes interesting, through the real code, and hand the
|
|
@@ -77,12 +81,16 @@ task's record (`task.md`), so there is no separate report to write.
|
|
|
77
81
|
|
|
78
82
|
## 4. After the verdict
|
|
79
83
|
|
|
80
|
-
- **pass:** `/rr-ship
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
- **pass:** `/rr-ship`; the record and the close are one call,
|
|
85
|
+
`$STATE review --verdict pass … <<'EOF' && $STATE close`. `review` exits 0 for every
|
|
86
|
+
verdict, so the chain is for `pass` only.
|
|
87
|
+
- **pass_with_findings:** fix every in-scope HIGH in one batch, then
|
|
83
88
|
`$STATE verify --scope all --after-fix "H1,H2: <one line>"` and
|
|
84
89
|
`$STATE review --closes "H1,H2"`. The findings close on that green run, on a
|
|
85
|
-
tree the fix changed — no second review.
|
|
90
|
+
tree the fix changed — no second review. Each MEDIUM and LOW is one
|
|
91
|
+
`$STATE memory risk add` (`.ai/project/known-risks.md` amended into the task
|
|
92
|
+
if missing), not a fix; only a BLOCKER, a HIGH or a regression buys an
|
|
93
|
+
`--after-fix` run.
|
|
86
94
|
- **blockers_open:** fix every BLOCKER and HIGH together, `verify --scope all
|
|
87
95
|
--after-fix "…"`, then **one scoped re-review** (`/rr-review B1,H1`): brief a fresh `ai-reviewer`
|
|
88
96
|
with the named findings and the fix's diff only — do they close, and what did
|
|
@@ -94,6 +102,8 @@ The `verify` after a fix is often the task's third whole-suite run: past
|
|
|
94
102
|
from their own terminal, with the command it prints, or the pick in the dialog.
|
|
95
103
|
|
|
96
104
|
A finding whose cause is the plan goes back to `/rr-plan` for that part only. A
|
|
97
|
-
real problem outside the task
|
|
105
|
+
real problem outside the task is recorded with `$STATE memory risk add`; a
|
|
106
|
+
fix in this task closes its risk with `$STATE memory risk close <rkey> --status
|
|
107
|
+
fixed --why "…"`. A mistake
|
|
98
108
|
this repository has seen before — the second time a review flags it — gets one
|
|
99
109
|
line in the project instruction file, in this task.
|
package/skills/rr-ship/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rr-ship
|
|
3
|
-
description: Close the task — state.py close measures the two facts (a green whole-suite verify on the tree as it is now; every changed file inside the task's files), applies the mode table and either archives the task or, in full mode, requests the human's approval and prints the exact approve command for their own terminal. Writes the commit message body and suggests the commit; never commits, pushes or approves. Use on "/rr-ship", "close the task", "ship it", "ready for approval", after /rr-build or /rr-review.
|
|
3
|
+
description: Close the task — state.py close measures the two facts (a green whole-suite verify on the tree as it is now; every changed file inside the task's files), applies the mode table and either archives the task or, in full mode, requests the human's approval and prints the exact approve command for their own terminal. Writes the commit message body and suggests the commit; never merges or deploys, and commits, pushes or approves only as the command the human picked in the dialog, verbatim, once. Use on "/rr-ship", "close the task", "ship it", "ready for approval", after /rr-build or /rr-review.
|
|
4
4
|
argument-hint: [--abandon]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -33,7 +33,8 @@ Then the mode table decides:
|
|
|
33
33
|
|---|---|---|
|
|
34
34
|
| 0, `closed` | archived: `task.md` holds the changes and the verdict | §3 |
|
|
35
35
|
| 0, `ready for approval` | full mode: the gate is requested | §2 |
|
|
36
|
-
| 2 `review required`
|
|
36
|
+
| 2 `review required` whose text holds `only documents changed since run …` (read this row first) | a green suite, then documents only | `$STATE verify --scope step --files "<doc_tests>" && $STATE verify --scope e2e && $STATE close` — `close` prints the files comma-joined; use its text |
|
|
37
|
+
| 2 `review required`, any other reason | light with a red fact, or guarded/full without its review | `/rr-review` |
|
|
37
38
|
| 2 `verify required` | e2e owed, or not on this tree | `$STATE verify --scope all` (or `--scope e2e`, or `--e2e not-applicable "<why>"`) |
|
|
38
39
|
| 4 | a question is pending | show it; §4 |
|
|
39
40
|
| 5 `APPROVAL_REFUSED` | rejected, and nothing changed since | address the rejection, `verify --scope all`, close again |
|
|
@@ -54,9 +55,13 @@ Show the human the summary (§3), the open findings, the rollback, and that
|
|
|
54
55
|
command **verbatim** — paths absolute and quoted, because they paste it into
|
|
55
56
|
their own shell, where `$AI_HOME` is not set. Then **stop**.
|
|
56
57
|
|
|
57
|
-
- **You
|
|
58
|
-
`
|
|
59
|
-
|
|
58
|
+
- **You approve only through the dialog.** With `.ai/policies/dialog.json`
|
|
59
|
+
`enabled: true`, `close` offers the `approve` command in the runtime's dialog;
|
|
60
|
+
once the human picks it, run exactly that command, verbatim and once. With the
|
|
61
|
+
switch off, or no pick, you cannot approve: `approve` refuses without a terminal
|
|
62
|
+
on stdin or `AI_UNATTENDED` in its own environment — neither of which a tool
|
|
63
|
+
call from this session has — and the path guard denies it. Never try another
|
|
64
|
+
route.
|
|
60
65
|
- **full_irreversible:** the command carries
|
|
61
66
|
`--confirm "<what it does, naming DROP …>"`; the human names every operation
|
|
62
67
|
the re-score found, in their own words.
|
|
@@ -91,11 +96,14 @@ Write the body from `.ai/reports/<task-id>/task.md` — no new opinion:
|
|
|
91
96
|
- the verification command and its result (suite and e2e);
|
|
92
97
|
- the review verdict, with any finding left open and why;
|
|
93
98
|
- the rollback: `git revert <commit>`, plus anything a revert does not undo;
|
|
94
|
-
- open risks
|
|
99
|
+
- open risks: the ones this task recorded or closed with `state.py memory risk
|
|
100
|
+
add|close`, by rkey (`state.py memory risks` lists them).
|
|
95
101
|
|
|
96
102
|
Suggest the commit command — `git add` of the task's files and its
|
|
97
|
-
`.ai/reports/<task-id
|
|
98
|
-
|
|
103
|
+
`.ai/reports/<task-id>/` (in packages mode also `.ai/memory/`, which holds the
|
|
104
|
+
task's record — the pre-push check refuses a closed task without it), then
|
|
105
|
+
`git commit` with that body — for the human to run. You never merge or deploy; you commit, push or
|
|
106
|
+
approve only as the command the human picked in the dialog (§2), verbatim, once.
|
|
99
107
|
|
|
100
108
|
## 4. Pending questions
|
|
101
109
|
|