riskrails 0.0.0-stage → 3.0.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.
- package/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +21 -0
- package/.claude-plugin/plugin.json +21 -0
- package/.codex-plugin/plugin.json +37 -0
- package/LICENSE +21 -0
- package/README.md +868 -2
- package/agents/Explore.md.tmpl +21 -0
- package/agents/ai-discovery.md.tmpl +65 -0
- package/agents/ai-reviewer.md.tmpl +144 -0
- package/agents/architect.md.tmpl +22 -0
- package/agents/log-reader.md.tmpl +23 -0
- package/agents/superseded/reviewer.md +16 -0
- package/ai/agents/context.md +59 -0
- package/ai/agents/discovery.md +56 -0
- package/ai/agents/implementer.md +67 -0
- package/ai/agents/manager.md +5 -0
- package/ai/agents/planner.md +71 -0
- package/ai/agents/release.md +43 -0
- package/ai/agents/reviewer.md +106 -0
- package/ai/agents/risk.md +46 -0
- package/ai/agents/security.md +53 -0
- package/ai/agents/tester.md +30 -0
- package/ai/policies/context-management.md +85 -0
- package/ai/policies/database.md +42 -0
- package/ai/policies/git.md +35 -0
- package/ai/policies/model-routing.md +112 -0
- package/ai/policies/production.md +42 -0
- package/ai/policies/release.md +48 -0
- package/ai/policies/review-economy.md +209 -0
- package/ai/policies/tooling.md +105 -0
- package/ai/templates/architecture-decision.md +29 -0
- package/ai/templates/impact-report.md +35 -0
- package/ai/templates/implementation-plan.md +54 -0
- package/ai/templates/release-report.md +52 -0
- package/ai/templates/review-report.md +30 -0
- package/ai/templates/task-context.md +18 -0
- package/ai/using-riskrails.md +60 -0
- package/ai/workflows/bugfix.md +4 -0
- package/ai/workflows/feature.md +4 -0
- package/ai/workflows/hotfix.md +4 -0
- package/ai/workflows/investigation.md +4 -0
- package/ai/workflows/refactoring.md +4 -0
- package/ai/workflows.md +81 -0
- package/bin/claude-1m +37 -0
- package/bin/riskrails.js +1358 -0
- package/codex/hooks.json +103 -0
- package/hooks/AGENTS.md +6 -0
- package/hooks/CLAUDE.md +6 -0
- package/hooks/ai-git-guard-defaults.json +28 -0
- package/hooks/ai-guard.py +92 -0
- package/hooks/ai-path-guard-defaults.json +48 -0
- package/hooks/cap-large-read.py +113 -0
- package/hooks/codex-hooks.json +103 -0
- package/hooks/context-guard.py +612 -0
- package/hooks/guard/__init__.py +1 -0
- package/hooks/guard/common.py +633 -0
- package/hooks/guard/ere.py +592 -0
- package/hooks/guard/git.py +245 -0
- package/hooks/guard/paths.py +1374 -0
- package/hooks/guard/scope.py +387 -0
- package/hooks/hooks.json +122 -0
- package/hooks/lib/ai-hook-common.sh +285 -0
- package/hooks/project-scaffold.py +292 -0
- package/hooks/project-scaffold.sh +14 -0
- package/hooks/runtime-gate.py +1167 -0
- package/instructions/routing.md +137 -0
- package/instructions/runtimes.json +48 -0
- package/instructions/stub.md +93 -0
- package/package.json +13 -4
- package/profiles/balanced-max.json +14 -0
- package/profiles/codex-balanced-max.json +97 -0
- package/profiles/codex-plus.json +96 -0
- package/profiles/codex-pro.json +96 -0
- package/profiles/max.json +77 -0
- package/profiles/max20.json +23 -0
- package/profiles/pro.json +74 -0
- package/scripts/ai-path +104 -0
- package/scripts/merge-codex-config.py +227 -0
- package/scripts/render-codex-agents.py +185 -0
- package/scripts/resolve-profile.py +128 -0
- package/settings.common.json +89 -0
- package/settings.gate.json +64 -0
- package/skills/AGENTS.md +6 -0
- package/skills/CLAUDE.md +6 -0
- package/skills/ai-audit/SKILL.md +9 -0
- package/skills/ai-audit/templates/ai-sdlc-adoption-plan.md +87 -0
- package/skills/ai-audit/templates/play-scoring-rubric.md +122 -0
- package/skills/ai-init/SKILL.md +9 -0
- package/skills/ai-init/scaffold-ai.sh +10 -0
- package/skills/ai-init/templates/.ai/AGENTS.md +67 -0
- package/skills/ai-init/templates/.ai/VERSION +1 -0
- package/skills/ai-init/templates/.ai/policies/coding.md +32 -0
- package/skills/ai-init/templates/.ai/policies/path-guard.json +5 -0
- package/skills/ai-init/templates/.ai/policies/risk-tiers.json +628 -0
- package/skills/ai-init/templates/.ai/policies/risk-tiers.md +180 -0
- package/skills/ai-init/templates/.ai/policies/safety.md +64 -0
- package/skills/ai-init/templates/.ai/policies/security.md +69 -0
- package/skills/ai-init/templates/.ai/policies/testing.md +118 -0
- package/skills/ai-init/templates/.ai/policies/weight.json +48 -0
- package/skills/ai-init/templates/.ai/policies/weight.md +32 -0
- package/skills/ai-init/templates/.ai/project/architecture.md +40 -0
- package/skills/ai-init/templates/.ai/project/business-rules.md +21 -0
- package/skills/ai-init/templates/.ai/project/dependencies.md +27 -0
- package/skills/ai-init/templates/.ai/project/glossary.md +8 -0
- package/skills/ai-init/templates/.ai/project/initial-assessment.md +8 -0
- package/skills/ai-init/templates/.ai/project/integrations.md +20 -0
- package/skills/ai-init/templates/.ai/project/known-risks.md +16 -0
- package/skills/ai-init/templates/.ai/project/legacy.md +28 -0
- package/skills/ai-init/templates/.ai/project/modules.md +18 -0
- package/skills/ai-init/templates/.ai/project/overview.md +27 -0
- package/skills/ai-init/templates/.ai/reports/.gitkeep +0 -0
- package/skills/ai-init/templates/.ai/rules/README.md +24 -0
- package/skills/ai-init/templates/.ai/state/README.md +64 -0
- package/skills/ai-init/templates/AGENTS.block.md +13 -0
- package/skills/ai-init/templates/AGENTS.minimal.md +23 -0
- package/skills/ai-init/templates/CLAUDE.block.md +13 -0
- package/skills/ai-init/templates/CLAUDE.minimal.md +23 -0
- package/skills/ai-init/templates/GEMINI.block.md +13 -0
- package/skills/ai-init/templates/GEMINI.minimal.md +23 -0
- package/skills/ai-init/templates/gitignore.snippet +5 -0
- package/skills/ai-init/templates/junie-guidelines.block.md +13 -0
- package/skills/ai-init/templates/junie-guidelines.minimal.md +23 -0
- package/skills/ai-status/SKILL.md +9 -0
- package/skills/ai-task/SKILL.md +9 -0
- package/skills/ai-task/sensors.py +424 -0
- package/skills/ai-task/state.py +4310 -0
- package/skills/ai-task/weight.py +300 -0
- package/skills/project-init/SKILL.md +9 -0
- package/skills/project-init/templates/AGENTS.md +27 -0
- package/skills/project-init/templates/CLAUDE.md +27 -0
- package/skills/project-init/templates/GEMINI.md +27 -0
- package/skills/project-init/templates/adr.md +29 -0
- package/skills/project-init/templates/constitution.md +15 -0
- package/skills/project-init/templates/gitignore.snippet +4 -0
- package/skills/project-init/templates/intent.md +35 -0
- package/skills/project-init/templates/junie-guidelines.md +27 -0
- package/skills/project-init/templates/memory-README.md +21 -0
- package/skills/project-init/templates/plan.md +25 -0
- package/skills/project-init/templates/project-config.toml +18 -0
- package/skills/project-init/templates/project-settings.json +5 -0
- package/skills/project-init/templates/sdlc-README.md +24 -0
- package/skills/project-init/templates/spec.md +30 -0
- package/skills/project-update/SKILL.md +9 -0
- package/skills/project-update/adopt-map.json +91 -0
- package/skills/project-update/adopt.py +2211 -0
- package/skills/project-update/history/blobs/01c32f8ff038787e49070b8b0eb160eb4b4704a020b050678292051fc73a4fc6 +106 -0
- package/skills/project-update/history/blobs/06e9d52c1720fca412803e3b07c4b228ff113e303f4c7ab94665319d832bbfb7 +1 -0
- package/skills/project-update/history/blobs/099f3debfe1ce808502661de4a31c3a349f149f5fe7246691d41a4966179a63c +5 -0
- package/skills/project-update/history/blobs/0b0a7e354e1d1c86351700d5fb63d16426536875f5fecb759d15e326b7f30289 +180 -0
- package/skills/project-update/history/blobs/0bb70da941a7fc0ae2a0dbfcf06441a40f0653b3b9c573328ad9fb6d66f2e133 +27 -0
- package/skills/project-update/history/blobs/0cb92e5048badfab2cb78ff030c824f8cccaf45b83b8587bcb20ab795e8d36ae +89 -0
- package/skills/project-update/history/blobs/0e221e9337f050ffe0e834be12c1a5b46d82dec446b57ebcfbaa0ec8996bd54c +372 -0
- package/skills/project-update/history/blobs/0ec82daa4a17bcd5bf9d4df20ce90fd09312d3d439f7064baf7c8dd77a6c44fc +27 -0
- package/skills/project-update/history/blobs/0f00cbb216a20c7f67749ffb88835bcaaa29cc1a4c15d468edb3c6039bd291d3 +53 -0
- package/skills/project-update/history/blobs/0fab5540c131185e2ccdc10baad52783d7d4ff164843cae7f1b7f310c7d102ec +73 -0
- package/skills/project-update/history/blobs/10159baf262b43a92d95db59dae1f72c645127301661e0a3ce4e38b295a97c58 +1 -0
- package/skills/project-update/history/blobs/1121cfccd5913f0a63fec40a6ffd44ea64f9dc135c66634ba001d10bcf4302a2 +1 -0
- package/skills/project-update/history/blobs/12288b1b5573ee6e9e18eccdc6f5ae6cef9bee7576f79fde175ad1ac53dae134 +145 -0
- package/skills/project-update/history/blobs/17f88e362fa19b7f2741ea1393164dc75b9c300b8727322f91fe205a985e088f +5 -0
- package/skills/project-update/history/blobs/17fa7392d1466e286d5aa83a19e364835c1977750ae1f186aec59e2046d688ea +106 -0
- package/skills/project-update/history/blobs/1987654b78c747f378109dbde1d51c4f31fd0eabc878ff16b3bcfaeaf99c8ff4 +28 -0
- package/skills/project-update/history/blobs/19b1a6390e96136619d23bc2ef9afed8f15e62107de7c1052bc5ea23e5bb5692 +64 -0
- package/skills/project-update/history/blobs/1a8995e5f7e51b5be74fca82551e5d9e4d970c546d9fd6eecb6809a7f6af8821 +69 -0
- package/skills/project-update/history/blobs/1ad77786ae3fed570aafe7612eac1d94ef1f52c3106fd64733951592dea759ff +62 -0
- package/skills/project-update/history/blobs/1b554eff73a270086f8cf8cba73f7d9ce162c6b6b9c288b822db36841b8a9228 +16 -0
- package/skills/project-update/history/blobs/1c2c3e5bbb132a152163ebeb678d57f0f7162a56ea92b84acc43cd2dedd4a935 +20 -0
- package/skills/project-update/history/blobs/1fdc406be22d9ea39f41e738c6bbd36a31ef4adc84ece06cfceebddaa86c9798 +75 -0
- package/skills/project-update/history/blobs/21319ce04158178b1d66ee8514e32c43bb1b4cd9cee11a456a9a863a5998c6ce +53 -0
- package/skills/project-update/history/blobs/28a0455a7b17204171c49891c39043040c8608f4e6f04caf09de3fe8aea68553 +27 -0
- package/skills/project-update/history/blobs/30b6dcbdcfbb8e9223af11edacc387b1102868261bbe7051c2d85ad1a18384e5 +27 -0
- package/skills/project-update/history/blobs/31bb922076c8dadb4a84bb6a03d331dafc7157893aaf2f92b13792270fbece9b +56 -0
- package/skills/project-update/history/blobs/3775eed295a794dda73b14f88af70bc2c99b5590f81da53f165423e4337dceed +13 -0
- package/skills/project-update/history/blobs/3a492555cac3198136e239539466fb768cf672d5a972f5afd7d57c038d3cfed6 +104 -0
- package/skills/project-update/history/blobs/3dd55bf5f9d9471c68af3353166da11593a11e639f7557397ce46787291fa629 +32 -0
- package/skills/project-update/history/blobs/3f40640377c8501ecb50dc044fc7951a9b96caac5335e92e0d54d0c1764de8f2 +30 -0
- package/skills/project-update/history/blobs/40ac73f706ba7d2578627f420076cdb9fa6aa146e16d0da6c6a5c63f65c2b03c +66 -0
- package/skills/project-update/history/blobs/4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865 +1 -0
- package/skills/project-update/history/blobs/465bd61887bae3c68b751ea02af09d00f570086617ff8e1362acf6ed0868396b +39 -0
- package/skills/project-update/history/blobs/4d1f9073276936834747199393159f1badc0277b5bb394f78f408d52c36c4e35 +13 -0
- package/skills/project-update/history/blobs/4e67b352e2d7a29a83c4fa9f80a0d3ed9272da0f976a084c344b55e349f741b2 +75 -0
- package/skills/project-update/history/blobs/504ac6f9c5efb8ecb404bb62fbb08c819e8cff0c6b522efeeeb383cb30d2778e +18 -0
- package/skills/project-update/history/blobs/514c8c4bc97f23fe2739954bad34024922464f54b3a057f00ac54d631a4d875d +26 -0
- package/skills/project-update/history/blobs/53376d1fca268d8fdb59a5a0d0e0a4fe2d3bc2a7689a79c00a227f41bd5a2165 +27 -0
- package/skills/project-update/history/blobs/53c234e5e8472b6ac51c1ae1cab3fe06fad053beb8ebfd8977b010655bfdd3c3 +1 -0
- package/skills/project-update/history/blobs/54eefe3d8cd6cd1ed56764e7bd412a4c919a28fc64b56b69dcafeecd7a921678 +67 -0
- package/skills/project-update/history/blobs/5551499579a0bceb74a79731d30213b1ddf9168b92f6d3dd0aecad91d8aff464 +23 -0
- package/skills/project-update/history/blobs/5c0619c1ee059477c9d92cf70b72da5d238d9176fc27ab0d38104ecba795624c +3 -0
- package/skills/project-update/history/blobs/5cbaaabe2c8d0e24582877aab05eeaaf4d53cb5e9515e81cd18368d13d2fe79e +40 -0
- package/skills/project-update/history/blobs/5ccacb666c22a8b6401563bf69ab0ed6bd1df7c93aeb46eacff7d2ff8653cd40 +27 -0
- package/skills/project-update/history/blobs/5e38d93c4f82300cc5d331f4ce3022d2872db15d108ae23bf33e2169a19b42f2 +15 -0
- package/skills/project-update/history/blobs/616a6da3c59073926c5ece428efa251fbe539d25a53bcf50be67522f44848368 +628 -0
- package/skills/project-update/history/blobs/61d0e67d59802a695f546e0a77e11a4daf1fafe77f50bead5f94bc7f08fb8457 +30 -0
- package/skills/project-update/history/blobs/62010250361ebe8644722d60397ce01e9b8abbfd497ede2c9f79b2ae4bce465d +374 -0
- package/skills/project-update/history/blobs/63c6dd07369cd71fad62a22f0ce352792cac0ed5c2998f8e7a4f4d0a64db7803 +102 -0
- package/skills/project-update/history/blobs/65acd4be95c695d0cc20cb5f4faffe0f44e0873b385c124140b223c41328cb56 +13 -0
- package/skills/project-update/history/blobs/664937c4293d82108a19302d4a55d15e3e1686091e5f3e40fd5510dca2d10af5 +27 -0
- package/skills/project-update/history/blobs/6a89cada6dc06bf5e0622a89fe7a8a6745e73c0e01505b7efe462f97d81c0956 +32 -0
- package/skills/project-update/history/blobs/6af1b12f814384e517e8f09131b0524930ac1c849350db765d8a77c7a59905b9 +8 -0
- package/skills/project-update/history/blobs/6b30b86994c130697aea047256ef20ef724f6fea42a4490dc220919e57453659 +354 -0
- package/skills/project-update/history/blobs/6c7b1b9b733f3ec7d8e038e62f484419c5e888cd094f64c1f1471b9cd9bb3fe8 +571 -0
- package/skills/project-update/history/blobs/6f098b31327fe52bfe1418b9f53af40e8734f027c7f1e21b02c1db1fabacdf15 +68 -0
- package/skills/project-update/history/blobs/70850fc7be7307455233177c1fd85e7f1d94c36430a0efc8e7f205b350505226 +31 -0
- package/skills/project-update/history/blobs/732b736e9877263621a0d616d8c466dd3a77eda5092db4e1def0dfb09c573e2a +51 -0
- package/skills/project-update/history/blobs/74549e7a525fdbce4a697fdabfab9b648730118b236123028820b5358002b404 +177 -0
- package/skills/project-update/history/blobs/7578025c0ce0a64dd37fe4c999541db5681199763df8b373ed0bfba11e2f581e +17 -0
- package/skills/project-update/history/blobs/77bd4e864d23176abc6bb8af8fba77775d88a0b135f5c985574d796a396d431d +76 -0
- package/skills/project-update/history/blobs/7cc03a94f8421069d92b6d89503beaa045d8162c303abfd996b2c019c9daad57 +27 -0
- package/skills/project-update/history/blobs/7de1555df0c2700329e815b93b32c571c3ea54dc967b89e81ab73b9972b72d1d +1 -0
- package/skills/project-update/history/blobs/7eee4ea9f6e778ff691c263621e717c021505b86386034cc64f8ebbfc9d8fe65 +13 -0
- package/skills/project-update/history/blobs/7f3859c34035fe32abf937eebdd7240ac72ab32d254286cff7d939cf0cf6eaef +48 -0
- package/skills/project-update/history/blobs/80cf708a42ad6d7851f4063e0d9127b850f274dcb6633c9a9773d01173d437f8 +628 -0
- package/skills/project-update/history/blobs/815d78ce95d18454cf0842335f81755bf3aceb87ee9d2197e121d3ff734cd2b5 +13 -0
- package/skills/project-update/history/blobs/84c3815fd46498443568285c8d839257ecb91b6f0639690cbdc38ba382fc349d +569 -0
- package/skills/project-update/history/blobs/89e7198e1dd42778a6a9af6c7381216aecf561a366426bd914bc57f099ddd390 +10 -0
- package/skills/project-update/history/blobs/8a839b7c0f1ec1cc6217d5275b0cd13860a888eb23eef1a0792a4e78f2bd9faf +35 -0
- package/skills/project-update/history/blobs/8ad13d2ca4504cfd8e4ab7fe3a49129b228d9979461f0f758a71daeec78b6ae1 +118 -0
- package/skills/project-update/history/blobs/8c97cfd63ee3dfba7aa61d9104e87fdbb086d3bf46cf648d349636912836c6d9 +18 -0
- package/skills/project-update/history/blobs/8fc1a5443a2b52a7a5945e2b972579202bd5e3f8c881a22cc1c97b52b7b2da6b +4 -0
- package/skills/project-update/history/blobs/9272fe1cc7ffa1805756c8b80bd14e8de69d03899b94fb0f49db6aa0bcb53b90 +33 -0
- package/skills/project-update/history/blobs/930ccfac4ba1306341e32279278410b451246a52223c42e0597b5ee83706ff00 +48 -0
- package/skills/project-update/history/blobs/933629cd5c872a11837046b13051a9b02bbc1033e3ba74f41966af2ed4edee5d +23 -0
- package/skills/project-update/history/blobs/962fd396da83337c3fadcc642d45e98429b18e79bb81f58915baaf2b9bffd3c5 +27 -0
- package/skills/project-update/history/blobs/965a03be82000866cb5275acda18ebb2172c9a50f0011df2fa475f74a1124c35 +3 -0
- package/skills/project-update/history/blobs/990a23740f15f50ec90f37bcabd1b1a8eedf102922a949343fdaf41a9fee07fe +27 -0
- package/skills/project-update/history/blobs/a00db51859bb7943174017a34b4a100f98e53d6c3b32f73d8f87d6072016a709 +5 -0
- package/skills/project-update/history/blobs/a1167f89faf809477a967aeefe514f443be57502f0afc832039a28ac5575216a +64 -0
- package/skills/project-update/history/blobs/a13cb0db5372c3ce3e71470165c17a2db76e7a2415717ba27fccd1b0593c61c4 +66 -0
- package/skills/project-update/history/blobs/a1558cb6add0a4d6264757c29ef7172c74626fe0034973983a3a39459cf9a1cb +106 -0
- package/skills/project-update/history/blobs/a1ed0b4f3b73b1a29adfdf0d4d495553ba48707aa5a676496ebc28f993a57dcb +24 -0
- package/skills/project-update/history/blobs/a349aaad234825ea429df33cafb7928579c0cb5b1801f0a237e103aa8d159642 +29 -0
- package/skills/project-update/history/blobs/a5ef05d1ec2323ffd61ae60f98f3dacd212cae507b798d7421c3a9f418806506 +49 -0
- package/skills/project-update/history/blobs/a883fab03be6557be0a4205f6e025ee5571098b0931f3bb60f28a9028bb87353 +25 -0
- package/skills/project-update/history/blobs/a8cf15b33301a76e1d899064d5cb95914cc49412ab223f00394b702c4a4508f1 +24 -0
- package/skills/project-update/history/blobs/aa67a169b0bba217aa0aa88a65346920c84c42447c36ba5f7ea65f422c1fe5d8 +1 -0
- package/skills/project-update/history/blobs/ab0ce5062b41aaff12b0525d56b42de6b9dee9ce9e1de2938f72675435013c6a +18 -0
- package/skills/project-update/history/blobs/ab13c708e91c1de2adbc9ccdb1caec5c320197708bcaaa6d5cfd30c18a7dac34 +21 -0
- package/skills/project-update/history/blobs/ad4c4f81855725f7fe6e0e3d8f557df0de5fc063465d428546f69c54020c69d9 +64 -0
- package/skills/project-update/history/blobs/ae49c96abe45e56e88ae5e28e046212f7114d6413785cbe998f692d2914792be +24 -0
- package/skills/project-update/history/blobs/ae9a22907ba9acbb7e80fac1ba4e3d1ff09e5f1df5c4456afb9099d7090fcaa6 +64 -0
- package/skills/project-update/history/blobs/b486fe10685d437b73c8fa2a3141621e29c36d70ec88b2a36e4573133504507b +30 -0
- package/skills/project-update/history/blobs/b7b697fc987617449ba10634f12f70326281cc182f8b7f20f9e047a75f3f182b +17 -0
- package/skills/project-update/history/blobs/b80e6b2b93a4b8a5a0f8eabc2a745247ad53df3235bb84c63fdd3f10ccc1ae99 +21 -0
- package/skills/project-update/history/blobs/b81eabd9248527e9abe1b6df7cf75ac772236b049008190d2a235e2eb22a931f +23 -0
- package/skills/project-update/history/blobs/b9da99bf05f0f08663469288f694f153fb6f2d806cdedf2cdb10cee3d3722295 +18 -0
- package/skills/project-update/history/blobs/ba9bb685dc2bb6de0ed5a8d601ef7ecedb517bb737565f75f6d4fff4ab4cd79c +24 -0
- package/skills/project-update/history/blobs/be29b8681b3de26b0120209971aaf0fab05c77baf8a4d65198929ef611f4fc55 +23 -0
- package/skills/project-update/history/blobs/be8c1556e8b0de1ce0f0fb0ca39f9f3b56ced57116b65a2812421c77cfff7585 +103 -0
- package/skills/project-update/history/blobs/c076d603cffc731823d2acf096bcc17cca1d99eee24b0aa313776d7d01571b4f +13 -0
- package/skills/project-update/history/blobs/c735911eb1a744f78213a9f7577b425c1605843f6d05fed798d7f41b47fa1e0c +13 -0
- package/skills/project-update/history/blobs/c9152d6dc2a5ddaadd870611675a24f89b442e2831a9207a14f2d438788553b0 +27 -0
- package/skills/project-update/history/blobs/c9ddacab2a6943af94c927799ba314877c1f19d40949e927c2d3825689005288 +13 -0
- package/skills/project-update/history/blobs/ca3d163bab055381827226140568f3bef7eaac187cebd76878e0b63e9e442356 +1 -0
- package/skills/project-update/history/blobs/cb2178079b6eda906eee8f3510b72d5c03ae5fe2195f5ee3c859756dd42f9b32 +84 -0
- package/skills/project-update/history/blobs/cb8b8328efd818835822dc60537e3ecdb648d4ca04e21a7c47c88bf1198a5474 +63 -0
- package/skills/project-update/history/blobs/cc808d5b940109f1703abfb3ca0334a3fcfd34267feefb2323627d0decc8b89a +52 -0
- package/skills/project-update/history/blobs/cdc2432f3581ad9dbf5bc215de1e0cb0b49a44e1303b4222a4df4c72d0e96cc3 +27 -0
- package/skills/project-update/history/blobs/d7b96902bf9d2078df1e09901327b02f565b174777af34a2b24be660cad81d01 +33 -0
- package/skills/project-update/history/blobs/d8011741c086a124cf69b2988e0452ee2eb4ccccc6a6696b02069ddf7db35bd1 +330 -0
- package/skills/project-update/history/blobs/d9abea96dbe584fd77c27d5ed0523eb20d048f2d146e4909d16b2a7948db38c5 +8 -0
- package/skills/project-update/history/blobs/da848b831443484c831fa630666c004e07c1c9669dd247e8e4066979c8599080 +13 -0
- package/skills/project-update/history/blobs/da90fc7cceda6ced501d32924126593b9bf90c59fc067abab9abbc68d43be8b2 +97 -0
- package/skills/project-update/history/blobs/dd174b27e5b3a2414d0605484f4e92423e2553931263f05ef15677b4aa389bab +72 -0
- package/skills/project-update/history/blobs/ddc088b8a289151c50bf073797c245c254939217970e6d58b75c3d7193b12466 +27 -0
- package/skills/project-update/history/blobs/de0685f9bc2ac22c1b0178d6a1fc8d07fa23451f29d0c36571cbf85c69716fc2 +13 -0
- package/skills/project-update/history/blobs/e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +0 -0
- package/skills/project-update/history/blobs/e584f106c4e65b1bdce69b78d05713347717bdc2228998982313e3eb15b52943 +76 -0
- package/skills/project-update/history/blobs/e639e99d3f59015dc21472de081ca7766231135399ac3a6f439e841e458251f4 +32 -0
- package/skills/project-update/history/blobs/e66a657a3977884b69435b51f77782e48f37f57c865b6c9ba294e8796b37c378 +101 -0
- package/skills/project-update/history/blobs/e7c01b6590c4e308cd2681beaa3b2242cd1e10a5ba851d9f756f4d49d301d144 +22 -0
- package/skills/project-update/history/blobs/e7cc8b00983d6022206aa576187a2d4dccc656aaea41b26dc32123b4b064e965 +349 -0
- package/skills/project-update/history/blobs/e8df28f07cb784d768bcafbced70fd15771afa61dbec7dc4c1c3f858f9002fec +13 -0
- package/skills/project-update/history/blobs/ebbc147c88c417b18ddc4d0530d87e4aa26b0659e085339f45015cf0be2b61a5 +579 -0
- package/skills/project-update/history/blobs/ee7c8321fff228d967c5d200c316967195d93a26196383f57f474e837b1b3d33 +13 -0
- package/skills/project-update/history/blobs/f00317bd27dc8184222e4b8ffe97f27e72d442d36a2bd67552f57f802590dd79 +25 -0
- package/skills/project-update/history/blobs/f0b5c2c2211c8d67ed15e75e656c7862d086e9245420892a7de62cd9ec582a06 +1 -0
- package/skills/project-update/history/blobs/f12f2ac77324b23aa9ef2c5096a2c08788570b32b0c0322671b0889e7a80d8bd +18 -0
- package/skills/project-update/history/blobs/f5594606990239af05aa73ba00efc8292c3ecfe0be408c9acd343abcbc9d2155 +156 -0
- package/skills/project-update/history/blobs/fce1ab62e4626119169fb2324a06526805227076359c844690f6374ae28e6804 +51 -0
- package/skills/project-update/history/blobs/fe513647c66e8883b326ea884a7e9cb045ce54c49b03d2e75a0b73c4756c423e +67 -0
- package/skills/project-update/history/blobs/fff19a00920c2d001d1614d0d7375c89e1e8c062d6de1f01501c24773acef973 +148 -0
- package/skills/project-update/history/index.json +410 -0
- package/skills/project-update/migrations/0001_schema_version.py +13 -0
- package/skills/project-update/migrations/0002_task_journal.py +123 -0
- package/skills/project-update/migrations/0003_context_diet.py +65 -0
- package/skills/project-update/migrations/0004_deterministic_gates.py +57 -0
- package/skills/project-update/migrations/0005_runtimes_and_plans.py +35 -0
- package/skills/project-update/migrations/0006_shared_files.py +154 -0
- package/skills/project-update/migrations/0007_weight_model.py +188 -0
- package/skills/project-update/migrations/0008_renames.py +43 -0
- package/skills/project-update/migrations/README.md +60 -0
- package/skills/project-update/migrations/__init__.py +181 -0
- package/skills/project-update/render_instructions.py +615 -0
- package/skills/project-update/update.py +1676 -0
- package/skills/rr-build/SKILL.md +185 -0
- package/skills/rr-plan/SKILL.md +100 -0
- package/skills/rr-review/SKILL.md +99 -0
- package/skills/rr-setup/SKILL.md +244 -0
- package/skills/rr-setup/scaffold_ai.py +303 -0
- package/skills/rr-setup/setup.py +541 -0
- package/skills/rr-ship/SKILL.md +110 -0
- package/skills/rr-spec/SKILL.md +108 -0
- package/skills/rr-status/SKILL.md +73 -0
- package/skills/rr-status/status.py +171 -0
- package/skills/sdlc-intent/SKILL.md +9 -0
- package/skills/sdlc-plan/SKILL.md +9 -0
- package/skills/sdlc-spec/SKILL.md +9 -0
- package/skills/usage-report/SKILL.md +10 -0
- package/skills/usage-report/prices.json +41 -0
- package/skills/usage-report/usage-report.py +893 -0
package/README.md
CHANGED
|
@@ -1,3 +1,869 @@
|
|
|
1
|
-
#
|
|
1
|
+
# RiskRails
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/vanssata/claude-agentic-sdlc-module/releases/tag/v3.0.0)
|
|
4
|
+
[](#one-module-two-runtimes)
|
|
5
|
+
[](#known-risks)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
**Let an AI agent work on your legacy production code without the agent
|
|
9
|
+
widening its own scope, reading a production secret, force-pushing or
|
|
10
|
+
deploying.**
|
|
11
|
+
|
|
12
|
+
**RiskRails** (`riskrails`) is a plugin for **Claude Code and Codex**, built for codebases
|
|
13
|
+
with undocumented business rules, old workarounds and behaviour customers
|
|
14
|
+
rely on today. Small, well-defined changes go through easily. Risky ones are
|
|
15
|
+
stopped by a hook, not by a polite request in a prompt.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx riskrails@3.0.0 # detects Claude Code, Codex or both (Node 18+, python3)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then, in any project: `/ai-init` once, and `/ai-task <what you want>` for every
|
|
22
|
+
change.
|
|
23
|
+
|
|
24
|
+
Upgrading from `claude-agentic`: `npx riskrails` moves `<home>/claude-agentic/` to
|
|
25
|
+
`<home>/riskrails/` and leaves a symlink at the old path for one version, and
|
|
26
|
+
`/rr-setup --update` renames each project's managed-block markers (migration
|
|
27
|
+
0008). The task state stays in `.ai/state/current.json`; a later release moves
|
|
28
|
+
it to `state.json`, and this one already reads either.
|
|
29
|
+
|
|
30
|
+
**What you get**
|
|
31
|
+
|
|
32
|
+
- **Guards, not guidelines.** Hooks refuse edits outside the approved step,
|
|
33
|
+
reads of production secrets, force-pushes and deploys. No agent commits,
|
|
34
|
+
merges or deploys: every task ends at your approval.
|
|
35
|
+
- **Risk-tiered pipeline.** Each change gets a tier from T0 to T6, by what it
|
|
36
|
+
reaches, never by how many files it touches. A typo fix stays a one-line
|
|
37
|
+
edit. A new resource with its screens gets the sensors. A payment change gets
|
|
38
|
+
a plan, tests, an adversarial review and a security review.
|
|
39
|
+
- **Cheap by default.** Routing puts readers on the cheapest model, keeps the
|
|
40
|
+
session on the one that does the thinking, and uses the top tier only when a
|
|
41
|
+
named trigger calls for it. `/usage-report` shows where the tokens went.
|
|
42
|
+
- **One `.ai/` tree for both runtimes.** Start a task in Claude Code and finish
|
|
43
|
+
it in Codex; the knowledge base, policies and task state are shared.
|
|
44
|
+
|
|
45
|
+
Tuned for **one developer who knows the codebase, on a Pro or Team Pro plan**,
|
|
46
|
+
following the [AI-native SDLC playbook](https://claude.com/blog/the-ai-native-sdlc-playbook).
|
|
47
|
+
A fully delegated `team` profile is one JSON key away.
|
|
48
|
+
|
|
49
|
+
**Version 3.0.0.** The guards have limits: read [Known risks](#known-risks)
|
|
50
|
+
before relying on them.
|
|
51
|
+
|
|
52
|
+
> This plugin absorbs the former `claude-routing`. Installing it migrates that
|
|
53
|
+
> plugin's managed `CLAUDE.md` block into its own, so the two never coexist; see
|
|
54
|
+
> [Migrating from claude-routing](#migrating-from-claude-routing).
|
|
55
|
+
|
|
56
|
+
## One module, two runtimes
|
|
57
|
+
|
|
58
|
+
`.ai/**`, the pipeline state machine, the risk tiers, the workflow contracts and
|
|
59
|
+
the skill bodies are provider-neutral. The runtime-specific part is a thin
|
|
60
|
+
adapter: where the files go, what an agent definition looks like, how hooks are
|
|
61
|
+
registered, and which model each tier resolves to.
|
|
62
|
+
|
|
63
|
+
| | Claude Code | Codex |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| install root | `~/.claude/` | `~/.codex/` |
|
|
66
|
+
| instruction file | `CLAUDE.md` | `AGENTS.md` |
|
|
67
|
+
| settings | `settings.json` (deep-merged) | `config.toml` (six managed keys) |
|
|
68
|
+
| agents | `agents/*.md`, YAML frontmatter | `agents/*.toml`, rendered from the same prompts |
|
|
69
|
+
| hooks | `settings.json` `hooks` block | `hooks.json` |
|
|
70
|
+
| edits arrive as | `Edit` / `Write`, one file | `apply_patch`, possibly many files |
|
|
71
|
+
| FAST | `haiku` | `gpt-5.6-terra` (Terra) |
|
|
72
|
+
| BALANCED | `sonnet` | `gpt-5.6-terra` (Terra) |
|
|
73
|
+
| STRONG | `opus` | `gpt-5.6-sol` (Sol) |
|
|
74
|
+
| EXPERT | Fable 5.1, or Opus 5 with `--fable no` | `gpt-6-astra` (Astra) |
|
|
75
|
+
| session | Opus 5.5 [1m] (`claude-opus-5-5[1m]`, 1M window) at `medium` by default on Max, `/model opus` for a 200k session (Sonnet on Pro) | Sol at `high` |
|
|
76
|
+
|
|
77
|
+
A repository can carry both instruction files over one `.ai/` tree. The task
|
|
78
|
+
state is `.ai/state/current.json` either way, so a task started in one runtime
|
|
79
|
+
resumes in the other.
|
|
80
|
+
|
|
81
|
+
Five files make that resume real, and every one of them is provider-neutral:
|
|
82
|
+
|
|
83
|
+
| File | Written by | Holds |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `.ai/state/current.json` | `state.py`, `update.py` | the task: stage, step, risk tier, approval |
|
|
86
|
+
| `.ai/reports/<task-id>/events.jsonl` | `state.py` | the journal — one append-only line per event, with the runtime that emitted it |
|
|
87
|
+
| `.ai/reports/<task-id>/task.md` §Questions | `state.py` | the open questions, each with an `[Answer]:` line a human fills in |
|
|
88
|
+
| `.ai/state/handoff.md` | `state.py`, rendered | thirty lines a session reads first: where the task is, what it may touch, what is pending |
|
|
89
|
+
| `.ai/reports/<task-id>/sensors.json` | `state.py review-gate` | what each deterministic sensor measured, and on which tree |
|
|
90
|
+
| `.ai/reports/<task-id>/tests-<scope>-<n>.log` | `state.py test-run` | the full test output, so it never reaches a context window |
|
|
91
|
+
| `.ai/state/session.json` | `context-guard.py` | which runtime is driving and when the human last took a turn |
|
|
92
|
+
|
|
93
|
+
A task also moves on purpose: `state.py handoff --to codex` (or `--to claude`)
|
|
94
|
+
hands it over, prints the command to resume it there and runs nothing; until the
|
|
95
|
+
other runtime resumes it, a state change (and `init --force`) from anywhere else
|
|
96
|
+
exits 7. `--for review` asks the other vendor for a T5+ review; its verdict never
|
|
97
|
+
clears the owner's own `blockers_open`, and moving the task again cancels an
|
|
98
|
+
open request. `init`, `quick` and `risk` print a
|
|
99
|
+
`preferred runtime:` line when the plan's table (refactoring → Codex on Claude
|
|
100
|
+
plans) or the quota rule points at the other runtime — advice only.
|
|
101
|
+
|
|
102
|
+
A subagent that needs a decision **returns** `QUESTIONS_NEEDED` instead of
|
|
103
|
+
asking; the manager writes the question into `task.md` §Questions, a human answers it
|
|
104
|
+
there or in the session, and `state.py questions --sync` puts the answer back
|
|
105
|
+
into the state. The journal is what `/ai-status` and `/usage-report` read, at
|
|
106
|
+
zero model cost — no model is involved in writing or reading any of these files.
|
|
107
|
+
|
|
108
|
+
## Install
|
|
109
|
+
|
|
110
|
+
Pin the version: `npx riskrails` alone runs whatever was published last, and the
|
|
111
|
+
hooks it installs see every command an agent runs.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
npx riskrails@3.0.0 # detects Claude Code, Codex, or both, and updates each
|
|
115
|
+
npx riskrails@3.0.0 --target codex # auto | claude | codex | both
|
|
116
|
+
npx riskrails@3.0.0 --dry-run # print what would be written, write nothing
|
|
117
|
+
npx riskrails@3.0.0 --home ~/alt-claude # another Claude home (--codex-home for Codex)
|
|
118
|
+
# The installer does not read CLAUDE_CONFIG_DIR or CODEX_HOME: with a home other than
|
|
119
|
+
# ~/.claude or ~/.codex, pass it with --home / --codex-home (or CLAUDE_DIR / CODEX_DIR).
|
|
120
|
+
|
|
121
|
+
# Claude-side options. The plan is detected from ~/.claude.json (organizationRateLimitTier
|
|
122
|
+
# tells Max 5x from 20x) and, on a terminal, proposed for you to confirm with Enter (--yes
|
|
123
|
+
# takes the detection without asking):
|
|
124
|
+
npx riskrails@3.0.0 --plan pro # Pro: opusplan session, opus pinned for EXPERT
|
|
125
|
+
npx riskrails@3.0.0 --plan team-pro # Team, Standard seat: the pro profile with the Team label
|
|
126
|
+
npx riskrails@3.0.0 --plan team-max # Team, Premium seat: the max profile, Fable on architect
|
|
127
|
+
npx riskrails@3.0.0 --plan max # Max 5x: Opus 5.5 [1m] session (1M window by default), Fable only on architect
|
|
128
|
+
npx riskrails@3.0.0 --plan max20 # Max 20x: max's settings, larger budgets (6 agents, EXPERT without asking)
|
|
129
|
+
npx riskrails@3.0.0 --plan max --fable no # no Fable anywhere; architect inherits the Opus session
|
|
130
|
+
npx riskrails@3.0.0 --plan balanced-max # BalancedMax: only the session is strong (Opus 5.5, 200k); readers on Haiku,
|
|
131
|
+
# judgement on Sonnet, reviews on Opus, EXPERT at high, no Fable, no xhigh;
|
|
132
|
+
# also picks the Codex balanced-max profile (Sol session, readers on Luna)
|
|
133
|
+
|
|
134
|
+
# Codex-side options (the ChatGPT plan is auto-detected from ~/.codex/auth.json):
|
|
135
|
+
npx riskrails@3.0.0 --codex-plan plus # Plus: Sol at medium, three agent threads, Astra at high, no xhigh
|
|
136
|
+
npx riskrails@3.0.0 --codex-plan pro # Pro: Sol at high, six agent threads, Astra at xhigh for ai-expert
|
|
137
|
+
npx riskrails@3.0.0 --codex-plan balanced-max # Pro's budgets, Sol session, FAST readers on Luna, Astra at high
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
From a checkout, `node bin/riskrails.js` takes the same flags. `./install.sh` only
|
|
141
|
+
prints the `npx` line now and exits 2; the 2.0.x installer is at the `v2.0.2` tag.
|
|
142
|
+
|
|
143
|
+
**The plugin route.** `/plugin install riskrails` (Claude Code) or the Codex
|
|
144
|
+
plugin directory installs the skills and the hooks. Run `npx riskrails@3.0.0`
|
|
145
|
+
as well: the plugin format cannot carry the agents, the plan profile, the
|
|
146
|
+
managed block or the settings. When the runtime records the plugin as
|
|
147
|
+
installed and enabled (Claude Code: `installed_plugins.json` at user scope and
|
|
148
|
+
`enabledPlugins`; Codex: `[plugins."riskrails@<marketplace>"] enabled = true`
|
|
149
|
+
in `config.toml`), `npx` registers none of the plugin's hooks and installs the
|
|
150
|
+
skills without their `SKILL.md`, so nothing loads or runs twice and the skills
|
|
151
|
+
still find their scripts under `~/.claude/skills/`. A plugin cache folder by
|
|
152
|
+
itself changes nothing: `npx` installs everything. With
|
|
153
|
+
the plugin alone there is no `ai-reviewer` agent, so a task whose mode needs a
|
|
154
|
+
review has nothing to run it with.
|
|
155
|
+
|
|
156
|
+
`--target auto` installs for each runtime whose CLI is on `PATH`, and asks for
|
|
157
|
+
that runtime's plan only. A `~/.claude` or `~/.codex` directory without its CLI
|
|
158
|
+
is skipped with a one-line note — `--target both` includes it anyway, which is
|
|
159
|
+
also the way in when the CLI exists but is not on this shell's `PATH` (an IDE
|
|
160
|
+
extension's bundled binary, `sudo` without `~/.local/bin`). If it
|
|
161
|
+
finds neither CLI it stops and tells you which `--target` to name; it never
|
|
162
|
+
guesses one.
|
|
163
|
+
|
|
164
|
+
Restart the runtime afterwards.
|
|
165
|
+
|
|
166
|
+
- **Claude Code**: `/skills` should list `ai-init`, `ai-audit`, `ai-task` and
|
|
167
|
+
`ai-status`; `/hooks` should list `ai-guard.py`, the one guard command.
|
|
168
|
+
- **Codex**: `/hooks` shows the hooks — **and you must review and trust them
|
|
169
|
+
there before they run.** Codex does not execute a non-managed hook until it has
|
|
170
|
+
been trusted, so until you do, nothing is being enforced.
|
|
171
|
+
|
|
172
|
+
Re-running the installer updates in place: it backs up what it replaces, never
|
|
173
|
+
duplicates a hook entry, and never overwrites your edits to `ai-git-guard.json`.
|
|
174
|
+
|
|
175
|
+
### What it installs
|
|
176
|
+
|
|
177
|
+
| Source | Claude target | Codex target |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `profiles/{pro,max}.json` + `settings.common.json` | deep-merged into `settings.json` | — |
|
|
180
|
+
| `profiles/codex-{plus,pro}.json` | — | six managed keys in `config.toml` |
|
|
181
|
+
| `instructions/stub.md` | a managed block in `~/.claude/CLAUDE.md` | a managed block in `~/.codex/AGENTS.md` |
|
|
182
|
+
| `instructions/routing.md` | `~/.claude/riskrails/routing.md`, read on demand | `~/.codex/riskrails/routing.md`, read on demand |
|
|
183
|
+
| `agents/*.md.tmpl` | rendered to `~/.claude/agents/*.md`, each tier's model and effort from the plan (`ai-expert` and `architect` have their own model line) | rendered to `~/.codex/agents/*.toml`, the model pinned per role |
|
|
184
|
+
| `profiles/*.json` | the plan's settings, and its tier and budget tables (`riskrails`), resolved by `scripts/resolve-profile.py` into `~/.claude/riskrails/profile.json` | the same, into `~/.codex/riskrails/profile.json` |
|
|
185
|
+
| `hooks/*` | `~/.claude/hooks/` — six hooks, `runtime-gate` (the old `fable-gate`/`codex-model-gate` names are shims), the shared library and the guards' default config | `~/.codex/hooks/` + `codex/hooks.json` |
|
|
186
|
+
| `skills/*/` | `~/.claude/skills/` | `~/.codex/skills/` |
|
|
187
|
+
|
|
188
|
+
The skills are `/ai-init`, `/ai-audit`, `/ai-task`, `/ai-status`, `/project-init`,
|
|
189
|
+
`/project-update`, `/sdlc-intent`, `/sdlc-spec`, `/sdlc-plan` and
|
|
190
|
+
`/usage-report`, identical in both runtimes.
|
|
191
|
+
|
|
192
|
+
The Codex install is a strict subset in one place: `cap-large-read.py` is not
|
|
193
|
+
installed there, because Codex's read tool is not on the hook path. The read
|
|
194
|
+
rule is still written into `AGENTS.md`; it is just not mechanical there.
|
|
195
|
+
`context-guard.py` **is** installed on both — Codex has `UserPromptSubmit`,
|
|
196
|
+
`PreCompact` and `SessionStart` too, so the handoff, the pending questions and
|
|
197
|
+
`session.json` cross unchanged. What does not cross is the transcript-derived
|
|
198
|
+
snapshot: it is built from a Claude transcript and stays Claude-only. One file
|
|
199
|
+
serves both; it reads its own location to know which runtime it is in.
|
|
200
|
+
|
|
201
|
+
`profiles/codex-{plus,pro}.json` is the machine-readable routing contract, one
|
|
202
|
+
file per ChatGPT plan — session model and effort, thread cap,
|
|
203
|
+
`[agents]` defaults, the four tiers and every role's tier and sandbox mode. Both
|
|
204
|
+
the agent renderer and the config merge read it, so there is one place to change
|
|
205
|
+
a Codex routing decision.
|
|
206
|
+
|
|
207
|
+
### What loads on every turn
|
|
208
|
+
|
|
209
|
+
Context length is the running cost: an always-loaded instruction file is re-read
|
|
210
|
+
on every turn of every task, whether it is relevant or not. So the plugin keeps
|
|
211
|
+
exactly one always-loaded file per runtime, and it is short.
|
|
212
|
+
|
|
213
|
+
| Where | What it is | Budget |
|
|
214
|
+
|---|---|---|
|
|
215
|
+
| `~/.claude/CLAUDE.md`, `~/.codex/AGENTS.md` | the managed block: the rules an agent is unsafe without | 2 560 B |
|
|
216
|
+
| a project's `CLAUDE.md`, `AGENTS.md`, `GEMINI.md`, `.junie/guidelines.md` | the same block, project scope | 2 048 B |
|
|
217
|
+
| `~/.claude/riskrails/routing.md` | the model ladder, the context-guard thresholds, the guard list — read when a routing question comes up | — |
|
|
218
|
+
| a project's `.ai/AGENTS.md` | a router: one row per job, pointing at the policy that answers it | advisory 4 096 B |
|
|
219
|
+
| `docs/sdlc/constitution.md` | the 10–15 principles the project does not negotiate, cited as `C<n>` by `/sdlc-spec` and the planner | 15 lines, 4 096 B |
|
|
220
|
+
| `.ai/rules/<slug>.md` | a rule scoped to the directories it names, rendered into their instruction files by `/project-update` | — |
|
|
221
|
+
|
|
222
|
+
All of the block text comes from one source, `instructions/stub.md`, rendered per
|
|
223
|
+
scope and runtime by `skills/project-update/render_instructions.py`; the committed
|
|
224
|
+
templates are build artefacts and `render_instructions.py build --check` fails the
|
|
225
|
+
suite on drift. `npx riskrails` prints what the block costs after every install
|
|
226
|
+
(`managed block 1 903 B (budget 2 560), file 8 457 B — the rest is yours`) and
|
|
227
|
+
never touches the rest of the file; `/ai-status` prints the same line for a
|
|
228
|
+
project. Downstream the budget is advisory — the plugin measures, it does not
|
|
229
|
+
refuse a file it does not own.
|
|
230
|
+
|
|
231
|
+
### Editing `config.toml` safely
|
|
232
|
+
|
|
233
|
+
There is no comment-preserving TOML writer in the standard library, so
|
|
234
|
+
`scripts/merge-codex-config.py` edits the six managed keys line by line, then
|
|
235
|
+
parses the file before and after and refuses to write unless the *only* keys that
|
|
236
|
+
differ are the six it manages. Your comments, `[projects.*]`, `[mcp_servers.*]`,
|
|
237
|
+
`[marketplaces.*]` and every other setting survive; a malformed file aborts the
|
|
238
|
+
merge and is left untouched. The previous version is kept as `config.toml.bak`.
|
|
239
|
+
|
|
240
|
+
**One accepted change to your defaults:** the Codex session is set to Sol at
|
|
241
|
+
`high`, not Astra. Astra stays available as the EXPERT escalation. This is the
|
|
242
|
+
whole point of the routing — the session model is the largest single cost, and
|
|
243
|
+
it should not be the most expensive model by default.
|
|
244
|
+
|
|
245
|
+
### Limits it sets
|
|
246
|
+
|
|
247
|
+
| Limit | Value | Default |
|
|
248
|
+
|---|---|---|
|
|
249
|
+
| `bashOutputMaxChars` (Claude) | 75 000 | 30 000 |
|
|
250
|
+
| `taskOutputMaxChars` (Claude) | 80 000 | — |
|
|
251
|
+
| `MAX_MCP_OUTPUT_TOKENS` (Claude) | 40 000 | 25 000 |
|
|
252
|
+
| `cap-large-read.py` (Claude) | refuses an unbounded `Read` over 4 000 lines or 250 KB | no limit |
|
|
253
|
+
| `autoCompactWindow` (Claude) | 800 000 on Max and Team Max, 300 000 on Pro and Team Pro. Claude Code caps it at the model's own window, so one setting means compaction near 167k on a 200k model and near 767k on a `[1m]` one; on Pro the cap decides, at 167k | the model window |
|
|
254
|
+
| `claude-1m [opus\|fable]` (Claude, Max and Team Max) | pins one session to `opus[1m]`, or to `fable[1m]` (Fable 5.1), at launch. The large window comes from the per-model cap, not from the launcher, so `/model opus[1m]` reaches it too; `CLAUDE_1M_COMPACT_WINDOW` exports `CLAUDE_CODE_AUTO_COMPACT_WINDOW` for that process alone to compact *earlier* than 767k | `/model` only, and the same cap applies |
|
|
255
|
+
| `context-guard.py` (both runtimes) | warns from 80% of the point where compaction fires and holds a prompt back once from 120% — 133k and 200k on a 200k Max session, 613k and 920k on a `[1m]` one; `AI_CONTEXT_WARN_TOKENS` / `AI_CONTEXT_BLOCK_TOKENS` set them in tokens, `0` turns one off | no guard |
|
|
256
|
+
| `model` (Claude) | `opusplan` on Pro and Team Pro: Opus in plan mode, Sonnet when executing; `claude-opus-5-5[1m]` (Opus 5.5, 1M window) by default on Max, Max 20x and Team Max, `opus` (200k) per task through `/model`; `claude-opus-5-5` (200k) on BalancedMax | Sonnet 5 on Pro |
|
|
257
|
+
| `effortLevel` (Claude) | `medium` on both plans; agents raise it per task | — |
|
|
258
|
+
| `model` (Codex) | `gpt-5.6-sol` at `high` on Pro, `medium` on Plus; subagents `gpt-5.6-terra` at `medium` | — |
|
|
259
|
+
| `max_concurrent_threads_per_session` (Codex) | 6 on Pro, 3 on Plus | runtime default |
|
|
260
|
+
| `ai-expert` effort (Codex) | `xhigh` on Pro, `high` on Plus; `xhigh` is never used on Plus | — |
|
|
261
|
+
|
|
262
|
+
The Read guard is a guardrail, not a cage: an explicit `limit` always goes
|
|
263
|
+
through, so reading something large stays possible but has to be deliberate.
|
|
264
|
+
|
|
265
|
+
## Use
|
|
266
|
+
|
|
267
|
+
The same commands in both runtimes:
|
|
268
|
+
|
|
269
|
+
```bash
|
|
270
|
+
/ai-init # in a project: survey it, build .ai/ and docs/sdlc/
|
|
271
|
+
/ai-task <what you want> # run one change through the pipeline
|
|
272
|
+
/ai-status # where does the current task stand, on which models
|
|
273
|
+
/ai-audit # score the repo against the twelve AI-SDLC plays
|
|
274
|
+
/usage-report # what it cost, from local transcripts, at zero model cost
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Updating a project after the plugin changes
|
|
278
|
+
|
|
279
|
+
`npx riskrails` updates `~/.claude/` (or `~/.codex/`), and with it the shared
|
|
280
|
+
tree at `<home>/riskrails/ai/`: the 29 policies, agent contracts,
|
|
281
|
+
workflows and templates that are the same in every project. A project does not
|
|
282
|
+
copy them; it reads them from there, and a file at the same path under `.ai/`
|
|
283
|
+
wins as an **override**. `<home>/riskrails/ai-path <path>` prints which one
|
|
284
|
+
applies. What a project owns stays in the project — `.ai/project/`, `rules/`,
|
|
285
|
+
`state/`, `reports/`, `VERSION`, `AGENTS.md`, and the policies `risk-tiers.json`,
|
|
286
|
+
`risk-tiers.md`, `path-guard.json`, `testing.md`, `coding.md`, `safety.md` and
|
|
287
|
+
`security.md` — together with `docs/sdlc/` and the `CLAUDE.md` block. Those are
|
|
288
|
+
copies, and stay as they were. Pull the new ones in with:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
/project-update # dry run, confirm the policy changes, apply, merge conflicts
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Running `/ai-init` or `/project-init` again in an initialised project does the
|
|
295
|
+
same. `/ai-status` says when a project is behind.
|
|
296
|
+
|
|
297
|
+
The plugin ships every version of every project-owned template it has ever
|
|
298
|
+
installed (`skills/project-update/history/`, built from git by
|
|
299
|
+
`tools/build-template-history.py`; the shared files keep only their hashes,
|
|
300
|
+
since nothing is merged into them any more). That is how the update tells files
|
|
301
|
+
apart:
|
|
302
|
+
|
|
303
|
+
| The project file is | What happens |
|
|
304
|
+
|---|---|
|
|
305
|
+
| missing | created |
|
|
306
|
+
| a version the plugin once shipped | replaced — nobody edited it |
|
|
307
|
+
| edited, markdown | three-way merged against the closest shipped version; every edit kept |
|
|
308
|
+
| edited, JSON policy | merged key by key; the project's value wins wherever both changed |
|
|
309
|
+
| edited where the plugin changed the same lines | left alone; the plugin's version goes to `.ai/local/plugin-update/` for a merge |
|
|
310
|
+
| `.ai/project/**`, `CLAUDE.md` outside the block, `.claude/settings.json` | never touched |
|
|
311
|
+
| moved by a migration | moved, with your edits merged at the new path; the original kept under `.ai/reports/project-update-<date>/` |
|
|
312
|
+
| proposed for deletion by a migration | listed as `delete?` and left alone until a human passes `--apply --confirm-delete NAME` |
|
|
313
|
+
| a shared file the plugin once shipped, unedited | `delete?` (`[0006]` during the migration, `[shared]` afterwards) — the project reads the shared tree instead, once a human confirms |
|
|
314
|
+
| a shared file the project edited | kept as an override, with a hint: it no longer receives the plugin's changes, and nothing tells you when it falls behind |
|
|
315
|
+
|
|
316
|
+
The tree also carries a schema version in `.ai/VERSION`; the current one is
|
|
317
|
+
**6** (the shared files: `.ai/AGENTS.md` gains a `## Shared files` section
|
|
318
|
+
first, then every unedited copy of a shared file is proposed for deletion,
|
|
319
|
+
edited ones are reported as overrides), and a project initialised before the
|
|
320
|
+
version existed is schema 0. Migration 0006 deletes nothing while any installed
|
|
321
|
+
home (`~/.claude`, `~/.codex`) lacks the shared file it would fall back to — it
|
|
322
|
+
exits 2 and asks for `npx riskrails` — and holds `.ai/VERSION` at 5 until the
|
|
323
|
+
deletion is confirmed. Every machine of a team upgrades the plugin before a
|
|
324
|
+
project at schema 6 is committed; an older plugin refuses it. Migrations under
|
|
325
|
+
`skills/project-update/migrations/` run in order before anything is merged —
|
|
326
|
+
they move, add, edit and propose deletions, all inside the same dry run — and
|
|
327
|
+
the version is written last, only once they are finished.
|
|
328
|
+
|
|
329
|
+
Changes to `.ai/policies/*.json` are listed per key and need a confirmation
|
|
330
|
+
before they are applied. A risk-tier mirror that was in sync stays in sync; one
|
|
331
|
+
that was already stale stays flagged. Nothing is deleted, and no version is
|
|
332
|
+
advanced, without the migration that asked for it finishing: a conflict *from a
|
|
333
|
+
migration*, or a deletion it proposed and nobody confirmed, holds `.ai/VERSION`
|
|
334
|
+
where it is, and `/ai-status` keeps reporting the project as behind. An ordinary
|
|
335
|
+
merge conflict does not.
|
|
336
|
+
|
|
337
|
+
Changed a template? Run `tools/build-template-history.py` and commit the result;
|
|
338
|
+
the test suite fails until you do.
|
|
339
|
+
|
|
340
|
+
**Rolling back 0006 is git first.** Commit `.ai/` before the run (the update
|
|
341
|
+
says so when it is dirty), then:
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
git restore --source=<commit before the migration> --staged --worktree -- .ai
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
That also reverts everything else under `.ai/` committed since — reports,
|
|
348
|
+
project notes. To keep them, restore only `.ai/VERSION`, `.ai/AGENTS.md` and the
|
|
349
|
+
paths `migration.json` lists.
|
|
350
|
+
|
|
351
|
+
and keep the project off `/project-update --apply` until the plugin is
|
|
352
|
+
downgraded, because a new plugin plans 0006 again. Without a commit, the
|
|
353
|
+
originals under `.ai/reports/project-update-<date>/original/` bring the deleted
|
|
354
|
+
files back (`migration.json` lists them), and nothing else: write the schema
|
|
355
|
+
back by hand with `printf '5\n' > .ai/VERSION`, or an older plugin refuses the
|
|
356
|
+
project (exit 2). The router keeps its new section, which stays true while the
|
|
357
|
+
copies exist. Roll projects back before installing a plugin older than the
|
|
358
|
+
shared tree.
|
|
359
|
+
|
|
360
|
+
A project that already carries another AI tool's structure — Spec Kit
|
|
361
|
+
(`.specify/`, `specs/`), Kiro (`.kiro/`), Cursor (`.cursorrules`,
|
|
362
|
+
`.cursor/rules/`), Copilot (`.github/copilot-instructions.md`), AI-DLC, or a
|
|
363
|
+
`CLAUDE.md`/`AGENTS.md` too large to load on every turn — is adopted with
|
|
364
|
+
`/project-update --adopt`. The dry run maps every file through
|
|
365
|
+
`skills/project-update/adopt-map.json` and writes nothing; `--apply` moves the
|
|
366
|
+
content into `docs/sdlc/` and `.ai/`, keeps each original under
|
|
367
|
+
`.ai/reports/adopt-<date>/original/`, and passes two checks on disk: no line
|
|
368
|
+
lost, no reference left pointing at an old path. A file no row maps stops the
|
|
369
|
+
run until a human decides. `--mode coexist` leaves the files where they are and
|
|
370
|
+
only routes to them. The foreign files are deleted by a separate
|
|
371
|
+
`--adopt --cleanup`, on a committed tree, and only with `--apply
|
|
372
|
+
--confirm-delete NAME` typed by a human in a terminal outside Claude Code or
|
|
373
|
+
Codex. `/ai-status` says when a structure is
|
|
374
|
+
waiting, or came back after an adopt.
|
|
375
|
+
|
|
376
|
+
For work that needs a written intent and specification before any code:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
/sdlc-intent <topic> # docs/sdlc/intent/<slug>.md
|
|
380
|
+
/sdlc-spec docs/sdlc/intent/<slug>.md # docs/sdlc/specs/<slug>.md
|
|
381
|
+
/sdlc-plan docs/sdlc/specs/<slug>.md # docs/sdlc/plans/<slug>.md
|
|
382
|
+
/ai-task build the plan in docs/sdlc/plans/<slug>.md
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
`/project-init` scaffolds only the SDLC layout, for a repository that does not
|
|
386
|
+
want the agentic pipeline. Both scaffolds take
|
|
387
|
+
`--runtime auto|claude|codex|gemini|junie|both` — or a comma list — and default
|
|
388
|
+
to what the project already declares: `CLAUDE.md`/`.claude/`, `AGENTS.md`/`.codex/`,
|
|
389
|
+
`GEMINI.md`/`.gemini/`, `.junie/`. Gemini and Junie get the rendered project stub
|
|
390
|
+
only; they are not full runtimes here.
|
|
391
|
+
|
|
392
|
+
`/ai-init` reads the codebase and writes `.ai/`. It does not touch application
|
|
393
|
+
code — not a rename, not a formatting fix. Problems it finds are documented in
|
|
394
|
+
`.ai/project/known-risks.md`, not fixed. By default it runs a **light** survey:
|
|
395
|
+
it asks you for what you know, confirms it with `grep`, and sends only two
|
|
396
|
+
discovery agents to the places memory is least reliable — legacy and risks,
|
|
397
|
+
tests and data. `/ai-init --survey full` fans out six agents for a codebase new
|
|
398
|
+
to you. Either way it ends with the test commands written into
|
|
399
|
+
`.ai/policies/testing.md` — the scoped one a step runs, the full verification
|
|
400
|
+
command, and the e2e suite — which every later task runs before reporting
|
|
401
|
+
done.
|
|
402
|
+
|
|
403
|
+
The tooling policy, `policies/tooling.md` (shared; a project overrides it in
|
|
404
|
+
`.ai/`), says which MCP servers this repository enables for every task and why, which stay off, and how a single task asks for
|
|
405
|
+
one. The default is none. A connected server is in the system prompt of every
|
|
406
|
+
turn whether a task calls it or not, so the scaffolded `.claude/settings.json`
|
|
407
|
+
ships with `enableAllProjectMcpServers: false` and an empty
|
|
408
|
+
`enabledMcpjsonServers`. The same file holds the reading rule: a file too large
|
|
409
|
+
to open is read by the cheapest model — `Explore` for code, `log-reader` for
|
|
410
|
+
logs — which hands back the matching ranges with `file:line`, never the file.
|
|
411
|
+
|
|
412
|
+
## Risk tiers
|
|
413
|
+
|
|
414
|
+
Every task is classified before it is planned. The tier decides who plans it, who
|
|
415
|
+
reviews it, and whether a human signs it off. It does not depend on the runtime,
|
|
416
|
+
and it comes from the **scope** of the change — a process, a migration, money,
|
|
417
|
+
identity, infrastructure — never from how many files or lines it touches.
|
|
418
|
+
|
|
419
|
+
| Tier | Covers | Plan review | Adversarial review | Security review | Human approval |
|
|
420
|
+
|---|---|---|---|---|---|
|
|
421
|
+
| T0 | documentation, comments | no | no | no | no |
|
|
422
|
+
| T1 | formatting, a label, a template tweak | no | no | no | no |
|
|
423
|
+
| T2 | an isolated screen or form, a new field, a small feature that changes no process | no | the sensors; a model only when one is red | no | no |
|
|
424
|
+
| T3 | CRUD and presentation: a new resource with its screens, a non-critical API extension | no | the sensors; a model only when one is red | no | no |
|
|
425
|
+
| T4 | shared domain behaviour and processes: orders, workflows, async, integrations, an additive migration, config | the human, in plan mode | yes, STRONG | when auth or personal data | yes |
|
|
426
|
+
| T5 | payments, accounting, tax, fiscal, auth, order state, customer data | yes | yes | yes | yes |
|
|
427
|
+
| T6 | migration strategy, infrastructure, production architecture, destructive or data migrations | yes | yes | yes | yes |
|
|
428
|
+
|
|
429
|
+
The machine-readable source of truth is `.ai/policies/risk-tiers.json`, which
|
|
430
|
+
`/ai-init` copies into each project so the tiers can be tuned to that codebase.
|
|
431
|
+
|
|
432
|
+
### Who does each stage: the pipeline profile
|
|
433
|
+
|
|
434
|
+
The tier decides *whether* a stage runs; `pipeline_profile` in the same file
|
|
435
|
+
decides *who* runs it. The default is `solo`, which has two modes: **direct**
|
|
436
|
+
for T0–T4 — no pipeline ceremony, cheap readers only, a `sonnet` review at T2
|
|
437
|
+
or T3 only when a sensor is red, one `opus` review at T4 whose plan the human
|
|
438
|
+
approves in plan mode — and **sdlc** for T5–T6, the full pipeline:
|
|
439
|
+
|
|
440
|
+
| Tier | `solo` delegates to a subagent | `team` delegates |
|
|
441
|
+
|---|---|---|
|
|
442
|
+
| T0, T1 | nothing — direct mode, no state file: say which files, edit, verify (T1) | discovery, test |
|
|
443
|
+
| T2, T3 | the adversarial review, on `sonnet`, only when `review-gate` finds a red sensor; the plan is a few lines in the conversation, recorded by one `state.py quick` call | everything except implementation |
|
|
444
|
+
| T4 | the adversarial review, on `opus`; the plan is written in plan mode and approved by the human, recorded by one `state.py quick` call | everything except implementation |
|
|
445
|
+
| T5 | plus the plan, its review, the security review and the release report | everything except implementation |
|
|
446
|
+
| T6 | plus discovery and impact; the plan goes to `ai-expert` | everything except implementation |
|
|
447
|
+
|
|
448
|
+
Before any of those reviews, the deterministic gates measure the change itself.
|
|
449
|
+
`state.py step-done` counts what a step actually changed, between the tree the
|
|
450
|
+
step began with and the tree now: outside the step's own files it exits 6 and
|
|
451
|
+
asks for `state.py step-split`, never for the work to be abandoned; over the
|
|
452
|
+
tier's diff budget it finishes the step and warns, naming `step-split` — the
|
|
453
|
+
budget is advisory, and only a project that writes `diff_budget.enforce: true`
|
|
454
|
+
makes it a gate again. The tier is then re-scored from the real diff by
|
|
455
|
+
**scope**, never by size — a change that reached `**/Payment/**` is T5 from
|
|
456
|
+
then on, and only a human, in their own terminal, ever lowers a tier.
|
|
457
|
+
`state.py test-run` owns the test runs, keeps their output in a file and caps
|
|
458
|
+
how many there may be. `state.py review-gate` runs the sensor set — the
|
|
459
|
+
recorded suite result, the project's own linter and type checker, the diff, the
|
|
460
|
+
re-score, step-to-test traceability, repeated blocks, and whether the named
|
|
461
|
+
tests **fail without the change** — and up to T3, with every one of them
|
|
462
|
+
green, records `review_status: skipped_green`: the sensors are the review. A
|
|
463
|
+
tool nobody wrote down is `unavailable`, not green, and keeps the review; so
|
|
464
|
+
does a task over its diff budget, and so does a change into `config/`, a
|
|
465
|
+
dependency manifest or a migration, whose floor is T4. From T4 the review
|
|
466
|
+
always runs, with the sensor rows already in the ledger so the reviewer does
|
|
467
|
+
not re-derive them. A project still on the six-tier table is read on its own
|
|
468
|
+
scale until `/project-update` renumbers it.
|
|
469
|
+
|
|
470
|
+
In `solo`, discovery, context, impact and risk come from the request plus
|
|
471
|
+
`grep -n`; up to T4 they are a few lines in the conversation, from T5 they are
|
|
472
|
+
recorded stage by stage. Tests run in three scopes: a step runs **only the
|
|
473
|
+
tests it names**, the verification command runs **once, after the last step, to
|
|
474
|
+
the end** (no fail-fast flag; the failing test first for a bugfix), and the
|
|
475
|
+
**e2e suite runs once after that**, at the end of the task — never per step.
|
|
476
|
+
Every failure of the two end-of-task runs is then fixed as **one batch** in a
|
|
477
|
+
`state.py remediate` step before one more run — at most two rounds, then the
|
|
478
|
+
human decides. Review
|
|
479
|
+
findings are handled the same way. Up to T4 the release report is the commit
|
|
480
|
+
message. A subagent is still sent on a stated trigger: an unfamiliar
|
|
481
|
+
area, an `UNKNOWN` the plan depends on, a non-obvious T4+ classification, or
|
|
482
|
+
verification output too long to read inline. Switch to `team` by editing the
|
|
483
|
+
key. No stage is ever skipped; the profile only changes who does it.
|
|
484
|
+
|
|
485
|
+
## Model tiers
|
|
486
|
+
|
|
487
|
+
Each plan is one file in `profiles/`: the runtime's own settings plus a
|
|
488
|
+
`riskrails` object with the tier table (which model and effort each of FAST,
|
|
489
|
+
BALANCED, STRONG and EXPERT is on that plan), the budgets (how many agents may run
|
|
490
|
+
at once and how many of them on STRONG, how far direct mode reaches, whether EXPERT
|
|
491
|
+
runs without asking, and a token figure per tier) and the preferred runtime per
|
|
492
|
+
workflow. `max20.json` is `max.json` with larger budgets; `balanced-max.json` is `max.json`
|
|
493
|
+
with the session pinned to Opus 5.5, no Fable and EXPERT at `high` — only the
|
|
494
|
+
session runs the strong model, every agent keeps its cheap tier. The installer writes the
|
|
495
|
+
resolved object to `<home>/riskrails/profile.json`; `runtime-gate` enforces the
|
|
496
|
+
fan-out and EXPERT budgets by asking, `state.py profile --tier <TIER>` prints a
|
|
497
|
+
tier's model, and `/usage-report --task <id>` compares a task's tokens with its
|
|
498
|
+
plan's figure — reported, never enforced. The prompts themselves name tiers only;
|
|
499
|
+
`tests/test_shared_prompts_model_free.py` keeps it that way.
|
|
500
|
+
|
|
501
|
+
| Tier | Claude Code | Codex | Does |
|
|
502
|
+
|---|---|---|---|
|
|
503
|
+
| FAST | `haiku`, low | Terra, low | reading and running: file search, inventories, logs, test output (`Explore`, `log-reader`, `ai-tester`, `ai-indexer`) |
|
|
504
|
+
| BALANCED | `sonnet` | Terra, medium | discovery, context, planning up to T3, mechanical edits, release, the T2/T3 review (`ai-discovery`, `ai-context`, `ai-implementer`, `ai-release`) |
|
|
505
|
+
| STRONG | `opus`, high | Sol, high | adversarial and security review (from T4), T5 risk and planning, root cause after a first diagnosis failed, reversible design (`ai-reviewer`, `ai-security`, `architect`) |
|
|
506
|
+
| EXPERT | the session model (Opus 5) on Max, `opus` pinned on Pro; Fable 5.1 [1m] on `architect` only | Astra, `xhigh` | T6, irreversible design, what STRONG could not settle |
|
|
507
|
+
|
|
508
|
+
The main session does the implementation itself. Every agent definition pins its
|
|
509
|
+
own `model:` — most of them the BALANCED tier — and `CLAUDE_CODE_SUBAGENT_MODEL` is
|
|
510
|
+
deliberately not set: before Claude Code v2.1.251 it overrides the frontmatter and
|
|
511
|
+
the per-call model, which put every agent on Sonnet. A STRONG or EXPERT agent runs
|
|
512
|
+
only when a named trigger fires; the triggers are listed in `policies/model-routing.md` of the shared tree.
|
|
513
|
+
|
|
514
|
+
On a Max plan the session runs Opus 5.5 [1m] by default at `medium` effort,
|
|
515
|
+
compacting near 767k tokens (`autoCompactWindow` 800 000, uncapped on a 1M model)
|
|
516
|
+
— `/model opus` gives a 200k session that compacts near 167k, cheaper per turn for
|
|
517
|
+
a small task — and escalates from there: `ai-expert` pins `opus` at `xhigh`, so a session switched to
|
|
518
|
+
Sonnet (the JetBrains agent's Model setting, or `/model`) cannot weaken the last-resort tier. Fable 5.1 [1m] is pinned on `architect` alone, at
|
|
519
|
+
`xhigh`, for design questions outside a task; nothing else ever runs on it, and
|
|
520
|
+
`runtime-gate` sends it to Opus while Fable is rate-limited or its weekly limit is
|
|
521
|
+
nearly used. `--fable no` leaves `architect` on the Opus session as well.
|
|
522
|
+
|
|
523
|
+
Team accounts map by seat: a Standard seat installs as `team-pro` and gets the
|
|
524
|
+
Pro profile, a Premium seat installs as `team-max` and gets the Max profile with
|
|
525
|
+
Fable on `architect`. The installer reads the seat from `~/.claude.json` and
|
|
526
|
+
falls back to `team-pro` when it cannot tell; `--plan team-max` overrides.
|
|
527
|
+
|
|
528
|
+
On Pro and Team Pro the session model is `opusplan`:
|
|
529
|
+
Opus 5 in plan mode, Sonnet 5 when executing. That is the playbook's "plan mode"
|
|
530
|
+
play priced for a $20 plan — the expensive model is spent on the plan, and the
|
|
531
|
+
cheaper one on typing it out. Because a subagent that omits `model:` would
|
|
532
|
+
inherit Sonnet outside plan mode, the installer pins `model: opus` on
|
|
533
|
+
`ai-expert` and `architect` for this plan. `log-reader`, `ai-tester` and
|
|
534
|
+
`ai-release` run at `low` effort: they read and report, they do not think.
|
|
535
|
+
|
|
536
|
+
Under Codex the ChatGPT plan chooses the profile. On Pro the session runs Sol
|
|
537
|
+
at `high` with six agent threads and `ai-expert` runs Astra at `xhigh`. On Plus
|
|
538
|
+
the usage window is a fraction of Pro's, so the session runs Sol at `medium`,
|
|
539
|
+
three agent threads, and `ai-expert` runs Astra at `high` — `xhigh` stays off
|
|
540
|
+
everywhere. The plan is read from `chatgpt_plan_type` in `~/.codex/auth.json`;
|
|
541
|
+
`--codex-plan plus|pro` overrides it, and an install that cannot tell assumes
|
|
542
|
+
Pro and says so.
|
|
543
|
+
|
|
544
|
+
**One difference worth knowing.** Under Claude Code you escalate by spawning
|
|
545
|
+
`ai-risk` or `ai-planner` with `model: opus`. Codex resolves an agent's own file
|
|
546
|
+
*ahead* of the model asked for at spawn time, so that would silently be ignored —
|
|
547
|
+
the Codex roster therefore carries dedicated `ai-risk-strong` and
|
|
548
|
+
`ai-planner-strong` agents that pin Sol. Same tier, same trigger, different
|
|
549
|
+
mechanism. `ai-expert-strong` is the third: the runtime gate reroutes an
|
|
550
|
+
`ai-expert` launch to it while the EXPERT model is unavailable. Every rendered Codex agent writes an explicit `model` and
|
|
551
|
+
`model_reasoning_effort` for the same reason: an omitted `model` falls back to the
|
|
552
|
+
Terra `[agents]` default, which is not the tier a reviewer needs.
|
|
553
|
+
|
|
554
|
+
Why route this way: in measured usage, over 80% of the cost was the main session
|
|
555
|
+
re-reading its context (cache read and write), not output, so the session model is
|
|
556
|
+
the lever that matters. `/usage-report` shows the split on your machine, across
|
|
557
|
+
both runtimes.
|
|
558
|
+
|
|
559
|
+
There is no LOCAL tier: neither runtime has a local-model backend. The work it
|
|
560
|
+
would have done is done by deterministic tools and by `ai-indexer` on the cheapest
|
|
561
|
+
model, and nothing in the design depends on a local model existing.
|
|
562
|
+
|
|
563
|
+
## The guards
|
|
564
|
+
|
|
565
|
+
| Hook | Runtimes | Where | Does |
|
|
566
|
+
|---|---|---|---|
|
|
567
|
+
| `ai-git-guard` | both | **every repository** | refuses force push, remote branch delete, history rewrite, push or merge to a protected branch, `gh pr merge`, `--no-verify`, staging a secret, production deploy commands |
|
|
568
|
+
| `ai-path-guard` | both | only where `.ai/` exists | refuses reading or writing `.env`, `secrets/`, keys, dumps, production logs; edits to the guards' own config, the task state, the journal, the questions file or the handoff; and `state.py approve` from an agent session — approval is a human's to give |
|
|
569
|
+
| `ai-scope-guard` | both | only during an implementation step | refuses editing a file the approved step does not name, with the `SCOPE_CHANGE_REQUIRED` signal |
|
|
570
|
+
| `cap-large-read.py` | Claude only | every session | refuses an unbounded `Read` of a large file; an explicit `limit` passes |
|
|
571
|
+
| `project-scaffold.sh` | Claude only | `Setup:init` | creates the `docs/sdlc/` and runtime layout on `/init` |
|
|
572
|
+
| `context-guard.py` | both | `UserPromptSubmit` / `PreCompact` / `SessionStart:startup\|resume\|clear\|compact` | reads the context size from the transcript: warns once per 10k from 80% of the compaction point, holds a prompt back once from 120% (the same prompt again passes). Before a compaction it writes a snapshot — edited files, latest instructions verbatim, todo list, git state, `.ai/` task state — and tells the summary what to keep; after it, the snapshot goes back into the context. On every session start it writes `.ai/state/session.json` and, with a task in flight, injects `handoff.md` and the pending questions. The snapshot is Claude-only; everything else crosses to Codex. Fails open |
|
|
573
|
+
| `runtime-gate.py` | both, every plan | `PreToolUse`/`PostToolUse` on `Agent` (Codex: `spawn_agent`, or `collaborationspawn_agent` under multi-agent v2 — matcher `^Agent$\|spawn_agent$`), `SubagentStart`/`SubagentStop`, `StopFailure` (Fable installs), the statusline | sends the top model's launches one tier down while it is rate-limited or unreachable (Fable → Opus; on Codex `ai-expert` → `ai-expert-strong` by rewriting `agent_type`, since a role's pinned model beats the call's); asks before an EXPERT launch or a launch past the plan's fan-out (explains instead on Codex, which cannot ask); records the quota; journals `model_fallback`, and `missed_reroute` when an EXPERT child starts during an outage anyway. After an upgrade, re-trust the changed Codex entries in `/hooks`. `fable-gate.py` and `codex-model-gate.py` are shims that exec it |
|
|
574
|
+
|
|
575
|
+
The three shared guards see Codex's `apply_patch` as well. One `apply_patch` can
|
|
576
|
+
touch many files, so every `*** Add/Update/Delete File:` and `*** Move to:` path
|
|
577
|
+
in the patch is checked separately — a single out-of-scope or protected file
|
|
578
|
+
rejects the whole patch. Split the patch rather than widening the step.
|
|
579
|
+
|
|
580
|
+
Codex has no `StopFailure` event, so on Codex `runtime-gate` attributes a failure at
|
|
581
|
+
`SubagentStop` instead, and only when the evidence points at an EXPERT agent:
|
|
582
|
+
the agent's name in the text, an explicit expert `model`, an agent file pinned to
|
|
583
|
+
the expert model, or an expert launch inside the last five minutes.
|
|
584
|
+
|
|
585
|
+
They are regex-based and run on every matching tool call. That makes them
|
|
586
|
+
defence-in-depth against ordinary agent mistakes — **not a security boundary**. A
|
|
587
|
+
determined process can still read a file through an interpreter, and a tool that
|
|
588
|
+
is not on the hook path is not gated at all. The real backstops are human review
|
|
589
|
+
and server-side branch protection.
|
|
590
|
+
|
|
591
|
+
## Known risks
|
|
592
|
+
|
|
593
|
+
What version 3.0.0 knowingly does **not** protect against. Each entry says what
|
|
594
|
+
can happen, why it was left that way, what limits the damage, and what you should
|
|
595
|
+
do. None is a secret. Each was found in a review or a spec, then accepted or
|
|
596
|
+
deferred with a written reason in the file named under **Source**.
|
|
597
|
+
|
|
598
|
+
### The guards are a tripwire, not a sandbox
|
|
599
|
+
|
|
600
|
+
**Risk.** Every guard rule is a regex over a command line or a path. A process
|
|
601
|
+
that wants to get past it can do so. It can read `.env` through a Python
|
|
602
|
+
one-liner, build a command from variables, pipe base64 into a shell, or use a
|
|
603
|
+
tool that is not on the hook path at all.
|
|
604
|
+
**Why it stays.** A real boundary needs an OS-level sandbox. A hook that runs
|
|
605
|
+
before a tool call cannot be one. The guards exist to stop the *honest mistake*,
|
|
606
|
+
like reading `.env` to check a value or editing one file too many.
|
|
607
|
+
**Limits.** A tripwire catches the common obfuscations (quoted flags,
|
|
608
|
+
`--opt=value`, interpreter one-liners that mention `.ai/state/` or
|
|
609
|
+
`.ai/reports/`).
|
|
610
|
+
**What to do.** Keep production secrets off the developer machine, turn on
|
|
611
|
+
server-side branch protection, and review every diff before merge. Those are the
|
|
612
|
+
real backstops.
|
|
613
|
+
**Source.** `docs/hooks.md`, "What these guards are, and are not".
|
|
614
|
+
|
|
615
|
+
### Human approval can be forged by a determined process
|
|
616
|
+
|
|
617
|
+
**Risk.** `state.py approve` refuses to run without a terminal on stdin, and the
|
|
618
|
+
path guard refuses it from an agent session. An obfuscated invocation that gets
|
|
619
|
+
past the regex and also allocates a pseudo-terminal (a pty) can still grant the
|
|
620
|
+
approval.
|
|
621
|
+
**Why it stays.** This is the same regex limit as above. The check is there to
|
|
622
|
+
make self-approval deliberate and visible, not impossible.
|
|
623
|
+
**Limits.** `approve` also refuses when no gate was ever requested
|
|
624
|
+
(`gate_requested` in the journal). Every approval is journalled with who, when
|
|
625
|
+
and how (`via: terminal`).
|
|
626
|
+
**What to do.** Read `state.py events` for the approval before you merge a
|
|
627
|
+
T4–T6 change. An approval you do not remember giving is a finding.
|
|
628
|
+
**Source.** WP2 security review. `hooks/guard/paths.py`, `docs/hooks.md`.
|
|
629
|
+
|
|
630
|
+
### The deletion gate stops an agent's command, not an agent's script
|
|
631
|
+
|
|
632
|
+
**Risk.** `--confirm-delete` of `/project-update` (plain `--apply` and
|
|
633
|
+
`--adopt --cleanup --apply`) is refused two ways: the path guard denies an agent
|
|
634
|
+
Bash command that runs `update.py` with `--apply` and any prefix of
|
|
635
|
+
`--confirm-delete`, and `adopt.py` refuses the flag whenever an agent-session
|
|
636
|
+
marker (`CLAUDECODE`, or Codex's `CODEX_THREAD_ID`, `CODEX_SESSION_ID`,
|
|
637
|
+
`CODEX_CI`, `CODEX_SANDBOX`, `CODEX_SANDBOX_NETWORK_DISABLED`,
|
|
638
|
+
`CODEX_VERSION`) is in its
|
|
639
|
+
environment, even with a terminal on stdin — an agent can open one with
|
|
640
|
+
`script`. The hook matches spellings, so any spelling it does not recognise is
|
|
641
|
+
past it: a script file written with the Write tool, arguments held in a
|
|
642
|
+
variable, command substitution (`$(…)`, backticks), arguments fed through
|
|
643
|
+
`xargs` or stdin, inline `-c` code that imports or runs `update.py`, a glob or a
|
|
644
|
+
renamed copy of it — and a session whose working directory has no `.ai/` above
|
|
645
|
+
it, where the path guard does not run at all. Each of those still needs the
|
|
646
|
+
markers unset (plus a pty) or `AI_UNATTENDED=1` on the command itself to pass
|
|
647
|
+
`adopt.py`, which is deliberate, not an honest mistake. A run with the markers
|
|
648
|
+
stripped under a pty records `via: terminal`, and `adopt.json` /
|
|
649
|
+
`migration.json` are not write-protected, so `via` is a record, not a proof.
|
|
650
|
+
**Why it stays.** Same regex limit as above: the hook sees a command line, not
|
|
651
|
+
what a file it runs will do.
|
|
652
|
+
**Limits.** The record says why the gate passed: `adopt.json` `cleanup.via` and
|
|
653
|
+
`migration.json` `deletions[].via` are `terminal` or `unattended`. A human
|
|
654
|
+
typing through Claude Code's `!` prefix, or in a shell started from an agent
|
|
655
|
+
session, is refused too — that shell carries the markers.
|
|
656
|
+
**What to do.** Run `--confirm-delete` in a terminal of your own. A `via:
|
|
657
|
+
unattended` on a run nobody launched unattended is a finding.
|
|
658
|
+
**Source.** WP6 finding F3, `.ai/reports/T-2026-09-27-003/`.
|
|
659
|
+
`hooks/guard/paths.py`, `skills/project-update/adopt.py` (`human_gate`).
|
|
660
|
+
|
|
661
|
+
### `AI_UNATTENDED=1` turns the human gates off
|
|
662
|
+
|
|
663
|
+
**Risk.** With `AI_UNATTENDED=1` in its environment, any process passes the
|
|
664
|
+
human-present check. That covers the approval gate and the deletion gates of
|
|
665
|
+
`/project-update --confirm-delete` and `--adopt --cleanup`. Those can then
|
|
666
|
+
approve a task or delete files with no human at the keyboard.
|
|
667
|
+
**Why it stays.** CI jobs, cron and scripted batches have no human to take a
|
|
668
|
+
turn. Without the variable they could not run at all.
|
|
669
|
+
**Limits.** It never hides. The approval is recorded permanently as
|
|
670
|
+
`unattended: true` in the state and the journal, `adopt.json` records
|
|
671
|
+
`cleanup.unattended: true` and `cleanup.via: unattended` before the first file
|
|
672
|
+
is removed, `migration.json` records `via: unattended` per deletion, the report prints
|
|
673
|
+
`deleted unattended`, and `/ai-status` names every such event.
|
|
674
|
+
**What to do.** Export it only in the environment of a launcher, never in an
|
|
675
|
+
interactive shell. There it silently disables the gates for every session the
|
|
676
|
+
shell starts. Check `/ai-status` after an unattended run.
|
|
677
|
+
**Source.** `.ai/reports/T-2026-09-21-001/release.md`, "Residual accepted
|
|
678
|
+
risk". `docs/hooks.md`.
|
|
679
|
+
|
|
680
|
+
### The routing hooks are less protected than the guards
|
|
681
|
+
|
|
682
|
+
**Risk.** The path guard protects the three guards' own configuration and the
|
|
683
|
+
shim `codex-model-gate.py` by name. It does **not** yet protect `runtime-gate.py`
|
|
684
|
+
or `context-guard.py`. An agent could edit those two hooks, and so change the
|
|
685
|
+
EXPERT reroute, the quota records or the session and compaction snapshot.
|
|
686
|
+
**Why it stays.** WP5 froze the guard files, so that the characterization golden
|
|
687
|
+
file proves no guard behaviour changed. Protection for both hooks was split off
|
|
688
|
+
as its own additive task.
|
|
689
|
+
**Limits.** The installed copies live under `~/.claude` or `~/.codex`, outside
|
|
690
|
+
any project, and a change to them shows up in `npx riskrails --dry-run`. On Codex an
|
|
691
|
+
edited hook entry loses its trust and stops running until you re-approve it.
|
|
692
|
+
**What to do.** Treat an unexpected diff under `hooks/` like a change to CI
|
|
693
|
+
configuration. Until the follow-up lands, review hook changes by hand.
|
|
694
|
+
**Status.** Open, planned as a follow-up (WP5 OQ3).
|
|
695
|
+
**Source.** `docs/sdlc/specs/adaptive-cross-runtime-sdlc-wp5-runtimes-and-plans.md`, concern 2 and OQ3.
|
|
696
|
+
|
|
697
|
+
### The compaction snapshot runs `git` in the working directory
|
|
698
|
+
|
|
699
|
+
**Risk.** Before a compaction, `context-guard.py` runs `git branch --show-current`
|
|
700
|
+
and `git status --short` in the session's directory. A hostile repository can
|
|
701
|
+
make those calls run its own code through its local git configuration (for
|
|
702
|
+
example `core.fsmonitor`).
|
|
703
|
+
**Why it stays.** This predates the plugin's own work. It is the same exposure as
|
|
704
|
+
any shell prompt that shows the git branch.
|
|
705
|
+
**Limits.** It runs only under Claude Code, only on compaction, and with your
|
|
706
|
+
own user rights. It gives no more than opening the repository in a git-aware
|
|
707
|
+
shell already does.
|
|
708
|
+
**What to do.** Do not run agent sessions inside repositories you do not trust.
|
|
709
|
+
**Status.** Open.
|
|
710
|
+
**Source.** WP2 security review. `hooks/context-guard.py` (`build_snapshot`).
|
|
711
|
+
|
|
712
|
+
### Codex runs only hooks you re-approved
|
|
713
|
+
|
|
714
|
+
**Risk.** Codex keeps each hook approval as a hash of the whole `config.toml`
|
|
715
|
+
entry. After an upgrade changes an entry, for example the gate's matcher
|
|
716
|
+
`^Agent$|spawn_agent$`, Codex **skips that hook** until you approve it again in
|
|
717
|
+
`/hooks`. Until then the scope, path and git guards, or the runtime gate, are
|
|
718
|
+
simply not running under Codex, and nothing on screen says so.
|
|
719
|
+
**Why it stays.** This is how Codex's trust model works. A plugin cannot and
|
|
720
|
+
should not approve itself.
|
|
721
|
+
**What to do.** After every `npx riskrails` that touches Codex, open `/hooks` in
|
|
722
|
+
Codex and approve the changed entries. The installer ends with that reminder.
|
|
723
|
+
**Source.** `docs/hooks.md`, runtime gate. `README.md`, "What it installs".
|
|
724
|
+
|
|
725
|
+
### Codex facts are observed, not guaranteed
|
|
726
|
+
|
|
727
|
+
**Risk.** Codex's multi-agent v2 launches agents as `collaborationspawn_agent`.
|
|
728
|
+
A role's pinned model beats a model given at launch, and a Codex hook cannot ask
|
|
729
|
+
the user a question. All three were established by live probes and one
|
|
730
|
+
documentation page, and Codex changes quickly. A future Codex release can make
|
|
731
|
+
the reroute or the fan-out check silently miss.
|
|
732
|
+
**Limits.** On Codex these rules degrade to "allow and explain" by design, never
|
|
733
|
+
to a block. The `SubagentStart` backstop journals `missed_reroute` when an
|
|
734
|
+
EXPERT agent starts during an outage anyway.
|
|
735
|
+
**What to do.** After a Codex upgrade, run `state.py events --type
|
|
736
|
+
missed_reroute`. Any line there means the reroute stopped matching.
|
|
737
|
+
**Source.** WP5 spec, accepted concern 6. PR #26.
|
|
738
|
+
|
|
739
|
+
### Budgets and quota are advice, not limits
|
|
740
|
+
|
|
741
|
+
**Risk.** Several numbers can be off, and none of them ever blocks work.
|
|
742
|
+
- **Quota signals can be stale.** Codex quota comes only from the rollouts of a
|
|
743
|
+
past or running session. Claude's comes only while a session with the
|
|
744
|
+
statusline runs.
|
|
745
|
+
- **The running-agent count can drift.** A `SubagentStop` lost to a crash leaves
|
|
746
|
+
an entry behind for up to 30 minutes, which costs one extra question.
|
|
747
|
+
- **The EXPERT launch count per task never shrinks.** Declined launches count
|
|
748
|
+
too.
|
|
749
|
+
- **On Pro/Plus, "strictly serial" is the plugin's rule, not Codex's.** Codex
|
|
750
|
+
still allows 3 threads and can run a second agent after the gate has explained
|
|
751
|
+
why it should not.
|
|
752
|
+
|
|
753
|
+
**What to do.** `runtime-gate.py clear` empties the count after a crash. Read
|
|
754
|
+
the quota with its `stale` and `resets_at` fields, not as a hard figure.
|
|
755
|
+
**Source.** WP5 spec, accepted concerns 1, 3 and 4. `hooks/runtime-gate.py`.
|
|
756
|
+
|
|
757
|
+
### `--adopt` edge cases fail safe, not smoothly
|
|
758
|
+
|
|
759
|
+
Three low-severity cases from the WP6 review were accepted. Each fails closed or
|
|
760
|
+
safe rather than losing data.
|
|
761
|
+
- An interrupted apply's `planned_writes` excuses those paths from the
|
|
762
|
+
clean-tree check. It never decides what is written or deleted.
|
|
763
|
+
- On resume, `original/<file>` is reused, so edits made between the crash and
|
|
764
|
+
the resume are not in the saved original. Git still has the committed version.
|
|
765
|
+
- In a monorepo subdirectory an interrupted apply cannot resume until you commit.
|
|
766
|
+
It refuses rather than guesses.
|
|
767
|
+
|
|
768
|
+
Two things have not been tried by hand yet: `--adopt` on a real Spec Kit or
|
|
769
|
+
Cursor project (the tests use fixtures), and a cleanup run in a real terminal.
|
|
770
|
+
**What to do.** Run `--adopt` on a clean, committed tree, read the dry run
|
|
771
|
+
first, and keep `original/` until you have checked the result.
|
|
772
|
+
**Source.** `.ai/reports/T-2026-09-21-001/review.md`, the LOW rows.
|
|
773
|
+
|
|
774
|
+
### The usage report's parse cache trusts mtime and size
|
|
775
|
+
|
|
776
|
+
**Risk.** `usage-report.py` keeps each transcript's parse state on disk, keyed by
|
|
777
|
+
path, mtime and size, and folds only the bytes past the offset it stopped at. A
|
|
778
|
+
file that was rewritten rather than appended to — same path, larger, and the
|
|
779
|
+
same first 256 bytes — would be resumed from a stale offset, and the report
|
|
780
|
+
would count the old records together with the new ones.
|
|
781
|
+
**Why it stays.** The alternative is hashing every transcript on every run,
|
|
782
|
+
which is the work the cache exists to avoid. Transcripts are append-only in both
|
|
783
|
+
runtimes; a rewrite that also preserves the opening bytes is not a case either
|
|
784
|
+
runtime produces.
|
|
785
|
+
**Limits.** A shrunk file, one whose first block changed, or one whose stored
|
|
786
|
+
state is not the shape and contents this version folds, is parsed from zero.
|
|
787
|
+
Same mtime and size means the file is not read again — unless its last line had
|
|
788
|
+
no newline after it, which is re-read until it is complete — so an in-place
|
|
789
|
+
rewrite of exactly the same length is the other side of the same assumption.
|
|
790
|
+
The cache is a report's cache: nothing else reads it, and a wrong number is a
|
|
791
|
+
wrong number in a report, not a wrong change to a repository.
|
|
792
|
+
**What to do.** `--no-cache` reports without it, and tells you within one run
|
|
793
|
+
whether a surprising number came from the cache. Deleting
|
|
794
|
+
`~/.cache/riskrails/usage-report.json` rebuilds it from scratch.
|
|
795
|
+
**Source.** This entry; `skills/usage-report/SKILL.md`, "The parse cache".
|
|
796
|
+
|
|
797
|
+
## Migrating from claude-routing
|
|
798
|
+
|
|
799
|
+
This plugin absorbed `claude-routing`. Run `npx riskrails` once and it:
|
|
800
|
+
|
|
801
|
+
- writes the routing settings itself, from the same `profiles/` — nothing about
|
|
802
|
+
your model, effort or limits changes;
|
|
803
|
+
- **removes the `<!-- claude-routing:start/end -->` block** from
|
|
804
|
+
`~/.claude/CLAUDE.md` and writes one `riskrails` block carrying both sets
|
|
805
|
+
of rules;
|
|
806
|
+
- also removes an older unmarked `# Model allocation by task and scope` section,
|
|
807
|
+
if one predates the plugins;
|
|
808
|
+
- **retires `agents/reviewer.md`** to `reviewer.md.superseded`, because
|
|
809
|
+
`ai-reviewer` replaces it — adversarial, tier-aware, and reading the project's
|
|
810
|
+
own policies. If you edited that file, it is left alone and the conflict is
|
|
811
|
+
reported instead;
|
|
812
|
+
- keeps every other hook, agent and settings key you have, including ones no
|
|
813
|
+
plugin owns.
|
|
814
|
+
|
|
815
|
+
Where the two disagreed, the agentic layer wins:
|
|
816
|
+
|
|
817
|
+
| Question | Answer |
|
|
818
|
+
|---|---|
|
|
819
|
+
| Who reviews a change before commit? | `ai-reviewer`, not `reviewer` |
|
|
820
|
+
| Where does a change start? | `/ai-task`. The `/sdlc-*` chain is for work needing a written intent and spec first, then hands its plan to `/ai-task` |
|
|
821
|
+
| Who designs? | `ai-planner` inside a task, `ai-expert` on escalation. `architect` is for design questions outside a task, or in a repository without `.ai/` |
|
|
822
|
+
| Which init? | `/ai-init`, which runs the SDLC scaffold too. `/project-init` is the SDLC layout alone |
|
|
823
|
+
|
|
824
|
+
The old `claude-routing` directory can be deleted once you have installed this
|
|
825
|
+
one; nothing references it any more.
|
|
826
|
+
|
|
827
|
+
## Tests
|
|
828
|
+
|
|
829
|
+
```bash
|
|
830
|
+
bash tests/run-all.sh
|
|
831
|
+
```
|
|
832
|
+
|
|
833
|
+
Twenty-seven suites, 2,904 assertions. The guards against JSON fixtures in both runtimes (including
|
|
834
|
+
`apply_patch` payloads that touch several files at once); the state machine and
|
|
835
|
+
its `triage` call; scaffold idempotency for one runtime, the other, and both
|
|
836
|
+
over a single `.ai/` tree; installer rendering for every plan combination and
|
|
837
|
+
every `--target`; the Codex agent renderer, asserting each role's *effective*
|
|
838
|
+
model and effort; the `config.toml` merge against a fixture full of third-party
|
|
839
|
+
settings, and its refusal on a malformed file; the migration off
|
|
840
|
+
`claude-routing`; `/project-update` against a project scaffolded from the oldest
|
|
841
|
+
shipped templates and edited by hand, for a Claude and for a Codex project; an
|
|
842
|
+
end-to-end run that installs both runtimes into scratch directories, scaffolds a
|
|
843
|
+
throwaway repository, drives a T5 task through the guards from Claude and then
|
|
844
|
+
from Codex, and proves both see the same state; the usage report for both
|
|
845
|
+
runtimes, including its incremental parse cache against the same run with the
|
|
846
|
+
cache off; and both escalation gates through every event.
|
|
847
|
+
|
|
848
|
+
No suite reads or writes the developer's real `~/.claude` or `~/.codex`.
|
|
849
|
+
|
|
850
|
+
## Documentation
|
|
851
|
+
|
|
852
|
+
| File | About |
|
|
853
|
+
|---|---|
|
|
854
|
+
| `docs/getting-started.md` | the first hour: install, `/ai-init`, a worked T1 and T4 task |
|
|
855
|
+
| `docs/architecture.md` | how the pieces fit: `.ai/`, the pipeline, state, hooks, the two adapters |
|
|
856
|
+
| `docs/agents.md` | the roster, contracts and when each agent runs |
|
|
857
|
+
| `docs/hooks.md` | every rule the guards enforce, their configuration and limits |
|
|
858
|
+
| `docs/hook-performance.md` | what the guards cost per tool call, the budget, and how a change is proved behaviour-preserving |
|
|
859
|
+
| `docs/risk-tiers.md` | how classification works and how to tune it |
|
|
860
|
+
| `docs/workflows.md` | the five workflows and how one is chosen |
|
|
861
|
+
| `docs/faq.md` | why something was blocked, and how to change it |
|
|
862
|
+
| `docs/sdlc/plans/dual-runtime-agentic-routing.md` | the approved plan this dual-runtime support was built from |
|
|
863
|
+
|
|
864
|
+
## Contributing, security and license
|
|
865
|
+
|
|
866
|
+
- [CONTRIBUTING.md](CONTRIBUTING.md): setup, tests, and how a change gets merged
|
|
867
|
+
- [SECURITY.md](SECURITY.md): what counts as a vulnerability and how to report
|
|
868
|
+
one privately
|
|
869
|
+
- [LICENSE](LICENSE): MIT
|