riskrails 3.0.1 → 3.1.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 (62) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +1 -1
  4. package/README.md +28 -15
  5. package/ai/policies/model-routing.md +7 -7
  6. package/ai/policies/production.md +3 -3
  7. package/ai/policies/release.md +2 -2
  8. package/ai/policies/review-economy.md +27 -30
  9. package/bin/riskrails.js +5 -5
  10. package/hooks/context-guard.py +1 -1
  11. package/hooks/guard/common.py +2 -0
  12. package/hooks/guard/paths.py +41 -30
  13. package/hooks/project-scaffold.py +1 -5
  14. package/hooks/runtime-gate.py +6 -6
  15. package/hooks/update_notice.py +20 -14
  16. package/instructions/routing.md +1 -1
  17. package/instructions/stub.md +3 -3
  18. package/package.json +1 -1
  19. package/skills/AGENTS.md +1 -1
  20. package/skills/CLAUDE.md +1 -1
  21. package/skills/ai-init/templates/.ai/AGENTS.md +1 -1
  22. package/skills/ai-init/templates/.ai/VERSION +1 -1
  23. package/skills/ai-init/templates/.ai/policies/security.md +7 -1
  24. package/skills/ai-init/templates/.ai/policies/testing.md +19 -6
  25. package/skills/ai-init/templates/AGENTS.block.md +2 -2
  26. package/skills/ai-init/templates/CLAUDE.block.md +2 -2
  27. package/skills/ai-init/templates/GEMINI.block.md +2 -2
  28. package/skills/ai-init/templates/gitignore.snippet +1 -0
  29. package/skills/ai-init/templates/junie-guidelines.block.md +2 -2
  30. package/skills/ai-task/sensors.py +24 -4
  31. package/skills/ai-task/state.py +37 -14
  32. package/skills/project-init/templates/constitution.md +1 -1
  33. package/skills/project-init/templates/sdlc-README.md +20 -14
  34. package/skills/project-update/history/blobs/00289f98434fed230eebe768dfb3425f83d737866a3aebc97aa95167c4fa0c6e +131 -0
  35. package/skills/project-update/history/blobs/079a91f976ad69b5cf49ccb9a28849576e4735ddd9485fc26599e528a69fd2f4 +30 -0
  36. package/skills/project-update/history/blobs/07ff7fa6f93d471ff533f553b4e523e4105ccde1f3dab70132c5237728f68422 +13 -0
  37. package/skills/project-update/history/blobs/0ef4a360c76da290173dea0f8073949cb0f8113710a38df95acae5d96bdd1286 +123 -0
  38. package/skills/project-update/history/blobs/18c7a2753ce9cb6f6d3d1e9d5d1125d75950b879d56b7325225b200869631b29 +15 -0
  39. package/skills/project-update/history/blobs/25d4f2a86deb5e2574bb3210b67bb24fcc4afb19f93a7b65a057daa874a9d18e +1 -0
  40. package/skills/project-update/history/blobs/48d9950f16e31d55475f566a80dc95f64b35f1c804d2f51729e313a4f29bac8d +13 -0
  41. package/skills/project-update/history/blobs/5a93f78b4ed4d416c171139b2ce610a117f9c1dd46fbb56ca86729cb4c53d10c +6 -0
  42. package/skills/project-update/history/blobs/6a3be0e624e5ad91e44d08857b7183ee53b7903e1e8d56ff196dbc9dde271e4a +75 -0
  43. package/skills/project-update/history/blobs/7170553410bba904ffb7edb4b231e3b3579b85542d84de717299980938f82c9d +13 -0
  44. package/skills/project-update/history/blobs/774b1e3a04ef0d49d33c44a2cfecd92eb6f6b738a12b6a681103ba7fc13e7b86 +67 -0
  45. package/skills/project-update/history/blobs/7f063e79195a5c85c37b7260dd20c184d3b9bea85e37202e0bbca73ad84bba49 +13 -0
  46. package/skills/project-update/history/blobs/c8573ca1f810ce6c4ac49456a4c1725b93e0d3b74c54ce95d46d8747777895f0 +13 -0
  47. package/skills/project-update/history/blobs/d6e5b34d475e7187d2a8cb2aac7e7f1a427142baf6461bda387d70ceb4d8a8c1 +30 -0
  48. package/skills/project-update/history/blobs/e120ff4e32b2e950fc94ada4e787d57dc9c790da37223e5a202d74f7e3aadf80 +13 -0
  49. package/skills/project-update/history/index.json +36 -15
  50. package/skills/project-update/migrations/0011_retire_risk_tiers.py +37 -0
  51. package/skills/project-update/migrations/__init__.py +6 -1
  52. package/skills/project-update/render_instructions.py +1 -1
  53. package/skills/project-update/update.py +374 -87
  54. package/skills/rr-build-all/SKILL.md +2 -2
  55. package/skills/rr-plan/SKILL.md +3 -1
  56. package/skills/rr-review/SKILL.md +13 -8
  57. package/skills/rr-setup/SKILL.md +15 -2
  58. package/skills/rr-setup/setup.py +7 -1
  59. package/skills/rr-spec/SKILL.md +4 -2
  60. package/skills/usage-report/usage-report.py +4 -2
  61. package/skills/ai-init/templates/.ai/policies/risk-tiers.json +0 -628
  62. package/skills/ai-init/templates/.ai/policies/risk-tiers.md +0 -180
