riskrails 3.2.1 → 4.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 +1 -1
- package/README.md +40 -83
- package/agents/ai-reviewer.md.tmpl +1 -1
- package/ai/using-riskrails.md +0 -3
- package/bin/riskrails.js +13 -59
- package/hooks/ai-path-guard-defaults.json +1 -1
- package/hooks/context-guard.py +2 -4
- package/hooks/guard/paths.py +3 -6
- package/hooks/guard/scope.py +1 -3
- package/hooks/runtime-gate.py +18 -58
- package/instructions/routing.md +2 -2
- package/package.json +1 -1
- package/scripts/ai-path +1 -1
- package/scripts/resolve-profile.py +0 -3
- package/skills/ai-audit/templates/ai-sdlc-adoption-plan.md +1 -1
- package/skills/ai-audit/templates/play-scoring-rubric.md +1 -1
- package/skills/ai-init/templates/.ai/AGENTS.md +6 -6
- package/skills/ai-init/templates/.ai/VERSION +1 -1
- package/skills/ai-init/templates/.ai/policies/security.md +1 -2
- package/skills/ai-init/templates/.ai/policies/testing.md +5 -12
- package/skills/ai-init/templates/.ai/policies/verification.md +18 -0
- package/skills/ai-init/templates/.ai/policies/weight.json +0 -1
- package/skills/ai-init/templates/.ai/policies/weight.md +1 -2
- package/skills/ai-init/templates/.ai/policies/weight.project.json +4 -0
- package/skills/ai-init/templates/.ai/project/architecture.md +1 -1
- package/skills/ai-init/templates/.ai/project/initial-assessment.md +2 -2
- package/skills/ai-init/templates/.ai/project/overview.md +1 -1
- package/skills/ai-init/templates/.ai/rules/README.md +2 -2
- package/skills/ai-init/templates/.ai/state/README.md +1 -1
- package/skills/ai-task/memory_store.py +8 -9
- package/skills/ai-task/rr_state/cli.py +1 -1
- package/skills/ai-task/rr_state/dialog.py +2 -4
- package/skills/ai-task/rr_state/fs.py +5 -13
- package/skills/ai-task/rr_state/profile.py +2 -4
- package/skills/ai-task/rr_state/questions_cmd.py +1 -1
- package/skills/ai-task/rr_state/report.py +3 -4
- package/skills/ai-task/rr_state/runtime.py +1 -1
- package/skills/ai-task/rr_state/start.py +7 -7
- package/skills/ai-task/sensors.py +10 -11
- package/skills/ai-task/state.py +4 -24
- package/skills/ai-task/weight.py +17 -17
- package/skills/ai-task/weight_overlay.py +38 -0
- package/skills/project-init/templates/constitution.md +2 -2
- package/skills/project-update/history/blobs/00f5e27ce2d66e3a1d8b222b013ae8fa1fed32612d91a551e0c661cee3ef9c2d +34 -0
- package/skills/project-update/history/blobs/0a6b1b6dd06a35582b2e9989a1f41c40abc29254b8e482714fcc6f0a7b16c406 +32 -0
- package/skills/project-update/history/blobs/0aeb04b04262683cac6513545683486a73dc473b447bba43b5aaab18403957a6 +34 -0
- package/skills/project-update/history/blobs/0ce913a28996f546f72d570b0e5a376362e993ce4d805bc4aae57d38caa44212 +41 -0
- package/skills/project-update/history/blobs/0ea9e36446b624b73b2a821231b2ee66a357b43d584a5b23da48b3c800855e65 +41 -0
- package/skills/project-update/history/blobs/0fb1d68678a1349195b2e79433bb20174d25874e3bfd0b70410bb4e428b4e4b8 +35 -0
- package/skills/project-update/history/blobs/119b2b9d0f9c647a243540724edac6b29afa020c69aa205797bcfa9eb06bc021 +35 -0
- package/skills/project-update/history/blobs/1d0fe3ee5fb8260ba610942d4bbdfff7410fbe80ed826ac07f32985031dc2b3f +34 -0
- package/skills/project-update/history/blobs/1de9a37ed6402893dcab6e61ddbf15ffd35f15a6d84b18e675a0c5bf4e981f85 +42 -0
- package/skills/project-update/history/blobs/1f44e1a236233dcbab58064f39b69f798b35d1d9a29f8c615b5b12854ce633cb +15 -0
- package/skills/project-update/history/blobs/1f824645299579cbdd8141642ddbb4bca9fd5fe9d3112f036d8221f0811e0abf +40 -0
- package/skills/project-update/history/blobs/235fb88393cfe20dd58b35fe9785cc45baf5ffe21a13d926652d76ec68cea8b7 +35 -0
- package/skills/project-update/history/blobs/3918b4ee011d9477b9d2779e2893ab599749c406d4b09439a9748b64fbff58f3 +18 -0
- package/skills/project-update/history/blobs/449273200dfec2a56885c881ff34d40e8ecc00da53c24c2d09b7fbeb1004d255 +40 -0
- package/skills/project-update/history/blobs/4c45aee9b9fc5f6b4e1d9739e434c4094975a5a8dec6b9703fb25f3080680c77 +124 -0
- package/skills/project-update/history/blobs/4dd3fa12bc45acc8c836ab65d790248ca7504a021bca6677499d17bb3d798ed9 +64 -0
- package/skills/project-update/history/blobs/51e3f15095d7123ea8566b512479ee10a6cb2f336b7352a259a083a887bd7116 +33 -0
- package/skills/project-update/history/blobs/5497a204967bea7dab29079a6e1dfa3d8713b2d2cb294c2779378039f03a55fc +36 -0
- package/skills/project-update/history/blobs/60c4d7e7fde7049d92d84295fc13ca9a91eb2de423be08f093b3ee5d5e817ff8 +64 -0
- package/skills/project-update/history/blobs/6221b7c14cc04634e485e562d464c6860d45666a7f63e293c06bb2944ff556cc +27 -0
- package/skills/project-update/history/blobs/637971cfb844ef4285e2886a4b1c834fb2ed5c46e773adb88c2c147fea626ad3 +33 -0
- package/skills/project-update/history/blobs/65af2282eea2a51fcc27a4acf2c26c727b0961c30e1be13176369200c460c219 +34 -0
- package/skills/project-update/history/blobs/66ecd73e303e7bbc1aa8ee72435d0d10812ff7b2eff0adac59bbf0a303e2cc01 +41 -0
- package/skills/project-update/history/blobs/6a43bf32461b22b87fafe2865529dc04fa66cd00182a2a7598aa071667ca255a +35 -0
- package/skills/project-update/history/blobs/6d6dee8634abf9ac057bb206828b83a893a2afcf4f86bbe69e839a3b47d0adde +48 -0
- package/skills/project-update/history/blobs/7224ede803ea81e65a456e21b6028a0e848e8a880456c6503eebe7534ca4f6aa +74 -0
- package/skills/project-update/history/blobs/765a39a202617096c232017822ae738d37e4405430c71700dc7bc14bf1ba794e +33 -0
- package/skills/project-update/history/blobs/77577440a933d1cabd8c6f4a6401cf361a784aa09a25500a6f7b44ead8ab5e55 +41 -0
- package/skills/project-update/history/blobs/7bae90789625d6fb9071ecb412d14a8d1eb0bc5659d8d284c4eaf213e1b5de56 +67 -0
- package/skills/project-update/history/blobs/7bcdf9a0e6b85277b9b60669150224b9414d2e32821ff06f4d148eb1d18785bb +42 -0
- package/skills/project-update/history/blobs/7f834103e9d97aea44e76717bcdcbbe349c560e5b81a42ce85a1cec341041281 +4 -0
- package/skills/project-update/history/blobs/7fb3acb0211818efebc2234863db0b8c846022a7280a6d2d69f267dbf63db48c +34 -0
- package/skills/project-update/history/blobs/87f0855859ff68cc6c988cc0b631ee7f56af7fbba062172bf80e01f4982cc054 +35 -0
- package/skills/project-update/history/blobs/8abab74759766d02b5cb7b0c3e59a3d440b25a454216cd8fea325c23fd822d36 +33 -0
- package/skills/project-update/history/blobs/a1fb50e6c86fae1679ef3351296fd6713411a08cf8dd1790a4fd05fae8688164 +1 -0
- package/skills/project-update/history/blobs/a3df7268feb0780be0d2cf9acced6ed81780a7790f36fe024b6ea0b1bd6eb7a6 +35 -0
- package/skills/project-update/history/blobs/b28721136482dafb9fd2801af340364cb97e9f6eaa987908606c786045b8d334 +28 -0
- package/skills/project-update/history/blobs/b3726422d767f9219fea633bea77f0c99ad9af843c591e6e928e1ccd2a47f374 +27 -0
- package/skills/project-update/history/blobs/b3839425f9d0ab2efa42a6f5e9488ec2d26ca5fb8dcd694b8ab098e10743ca46 +32 -0
- package/skills/project-update/history/blobs/ba14a457e83f9dde65e4190fdfab83b912f7398c1442a2a1cb3d89bfac741cf3 +8 -0
- package/skills/project-update/history/blobs/bceb7189444bb6291b262ca08e34db01010dda2f6e64d696231ec3c343c95c66 +34 -0
- package/skills/project-update/history/blobs/bf82a2bb4fce1bd349ff66118930a01d61a7af8e2bd8d200c721d43afc58c713 +34 -0
- package/skills/project-update/history/blobs/c4dbeb180292a6199ad73a3be861ece07c1f8bf6bf0cc7ca204412bc8e1bb1d8 +31 -0
- package/skills/project-update/history/blobs/c644838866df2001a42501a988dd7b77aacf862bf09d22b465f3cd8a22c6b6eb +33 -0
- package/skills/project-update/history/blobs/c980d74f76a4bdfb38c94b573ac10a54eb50b850b052e15fa6f2442889b36ccb +32 -0
- package/skills/project-update/history/blobs/ceed2f3bd937f862d0e6ca59ce1b1e3603e19a0d7f85d90d6dfeb7bf690153be +29 -0
- package/skills/project-update/history/blobs/d51ea2e893482a20c5882056cf8043327ca1dc1c957927f6746929a47ee8368e +45 -0
- package/skills/project-update/history/blobs/d78f5e0bb1380259fce2cce009785a9a11f6de8b87a160080b9872c059f95060 +34 -0
- package/skills/project-update/history/blobs/d97f46a2cca020406252b1f7baa4184617fa71faca3885e2379c44ae4e1d9327 +67 -0
- package/skills/project-update/history/blobs/da3ecd4c4c414c93d04488685931df39a56bf959bfeb9c45cb1aea2c13bd991b +38 -0
- package/skills/project-update/history/blobs/e129bf71a5a922e24b2c1bc8daa8a5d2b5589b0069770e17ce17e7db5ed4e7a4 +27 -0
- package/skills/project-update/history/blobs/e504529519a371892838725f8b89b5d32e3300e345bcbf2643a3a1a48434b3dd +24 -0
- package/skills/project-update/history/blobs/e9e62d03ca70b3dffccef8dceeb214173352cfef005145e519f0e037993f1c03 +36 -0
- package/skills/project-update/history/blobs/effefbaaf4beb8f1ba55081d6b7e74bf25ebb91045dd10613418f17b95fa7182 +33 -0
- package/skills/project-update/history/blobs/f6af4581bafbf62b257d57e06c3ae2c5998aeca608ee7df037fcc3c3e4b563a9 +34 -0
- package/skills/project-update/history/blobs/fc35045777d29630303430752a651b3e553580a581036a02cc103eb96a46f4b0 +34 -0
- package/skills/project-update/history/blobs/fdc21345c77f92a42d244aa104f393f439a0ff9981a9fd462bd837e8a47931bb +48 -0
- package/skills/project-update/history/index.json +32 -13
- package/skills/project-update/render_instructions.py +12 -45
- package/skills/project-update/update.py +757 -1172
- package/skills/rr-setup/SKILL.md +42 -81
- package/skills/rr-setup/scaffold_ai.py +7 -7
- package/skills/rr-setup/setup.py +96 -164
- package/skills/rr-status/status.py +7 -10
- package/skills/usage-report/usage-report.py +4 -5
- package/skills/ai-audit/SKILL.md +0 -9
- package/skills/ai-init/SKILL.md +0 -9
- package/skills/ai-status/SKILL.md +0 -9
- package/skills/ai-task/SKILL.md +0 -9
- package/skills/project-init/SKILL.md +0 -9
- package/skills/project-update/SKILL.md +0 -9
- package/skills/project-update/adopt-map.json +0 -91
- package/skills/project-update/adopt.py +0 -2225
- package/skills/project-update/migrations/0001_schema_version.py +0 -13
- package/skills/project-update/migrations/0002_task_journal.py +0 -123
- package/skills/project-update/migrations/0003_context_diet.py +0 -65
- package/skills/project-update/migrations/0004_deterministic_gates.py +0 -57
- package/skills/project-update/migrations/0005_runtimes_and_plans.py +0 -35
- package/skills/project-update/migrations/0006_shared_files.py +0 -154
- package/skills/project-update/migrations/0007_weight_model.py +0 -295
- package/skills/project-update/migrations/0008_renames.py +0 -43
- package/skills/project-update/migrations/0009_state_file.py +0 -25
- package/skills/project-update/migrations/0010_dialog_switch.py +0 -30
- package/skills/project-update/migrations/0011_retire_risk_tiers.py +0 -37
- package/skills/project-update/migrations/README.md +0 -76
- package/skills/project-update/migrations/__init__.py +0 -186
- package/skills/sdlc-intent/SKILL.md +0 -9
- package/skills/sdlc-plan/SKILL.md +0 -9
- package/skills/sdlc-spec/SKILL.md +0 -9
- package/skills/usage-report/SKILL.md +0 -10
- /package/{ai/workflows/refactoring.md → skills/project-update/history/blobs/36cb593293496fbcf38df828a9b9b2bc0d5a53333f584a5319ebc3d799016e24} +0 -0
- /package/{ai/workflows/feature.md → skills/project-update/history/blobs/56e16072c2f3edc6c8897c690d09a11d12fc414c3e3f361f359f7dc609a21282} +0 -0
- /package/{ai/workflows/hotfix.md → skills/project-update/history/blobs/8cbefbf1aa412bae3e5019acd40b8fe0598fceba6c781906b3bc6dbd014f6b23} +0 -0
- /package/{ai/workflows/bugfix.md → skills/project-update/history/blobs/af56dc16e44ae1d8c3dac4c3ca82e2163b719553c02ea455e77430bab9a14089} +0 -0
- /package/{ai/workflows/investigation.md → skills/project-update/history/blobs/b9e09cb24958cd6831589997558974bd6356305306e8f9685e226bcdc30d60ac} +0 -0
- /package/{ai/agents/manager.md → skills/project-update/history/blobs/d0cf6388f35a92a0cf607d33909278382f6d7b6a4c32e281b9f9e0ea652c7b91} +0 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Workflow: bugfix
|
|
2
|
+
|
|
3
|
+
Something behaves wrongly. The goal is the smallest change that fixes it without
|
|
4
|
+
changing anything else.
|
|
5
|
+
|
|
6
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
7
|
+
> The table names the agent for when a stage is delegated. In the default `solo`
|
|
8
|
+
> profile T0–T2 run in direct mode — the session does every stage itself, in a
|
|
9
|
+
> few lines, with cheap readers and one `sonnet` review at T2 — and T3+ run the
|
|
10
|
+
> full pipeline with the delegations below.
|
|
11
|
+
|
|
12
|
+
| Stage | Who | Notes |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| DISCOVERY | `ai-discovery` | reproduce first: find the exact path that produces the symptom |
|
|
15
|
+
| CONTEXT | `ai-context` | include the *correct* behaviour and where it is defined |
|
|
16
|
+
| IMPACT ANALYSIS | `ai-discovery` | who else depends on the current, wrong behaviour |
|
|
17
|
+
| RISK CLASSIFICATION | `ai-risk` | a bug in a payment path is still T4 |
|
|
18
|
+
| PLAN | `ai-planner` | failing test first, then the fix |
|
|
19
|
+
| IMPLEMENTATION | the session | the failing test is its own step |
|
|
20
|
+
| TEST | the session (`ai-tester` in `team`) | the new test is shown failing before the fix; each step runs only its own scoped tests; the full verification command runs once after the last step, to the end, then the e2e suite once; every failure fixed as one batch |
|
|
21
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | T2 and above |
|
|
22
|
+
| SECURITY REVIEW | `ai-security` | if the bug was a security bug, always |
|
|
23
|
+
| RELEASE REPORT | `ai-release` | |
|
|
24
|
+
| HUMAN APPROVAL | the human | |
|
|
25
|
+
|
|
26
|
+
## Specific to this workflow
|
|
27
|
+
|
|
28
|
+
- **Write the failing test first.** A bugfix without a test that failed before it
|
|
29
|
+
is a bugfix nobody can prove.
|
|
30
|
+
- Find out *why* the bug exists before fixing it. A bug that is deliberate
|
|
31
|
+
behaviour somebody depends on is not a bug; it is a requirements conflict, and
|
|
32
|
+
it goes back to the human.
|
|
33
|
+
- Resist the urge to fix the surrounding code. Note it, fix the bug.
|
|
34
|
+
- If the same bug exists in three places, fix the one that was reported and list
|
|
35
|
+
the other two in `project/known-risks.md`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Verification — this project's commands
|
|
2
|
+
<!-- Yours. Read by state.py verify and close, setup.py check, update.py hints; /rr-setup --update never rewrites it.
|
|
3
|
+
Each line is `field: value`; a line left empty reads as "not written down yet", `none` says the project has none.
|
|
4
|
+
What each command must do is in policies/testing.md (Verification). -->
|
|
5
|
+
|
|
6
|
+
verify_command: # the full fast suite, e2e excluded, no fail-fast — e.g. make test | composer qa && vendor/bin/phpunit --exclude-group e2e
|
|
7
|
+
step_test_command: # the same runner scoped to a path or filter, `{files}` replaced by the step's paths — e.g. vendor/bin/phpunit {files} | pytest {files}
|
|
8
|
+
e2e_command: # the end-to-end suite, run once at the end of a task — e.g. make e2e | vendor/bin/behat | npx playwright test — `none` if the project has none
|
|
9
|
+
lint_command: # e.g. vendor/bin/php-cs-fixer fix --dry-run | ruff check . | npm run lint — `none` if the project has none
|
|
10
|
+
typecheck_command: # e.g. vendor/bin/phpstan analyse --no-progress | mypy . | npx tsc --noEmit — `none` if the project has none
|
|
11
|
+
single_test: # how to run one test, for the failing-test-first step of a bugfix
|
|
12
|
+
doc_tests: # the suites a documents-only edit runs after a green suite — e.g. tests/test_docs.py; `none` if the project has none
|
|
13
|
+
bite_codes: # exit codes that mean "a test failed" (default 1) — e.g. 1,2 for pytest and phpunit, 101 for cargo
|
|
14
|
+
healthy_output: # two or three lines of what a green run ends with
|
|
15
|
+
|
|
16
|
+
## Project specifics
|
|
17
|
+
|
|
18
|
+
<!-- How to run unit tests, integration tests, a single test. Where fixtures live. What the CI runs. Cite the config. -->
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
<!-- Filled by /rr-setup. Describe what the code does, not what the framework's
|
|
4
|
+
documentation says it should do. -->
|
|
5
|
+
|
|
6
|
+
## Style
|
|
7
|
+
|
|
8
|
+
<!-- Layered, hexagonal, modular monolith, service-oriented, or — most often —
|
|
9
|
+
several of these in different parts of the code. Say which is where. -->
|
|
10
|
+
|
|
11
|
+
## Entry points
|
|
12
|
+
|
|
13
|
+
<!-- HTTP routes, console commands, message consumers, cron jobs, webhooks.
|
|
14
|
+
KNOWN FACT with the file that defines each. -->
|
|
15
|
+
|
|
16
|
+
## Request and message flow
|
|
17
|
+
|
|
18
|
+
<!-- One paragraph per major flow: what comes in, what it touches, what it
|
|
19
|
+
writes, what goes out. -->
|
|
20
|
+
|
|
21
|
+
## Module boundaries
|
|
22
|
+
|
|
23
|
+
<!-- Where the seams are, and where they leak. -->
|
|
24
|
+
|
|
25
|
+
## Where state lives
|
|
26
|
+
|
|
27
|
+
<!-- Database, cache, queue, session, external systems, filesystem. -->
|
|
28
|
+
|
|
29
|
+
## Cross-cutting mechanisms
|
|
30
|
+
|
|
31
|
+
<!-- Events, the command bus, state machines, workflows, the DI container,
|
|
32
|
+
configuration and how it is layered per environment. -->
|
|
33
|
+
|
|
34
|
+
## Contradictions found
|
|
35
|
+
|
|
36
|
+
<!-- Documented behaviour: …
|
|
37
|
+
Observed behaviour: …
|
|
38
|
+
Evidence: …
|
|
39
|
+
Risk: …
|
|
40
|
+
One block per contradiction. Do not resolve it here. -->
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Testing policy
|
|
2
|
+
|
|
3
|
+
Tests describe behaviour. Coverage percentage is a side effect, not a goal.
|
|
4
|
+
|
|
5
|
+
## Characterization first
|
|
6
|
+
|
|
7
|
+
Before changing behaviour that is not covered by a test — which is most legacy
|
|
8
|
+
behaviour — write a test that passes against the code **as it is today**. That
|
|
9
|
+
test is the definition of what must not break. Only then change the code.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
characterization test → refactor → verify identical behaviour → feature change
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Never do those in one step, and never in one commit.
|
|
16
|
+
|
|
17
|
+
## What to consider, by kind of change
|
|
18
|
+
|
|
19
|
+
| Change touches | Also test |
|
|
20
|
+
|---|---|
|
|
21
|
+
| a shared service | the existing callers, not only the new one |
|
|
22
|
+
| money, tax, fiscal | rounding, currency, negative and zero amounts, refunds |
|
|
23
|
+
| a state machine | every transition that is now reachable, and the ones that must stay unreachable |
|
|
24
|
+
| an async consumer | retry, double delivery, out-of-order delivery, poison message |
|
|
25
|
+
| an external integration | timeout, 500, malformed response, partial write |
|
|
26
|
+
| a write path | idempotency, concurrency, transaction boundaries |
|
|
27
|
+
| authorization | the negative case, for every role |
|
|
28
|
+
| a public API or event | the old shape still works |
|
|
29
|
+
|
|
30
|
+
## Three scopes, three moments
|
|
31
|
+
|
|
32
|
+
A task runs tests three times at most, and each run has its own scope. Nothing
|
|
33
|
+
else runs in between.
|
|
34
|
+
|
|
35
|
+
| When | What runs | Command |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| after each implementation step, before `step-done` | **only the tests the plan named for that step** — the files it touched, their direct callers' tests | `step_test_command` |
|
|
38
|
+
| once, after the **last** step | the full fast suite — unit and integration, no e2e | `verify_command` |
|
|
39
|
+
| once, at the **end of the task**, after the full suite is green | the end-to-end suite | `e2e_command` |
|
|
40
|
+
|
|
41
|
+
- A step never runs the full suite, and **never** runs e2e. If the plan named
|
|
42
|
+
no test for a step, nothing runs for it.
|
|
43
|
+
- A step's tests are scoped by path or filter, not by `--stop-on-failure`: the
|
|
44
|
+
scoped run still goes to the end, and its failures are fixed inside that step.
|
|
45
|
+
- The e2e suite runs **once per task**, at the very end, never per step. Skip it
|
|
46
|
+
at T0/T1, and when the change cannot reach a flow the e2e suite covers — say
|
|
47
|
+
which, in one line; silence is not a verdict.
|
|
48
|
+
- A failure in a step's own tests is fixed in that step, before `step-done`;
|
|
49
|
+
the batch rule below is for the two end-of-task runs.
|
|
50
|
+
- After a green suite, a documents-only edit runs `doc_tests` (step scope), not the suite.
|
|
51
|
+
|
|
52
|
+
## Reading a failure
|
|
53
|
+
|
|
54
|
+
**Run to the end, then fix as one batch.** The verification command runs with
|
|
55
|
+
no fail-fast flag and is never interrupted at the first failure. Collect every
|
|
56
|
+
failure, classify each one, fix all the new regressions in one batch
|
|
57
|
+
(`state.py start --amend` widens the task when a fix needs more files), and run the
|
|
58
|
+
command once more. One failure never
|
|
59
|
+
sends the task back to the start: the plan, the tier and the finished steps
|
|
60
|
+
stand. At most two remediation rounds; a third means the human decides.
|
|
61
|
+
|
|
62
|
+
Classify before fixing. The four answers are:
|
|
63
|
+
|
|
64
|
+
- **EXISTING TEST FAILURE** — it failed before this change too. Say so, do not
|
|
65
|
+
fix it inside this task.
|
|
66
|
+
- **NEW REGRESSION** — this change broke it. Fix the code, not the test.
|
|
67
|
+
- **TEST ENVIRONMENT FAILURE** — database, fixtures, network, container. Say what
|
|
68
|
+
is missing.
|
|
69
|
+
- **UNKNOWN** — you could not tell. Say what you tried.
|
|
70
|
+
|
|
71
|
+
A review's MEDIUM and LOW findings are recorded with `state.py memory risk add`, not
|
|
72
|
+
fixed in the task; only a BLOCKER, a HIGH or a regression buys an `--after-fix` run.
|
|
73
|
+
|
|
74
|
+
**Never edit a test to make it pass when production behaviour changed
|
|
75
|
+
unexpectedly.** A test that suddenly disagrees with the code is evidence, and
|
|
76
|
+
deleting evidence is the worst available option.
|
|
77
|
+
|
|
78
|
+
## Verification
|
|
79
|
+
|
|
80
|
+
Three commands, one per scope. `verify_command` proves the project is healthy;
|
|
81
|
+
`step_test_command` proves one step is; `e2e_command` proves the whole flow
|
|
82
|
+
still works. Keep each to one command — chain the pieces in a Makefile or
|
|
83
|
+
composer script if there are several — and make sure none of them stops at the
|
|
84
|
+
first failure (`--stop-on-failure`, `-x`, `--bail`, `failfast` are off).
|
|
85
|
+
|
|
86
|
+
`verify_command` must **exclude** the e2e suite: it is the fast loop run after
|
|
87
|
+
the last step and again after a remediation batch. `e2e_command` runs once, at
|
|
88
|
+
the end of the task. A bugfix still shows its new failing test first — that one
|
|
89
|
+
test only, through `single_test`.
|
|
90
|
+
|
|
91
|
+
The commands themselves are written in `policies/verification.md` (`verify_command`,
|
|
92
|
+
`step_test_command`, `e2e_command`, `lint_command`, `typecheck_command`, `single_test`,
|
|
93
|
+
`doc_tests`, `bite_codes`, `healthy_output`): a human fills them in, `state.py` reads them from
|
|
94
|
+
there, and `/rr-setup --update` never rewrites that file.
|
|
95
|
+
|
|
96
|
+
`step_test_command` may contain `{files}`, which is replaced by the paths the
|
|
97
|
+
step names; without it the paths are appended. The placeholder is what lets
|
|
98
|
+
`sensors.py` run a step's own tests for the "test must bite" check, so a runner
|
|
99
|
+
that only takes a `--filter` gets `bite: unavailable` rather than a wrong answer.
|
|
100
|
+
|
|
101
|
+
`bite_codes` (optional, in `policies/verification.md`) lists the exit codes that mean "a test failed" when a
|
|
102
|
+
test is shown failing before its fix; the default is `1`. Runners that exit
|
|
103
|
+
differently say so here — `bite_codes: 1,2` for pytest (2 is a collection
|
|
104
|
+
error, such as a missing import), `1,2` for phpunit, `101` for cargo. Any other
|
|
105
|
+
code is the runner's own usage error and does not count as a bite.
|
|
106
|
+
|
|
107
|
+
`lint_command` and `typecheck_command` are read by the deterministic sensors,
|
|
108
|
+
never by a model. They decide, together with the test run, whether a light-mode change
|
|
109
|
+
can skip its model review (`state.py close` measures them). A **missing** line is
|
|
110
|
+
`unavailable` and keeps the review; only the literal `none`, written by a human,
|
|
111
|
+
says the project has no such tool. Read the exact line from the project's
|
|
112
|
+
config files (`package.json`, `composer.json`, `pyproject.toml`, `Makefile`), and
|
|
113
|
+
never run a command just to find it out.
|
|
114
|
+
|
|
115
|
+
If the project has no e2e suite, write `e2e_command: none` and say so — an
|
|
116
|
+
empty line is read as "not written down yet" and the next task will go looking
|
|
117
|
+
for it. Say which group, tag or directory marks the e2e tests and how
|
|
118
|
+
`verify_command` excludes them, so a step's scoped run and the fast suite stay
|
|
119
|
+
free of them.
|
|
120
|
+
|
|
121
|
+
## Project specifics
|
|
122
|
+
|
|
123
|
+
<!-- The real commands: how to run unit tests, integration tests, a single test.
|
|
124
|
+
Where fixtures live. What the CI runs. Cite the config. -->
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Manager
|
|
2
|
+
|
|
3
|
+
The manager is the main session, not a subagent. It orchestrates; it does not
|
|
4
|
+
collect facts itself, and it keeps its own context small so it can stay in the
|
|
5
|
+
task until the end.
|
|
6
|
+
|
|
7
|
+
The role is the same whichever runtime the session is: Claude Code or Codex. The
|
|
8
|
+
agents it delegates to carry the same names in both, and the tier each runs at is
|
|
9
|
+
the same; only the model behind that tier differs.
|
|
10
|
+
|
|
11
|
+
## Responsibilities
|
|
12
|
+
|
|
13
|
+
- Understand the request and restate it in one sentence the human can correct.
|
|
14
|
+
- Classify the task: which workflow, which risk tier.
|
|
15
|
+
- Establish scope, and defend it.
|
|
16
|
+
- Choose the stages the tier requires, and the agent for each.
|
|
17
|
+
- Do inline what the pipeline profile leaves inline — in a few lines — and
|
|
18
|
+
delegate the rest. In the `solo` profile T0–T2 are direct mode: the
|
|
19
|
+
developer's request and `grep -n` are the context, the plan is a few lines in
|
|
20
|
+
the conversation, and a subagent is spawned only as a cheap reader, for the
|
|
21
|
+
one BALANCED review at T2, or on a trigger from `policies/risk-tiers.json`.
|
|
22
|
+
From T3 the full pipeline runs, stage by stage. Never read logs, test output
|
|
23
|
+
or large files into its own context.
|
|
24
|
+
- Run the tests once, to the end, and fix every failure as one batch in a
|
|
25
|
+
`state.py remediate` step. One failure never restarts the task.
|
|
26
|
+
- Split the work into steps small enough that each one names the files it touches.
|
|
27
|
+
- Track state through `state.py` after every stage. The state file, not the
|
|
28
|
+
conversation, is what survives.
|
|
29
|
+
- Decide when to escalate a model tier, one task at a time, against the triggers
|
|
30
|
+
in `policies/risk-tiers.json`, and name the trigger when it does.
|
|
31
|
+
- Record, in every artifact, the tier **and the model that actually ran** — see
|
|
32
|
+
`policies/model-routing.md`. A gate may have moved an agent down a tier, and a
|
|
33
|
+
Codex agent file may override the model asked for at spawn time.
|
|
34
|
+
- Write the final summary the human reads.
|
|
35
|
+
|
|
36
|
+
## What the manager must not do
|
|
37
|
+
|
|
38
|
+
- Skip a stage because the task looks easy. Make it lightweight instead, and
|
|
39
|
+
record that it happened.
|
|
40
|
+
- Expand scope. A discovered problem goes into `project/known-risks.md`.
|
|
41
|
+
- Delegate the conclusion. The synthesis a human reads is written by the session.
|
|
42
|
+
- Commit, push, merge or deploy. The pipeline ends at human approval.
|
|
43
|
+
|
|
44
|
+
## Implementation
|
|
45
|
+
|
|
46
|
+
The manager implements approved steps itself, under this policy and under
|
|
47
|
+
`ai-scope-guard`. `ai-implementer` exists for mechanical, pattern-copying steps
|
|
48
|
+
and for when the human asks for it — not as the default.
|
|
49
|
+
|
|
50
|
+
## Questions, and who may answer them
|
|
51
|
+
|
|
52
|
+
The manager is the only role that asks the human, and `state.py` is the only
|
|
53
|
+
thing that writes the questions file — the path guard denies an edit to it.
|
|
54
|
+
|
|
55
|
+
- A subagent that cannot continue returns a `QUESTIONS_NEEDED` section instead of
|
|
56
|
+
guessing. Convert it, unchanged in meaning, with `state.py ask --batch`, and
|
|
57
|
+
render it for the human with `state.py questions --pending --format md`.
|
|
58
|
+
- Record the human's reply with `state.py answer Q1=B Q2:"free text"` (or
|
|
59
|
+
`--prose "1B 2A"`). Never hand-edit the file, and never answer on their behalf.
|
|
60
|
+
- While a question is pending, every stage-moving command exits 4. That is the
|
|
61
|
+
point: the pipeline stops rather than drifting on an assumption.
|
|
62
|
+
- Human approval is not the manager's to grant. `state.py approve` refuses
|
|
63
|
+
without a terminal, an `AI_UNATTENDED` launcher, or an `[Answer]:` filled into
|
|
64
|
+
the gate question by the human. Print the exact command and stop.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Workflow: feature
|
|
2
|
+
|
|
3
|
+
New behaviour that someone asked for. The default workflow.
|
|
4
|
+
|
|
5
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
6
|
+
> The table names the agent for when a stage is delegated. In the default `solo`
|
|
7
|
+
> profile T0–T2 run in direct mode — the session does every stage itself, in a
|
|
8
|
+
> few lines, with cheap readers and one BALANCED review at T2 — and T3+ run the
|
|
9
|
+
> full pipeline with the delegations below.
|
|
10
|
+
|
|
11
|
+
| Stage | Who | Notes |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| DISCOVERY | `ai-indexer` then `ai-discovery` | where the feature lands, what it will touch |
|
|
14
|
+
| CONTEXT | `ai-context` | the structured summary everything downstream reads |
|
|
15
|
+
| IMPACT ANALYSIS | `ai-discovery` (second pass) | callers, data, contracts, other environments |
|
|
16
|
+
| RISK CLASSIFICATION | `ai-risk` | one tier, from `policies/risk-tiers.json` |
|
|
17
|
+
| PLAN | none at T0/T1; the session at T2; `ai-planner` from T3 | steps with `allowed_files`; STRONG for T3/T4, `ai-expert` for T5 |
|
|
18
|
+
| PLAN REVIEW | `ai-reviewer` | T3 and above |
|
|
19
|
+
| IMPLEMENTATION | the session, one step at a time | scope-guarded |
|
|
20
|
+
| TEST | the session (`ai-tester` in `team`) | per step, only that step's tests; the full suite once after the last step, to the end, then the e2e suite once at the end of the task; every failure fixed as one batch, then one more run |
|
|
21
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | T2 and above |
|
|
22
|
+
| SECURITY REVIEW | `ai-security` | T4, T5, and anything touching auth or personal data |
|
|
23
|
+
| RELEASE REPORT | `ai-release` | full report from T2 up |
|
|
24
|
+
| HUMAN APPROVAL | the human | the pipeline stops here |
|
|
25
|
+
|
|
26
|
+
## Specific to this workflow
|
|
27
|
+
|
|
28
|
+
- The plan states what stays the same, not only what changes. A feature that
|
|
29
|
+
quietly alters an existing behaviour is the most common source of regressions.
|
|
30
|
+
- New code paths need their negative cases tested: not authorized, not found,
|
|
31
|
+
invalid input, external system down.
|
|
32
|
+
- If the feature needs a new dependency, that is a decision worth its own line in
|
|
33
|
+
the plan.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Workflow: bugfix
|
|
2
|
+
|
|
3
|
+
Something behaves wrongly. The goal is the smallest change that fixes it without
|
|
4
|
+
changing anything else.
|
|
5
|
+
|
|
6
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
7
|
+
> The table names the agent for when a stage is delegated. In the default `solo`
|
|
8
|
+
> profile T0–T4 run in direct mode — the session does every stage itself, in a
|
|
9
|
+
> few lines, with cheap readers and one review (BALANCED at T2/T3, and only
|
|
10
|
+
> when a sensor is red; STRONG at T4, whose plan the human approves in plan
|
|
11
|
+
> mode) — and T5+ run the full pipeline with the delegations below.
|
|
12
|
+
|
|
13
|
+
| Stage | Who | Notes |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| DISCOVERY | `ai-discovery` | reproduce first: find the exact path that produces the symptom |
|
|
16
|
+
| CONTEXT | `ai-context` | include the *correct* behaviour and where it is defined |
|
|
17
|
+
| IMPACT ANALYSIS | `ai-discovery` | who else depends on the current, wrong behaviour |
|
|
18
|
+
| RISK CLASSIFICATION | `ai-risk` | a bug in a payment path is still T5 |
|
|
19
|
+
| PLAN | `ai-planner` | failing test first, then the fix |
|
|
20
|
+
| IMPLEMENTATION | the session | the failing test is its own step |
|
|
21
|
+
| TEST | the session (`ai-tester` in `team`) | the new test is shown failing before the fix; each step runs only its own scoped tests; the full verification command runs once after the last step, to the end, then the e2e suite once; every failure fixed as one batch |
|
|
22
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | T2 and above; up to T3 the sensors stand in when all are green |
|
|
23
|
+
| SECURITY REVIEW | `ai-security` | if the bug was a security bug, always |
|
|
24
|
+
| RELEASE REPORT | `ai-release` | |
|
|
25
|
+
| HUMAN APPROVAL | the human | |
|
|
26
|
+
|
|
27
|
+
## Specific to this workflow
|
|
28
|
+
|
|
29
|
+
- **Write the failing test first.** A bugfix without a test that failed before it
|
|
30
|
+
is a bugfix nobody can prove.
|
|
31
|
+
- Find out *why* the bug exists before fixing it. A bug that is deliberate
|
|
32
|
+
behaviour somebody depends on is not a bug; it is a requirements conflict, and
|
|
33
|
+
it goes back to the human.
|
|
34
|
+
- Resist the urge to fix the surrounding code. Note it, fix the bug.
|
|
35
|
+
- If the same bug exists in three places, fix the one that was reported and list
|
|
36
|
+
the other two in `project/known-risks.md`.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Manager
|
|
2
|
+
|
|
3
|
+
The manager is the main session, not a subagent. It orchestrates; it does not
|
|
4
|
+
collect facts itself, and it keeps its own context small so it can stay in the
|
|
5
|
+
task until the end.
|
|
6
|
+
|
|
7
|
+
The role is the same whichever runtime the session is: Claude Code or Codex. The
|
|
8
|
+
agents it delegates to carry the same names in both, and the tier each runs at is
|
|
9
|
+
the same; only the model behind that tier differs.
|
|
10
|
+
|
|
11
|
+
## Responsibilities
|
|
12
|
+
|
|
13
|
+
- Understand the request and restate it in one sentence the human can correct.
|
|
14
|
+
- Classify the task: which workflow, which risk tier.
|
|
15
|
+
- Establish scope, and defend it.
|
|
16
|
+
- Choose the stages the tier requires, and the agent for each.
|
|
17
|
+
- Do inline what the pipeline profile leaves inline — in a few lines — and
|
|
18
|
+
delegate the rest. In the `solo` profile T0–T2 are direct mode: the
|
|
19
|
+
developer's request and `grep -n` are the context, the plan is a few lines in
|
|
20
|
+
the conversation, and a subagent is spawned only as a cheap reader, for the
|
|
21
|
+
one `sonnet` review at T2, or on a trigger from `policies/risk-tiers.json`.
|
|
22
|
+
From T3 the full pipeline runs, stage by stage. Never read logs, test output
|
|
23
|
+
or large files into its own context.
|
|
24
|
+
- Run the tests once, to the end, and fix every failure as one batch in a
|
|
25
|
+
`state.py remediate` step. One failure never restarts the task.
|
|
26
|
+
- Split the work into steps small enough that each one names the files it touches.
|
|
27
|
+
- Track state through `state.py` after every stage. The state file, not the
|
|
28
|
+
conversation, is what survives.
|
|
29
|
+
- Decide when to escalate a model tier, one task at a time, against the triggers
|
|
30
|
+
in `policies/risk-tiers.json`, and name the trigger when it does.
|
|
31
|
+
- Record, in every artifact, the tier **and the model that actually ran** — see
|
|
32
|
+
`policies/model-routing.md`. A gate may have moved an agent down a tier, and a
|
|
33
|
+
Codex agent file may override the model asked for at spawn time.
|
|
34
|
+
- Write the final summary the human reads.
|
|
35
|
+
|
|
36
|
+
## What the manager must not do
|
|
37
|
+
|
|
38
|
+
- Skip a stage because the task looks easy. Make it lightweight instead, and
|
|
39
|
+
record that it happened.
|
|
40
|
+
- Expand scope. A discovered problem goes into `project/known-risks.md`.
|
|
41
|
+
- Delegate the conclusion. The synthesis a human reads is written by the session.
|
|
42
|
+
- Commit, push, merge or deploy. The pipeline ends at human approval.
|
|
43
|
+
|
|
44
|
+
## Implementation
|
|
45
|
+
|
|
46
|
+
The manager implements approved steps itself, under this policy and under
|
|
47
|
+
`ai-scope-guard`. `ai-implementer` exists for mechanical, pattern-copying steps
|
|
48
|
+
and for when the human asks for it — not as the default.
|
|
49
|
+
|
|
50
|
+
## Questions, and who may answer them
|
|
51
|
+
|
|
52
|
+
The manager is the only role that asks the human, and `state.py` is the only
|
|
53
|
+
thing that writes the questions file — the path guard denies an edit to it.
|
|
54
|
+
|
|
55
|
+
- A subagent that cannot continue returns a `QUESTIONS_NEEDED` section instead of
|
|
56
|
+
guessing. Convert it, unchanged in meaning, with `state.py ask --batch`, and
|
|
57
|
+
render it for the human with `state.py questions --pending --format md`.
|
|
58
|
+
- Record the human's reply with `state.py answer Q1=B Q2:"free text"` (or
|
|
59
|
+
`--prose "1B 2A"`). Never hand-edit the file, and never answer on their behalf.
|
|
60
|
+
- While a question is pending, every stage-moving command exits 4. That is the
|
|
61
|
+
point: the pipeline stops rather than drifting on an assumption.
|
|
62
|
+
- Human approval is not the manager's to grant. `state.py approve` refuses
|
|
63
|
+
without a terminal, an `AI_UNATTENDED` launcher, or an `[Answer]:` filled into
|
|
64
|
+
the gate question by the human. Print the exact command and stop.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Project overview
|
|
2
|
+
|
|
3
|
+
<!-- Filled by /rr-setup from the repository. Every statement carries a label:
|
|
4
|
+
KNOWN FACT (with file:line) · INFERENCE (with what it rests on) ·
|
|
5
|
+
UNKNOWN (with what would answer it) · RISK (with what could go wrong). -->
|
|
6
|
+
|
|
7
|
+
## What this system does
|
|
8
|
+
|
|
9
|
+
## Stack
|
|
10
|
+
|
|
11
|
+
<!-- Languages, frameworks and their versions, package managers. KNOWN FACT with
|
|
12
|
+
the manifest that proves each one. -->
|
|
13
|
+
|
|
14
|
+
## How it runs
|
|
15
|
+
|
|
16
|
+
<!-- Local: containers, services, entry points. Production: where, how deployed. -->
|
|
17
|
+
|
|
18
|
+
## Repository layout
|
|
19
|
+
|
|
20
|
+
<!-- The directories that matter and what lives in each. Skip the obvious. -->
|
|
21
|
+
|
|
22
|
+
## Team and process context
|
|
23
|
+
|
|
24
|
+
<!-- Supplied by the human, not discoverable from the code: team size, who owns
|
|
25
|
+
what, the tracker, regulatory constraints, release cadence. -->
|
|
26
|
+
|
|
27
|
+
## Unknowns
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Workflow: hotfix
|
|
2
|
+
|
|
3
|
+
Production is broken now. Stages get shorter; none of them disappears.
|
|
4
|
+
|
|
5
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
6
|
+
> The table names the agent for when a stage is delegated; in the default `solo`
|
|
7
|
+
> profile the session does the stage inline up to the tier where the profile
|
|
8
|
+
> delegates it.
|
|
9
|
+
|
|
10
|
+
| Stage | Who | Notes |
|
|
11
|
+
|---|---|---|
|
|
12
|
+
| DISCOVERY | `ai-discovery` | narrow: the failing path only |
|
|
13
|
+
| CONTEXT | the session, inline | a paragraph, recorded in the state file |
|
|
14
|
+
| RISK CLASSIFICATION | `ai-risk` | the tier of the code being touched, not of the urgency |
|
|
15
|
+
| PLAN | `ai-planner` or the session | the smallest change that stops the bleeding |
|
|
16
|
+
| IMPLEMENTATION | the session | one step |
|
|
17
|
+
| TEST | `ai-tester` | at minimum, a test that reproduces the incident |
|
|
18
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | short, focused on "what else does this touch" |
|
|
19
|
+
| SECURITY REVIEW | `ai-security` | if the incident is a security incident |
|
|
20
|
+
| RELEASE REPORT | `ai-release` | short form, but rollback is mandatory |
|
|
21
|
+
| HUMAN APPROVAL | the human | always, and usually faster than the rest |
|
|
22
|
+
|
|
23
|
+
## Rules
|
|
24
|
+
|
|
25
|
+
- Urgency lowers the *depth* of a stage, never its existence. The risk tier is a
|
|
26
|
+
property of the code, not of how loudly someone is asking.
|
|
27
|
+
- A hotfix is the smallest possible change. Everything else — the real fix, the
|
|
28
|
+
cleanup, the missing test — becomes a follow-up task, written down before the
|
|
29
|
+
hotfix is approved so it does not evaporate when the incident closes.
|
|
30
|
+
- Record what actually happened in `project/known-risks.md`: the trigger, the
|
|
31
|
+
detection, and what would have caught it earlier.
|
|
32
|
+
- Never disable a test or a check to get a hotfix out. If CI is the obstacle, a
|
|
33
|
+
human decides that, explicitly.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Workflow: feature
|
|
2
|
+
|
|
3
|
+
New behaviour that someone asked for. The default workflow.
|
|
4
|
+
|
|
5
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
6
|
+
> The table names the agent for when a stage is delegated. In the default `solo`
|
|
7
|
+
> profile T0–T4 run in direct mode — the session does every stage itself, in a
|
|
8
|
+
> few lines, with cheap readers and one review (BALANCED at T2/T3, and only
|
|
9
|
+
> when a sensor is red; STRONG at T4, whose plan the human approves in plan
|
|
10
|
+
> mode) — and T5+ run the full pipeline with the delegations below.
|
|
11
|
+
|
|
12
|
+
| Stage | Who | Notes |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| DISCOVERY | `ai-indexer` then `ai-discovery` | where the feature lands, what it will touch |
|
|
15
|
+
| CONTEXT | `ai-context` | the structured summary everything downstream reads |
|
|
16
|
+
| IMPACT ANALYSIS | `ai-discovery` (second pass) | callers, data, contracts, other environments |
|
|
17
|
+
| RISK CLASSIFICATION | `ai-risk` | one tier, from `policies/risk-tiers.json` |
|
|
18
|
+
| PLAN | none at T0/T1; the session at T2/T3, in plan mode at T4; `ai-planner` from T5 | steps with `allowed_files`; STRONG for T5, `ai-expert` for T6 |
|
|
19
|
+
| PLAN REVIEW | the human at T4 (plan mode); `ai-reviewer` from T5 | |
|
|
20
|
+
| IMPLEMENTATION | the session, one step at a time | scope-guarded |
|
|
21
|
+
| TEST | the session (`ai-tester` in `team`) | per step, only that step's tests; the full suite once after the last step, to the end, then the e2e suite once at the end of the task; every failure fixed as one batch, then one more run |
|
|
22
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | T2 and above; up to T3 the sensors stand in when all are green |
|
|
23
|
+
| SECURITY REVIEW | `ai-security` | T5, T6, and anything touching auth or personal data |
|
|
24
|
+
| RELEASE REPORT | `ai-release` | full report from T2 up |
|
|
25
|
+
| HUMAN APPROVAL | the human | the pipeline stops here |
|
|
26
|
+
|
|
27
|
+
## Specific to this workflow
|
|
28
|
+
|
|
29
|
+
- The plan states what stays the same, not only what changes. A feature that
|
|
30
|
+
quietly alters an existing behaviour is the most common source of regressions.
|
|
31
|
+
- New code paths need their negative cases tested: not authorized, not found,
|
|
32
|
+
invalid input, external system down.
|
|
33
|
+
- If the feature needs a new dependency, that is a decision worth its own line in
|
|
34
|
+
the plan.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Manager
|
|
2
|
+
|
|
3
|
+
The manager is the main session, not a subagent. It orchestrates; it does not
|
|
4
|
+
collect facts itself, and it keeps its own context small so it can stay in the
|
|
5
|
+
task until the end.
|
|
6
|
+
|
|
7
|
+
The role is the same whichever runtime the session is: Claude Code or Codex. The
|
|
8
|
+
agents it delegates to carry the same names in both, and the tier each runs at is
|
|
9
|
+
the same; only the model behind that tier differs.
|
|
10
|
+
|
|
11
|
+
## Responsibilities
|
|
12
|
+
|
|
13
|
+
- Understand the request and restate it in one sentence the human can correct.
|
|
14
|
+
- Classify the task: which workflow, which risk tier.
|
|
15
|
+
- Establish scope, and defend it.
|
|
16
|
+
- Choose the stages the tier requires, and the agent for each.
|
|
17
|
+
- Delegate every reading and analysis stage. Never read logs, test output or
|
|
18
|
+
large files into its own context.
|
|
19
|
+
- Split the work into steps small enough that each one names the files it touches.
|
|
20
|
+
- Track state through `state.py` after every stage. The state file, not the
|
|
21
|
+
conversation, is what survives.
|
|
22
|
+
- Decide when to escalate a model tier, one task at a time, against the triggers
|
|
23
|
+
in `policies/risk-tiers.json`, and name the trigger when it does.
|
|
24
|
+
- Record, in every artifact, the tier **and the model that actually ran** — see
|
|
25
|
+
`policies/model-routing.md`. A gate may have moved an agent down a tier, and a
|
|
26
|
+
Codex agent file may override the model asked for at spawn time.
|
|
27
|
+
- Write the final summary the human reads.
|
|
28
|
+
|
|
29
|
+
## What the manager must not do
|
|
30
|
+
|
|
31
|
+
- Skip a stage because the task looks easy. Make it lightweight instead, and
|
|
32
|
+
record that it happened.
|
|
33
|
+
- Expand scope. A discovered problem goes into `project/known-risks.md`.
|
|
34
|
+
- Delegate the conclusion. The synthesis a human reads is written by the session.
|
|
35
|
+
- Commit, push, merge or deploy. The pipeline ends at human approval.
|
|
36
|
+
|
|
37
|
+
## Implementation
|
|
38
|
+
|
|
39
|
+
The manager implements approved steps itself, under this policy and under
|
|
40
|
+
`ai-scope-guard`. `ai-implementer` exists for mechanical, pattern-copying steps
|
|
41
|
+
and for when the human asks for it — not as the default.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Workflow: hotfix
|
|
2
|
+
|
|
3
|
+
Production is broken now. Stages get shorter; none of them disappears.
|
|
4
|
+
|
|
5
|
+
> Who runs a stage is set by `pipeline_profile` in `policies/risk-tiers.json`.
|
|
6
|
+
> The table names the agent for when a stage is delegated. In the default `solo`
|
|
7
|
+
> profile T0–T4 run in direct mode — the session does every stage itself, in a
|
|
8
|
+
> few lines, with cheap readers and one review (BALANCED at T2/T3, and only
|
|
9
|
+
> when a sensor is red; STRONG at T4, whose plan the human approves in plan
|
|
10
|
+
> mode) — and T5+ run the full pipeline with the delegations below.
|
|
11
|
+
|
|
12
|
+
| Stage | Who | Notes |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| DISCOVERY | `ai-discovery` | narrow: the failing path only |
|
|
15
|
+
| CONTEXT | the session, inline | a paragraph, recorded in the state file |
|
|
16
|
+
| RISK CLASSIFICATION | `ai-risk` | the tier of the code being touched, not of the urgency |
|
|
17
|
+
| PLAN | `ai-planner` or the session | the smallest change that stops the bleeding |
|
|
18
|
+
| IMPLEMENTATION | the session | one step |
|
|
19
|
+
| TEST | the session (`ai-tester` in `team`) | at minimum, a test that reproduces the incident, run scoped; the full command once after the fix, then e2e only if the incident is in a flow it covers; failures fixed as one batch |
|
|
20
|
+
| ADVERSARIAL REVIEW | `ai-reviewer` | short, focused on "what else does this touch" |
|
|
21
|
+
| SECURITY REVIEW | `ai-security` | if the incident is a security incident |
|
|
22
|
+
| RELEASE REPORT | `ai-release` | short form, but rollback is mandatory |
|
|
23
|
+
| HUMAN APPROVAL | the human | always, and usually faster than the rest |
|
|
24
|
+
|
|
25
|
+
## Rules
|
|
26
|
+
|
|
27
|
+
- Urgency lowers the *depth* of a stage, never its existence. The risk tier is a
|
|
28
|
+
property of the code, not of how loudly someone is asking.
|
|
29
|
+
- A hotfix is the smallest possible change. Everything else — the real fix, the
|
|
30
|
+
cleanup, the missing test — becomes a follow-up task, written down before the
|
|
31
|
+
hotfix is approved so it does not evaporate when the incident closes.
|
|
32
|
+
- Record what actually happened in `project/known-risks.md`: the trigger, the
|
|
33
|
+
detection, and what would have caught it earlier.
|
|
34
|
+
- Never disable a test or a check to get a hotfix out. If CI is the obstacle, a
|
|
35
|
+
human decides that, explicitly.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"axes": {
|
|
4
|
+
"scope": {"measure": "references", "bands": [0, 5], "hot_paths": ["hooks/**", "src/Shared/**"]},
|
|
5
|
+
"behaviour": {"measure": "session",
|
|
6
|
+
"keywords": ["workflow", "transition", "state machine", "messenger", "queue", "async", "transaction"]},
|
|
7
|
+
"reversibility": {"measure": "paths+content",
|
|
8
|
+
"needs_step": ["**/migrations/**", "**/Migrations/**", "config/**", "k8s/**", "**/env/**"],
|
|
9
|
+
"irreversible": ["**/prod/**", "**/production/**", "deploy/**", "**/*.deploy.*"],
|
|
10
|
+
"irreversible_content": ["DROP ", "TRUNCATE", "DELETE FROM", "ALTER .* DROP", "RENAME"]},
|
|
11
|
+
"domain": {"measure": "modules+session",
|
|
12
|
+
"modules": ["**/Payment/**", "**/Tax/**", "**/Invoice/**", "**/Security/**", "**/account/**"],
|
|
13
|
+
"customer_visible": ["templates/**", "**/Shop/**", "**/Resources/views/**"]},
|
|
14
|
+
"novelty": {"measure": "session",
|
|
15
|
+
"manifests": ["composer.json", "requirements*.txt", "package.json", "pyproject.toml", "Gemfile"]},
|
|
16
|
+
"coverage": {"measure": "tests-map",
|
|
17
|
+
"code_globs": ["**/*.php", "**/*.py", "**/*.js", "**/*.ts", "**/*.sh"],
|
|
18
|
+
"test_globs": ["tests/**", "spec/**", "**/*Test.php", "**/*.test.*", "**/*.spec.*", "**/test_*.py"],
|
|
19
|
+
"map": {}}
|
|
20
|
+
},
|
|
21
|
+
"hints": [
|
|
22
|
+
{"paths": ["**/login*", "**/Security/**", "**/*Auth*"], "axis": "domain", "note": "auth-shaped path"},
|
|
23
|
+
{"paths": [".ai/policies/**", ".claude/**", ".codex/**", "CLAUDE.md", "AGENTS.md"], "axis": "behaviour", "note": "pipeline"},
|
|
24
|
+
{"paths": ["composer.json", "package.json", "requirements*.txt"], "axis": "novelty", "note": "dependency manifest"}
|
|
25
|
+
],
|
|
26
|
+
"modes": {
|
|
27
|
+
"light": {"max_w": 2, "plan": "inline", "review": "on_red_fact", "reviewer": "BALANCED",
|
|
28
|
+
"human_stops": 0, "suite": "verify", "e2e": false},
|
|
29
|
+
"guarded": {"max_w": 7, "plan": "plan_mode", "review": "one", "reviewer": "BALANCED",
|
|
30
|
+
"human_stops": 1, "suite": "verify+e2e", "e2e": true},
|
|
31
|
+
"full": {"min_w": 8, "hard_axes": ["reversibility", "domain"], "plan": "written", "review": "one",
|
|
32
|
+
"reviewer": "STRONG", "security_focus_when": "domain=2", "human_stops": 2, "suite": "verify+e2e", "e2e": true},
|
|
33
|
+
"full_irreversible": {"when": "reversibility=2 and domain=2, or irreversible_content",
|
|
34
|
+
"human_stops": 3, "confirm_names_operation": true}
|
|
35
|
+
},
|
|
36
|
+
"rules": {"unknown_scores": 1, "hint_raises_by": 1, "hint_raises_once_per_axis": true,
|
|
37
|
+
"rescore_axes": ["reversibility", "domain"], "rescore_direction": "up", "lower_by": "human",
|
|
38
|
+
"steps_advice_over": 8},
|
|
39
|
+
"review_rounds_max": 2,
|
|
40
|
+
"remediation_rounds": 2,
|
|
41
|
+
"tests": {"max_suite_runs": 2, "timeout_seconds": 1800, "env_retries": 1, "log_max_bytes": 2097152},
|
|
42
|
+
"batch": {"default": false, "review_rounds_max": 3, "max_suite_runs": 8, "parallel": 3, "tier": "BALANCED"},
|
|
43
|
+
"examples": {
|
|
44
|
+
"light": ["a font or copy change in one template", "a test-only change", "a message-text change"],
|
|
45
|
+
"guarded": ["a regex fix in a hot guard script", "a dev-environment manifest", "a feature with a new screen and an additive migration"],
|
|
46
|
+
"full": ["a change in Payment/, Tax/ or Security/", "a migration that rewrites user trees", "a production manifest or secret"]
|
|
47
|
+
}
|
|
48
|
+
}
|