@@ -1,628 +0,0 @@
1
- {
2
- "_comment": "SOURCE OF TRUTH for risk classification. /ai-task reads this file to decide which stages are mandatory, which model tier plans and reviews the change, whether a human must approve before anything leaves the branch, and — through pipeline_profile — which stages the main session does inline and which go to a subagent. The tier comes from the SCOPE of a change — what it reaches: a migration, a process whose behaviour changes, money, identity, infrastructure — never from how many files or lines it touches; the diff budget below measures size and reports it, it does not classify. risk-tiers.md is a human-readable mirror of this file; when they disagree, this file wins. Adjust the triggers to the project after /ai-init — the defaults are generic.",
3
- "version": 4,
4
- "pipeline_profile": "solo",
5
- "pipeline_profiles": {
6
- "_comment": "WHO runs a stage, not WHETHER it runs: stages_required is fixed per tier, the profile decides which of them are delegated to a subagent and which the main session does inline in a few lines. 'solo' is for one developer who knows the codebase and has two modes. DIRECT (T0–T4): no pipeline ceremony — the session names the files, edits, runs each step's own scoped tests, then the verification command once at the end and the e2e suite once after it, fixing every failure as one batch; the only subagents are cheap readers (Explore, log-reader), one BALANCED review at T2/T3 when a sensor is red, and at T4 — where the plan is written in plan mode and approved by the human — one review on STRONG. SDLC (T5–T6): the full pipeline with delegated plan, plan review, adversarial review, security review and release report, on the STRONG and EXPERT tiers. 'team' is the fully delegated pipeline. Switch by editing pipeline_profile.",
7
- "solo": {
8
- "direct_mode_cap": "T4",
9
- "delegated_stages": {
10
- "T0": [],
11
- "T1": [],
12
- "T2": [
13
- "adversarial_review"
14
- ],
15
- "T3": [
16
- "adversarial_review"
17
- ],
18
- "T4": [
19
- "adversarial_review"
20
- ],
21
- "T5": [
22
- "plan",
23
- "plan_review",
24
- "adversarial_review",
25
- "security_review",
26
- "release_report"
27
- ],
28
- "T6": [
29
- "discovery",
30
- "impact_analysis",
31
- "plan",
32
- "plan_review",
33
- "adversarial_review",
34
- "security_review",
35
- "release_report"
36
- ]
37
- },
38
- "delegate_anyway_when": [
39
- "the developer says the area is unfamiliar, or the request names no entry point and grep does not find one within a few calls (Explore on FAST, then ai-discovery if Explore returned nothing usable)",
40
- "the inline context summary has an UNKNOWN the plan depends on (ai-discovery, one agent)",
41
- "the risk tier is T4 or above and not obvious from the trigger table (ai-risk on STRONG)",
42
- "the verification command prints more than ~40 lines (log-reader on FAST), or the test setup is unfamiliar (ai-tester on FAST)",
43
- "at T4, the change crosses a module the developer does not own, or plan mode leaves a (blocking) question open (ai-planner on STRONG, one call)"
44
- ],
45
- "review_model": {
46
- "T2": "BALANCED",
47
- "T3": "BALANCED",
48
- "T4": "STRONG",
49
- "T5": "STRONG",
50
- "T6": "STRONG"
51
- },
52
- "release_report": "T0–T3: the commit message body; T4: the same short form, also appended to task.md; T5 and T6: ai-release",
53
- "plan": {
54
- "T0": "none",
55
- "T1": "none",
56
- "T2": "three to five lines in the conversation, registered through `state.py quick`",
57
- "T3": "three to five lines in the conversation — the files of the resource and its screens — registered through `state.py quick`; plan mode only when the change spans several modules",
58
- "T4": "the session, in plan mode: numbered steps with their files, the characterization tests first, a one-line rollback; the human accepting plan mode is the plan approval, then `state.py quick --tier T4`",
59
- "T5": "ai-planner on STRONG, in plan mode",
60
- "T6": "ai-expert"
61
- },
62
- "test": "three scopes. During a step: only the tests the plan named for that step (`step_test_command` scoped to its files), fixed inside the step before `state.py step-done` — never the full suite, never e2e. After the LAST step: `verify_command` once, to the end, no fail-fast flag, output through tail -40 or log-reader; every failure is collected and classified first, every NEW REGRESSION is fixed in ONE `state.py remediate` step and the command runs once more, at most two rounds. At the END of the task, after the full suite is green: `e2e_command` once, never per step, skipped at T0/T1 and when no e2e-covered flow can be reached (say which).",
63
- "e2e": "once per task, at the end, after verify_command is green and before the adversarial review. T0/T1: none. T2+: required when the change can reach a flow the e2e suite covers, otherwise one line saying why it cannot. T5/T6: always, and its result goes in the release report. Record it with `state.py set e2e_status <passing|failing|not_applicable|not_run>`.",
64
- "triage": "T0/T1: no state file. T2, T3 and T4: `state.py quick` records discovery, context, impact, risk and the one-step plan in a single call (at T4 after the human approved the plan). T5+: the stages run and are recorded one at a time.",
65
- "artifacts": {
66
- "T0": "none — the commit message",
67
- "T1": "none — the commit message",
68
- "T2": "none — the state archive and the commit message",
69
- "T3": "none — the state archive and the commit message",
70
- "T4": "task.md with the plan, the review verdict and the release short form",
71
- "T5": "the full set",
72
- "T6": "the full set"
73
- },
74
- "mode": {
75
- "T0": "direct",
76
- "T1": "direct",
77
- "T2": "direct",
78
- "T3": "direct",
79
- "T4": "direct",
80
- "T5": "sdlc",
81
- "T6": "sdlc"
82
- },
83
- "direct": {
84
- "state": "T0/T1: none — the commit message is the record. T2–T4: one `state.py quick` call (init + triage + one-step plan) so the scope guard is armed; `state.py close` at the end (T4: after the human approved the result)",
85
- "plan": "T0/T1: say which files, in one line. T2/T3: three to five lines in the conversation — steps and files — never a file. T4: the same list written in plan mode, with characterization tests first and a rollback line; the human approves it before any edit",
86
- "artifacts": "none below T4; T4: task.md",
87
- "agents": "Explore and log-reader on FAST for reading; ai-implementer on BALANCED for a mechanical pattern-copy step; ai-reviewer on BALANCED at T2/T3 only when `state.py review-gate` says the review is required, and on STRONG once at T4 — no ai-planner, no plan-review agent, no ai-release",
88
- "review": "T0/T1: none. T2/T3: `state.py review-gate` first — every sensor green is the review (`skipped_green`); otherwise one ai-reviewer on the BALANCED model over the diff, after the tests pass. T4: one ai-reviewer on STRONG after review-gate, plus ai-security only when auth, authorization or personal data is touched. Findings fixed as one batch in a `state.py remediate` step; one scoped re-review only when a BLOCKER was fixed",
89
- "release": "the commit message body: what changed, verification command and result, rollback"
90
- }
91
- },
92
- "team": {
93
- "delegated_stages": {
94
- "T0": [
95
- "discovery"
96
- ],
97
- "T1": [
98
- "discovery",
99
- "test"
100
- ],
101
- "T2": [
102
- "discovery",
103
- "context",
104
- "impact_analysis",
105
- "risk_classification",
106
- "plan",
107
- "test",
108
- "adversarial_review",
109
- "release_report"
110
- ],
111
- "T3": [
112
- "discovery",
113
- "context",
114
- "impact_analysis",
115
- "risk_classification",
116
- "plan",
117
- "test",
118
- "adversarial_review",
119
- "release_report"
120
- ],
121
- "T4": [
122
- "discovery",
123
- "context",
124
- "impact_analysis",
125
- "risk_classification",
126
- "plan",
127
- "test",
128
- "adversarial_review",
129
- "release_report"
130
- ],
131
- "T5": [
132
- "discovery",
133
- "context",
134
- "impact_analysis",
135
- "risk_classification",
136
- "plan",
137
- "plan_review",
138
- "test",
139
- "adversarial_review",
140
- "security_review",
141
- "release_report"
142
- ],
143
- "T6": [
144
- "discovery",
145
- "context",
146
- "impact_analysis",
147
- "risk_classification",
148
- "plan",
149
- "plan_review",
150
- "test",
151
- "adversarial_review",
152
- "security_review",
153
- "release_report"
154
- ]
155
- },
156
- "review_model": {
157
- "T2": "STRONG",
158
- "T3": "STRONG",
159
- "T4": "STRONG",
160
- "T5": "STRONG",
161
- "T6": "STRONG"
162
- },
163
- "test": "step-scoped tests inside each step (`step_test_command`, the tests the plan named for that step); ai-tester once after the last step on `verify_command`, to the end with no fail-fast flag; every failure is fixed as one batch in a `state.py remediate` step, then one more run",
164
- "e2e": "ai-tester once at the end of the task on `e2e_command`, after verify_command is green; never inside a step"
165
- }
166
- },
167
- "tiers": {
168
- "_comment": "Seven tiers, by scope. T0–T3 add or present; T4 changes a process; T5 touches money, identity or customer data; T6 is irreversible. The heavy gates — a delegated plan and its review, the security review, the full release report — start at T5.",
169
- "T0": {
170
- "label": "documentation only",
171
- "examples": [
172
- "comments",
173
- "README and docs",
174
- "translation strings with no logic"
175
- ],
176
- "model_tier": "FAST",
177
- "stages_required": [
178
- "discovery",
179
- "context",
180
- "implementation"
181
- ],
182
- "plan_review": false,
183
- "human_plan_approval": false,
184
- "adversarial_review": false,
185
- "security_review": false,
186
- "release_report": "light",
187
- "human_approval": false,
188
- "plan": "none — say which files you will touch, then edit"
189
- },
190
- "T1": {
191
- "label": "isolated presentation tweak",
192
- "examples": [
193
- "formatting",
194
- "a label or a small presentation tweak",
195
- "a template or stylesheet change with no logic"
196
- ],
197
- "model_tier": "FAST",
198
- "stages_required": [
199
- "discovery",
200
- "context",
201
- "implementation",
202
- "test"
203
- ],
204
- "plan_review": false,
205
- "human_plan_approval": false,
206
- "adversarial_review": false,
207
- "security_review": false,
208
- "release_report": "light",
209
- "human_approval": false,
210
- "plan": "none — say which files you will touch, then edit"
211
- },
212
- "T2": {
213
- "label": "isolated screen or small feature",
214
- "examples": [
215
- "an isolated admin screen or form",
216
- "a new field on an existing form, a grid column or filter",
217
- "a small isolated feature that changes no existing process"
218
- ],
219
- "model_tier": "BALANCED",
220
- "stages_required": [
221
- "discovery",
222
- "context",
223
- "impact_analysis",
224
- "risk_classification",
225
- "plan",
226
- "implementation",
227
- "test",
228
- "adversarial_review"
229
- ],
230
- "plan_review": false,
231
- "human_plan_approval": false,
232
- "adversarial_review": "the sensors, with the named tests proven to bite; one BALANCED model review only when a sensor is red",
233
- "security_review": false,
234
- "release_report": "light",
235
- "human_approval": false,
236
- "plan": "a short numbered list of steps with their files, inline"
237
- },
238
- "T3": {
239
- "label": "CRUD and presentation",
240
- "examples": [
241
- "a new resource: entity, repository, form, grid, routes, menu, translations",
242
- "a non-critical API extension",
243
- "a new service with limited blast radius",
244
- "anything that adds and presents data without changing an existing process"
245
- ],
246
- "model_tier": "BALANCED",
247
- "stages_required": [
248
- "discovery",
249
- "context",
250
- "impact_analysis",
251
- "risk_classification",
252
- "plan",
253
- "implementation",
254
- "test",
255
- "adversarial_review",
256
- "release_report"
257
- ],
258
- "plan_review": false,
259
- "human_plan_approval": false,
260
- "adversarial_review": "the sensors, with the named tests proven to bite; one BALANCED model review only when a sensor is red",
261
- "security_review": false,
262
- "release_report": "light",
263
- "human_approval": false,
264
- "plan": "a short numbered list of steps with their files, inline — no characterization tests, no STRONG review: this tier adds, it does not change a process"
265
- },
266
- "T4": {
267
- "label": "shared domain behaviour and processes",
268
- "examples": [
269
- "shared services",
270
- "order processing",
271
- "state machines and workflows",
272
- "asynchronous processing",
273
- "an important integration",
274
- "a schema migration that adds to an existing table",
275
- "configuration and dependencies"
276
- ],
277
- "model_tier": "STRONG",
278
- "stages_required": [
279
- "discovery",
280
- "context",
281
- "impact_analysis",
282
- "risk_classification",
283
- "plan",
284
- "implementation",
285
- "test",
286
- "adversarial_review",
287
- "release_report"
288
- ],
289
- "plan_review": false,
290
- "human_plan_approval": true,
291
- "adversarial_review": true,
292
- "security_review": "when the change touches authentication, authorization or personal data",
293
- "release_report": "light",
294
- "human_approval": true,
295
- "characterization_tests": "required before changing legacy behaviour",
296
- "plan": "plan mode in the session; the human approves the plan before implementation"
297
- },
298
- "T5": {
299
- "label": "critical business or system behaviour",
300
- "examples": [
301
- "payments",
302
- "accounting",
303
- "taxation",
304
- "fiscal devices and reporting",
305
- "authentication",
306
- "authorization",
307
- "order state transitions",
308
- "customer data",
309
- "external financial systems"
310
- ],
311
- "model_tier": "STRONG",
312
- "stages_required": [
313
- "discovery",
314
- "context",
315
- "impact_analysis",
316
- "risk_classification",
317
- "plan",
318
- "plan_review",
319
- "implementation",
320
- "test",
321
- "adversarial_review",
322
- "security_review",
323
- "release_report",
324
- "human_approval"
325
- ],
326
- "plan_review": true,
327
- "human_plan_approval": true,
328
- "adversarial_review": true,
329
- "security_review": true,
330
- "release_report": "full",
331
- "human_approval": true,
332
- "characterization_tests": "required",
333
- "extra_requirements": [
334
- "rollback section is mandatory",
335
- "monitoring section is mandatory",
336
- "idempotency and retry behaviour must be stated explicitly"
337
- ]
338
- },
339
- "T6": {
340
- "label": "system level, irreversible, production architecture",
341
- "examples": [
342
- "database migration strategy",
343
- "infrastructure architecture",
344
- "Kubernetes topology",
345
- "production deployment mechanics",
346
- "data migration",
347
- "destructive schema changes",
348
- "distributed transactions",
349
- "cross-system migration"
350
- ],
351
- "model_tier": "EXPERT",
352
- "stages_required": [
353
- "discovery",
354
- "context",
355
- "impact_analysis",
356
- "risk_classification",
357
- "plan",
358
- "plan_review",
359
- "implementation",
360
- "test",
361
- "adversarial_review",
362
- "security_review",
363
- "release_report",
364
- "human_approval"
365
- ],
366
- "plan_review": true,
367
- "human_plan_approval": true,
368
- "adversarial_review": true,
369
- "security_review": true,
370
- "release_report": "full",
371
- "human_approval": true,
372
- "characterization_tests": "required",
373
- "extra_requirements": [
374
- "migration analysis: locks, table size, duration, deployment ordering, old-version compatibility",
375
- "a rehearsed rollback plan, not a described one",
376
- "destructive operations need explicit, separate human approval naming the operation"
377
- ]
378
- }
379
- },
380
- "model_tiers": {
381
- "LOCAL": {
382
- "agent": null,
383
- "note": "No local model runs inside Claude Code or Codex. The work this tier would do — indexing, listing, counting, summarising git history — is done by deterministic tools (rg, git, jq, the framework CLI) and by ai-indexer on the cheapest model."
384
- },
385
- "FAST": {
386
- "agent": "ai-indexer, Explore, log-reader, ai-tester",
387
- "effort": "low",
388
- "note": "readers and runners: they collect, run and report; anything they cannot settle is escalated one tier, never retried on the same one"
389
- },
390
- "BALANCED": {
391
- "agent": "ai-discovery, ai-context, ai-risk, ai-planner, ai-release, ai-implementer; ai-reviewer at T2 and T3",
392
- "effort": "low for compression and mechanical edits, medium for judgement",
393
- "note": "the default tier for agents; the main session runs the installed profile's model and does the implementation itself"
394
- },
395
- "STRONG": {
396
- "agent": "ai-reviewer from T4, ai-security; ai-planner and ai-risk on STRONG (under Codex the ai-planner-strong and ai-risk-strong agents, because a Codex agent file outranks a spawn-time model)",
397
- "effort": "high"
398
- },
399
- "EXPERT": {
400
- "agent": "ai-expert; architect for design outside a task",
401
- "effort": "set at install time"
402
- }
403
- },
404
- "diff_budget": {
405
- "_comment": "A per-tier size measurement of what one step and one task changed, taken by skills/ai-task/sensors.py between two tree objects. ALWAYS advisory: over the budget, state.py step-done finishes the step and prints a warning that names step-split, the re-score records `over_budget`, and neither the tier nor the review depends on it — the tier comes from the scope of a change (the trigger table), never from its size. `enforce` is still read and ignored, `true` included. lines = added + deleted after `exclude` and `unbudgeted_scopes`. The numbers sit near the band where a review still finds defects (a few hundred lines); T3/T4 are wider because a resource and its screens, or shared-domain work and its callers, legitimately span many files; T5/T6 are tighter because those reviews read every line. Adjust them to the project and calibrate from /usage-report.",
406
- "enforce": false,
407
- "per_step": {
408
- "T0": {
409
- "max_lines": 300,
410
- "max_files": 15
411
- },
412
- "T1": {
413
- "max_lines": 120,
414
- "max_files": 5
415
- },
416
- "T2": {
417
- "max_lines": 200,
418
- "max_files": 8
419
- },
420
- "T3": {
421
- "max_lines": 250,
422
- "max_files": 10
423
- },
424
- "T4": {
425
- "max_lines": 250,
426
- "max_files": 10
427
- },
428
- "T5": {
429
- "max_lines": 150,
430
- "max_files": 6
431
- },
432
- "T6": {
433
- "max_lines": 150,
434
- "max_files": 6
435
- }
436
- },
437
- "per_task": {
438
- "T0": {
439
- "max_lines": 600,
440
- "max_files": 30
441
- },
442
- "T1": {
443
- "max_lines": 300,
444
- "max_files": 10
445
- },
446
- "T2": {
447
- "max_lines": 400,
448
- "max_files": 15
449
- },
450
- "T3": {
451
- "max_lines": 800,
452
- "max_files": 30
453
- },
454
- "T4": {
455
- "max_lines": 800,
456
- "max_files": 30
457
- },
458
- "T5": {
459
- "max_lines": 400,
460
- "max_files": 15
461
- },
462
- "T6": {
463
- "max_lines": 400,
464
- "max_files": 15
465
- }
466
- },
467
- "exclude": [
468
- "**/*.lock",
469
- "package-lock.json",
470
- "composer.lock",
471
- "**/__snapshots__/**",
472
- "**/*.snap",
473
- "**/*.min.*",
474
- "**/*.map",
475
- "**/generated/**",
476
- "**/*.generated.*",
477
- ".ai/state/**",
478
- ".ai/reports/**"
479
- ],
480
- "unbudgeted_scopes": [
481
- "docs"
482
- ]
483
- },
484
- "path_scopes": [
485
- {
486
- "scope": "pipeline",
487
- "min_tier": "T4",
488
- "paths": [
489
- ".ai/policies/**",
490
- ".ai/workflows/**",
491
- ".claude/**",
492
- ".codex/**",
493
- "CLAUDE.md",
494
- "AGENTS.md"
495
- ]
496
- },
497
- {
498
- "scope": "tests",
499
- "min_tier": "T1",
500
- "paths": [
501
- "tests/**",
502
- "spec/**",
503
- "**/*Test.php",
504
- "**/*.test.*",
505
- "**/*.spec.*",
506
- "**/test_*.py"
507
- ]
508
- },
509
- {
510
- "scope": "dependencies",
511
- "min_tier": "T4",
512
- "paths": [
513
- "composer.json",
514
- "package.json",
515
- "pyproject.toml",
516
- "requirements*.txt",
517
- "go.mod"
518
- ]
519
- },
520
- {
521
- "scope": "docs",
522
- "min_tier": "T0",
523
- "paths": [
524
- "docs/**",
525
- "**/*.md",
526
- "**/*.rst",
527
- "**/*.txt"
528
- ]
529
- },
530
- {
531
- "scope": "migrations",
532
- "min_tier": "T4",
533
- "paths": [
534
- "**/migrations/**",
535
- "**/Migrations/**",
536
- "db/migrate/**"
537
- ]
538
- },
539
- {
540
- "scope": "infra",
541
- "min_tier": "T6",
542
- "paths": [
543
- "Dockerfile*",
544
- "docker-compose*",
545
- "k8s/**",
546
- "helm/**",
547
- "terraform/**",
548
- ".github/workflows/**"
549
- ]
550
- },
551
- {
552
- "scope": "auth",
553
- "min_tier": "T5",
554
- "paths": [
555
- "**/Security/**",
556
- "**/Auth/**",
557
- "**/auth/**"
558
- ]
559
- },
560
- {
561
- "scope": "payments",
562
- "min_tier": "T5",
563
- "paths": [
564
- "**/Payment/**",
565
- "**/Billing/**",
566
- "**/Tax/**",
567
- "**/Invoice/**"
568
- ]
569
- },
570
- {
571
- "scope": "config",
572
- "min_tier": "T4",
573
- "paths": [
574
- "config/**",
575
- ".env*"
576
- ]
577
- }
578
- ],
579
- "_path_scopes_comment": "Ordered, first match wins per file — that is why `pipeline` stands above `docs` (an instruction file is pipeline, not documentation), `dependencies` above `docs` (requirements.txt is a manifest, not a text file) and `tests` above `payments` (a test for the payment code is a test). A file matching nothing is scope `source` and demands no tier. min_tier is a HINT, not a floor: the tier a change touching that scope usually deserves. Every scope that changes a process — pipeline, dependencies, migrations, config — says T4, above the ceiling at which the sensors may stand in for a reader: a migration file is T4 (it changes a process, even when it only adds a table — a destructive or data migration is T6 by the trigger table), money and identity are T5, infrastructure is T6. state.py step-done prints `hint: <scope> (<file>) — path_scopes says <tier>; tier unchanged` once per scope and never moves the tier: raising it is `state.py risk`, lowering it a human's, in writing.",
580
- "sensors": {
581
- "_comment": "The deterministic checks that run before any model review. A red sensor costs one review at the tier's model — today's price. A green one must therefore be impossible to fake: every ambiguity resolves to red, `unavailable` or `stale`, never to green. A missing lint_command is NOT green; only a human writing `lint_command: none` in testing.md makes it not_applicable. At or below skip_review_at_or_below, all green replaces the model review (risk-tiers.md, 'When the sensors replace the review'); size never decides it. The `diff` sensor is red only for a file outside the step: over the budget it reports the size and stays green.",
582
- "skip_review_at_or_below": "T3",
583
- "required_for_skip": [
584
- "tests",
585
- "lint",
586
- "typecheck",
587
- "diff",
588
- "rescore",
589
- "traceability",
590
- "duplicates",
591
- "bite"
592
- ],
593
- "tests": {
594
- "timeout_seconds": 1800,
595
- "env_retries": 1,
596
- "max_suite_runs": 2,
597
- "log_max_bytes": 2097152
598
- },
599
- "lint": {
600
- "timeout_seconds": 600
601
- },
602
- "typecheck": {
603
- "timeout_seconds": 600
604
- },
605
- "bite": {
606
- "timeout_seconds": 600,
607
- "required_from": "T2"
608
- },
609
- "duplicates": {
610
- "min_lines": 8,
611
- "ignore_scopes": [
612
- "tests",
613
- "docs"
614
- ]
615
- }
616
- },
617
- "remediation_rounds": 2,
618
- "escalation_triggers": [
619
- "the STRONG tier could not resolve an ambiguity and said so",
620
- "two constraints in the architecture contradict each other",
621
- "the task is classified T6",
622
- "several viable high-risk designs remain and the choice is not reversible",
623
- "the cost of being wrong is very high (money, data loss, legal or fiscal exposure)"
624
- ],
625
- "escalation_rule": "Start at the tier the table gives. Escalate one step, for one task, when a trigger fires — never escalate the whole pipeline, and never start at EXPERT because it exists. Never retry a failed reasoning task on a cheaper tier; downgrading is for mechanical work only.",
626
- "downgrade_rule": "A tier may be lowered only by a human, in writing, in the task record. An agent may propose a lower tier with evidence; it may not apply one.",
627
- "remediation_rule": "Failures are fixed in batches, never one at a time. A step's own scoped tests are the exception: they fail and are fixed inside that step. After the verification run, the e2e run (and after a review) collect every finding, classify each, open ONE `state.py remediate` step whose scope is the union of the finished steps plus the failing tests, fix them all, then run the verification command once more. A remediation never re-triages or re-plans the task; at most two rounds before the human decides."
628
- }