@bonesofspring/ai-rules 0.2.23 → 0.2.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +20 -5
  3. package/bin/cli.js +121 -15
  4. package/bin/mavis-install.js +5 -1
  5. package/bin/opencode-install.js +535 -0
  6. package/package.json +10 -3
  7. package/presets/_shared/core/agent-team/agent-team-orchestrator.md +2 -2
  8. package/presets/_shared/core/meta/preset-layering.md +3 -3
  9. package/presets/_shared/core/meta/preset-no-cross-stack-leakage.md +1 -1
  10. package/presets/_shared/core/meta/preset-pr-checklist.md +4 -3
  11. package/presets/_shared/core/meta/preset-token-budget.md +3 -0
  12. package/presets/_shared/core/meta/preset-twin-sync.md +16 -0
  13. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-layering.md +3 -3
  14. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  15. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  16. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-token-budget.md +3 -0
  17. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-twin-sync.md +16 -0
  18. package/presets/claude/go/rules/tooling-and-review/preset-layering.md +3 -3
  19. package/presets/claude/go/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  20. package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  21. package/presets/claude/go/rules/tooling-and-review/preset-token-budget.md +3 -0
  22. package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +16 -0
  23. package/presets/claude/ios-swift/rules/tooling-and-review/preset-layering.md +3 -3
  24. package/presets/claude/ios-swift/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  25. package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  26. package/presets/claude/ios-swift/rules/tooling-and-review/preset-token-budget.md +3 -0
  27. package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +16 -0
  28. package/presets/claude/java/rules/tooling-and-review/preset-layering.md +3 -3
  29. package/presets/claude/java/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  30. package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  31. package/presets/claude/java/rules/tooling-and-review/preset-token-budget.md +3 -0
  32. package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +16 -0
  33. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-layering.md +3 -3
  34. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  35. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  36. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-token-budget.md +3 -0
  37. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +16 -0
  38. package/presets/claude/next/REPO_AGENTS.md +34 -8
  39. package/presets/claude/next/agents/build-verifier.md +3 -1
  40. package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +1 -1
  41. package/presets/claude/next/rules/tooling-and-review/preset-layering.md +3 -3
  42. package/presets/claude/next/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  43. package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  44. package/presets/claude/next/rules/tooling-and-review/preset-token-budget.md +3 -0
  45. package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +16 -0
  46. package/presets/claude/nuxt/rules/tooling-and-review/preset-layering.md +3 -3
  47. package/presets/claude/nuxt/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  48. package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  49. package/presets/claude/nuxt/rules/tooling-and-review/preset-token-budget.md +3 -0
  50. package/presets/claude/nuxt/rules/tooling-and-review/preset-twin-sync.md +16 -0
  51. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-layering.md +3 -3
  52. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  53. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  54. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-token-budget.md +3 -0
  55. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +16 -0
  56. package/presets/claude/php-laravel/rules/tooling-and-review/preset-layering.md +3 -3
  57. package/presets/claude/php-laravel/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  58. package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  59. package/presets/claude/php-laravel/rules/tooling-and-review/preset-token-budget.md +3 -0
  60. package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +16 -0
  61. package/presets/claude/svelte/rules/tooling-and-review/preset-layering.md +3 -3
  62. package/presets/claude/svelte/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  63. package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  64. package/presets/claude/svelte/rules/tooling-and-review/preset-token-budget.md +3 -0
  65. package/presets/claude/svelte/rules/tooling-and-review/preset-twin-sync.md +16 -0
  66. package/presets/cursor/android-kotlin/rules/preset-layering.mdc +3 -3
  67. package/presets/cursor/android-kotlin/rules/preset-no-cross-stack-leakage.mdc +1 -1
  68. package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +4 -3
  69. package/presets/cursor/android-kotlin/rules/preset-token-budget.mdc +3 -0
  70. package/presets/cursor/android-kotlin/rules/preset-twin-sync.mdc +16 -0
  71. package/presets/cursor/go/rules/preset-layering.mdc +3 -3
  72. package/presets/cursor/go/rules/preset-no-cross-stack-leakage.mdc +1 -1
  73. package/presets/cursor/go/rules/preset-pr-checklist.mdc +4 -3
  74. package/presets/cursor/go/rules/preset-token-budget.mdc +3 -0
  75. package/presets/cursor/go/rules/preset-twin-sync.mdc +16 -0
  76. package/presets/cursor/ios-swift/rules/preset-layering.mdc +3 -3
  77. package/presets/cursor/ios-swift/rules/preset-no-cross-stack-leakage.mdc +1 -1
  78. package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +4 -3
  79. package/presets/cursor/ios-swift/rules/preset-token-budget.mdc +3 -0
  80. package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +16 -0
  81. package/presets/cursor/java/rules/preset-layering.mdc +3 -3
  82. package/presets/cursor/java/rules/preset-no-cross-stack-leakage.mdc +1 -1
  83. package/presets/cursor/java/rules/preset-pr-checklist.mdc +4 -3
  84. package/presets/cursor/java/rules/preset-token-budget.mdc +3 -0
  85. package/presets/cursor/java/rules/preset-twin-sync.mdc +16 -0
  86. package/presets/cursor/mcp-ts/rules/preset-layering.mdc +3 -3
  87. package/presets/cursor/mcp-ts/rules/preset-no-cross-stack-leakage.mdc +1 -1
  88. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +4 -3
  89. package/presets/cursor/mcp-ts/rules/preset-token-budget.mdc +3 -0
  90. package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +16 -0
  91. package/presets/cursor/next/REPO_AGENTS.md +26 -8
  92. package/presets/cursor/next/agents/build-verifier.md +3 -1
  93. package/presets/cursor/next/rules/ai-local-overlay.mdc +1 -1
  94. package/presets/cursor/next/rules/preset-layering.mdc +3 -3
  95. package/presets/cursor/next/rules/preset-no-cross-stack-leakage.mdc +1 -1
  96. package/presets/cursor/next/rules/preset-pr-checklist.mdc +4 -3
  97. package/presets/cursor/next/rules/preset-token-budget.mdc +3 -0
  98. package/presets/cursor/next/rules/preset-twin-sync.mdc +16 -0
  99. package/presets/cursor/nuxt/rules/preset-layering.mdc +3 -3
  100. package/presets/cursor/nuxt/rules/preset-no-cross-stack-leakage.mdc +1 -1
  101. package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +4 -3
  102. package/presets/cursor/nuxt/rules/preset-token-budget.mdc +3 -0
  103. package/presets/cursor/nuxt/rules/preset-twin-sync.mdc +16 -0
  104. package/presets/cursor/php-hexagonal/rules/preset-layering.mdc +3 -3
  105. package/presets/cursor/php-hexagonal/rules/preset-no-cross-stack-leakage.mdc +1 -1
  106. package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +4 -3
  107. package/presets/cursor/php-hexagonal/rules/preset-token-budget.mdc +3 -0
  108. package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +16 -0
  109. package/presets/cursor/php-laravel/rules/preset-layering.mdc +3 -3
  110. package/presets/cursor/php-laravel/rules/preset-no-cross-stack-leakage.mdc +1 -1
  111. package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +4 -3
  112. package/presets/cursor/php-laravel/rules/preset-token-budget.mdc +3 -0
  113. package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +16 -0
  114. package/presets/cursor/svelte/rules/preset-layering.mdc +3 -3
  115. package/presets/cursor/svelte/rules/preset-no-cross-stack-leakage.mdc +1 -1
  116. package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +4 -3
  117. package/presets/cursor/svelte/rules/preset-token-budget.mdc +3 -0
  118. package/presets/cursor/svelte/rules/preset-twin-sync.mdc +16 -0
  119. package/presets/mavis/next/MAVIS.md +1 -0
  120. package/presets/mavis/next/REPO_AGENTS.md +28 -48
  121. package/presets/mavis/next/adapter-map.json +3 -3
  122. package/presets/mavis/next/agents/build-verifier.md +3 -1
  123. package/presets/mavis/next/rules/agent-team-orchestrator.md +2 -2
  124. package/presets/mavis/next/rules/ai-local-overlay.md +1 -1
  125. package/presets/mavis/next/rules/preset-layering.md +3 -3
  126. package/presets/mavis/next/rules/preset-no-cross-stack-leakage.md +1 -1
  127. package/presets/mavis/next/rules/preset-pr-checklist.md +4 -3
  128. package/presets/mavis/next/rules/preset-token-budget.md +3 -0
  129. package/presets/mavis/next/rules/preset-twin-sync.md +16 -0
  130. package/presets/opencode/README.md +61 -0
  131. package/presets/opencode/next/MCP.md +36 -0
  132. package/presets/opencode/next/OPENCODE.md +65 -0
  133. package/presets/opencode/next/README.md +16 -0
  134. package/presets/opencode/next/REPO_AGENTS.md +74 -0
  135. package/presets/opencode/next/adapter-map.json +959 -0
  136. package/presets/opencode/next/agents/README.md +201 -0
  137. package/presets/opencode/next/agents/accessibility-reviewer.md +73 -0
  138. package/presets/opencode/next/agents/api-contract-reviewer.md +69 -0
  139. package/presets/opencode/next/agents/build-verifier.md +124 -0
  140. package/presets/opencode/next/agents/ci-investigator.md +71 -0
  141. package/presets/opencode/next/agents/code-reviewer.md +73 -0
  142. package/presets/opencode/next/agents/codebase-analyzer.md +33 -0
  143. package/presets/opencode/next/agents/debugger.md +88 -0
  144. package/presets/opencode/next/agents/feature-developer.md +109 -0
  145. package/presets/opencode/next/agents/migration-specialist.md +79 -0
  146. package/presets/opencode/next/agents/mockup-reviewer.md +65 -0
  147. package/presets/opencode/next/agents/openspec-author.md +169 -0
  148. package/presets/opencode/next/agents/performance-auditor.md +80 -0
  149. package/presets/opencode/next/agents/playwright-test-generator.md +36 -0
  150. package/presets/opencode/next/agents/playwright-test-healer.md +36 -0
  151. package/presets/opencode/next/agents/playwright-test-planner.md +33 -0
  152. package/presets/opencode/next/agents/qa-tester.md +60 -0
  153. package/presets/opencode/next/agents/security-reviewer.md +66 -0
  154. package/presets/opencode/next/agents/solution-architect.md +80 -0
  155. package/presets/opencode/next/agents/task-analyst.md +178 -0
  156. package/presets/opencode/next/agents/task-router.md +190 -0
  157. package/presets/opencode/next/agents/tech-writer.md +69 -0
  158. package/presets/opencode/next/agents/unit-test-generator.md +39 -0
  159. package/presets/opencode/next/agents/unit-test-healer.md +40 -0
  160. package/presets/opencode/next/agents/unit-test-planner.md +66 -0
  161. package/presets/opencode/next/commands/README.md +49 -0
  162. package/presets/opencode/next/commands/spec-start.md +32 -0
  163. package/presets/opencode/next/commands/task-continue.md +58 -0
  164. package/presets/opencode/next/commands/task.md +58 -0
  165. package/presets/opencode/next/commands/technical-retro.md +88 -0
  166. package/presets/opencode/next/hooks/README.md +22 -0
  167. package/presets/opencode/next/hooks/chain-team-phases.sh +845 -0
  168. package/presets/opencode/next/opencode.json +33 -0
  169. package/presets/opencode/next/rules/README.md +20 -0
  170. package/presets/opencode/next/rules/agent-team-intake.md +11 -0
  171. package/presets/opencode/next/rules/agent-team-orchestrator.md +214 -0
  172. package/presets/opencode/next/rules/ai-local-overlay.md +37 -0
  173. package/presets/opencode/next/rules/anti-sycophancy-discipline.md +23 -0
  174. package/presets/opencode/next/rules/api-services.md +72 -0
  175. package/presets/opencode/next/rules/architecture-boundaries-ui.md +9 -0
  176. package/presets/opencode/next/rules/architecture-boundaries.md +86 -0
  177. package/presets/opencode/next/rules/arrow-functions.md +25 -0
  178. package/presets/opencode/next/rules/code-quality-and-refactoring.md +40 -0
  179. package/presets/opencode/next/rules/code-review-mr.md +40 -0
  180. package/presets/opencode/next/rules/css-property-order-stylelint.md +5 -0
  181. package/presets/opencode/next/rules/design-guidance.md +99 -0
  182. package/presets/opencode/next/rules/feature-delivery-workflow.md +49 -0
  183. package/presets/opencode/next/rules/http-client.md +55 -0
  184. package/presets/opencode/next/rules/layer-barrel-exports.md +68 -0
  185. package/presets/opencode/next/rules/mcp-usage.md +86 -0
  186. package/presets/opencode/next/rules/mockup-review.md +107 -0
  187. package/presets/opencode/next/rules/navigation-router-stack.md +56 -0
  188. package/presets/opencode/next/rules/navigation-router-ui.md +10 -0
  189. package/presets/opencode/next/rules/next-app-core.md +29 -0
  190. package/presets/opencode/next/rules/next-app-router.md +44 -0
  191. package/presets/opencode/next/rules/no-props-spread.md +56 -0
  192. package/presets/opencode/next/rules/no-type-assertion-as-import-export.md +51 -0
  193. package/presets/opencode/next/rules/package-manager.md +11 -0
  194. package/presets/opencode/next/rules/playwright-agents.md +67 -0
  195. package/presets/opencode/next/rules/post-change-lint.md +35 -0
  196. package/presets/opencode/next/rules/preset-layering.md +27 -0
  197. package/presets/opencode/next/rules/preset-no-cross-stack-leakage.md +90 -0
  198. package/presets/opencode/next/rules/preset-pr-checklist.md +36 -0
  199. package/presets/opencode/next/rules/preset-token-budget.md +39 -0
  200. package/presets/opencode/next/rules/preset-twin-sync.md +81 -0
  201. package/presets/opencode/next/rules/product-specs-authoring.md +112 -0
  202. package/presets/opencode/next/rules/product-specs.md +56 -0
  203. package/presets/opencode/next/rules/public-imports.md +50 -0
  204. package/presets/opencode/next/rules/react-a11y-coding.md +31 -0
  205. package/presets/opencode/next/rules/react-next-anti-hallucination.md +60 -0
  206. package/presets/opencode/next/rules/react-ui.md +105 -0
  207. package/presets/opencode/next/rules/reference-features.md +45 -0
  208. package/presets/opencode/next/rules/security-next.md +45 -0
  209. package/presets/opencode/next/rules/store-rtk.md +78 -0
  210. package/presets/opencode/next/rules/technical-retro.md +11 -0
  211. package/presets/opencode/next/rules/tests-e2e-structure.md +72 -0
  212. package/presets/opencode/next/rules/tests-unit.md +72 -0
  213. package/presets/opencode/next/rules/types-jsdoc.md +43 -0
  214. package/presets/opencode/next/rules/ux-design.md +99 -0
  215. package/presets/opencode/next/skills/README.md +21 -0
  216. package/presets/opencode/next/skills/ci-investigation/SKILL.md +44 -0
  217. package/presets/opencode/next/skills/code-review/SKILL.md +44 -0
  218. package/presets/opencode/next/skills/debug-investigation/SKILL.md +59 -0
  219. package/presets/opencode/next/skills/feature-delivery/SKILL.md +39 -0
  220. package/presets/opencode/next/skills/mockup-review/SKILL.md +29 -0
  221. package/presets/opencode/next/skills/playwright-e2e/SKILL.md +33 -0
  222. package/presets/opencode/next/skills/react-performance/SKILL.md +44 -0
  223. package/presets/opencode/next/skills/spec-authoring/SKILL.md +26 -0
  224. package/presets/opencode/next/skills/spec-discovery/SKILL.md +58 -0
  225. package/presets/opencode/next/skills/technical-retro/SKILL.md +54 -0
  226. package/presets/opencode/next/skills/unit-testing/SKILL.md +34 -0
  227. package/presets/opencode/next/skills/ux-design/SKILL.md +36 -0
  228. package/presets/opencode/next/skills/write-adr/SKILL.md +41 -0
  229. package/presets/opencode/next/team/README.md +148 -0
  230. package/presets/opencode/next/team/conventions.md +21 -0
  231. package/presets/opencode/next/team/fixtures/artifact-manifest.example.json +79 -0
  232. package/presets/opencode/next/team/fixtures/bugfix-standard.json +25 -0
  233. package/presets/opencode/next/team/fixtures/feature-full.json +29 -0
  234. package/presets/opencode/next/team/fixtures/feature-light.json +27 -0
  235. package/presets/opencode/next/team/fixtures/feature-with-figma-url.json +17 -0
  236. package/presets/opencode/next/team/fixtures/feature-with-ux-no-figma.json +17 -0
  237. package/presets/opencode/next/team/fixtures/memlog.example.md +9 -0
  238. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/human-gate/metrics.json +69 -0
  239. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/missing-ledger/status.json +5 -0
  240. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/parallel-receipts/metrics.json +79 -0
  241. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/serial-retry/metrics.json +124 -0
  242. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/validation-failed/metrics.json +124 -0
  243. package/presets/opencode/next/team/fixtures/metrics.example.json +54 -0
  244. package/presets/opencode/next/team/fixtures/mockup-review-fail-embedded-status.json +8 -0
  245. package/presets/opencode/next/team/fixtures/mockup-review-standalone.json +14 -0
  246. package/presets/opencode/next/team/fixtures/ux-design-standalone.json +15 -0
  247. package/presets/opencode/next/team/tasks/.gitkeep +0 -0
  248. package/presets/opencode/platform-contract.json +131 -0
  249. package/scripts/capture-cli-golden.mjs +5 -1
  250. package/scripts/check-chain-hook-coverage.sh +1 -0
  251. package/scripts/check-opencode-adapter-map.mjs +294 -0
  252. package/scripts/check-opencode-local-overlay.mjs +56 -0
  253. package/scripts/check-opencode-platform-contract.mjs +388 -0
  254. package/scripts/check-opencode-token-budget.mjs +48 -0
  255. package/scripts/check-preset-leakage.sh +30 -1
  256. package/scripts/check-preset-structure.sh +45 -0
  257. package/scripts/check-task-router-intents.sh +4 -4
  258. package/scripts/fixtures/cli-golden/claude/next.json +8 -8
  259. package/scripts/fixtures/cli-golden/cursor/next.json +8 -8
  260. package/scripts/fixtures/cli-golden/mavis/next.json +10 -10
  261. package/scripts/fixtures/cli-golden/opencode/next.json +125 -0
  262. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/AGENTS.md +1 -0
  263. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/rules/extra.mdc +1 -0
  264. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/rules/sample.mdc +2 -0
  265. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/OPENCODE.md +1 -0
  266. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/adapter-map.json +26 -0
  267. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/rules/sample.md +2 -0
  268. package/scripts/fixtures/opencode-adapter-map/valid/cursor/AGENTS.md +1 -0
  269. package/scripts/fixtures/opencode-adapter-map/valid/cursor/rules/sample.mdc +2 -0
  270. package/scripts/fixtures/opencode-adapter-map/valid/opencode/OPENCODE.md +1 -0
  271. package/scripts/fixtures/opencode-adapter-map/valid/opencode/adapter-map.json +26 -0
  272. package/scripts/fixtures/opencode-adapter-map/valid/opencode/rules/sample.md +2 -0
  273. package/scripts/fixtures/opencode-platform-contract/invalid-home-destination.json +131 -0
  274. package/scripts/fixtures/opencode-platform-contract/invalid-missing-capability.json +126 -0
  275. package/scripts/fixtures/opencode-platform-contract/invalid-released-unknown-stack.json +133 -0
  276. package/scripts/fixtures/opencode-platform-contract/invalid-unknown-native-path.json +131 -0
  277. package/scripts/fixtures/opencode-platform-contract/invalid-version-pin.json +132 -0
  278. package/scripts/fixtures/opencode-platform-contract/valid.json +131 -0
  279. package/scripts/generate-mavis-next.mjs +4 -101
  280. package/scripts/generate-opencode-next.mjs +730 -0
  281. package/scripts/lib/discover-hooks.mjs +23 -1
  282. package/scripts/sync-dogfood-mavis.sh +90 -0
  283. package/scripts/sync-dogfood-opencode.sh +85 -0
  284. package/scripts/test-agent-task-metrics-hooks.mjs +4 -1
  285. package/scripts/test-chain-team-phases-coverage.mjs +6 -1
  286. package/scripts/test-cli-init-clean.mjs +180 -2
  287. package/scripts/test-opencode-context-budget.mjs +53 -0
@@ -42,6 +42,20 @@ _shared/core → cursor/<stack> → mavis/<stack>
42
42
 
43
43
  Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
44
44
 
45
+ ## OpenCode derivation (not a Claude twin)
46
+
47
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
48
+ |-------|------------|-----------------|----------|
49
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
50
+
51
+ OpenCode is a **fourth platform adapter** with a **native** install root (`.opencode/`), not a Claude-style topic twin and not an owned overlay like `.mavis/`:
52
+
53
+ ```text
54
+ _shared/core → cursor/<stack> → opencode/<stack>
55
+ ```
56
+
57
+ Regenerate with `node packages/ai-rules/scripts/generate-opencode-next.mjs`; validate with `node packages/ai-rules/scripts/check-opencode-adapter-map.mjs`. Do not derive OpenCode sources from Claude.
58
+
45
59
  ## Same-PR checklist
46
60
 
47
61
  1. Edit Cursor rule first (body + frontmatter).
@@ -49,6 +63,7 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
49
63
  3. Update mapping table row if stem/path changed.
50
64
  4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
51
65
  5. When mapped `cursor/<stack>/` sources change, regenerate `mavis/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`).
66
+ 6. When mapped `cursor/<stack>/` sources change, regenerate `opencode/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`).
52
67
 
53
68
  ## Twin depth
54
69
 
@@ -70,5 +85,6 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
70
85
  - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
71
86
  - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
72
87
  - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
88
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
73
89
 
74
90
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -1,19 +1,34 @@
1
1
  # Next.js — agent instructions
2
2
 
3
- Cross-tool repo-root guide. Tool-specific maps stay under `.cursor/AGENTS.md` and `.claude/CLAUDE.md`.
3
+ Cross-tool repo-root guide. Tool-specific maps stay under `.cursor/AGENTS.md`, `.claude/CLAUDE.md`, `.mavis/AGENTS.md`, and `.opencode/AGENTS.md`.
4
4
 
5
5
  ## Cross-tool setup
6
6
 
7
- - Treat this file as the **shared** entry for any agent (Cursor, Claude Code, or other).
8
- - Tool maps (agent-team tables, slash commands) live in `.cursor/AGENTS.md` / `.claude/CLAUDE.md` — use them when that tool is installed.
7
+ - Treat this file as the **shared** entry for any agent (Cursor, Claude Code, Mavis, OpenCode, or other).
8
+ - All four platforms ship **the same** root file. `init` overwrites it; content does not depend on which tool ran last.
9
+ - Tool maps (agent-team tables, slash commands) live in `.cursor/AGENTS.md` / `.claude/CLAUDE.md` / `.mavis/AGENTS.md` / `.opencode/AGENTS.md` — use them when that tool is installed.
9
10
  - Install:
10
11
 
11
12
  ```bash
12
- npx @bonesofspring/ai-rules init cursor --preset next
13
- npx @bonesofspring/ai-rules init claude --preset next
13
+ npx @bonesofspring/ai-rules init multi --preset next
14
14
  ```
15
15
 
16
- `init` overwrites this file from the preset (`REPO_AGENTS.md` → `AGENTS.md`). Living gotchas belong in `team/conventions.md`, not here.
16
+ Per-tool: `init cursor|claude|mavis|opencode --preset next`. `init` overwrites this file from the preset (`REPO_AGENTS.md` → `AGENTS.md`). `clean` of one tool leaves this file if another tool install remains. Living gotchas belong in `team/conventions.md` and `.ai.local/conventions.md`, not here.
17
+
18
+ ## Presence-based load
19
+
20
+ When the tree exists, read the tool map, then the essential rules. Do not preload the full catalog.
21
+
22
+ - If `.cursor/` exists: read `.cursor/AGENTS.md`.
23
+ - If `.claude/` exists: read `.claude/CLAUDE.md`.
24
+ - If `.mavis/` exists: read `.mavis/AGENTS.md`, then `.mavis/rules/next-app-core.md`, `.mavis/rules/package-manager.md`, `.mavis/rules/code-quality-and-refactoring.md`, `.mavis/rules/ai-local-overlay.md`.
25
+ - If `.opencode/` exists: read `.opencode/AGENTS.md`, then `.opencode/rules/next-app-core.md`, `.opencode/rules/package-manager.md`, `.opencode/rules/code-quality-and-refactoring.md`, `.opencode/rules/ai-local-overlay.md`.
26
+
27
+ Mavis has no native rule discovery without those root paths. OpenCode has no `alwaysApply` engine — the four `.opencode/rules/*.md` files above are the always-on set.
28
+
29
+ ## Pipelines are per-tool
30
+
31
+ `/task` slug, `status.json`, and `metrics.json` live under `.tool/team/tasks/<slug>/`. They are **not** shared across Cursor, Claude, Mavis, and OpenCode.
17
32
 
18
33
  ## Commands (test / lint / build)
19
34
 
@@ -40,9 +55,20 @@ After code edits: invoke **`post-change-lint`** (requestable). Full gate: agent
40
55
  |------|-----|
41
56
  | Cursor | `.cursor/AGENTS.md` (optional if Cursor not installed) |
42
57
  | Claude Code | `.claude/CLAUDE.md` (optional if Claude not installed) |
58
+ | Mavis | `.mavis/AGENTS.md` (optional if Mavis not installed) |
59
+ | OpenCode | `.opencode/AGENTS.md` (optional if OpenCode not installed) |
43
60
 
44
- Rules: `.cursor/rules/` or `.claude/rules/`. Skills: `.cursor/skills/` or `.claude/skills/`.
61
+ Rules: `.cursor/rules/`, `.claude/rules/`, `.mavis/rules/`, or `.opencode/rules/`.
62
+ Skills: `.cursor/skills/`, `.claude/skills/`, `.mavis/skills/`, or `.opencode/skills/`.
45
63
 
46
64
  ## Living conventions
47
65
 
48
- Gotchas, local patterns, and team decisions: **`.cursor/team/conventions.md`** and/or **`.claude/team/conventions.md`** (fill after init; not overwritten on every dogfood sync when already present).
66
+ Gotchas, local patterns, and team decisions: **`.cursor/team/conventions.md`**, **`.claude/team/conventions.md`**, **`.mavis/team/conventions.md`**, and/or **`.opencode/team/conventions.md`** (fill after init; not overwritten on every dogfood sync when already present).
67
+
68
+ ## Local overlay (`.ai.local/`) — MANDATORY
69
+
70
+ A `.ai.local/` directory MAY exist at the repo root or at any nesting depth in monorepos. **All agents MUST read and apply it on every turn.** Rules there override preset rules; in conflicts, the local rule wins. `override: kill <preset-rule-name>` drops the named preset rule from the agent's context entirely.
71
+
72
+ Plain markdown rules under `.ai.local/rules/*.md` are read by the agent with higher priority than preset rules. Living gotchas live in `.ai.local/conventions.md`.
73
+
74
+ Authoring guide: `docs/LOCAL-OVERLAY.md` in the `@bonesofspring/ai-rules` package. The `ai-local-overlay` rule (always-on for Cursor, on-demand for Claude) is the mechanism; this `MANDATORY` section is the reinforcement.
@@ -46,13 +46,15 @@ When validating **preset packaging** changes (paths under `packages/ai-rules/pre
46
46
  7. **Embed drift (hard in `check:preset-structure`):** run `packages/ai-rules/scripts/check-shared-core-drift.sh` with `AI_RULES_DRIFT_FAIL=1` (bundled by the structure orchestrator). Lineage stems excluded from body equality.
47
47
  8. **Dogfood (monorepo soft):** prefer `packages/ai-rules/scripts/sync-dogfood-cursor.sh`; mass dogfood deletion without migration doc → risk / FAIL for maintainers.
48
48
 
49
- 9. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|nuxt|svelte|ios-swift|go|java|mcp-ts|php-hexagonal|php-laravel`) must ship `REPO_AGENTS.md` when validating preset packaging → **FAIL** if missing.
49
+ 9. **Root AGENTS template:** each installable preset (`cursor|claude` × `next|nuxt|svelte|ios-swift|go|java|mcp-ts|php-hexagonal|php-laravel`, plus released `mavis/<stack>` and `opencode/<stack>`) must ship `REPO_AGENTS.md` when validating preset packaging → **FAIL** if missing.
50
50
  10. **Hooks cookbook:** default `hooks.json` must **not** reference `hooks/examples/` → **FAIL** if it does.
51
51
  11. **Performance skill by stack:** next → `react-performance`; nuxt → `vue-performance`. **No react-performance/vue-performance on ios/go/java:** skill directory / required handoff must be absent under ios-swift, go, java, mcp-ts, php-hexagonal, and php-laravel → **FAIL** (leakage). Prefer `check:preset-leakage`.
52
52
  12. **Rule eval (WARN):** `scripts/check-rule-eval.mjs` / `yarn check:rule-eval` should exist for maintainers; smoke optional. Hard fail only when the opt-in eval job runs — not part of default `check:preset-structure`.
53
53
 
54
54
  13. **Product-specs assets (FAIL):** package must ship `presets/_shared/assets/docs-specs/INDEX.md`, `_templates/page.md`, `_templates/feature.md`. Cursor+Claude twins for `product-specs` and `product-specs-authoring` must embed matching shared-core markers; both stems **requestable** (`alwaysApply: false` / Claude `paths: docs/specs/**`) — never session-start.
55
55
  14. **Optional consumer check (WARN default):** `scripts/check-product-specs.sh` + schema stub may exist for opt-in consumer CI; **FAIL** only with `--strict` or AC that requires named specs — do not force consumer CI.
56
+ 15. **Mavis derive (next):** when `presets/mavis/**` or mapped `cursor/next` sources change, run `check:mavis-adapter-map`, `check:mavis-token-budget`, `check:mavis-local-overlay`, and `check:mavis-platform-contract`. Adapter-map `sourceRevision` drift → **FAIL**.
57
+ 16. **OpenCode derive (next):** when `presets/opencode/**` or mapped `cursor/next` sources change, run `check:opencode-adapter-map`, `check:opencode-token-budget`, `check:opencode-local-overlay`, `check:opencode-platform-contract`, and `test:opencode-context-budget`. Adapter-map `sourceRevision` drift → **FAIL**.
56
58
 
57
59
 
58
60
  **mockup-reviewer (UI):** `agents/mockup-reviewer.md` and `skills/mockup-review/` must exist (Cursor + Claude). Missing → **FAIL**. Backend stacks must **not** ship that agent file or a required `mockup-reviewer` chain handoff → **FAIL** if present.
@@ -36,7 +36,7 @@ Keep files ≤ 120 lines. Match the style of preset rules (short sections, bulle
36
36
 
37
37
  ## Limitations (read this)
38
38
 
39
- - Cursor/Claude do **not** natively read `.ai.local/`. This rule is a **prompt-only** mechanism: it asks you, the model, to read and apply the files. Reliability is high but not 100%.
39
+ - Cursor, Claude, Mavis, and OpenCode do **not** natively read `.ai.local/`. This rule is a **prompt-only** mechanism: it asks you, the model, to read and apply the files. Reliability is high but not 100%.
40
40
  - If a user adds a file to `.ai.local/` mid-session, **restart the session** to be sure it is picked up.
41
41
  - "Priority" is **contextual**, not enforced. Always re-read the local rule before answering questions that touch it.
42
42
  - This rule is **not** session-start (Claude convention); it loads on touch of `.ai.local/**` or `AGENTS.md`/`CLAUDE.md`. The "every turn" mandate is enforced by the body text, not by Cursor/Claude loading semantics.
@@ -18,14 +18,14 @@ Rules for **preset authors** (`packages/ai-rules/presets/**`). Not always-on in
18
18
  | Layer | Where | What to put |
19
19
  |-------|-------|-------------|
20
20
  | **Core** | `presets/_shared/core/**` | Stack-agnostic prose + checklists; no frontmatter; no paths `app/**`, `Features/**`, Playwright, xcodebuild |
21
- | **Stack** | `presets/{cursor\|claude}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
22
- | **Platform** | Cursor `.mdc` / Claude `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
21
+ | **Stack** | `presets/{cursor\|claude\|mavis\|opencode}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
22
+ | **Platform** | Cursor `.mdc` / Claude `.md` / Mavis `.md` / OpenCode `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:` vs OpenCode `mode`/`permission`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
23
23
 
24
24
  ## Where to put a new rule
25
25
 
26
26
  1. Shared principles for all stacks → **core** + adapters with `<!-- shared-core: … -->`.
27
27
  2. Only one of the installable stacks (`next` / `nuxt` / `svelte` / `ios-swift` / `android-kotlin` / `go` / `java` / `mcp-ts` / `php-hexagonal` / `php-laravel`) → **stack-specific** (not in `_shared`).
28
- 3. Only Cursor or only Claude packaging → platform artifact / frontmatter; do not duplicate semantics.
28
+ 3. Only Cursor, Claude, Mavis, or OpenCode packaging → platform artifact / frontmatter; do not duplicate semantics.
29
29
 
30
30
  ## SoT
31
31
 
@@ -96,4 +96,4 @@ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`,
96
96
 
97
97
  ## Chain fork
98
98
 
99
- `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform).
99
+ `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform). Released Mavis/OpenCode stacks must also differ from the Cursor and Claude twins of the same stack.
@@ -19,17 +19,18 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
19
19
  - [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
20
20
  - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, nuxt, svelte, ios-swift, android-kotlin, go, java, mcp-ts, php-hexagonal, and php-laravel — see `preset-twin-sync`)
21
21
  - [ ] **Mavis derive:** mapped `cursor/<stack>/` change → `mavis/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`; see `preset-twin-sync` § Mavis derivation)
22
+ - [ ] **OpenCode derive:** mapped `cursor/<stack>/` change → `opencode/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`; see `preset-twin-sync` § OpenCode derivation)
22
23
  - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
23
24
  - [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
24
25
  - [ ] **Local overlay coverage:** every installable stack ships `ai-local-overlay.mdc` (Cursor) and `ai-local-overlay.md` (Claude) with `MANDATORY` + acknowledgement format + `docs/LOCAL-OVERLAY.md` pointer; Claude twin listed in `claude/<stack>/rules/README.md` mapping table. Run `packages/ai-rules/scripts/check-local-overlay.sh`.
25
26
  - [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
26
27
  - [ ] **Hook-only lifecycle:** `status.json` / `metrics.json` writes happen only inside `hooks/`; agents read but never rewrite lifecycle fields. Run `packages/ai-rules/scripts/check-hook-only-lifecycle.sh`.
27
- - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` across the 10 stacks × 2 platforms (20 hooks) holds. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
28
+ - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` holds pairwise among the 10 stacks × Cursor/Claude platforms, and each released Mavis/OpenCode stack hook must also differ from the Cursor and Claude twins of the same stack. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
28
29
  - [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
29
30
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
30
31
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
31
32
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
32
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (or document intentional skip) when maintaining this monorepo
33
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
33
34
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
34
35
 
35
36
  ## Pointers
@@ -39,6 +40,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
39
40
  - Budget: `preset-token-budget`
40
41
  - Leakage: `preset-no-cross-stack-leakage`
41
42
  - Validation: stack `agents/build-verifier.md` → preset-structure section
42
- - Dogfood script: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`
43
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
43
44
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
44
45
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -19,6 +19,8 @@ Invariants for rule loading in an **installed** preset (consumer app).
19
19
  |----------|-----------|-----|
20
20
  | Cursor | `alwaysApply: true` | **≤ 4** |
21
21
  | Claude | rules **without** `paths:` | **exactly 3** |
22
+ | Mavis | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
23
+ | OpenCode | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
22
24
 
23
25
  **Cursor 4th slot is reserved for `ai-local-overlay`** (consumer-owned `.ai.local/` rules). If you do not need local overlay, demote that rule to `globs: ["**/.ai.local/**"]` and revert to ≤3.
24
26
 
@@ -27,6 +29,7 @@ Invariants for rule loading in an **installed** preset (consumer app).
27
29
  Session-start body budget:
28
30
  - Claude trio: ≤140 lines total (stretch ≤120).
29
31
  - Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
32
+ - Mavis / OpenCode: ≤4 root-entry rule files; combined root `AGENTS.md` + platform entry ≤170 nonempty lines. Do not dump the full rule catalog into `AGENTS.md`.
30
33
 
31
34
  ## Meta / author rules
32
35
 
@@ -42,6 +42,20 @@ _shared/core → cursor/<stack> → mavis/<stack>
42
42
 
43
43
  Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
44
44
 
45
+ ## OpenCode derivation (not a Claude twin)
46
+
47
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
48
+ |-------|------------|-----------------|----------|
49
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
50
+
51
+ OpenCode is a **fourth platform adapter** with a **native** install root (`.opencode/`), not a Claude-style topic twin and not an owned overlay like `.mavis/`:
52
+
53
+ ```text
54
+ _shared/core → cursor/<stack> → opencode/<stack>
55
+ ```
56
+
57
+ Regenerate with `node packages/ai-rules/scripts/generate-opencode-next.mjs`; validate with `node packages/ai-rules/scripts/check-opencode-adapter-map.mjs`. Do not derive OpenCode sources from Claude.
58
+
45
59
  ## Same-PR checklist
46
60
 
47
61
  1. Edit Cursor rule first (body + frontmatter).
@@ -49,6 +63,7 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
49
63
  3. Update mapping table row if stem/path changed.
50
64
  4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
51
65
  5. When mapped `cursor/<stack>/` sources change, regenerate `mavis/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`).
66
+ 6. When mapped `cursor/<stack>/` sources change, regenerate `opencode/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`).
52
67
 
53
68
  ## Twin depth
54
69
 
@@ -70,5 +85,6 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
70
85
  - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
71
86
  - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
72
87
  - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
88
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
73
89
 
74
90
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -14,14 +14,14 @@ Rules for **preset authors** (`packages/ai-rules/presets/**`). Not always-on in
14
14
  | Layer | Where | What to put |
15
15
  |-------|-------|-------------|
16
16
  | **Core** | `presets/_shared/core/**` | Stack-agnostic prose + checklists; no frontmatter; no paths `app/**`, `Features/**`, Playwright, xcodebuild |
17
- | **Stack** | `presets/{cursor\|claude}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
18
- | **Platform** | Cursor `.mdc` / Claude `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
17
+ | **Stack** | `presets/{cursor\|claude\|mavis\|opencode}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
18
+ | **Platform** | Cursor `.mdc` / Claude `.md` / Mavis `.md` / OpenCode `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:` vs OpenCode `mode`/`permission`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
19
19
 
20
20
  ## Where to put a new rule
21
21
 
22
22
  1. Shared principles for all stacks → **core** + adapters with `<!-- shared-core: … -->`.
23
23
  2. Only one of the installable stacks (`next` / `nuxt` / `svelte` / `ios-swift` / `android-kotlin` / `go` / `java` / `mcp-ts` / `php-hexagonal` / `php-laravel`) → **stack-specific** (not in `_shared`).
24
- 3. Only Cursor or only Claude packaging → platform artifact / frontmatter; do not duplicate semantics.
24
+ 3. Only Cursor, Claude, Mavis, or OpenCode packaging → platform artifact / frontmatter; do not duplicate semantics.
25
25
 
26
26
  ## SoT
27
27
 
@@ -92,4 +92,4 @@ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`,
92
92
 
93
93
  ## Chain fork
94
94
 
95
- `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform).
95
+ `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform). Released Mavis/OpenCode stacks must also differ from the Cursor and Claude twins of the same stack.
@@ -15,17 +15,18 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
15
15
  - [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
16
16
  - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, nuxt, svelte, ios-swift, android-kotlin, go, java, mcp-ts, php-hexagonal, and php-laravel — see `preset-twin-sync`)
17
17
  - [ ] **Mavis derive:** mapped `cursor/<stack>/` change → `mavis/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`; see `preset-twin-sync` § Mavis derivation)
18
+ - [ ] **OpenCode derive:** mapped `cursor/<stack>/` change → `opencode/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`; see `preset-twin-sync` § OpenCode derivation)
18
19
  - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
19
20
  - [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
20
21
  - [ ] **Local overlay coverage:** every installable stack ships `ai-local-overlay.mdc` (Cursor) and `ai-local-overlay.md` (Claude) with `MANDATORY` + acknowledgement format + `docs/LOCAL-OVERLAY.md` pointer; Claude twin listed in `claude/<stack>/rules/README.md` mapping table. Run `packages/ai-rules/scripts/check-local-overlay.sh`.
21
22
  - [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
22
23
  - [ ] **Hook-only lifecycle:** `status.json` / `metrics.json` writes happen only inside `hooks/`; agents read but never rewrite lifecycle fields. Run `packages/ai-rules/scripts/check-hook-only-lifecycle.sh`.
23
- - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` across the 10 stacks × 2 platforms (20 hooks) holds. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
24
+ - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` holds pairwise among the 10 stacks × Cursor/Claude platforms, and each released Mavis/OpenCode stack hook must also differ from the Cursor and Claude twins of the same stack. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
24
25
  - [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
25
26
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
26
27
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
27
28
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
28
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (or document intentional skip) when maintaining this monorepo
29
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
29
30
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
30
31
 
31
32
  ## Pointers
@@ -35,6 +36,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
35
36
  - Budget: `preset-token-budget`
36
37
  - Leakage: `preset-no-cross-stack-leakage`
37
38
  - Validation: stack `agents/build-verifier.md` → preset-structure section
38
- - Dogfood script: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`
39
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
39
40
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
40
41
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -16,6 +16,8 @@ Invariants for rule loading in an **installed** preset (consumer app).
16
16
  |----------|-----------|-----|
17
17
  | Cursor | `alwaysApply: true` | **≤ 4** |
18
18
  | Claude | rules **without** `paths:` | **exactly 3** |
19
+ | Mavis | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
20
+ | OpenCode | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
19
21
 
20
22
  **Cursor 4th slot is reserved for `ai-local-overlay`** (consumer-owned `.ai.local/` rules). If you do not need local overlay, demote that rule to `globs: ["**/.ai.local/**"]` and revert to ≤3.
21
23
 
@@ -24,6 +26,7 @@ Invariants for rule loading in an **installed** preset (consumer app).
24
26
  Session-start body budget:
25
27
  - Claude trio: ≤140 lines total (stretch ≤120).
26
28
  - Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
29
+ - Mavis / OpenCode: ≤4 root-entry rule files; combined root `AGENTS.md` + platform entry ≤170 nonempty lines. Do not dump the full rule catalog into `AGENTS.md`.
27
30
 
28
31
  ## Meta / author rules
29
32
 
@@ -38,6 +38,20 @@ _shared/core → cursor/<stack> → mavis/<stack>
38
38
 
39
39
  Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
40
40
 
41
+ ## OpenCode derivation (not a Claude twin)
42
+
43
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
44
+ |-------|------------|-----------------|----------|
45
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
46
+
47
+ OpenCode is a **fourth platform adapter** with a **native** install root (`.opencode/`), not a Claude-style topic twin and not an owned overlay like `.mavis/`:
48
+
49
+ ```text
50
+ _shared/core → cursor/<stack> → opencode/<stack>
51
+ ```
52
+
53
+ Regenerate with `node packages/ai-rules/scripts/generate-opencode-next.mjs`; validate with `node packages/ai-rules/scripts/check-opencode-adapter-map.mjs`. Do not derive OpenCode sources from Claude.
54
+
41
55
  ## Same-PR checklist
42
56
 
43
57
  1. Edit Cursor rule first (body + frontmatter).
@@ -45,6 +59,7 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
45
59
  3. Update mapping table row if stem/path changed.
46
60
  4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
47
61
  5. When mapped `cursor/<stack>/` sources change, regenerate `mavis/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`).
62
+ 6. When mapped `cursor/<stack>/` sources change, regenerate `opencode/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`).
48
63
 
49
64
  ## Twin depth
50
65
 
@@ -66,5 +81,6 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
66
81
  - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
67
82
  - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
68
83
  - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
84
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
69
85
 
70
86
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -18,14 +18,14 @@ Rules for **preset authors** (`packages/ai-rules/presets/**`). Not always-on in
18
18
  | Layer | Where | What to put |
19
19
  |-------|-------|-------------|
20
20
  | **Core** | `presets/_shared/core/**` | Stack-agnostic prose + checklists; no frontmatter; no paths `app/**`, `Features/**`, Playwright, xcodebuild |
21
- | **Stack** | `presets/{cursor\|claude}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
22
- | **Platform** | Cursor `.mdc` / Claude `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
21
+ | **Stack** | `presets/{cursor\|claude\|mavis\|opencode}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
22
+ | **Platform** | Cursor `.mdc` / Claude `.md` / Mavis `.md` / OpenCode `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:` vs OpenCode `mode`/`permission`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
23
23
 
24
24
  ## Where to put a new rule
25
25
 
26
26
  1. Shared principles for all stacks → **core** + adapters with `<!-- shared-core: … -->`.
27
27
  2. Only one of the installable stacks (`next` / `nuxt` / `svelte` / `ios-swift` / `android-kotlin` / `go` / `java` / `mcp-ts` / `php-hexagonal` / `php-laravel`) → **stack-specific** (not in `_shared`).
28
- 3. Only Cursor or only Claude packaging → platform artifact / frontmatter; do not duplicate semantics.
28
+ 3. Only Cursor, Claude, Mavis, or OpenCode packaging → platform artifact / frontmatter; do not duplicate semantics.
29
29
 
30
30
  ## SoT
31
31
 
@@ -96,4 +96,4 @@ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`,
96
96
 
97
97
  ## Chain fork
98
98
 
99
- `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform).
99
+ `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform). Released Mavis/OpenCode stacks must also differ from the Cursor and Claude twins of the same stack.
@@ -19,17 +19,18 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
19
19
  - [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
20
20
  - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, nuxt, svelte, ios-swift, android-kotlin, go, java, mcp-ts, php-hexagonal, and php-laravel — see `preset-twin-sync`)
21
21
  - [ ] **Mavis derive:** mapped `cursor/<stack>/` change → `mavis/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`; see `preset-twin-sync` § Mavis derivation)
22
+ - [ ] **OpenCode derive:** mapped `cursor/<stack>/` change → `opencode/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`; see `preset-twin-sync` § OpenCode derivation)
22
23
  - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
23
24
  - [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
24
25
  - [ ] **Local overlay coverage:** every installable stack ships `ai-local-overlay.mdc` (Cursor) and `ai-local-overlay.md` (Claude) with `MANDATORY` + acknowledgement format + `docs/LOCAL-OVERLAY.md` pointer; Claude twin listed in `claude/<stack>/rules/README.md` mapping table. Run `packages/ai-rules/scripts/check-local-overlay.sh`.
25
26
  - [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
26
27
  - [ ] **Hook-only lifecycle:** `status.json` / `metrics.json` writes happen only inside `hooks/`; agents read but never rewrite lifecycle fields. Run `packages/ai-rules/scripts/check-hook-only-lifecycle.sh`.
27
- - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` across the 10 stacks × 2 platforms (20 hooks) holds. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
28
+ - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` holds pairwise among the 10 stacks × Cursor/Claude platforms, and each released Mavis/OpenCode stack hook must also differ from the Cursor and Claude twins of the same stack. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
28
29
  - [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
29
30
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
30
31
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
31
32
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
32
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (or document intentional skip) when maintaining this monorepo
33
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
33
34
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
34
35
 
35
36
  ## Pointers
@@ -39,6 +40,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
39
40
  - Budget: `preset-token-budget`
40
41
  - Leakage: `preset-no-cross-stack-leakage`
41
42
  - Validation: stack `agents/build-verifier.md` → preset-structure section
42
- - Dogfood script: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`
43
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
43
44
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
44
45
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -19,6 +19,8 @@ Invariants for rule loading in an **installed** preset (consumer app).
19
19
  |----------|-----------|-----|
20
20
  | Cursor | `alwaysApply: true` | **≤ 4** |
21
21
  | Claude | rules **without** `paths:` | **exactly 3** |
22
+ | Mavis | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
23
+ | OpenCode | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
22
24
 
23
25
  **Cursor 4th slot is reserved for `ai-local-overlay`** (consumer-owned `.ai.local/` rules). If you do not need local overlay, demote that rule to `globs: ["**/.ai.local/**"]` and revert to ≤3.
24
26
 
@@ -27,6 +29,7 @@ Invariants for rule loading in an **installed** preset (consumer app).
27
29
  Session-start body budget:
28
30
  - Claude trio: ≤140 lines total (stretch ≤120).
29
31
  - Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
32
+ - Mavis / OpenCode: ≤4 root-entry rule files; combined root `AGENTS.md` + platform entry ≤170 nonempty lines. Do not dump the full rule catalog into `AGENTS.md`.
30
33
 
31
34
  ## Meta / author rules
32
35
 
@@ -42,6 +42,20 @@ _shared/core → cursor/<stack> → mavis/<stack>
42
42
 
43
43
  Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
44
44
 
45
+ ## OpenCode derivation (not a Claude twin)
46
+
47
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
48
+ |-------|------------|-----------------|----------|
49
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
50
+
51
+ OpenCode is a **fourth platform adapter** with a **native** install root (`.opencode/`), not a Claude-style topic twin and not an owned overlay like `.mavis/`:
52
+
53
+ ```text
54
+ _shared/core → cursor/<stack> → opencode/<stack>
55
+ ```
56
+
57
+ Regenerate with `node packages/ai-rules/scripts/generate-opencode-next.mjs`; validate with `node packages/ai-rules/scripts/check-opencode-adapter-map.mjs`. Do not derive OpenCode sources from Claude.
58
+
45
59
  ## Same-PR checklist
46
60
 
47
61
  1. Edit Cursor rule first (body + frontmatter).
@@ -49,6 +63,7 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
49
63
  3. Update mapping table row if stem/path changed.
50
64
  4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
51
65
  5. When mapped `cursor/<stack>/` sources change, regenerate `mavis/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`).
66
+ 6. When mapped `cursor/<stack>/` sources change, regenerate `opencode/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`).
52
67
 
53
68
  ## Twin depth
54
69
 
@@ -70,5 +85,6 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
70
85
  - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
71
86
  - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
72
87
  - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
88
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
73
89
 
74
90
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -16,14 +16,14 @@ Rules for **preset authors** (`packages/ai-rules/presets/**`). Not always-on in
16
16
  | Layer | Where | What to put |
17
17
  |-------|-------|-------------|
18
18
  | **Core** | `presets/_shared/core/**` | Stack-agnostic prose + checklists; no frontmatter; no paths `app/**`, `Features/**`, Playwright, xcodebuild |
19
- | **Stack** | `presets/{cursor\|claude}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
20
- | **Platform** | Cursor `.mdc` / Claude `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
19
+ | **Stack** | `presets/{cursor\|claude\|mavis\|opencode}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
20
+ | **Platform** | Cursor `.mdc` / Claude `.md` / Mavis `.md` / OpenCode `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:` vs OpenCode `mode`/`permission`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
21
21
 
22
22
  ## Where to put a new rule
23
23
 
24
24
  1. Shared principles for all stacks → **core** + adapters with `<!-- shared-core: … -->`.
25
25
  2. Only one of the installable stacks (`next` / `nuxt` / `svelte` / `ios-swift` / `android-kotlin` / `go` / `java` / `mcp-ts` / `php-hexagonal` / `php-laravel`) → **stack-specific** (not in `_shared`).
26
- 3. Only Cursor or only Claude packaging → platform artifact / frontmatter; do not duplicate semantics.
26
+ 3. Only Cursor, Claude, Mavis, or OpenCode packaging → platform artifact / frontmatter; do not duplicate semantics.
27
27
 
28
28
  ## SoT
29
29
 
@@ -94,4 +94,4 @@ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`,
94
94
 
95
95
  ## Chain fork
96
96
 
97
- `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform).
97
+ `hooks/chain-team-phases.sh` must differ **byte-wise** pairwise among `next`, `nuxt`, `svelte`, `ios-swift`, `android-kotlin`, `go`, `java`, `mcp-ts`, `php-hexagonal`, and `php-laravel` (per platform). Released Mavis/OpenCode stacks must also differ from the Cursor and Claude twins of the same stack.
@@ -17,17 +17,18 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
17
17
  - [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
18
18
  - [ ] **Twin:** Cursor change → Claude twin **same PR** (**FAIL** if missing on next, nuxt, svelte, ios-swift, android-kotlin, go, java, mcp-ts, php-hexagonal, and php-laravel — see `preset-twin-sync`)
19
19
  - [ ] **Mavis derive:** mapped `cursor/<stack>/` change → `mavis/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`; see `preset-twin-sync` § Mavis derivation)
20
+ - [ ] **OpenCode derive:** mapped `cursor/<stack>/` change → `opencode/<stack>/` + `adapter-map.json` **same PR** when the stack is in `releasedStacks` (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`; see `preset-twin-sync` § OpenCode derivation)
20
21
  - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
21
22
  - [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
22
23
  - [ ] **Local overlay coverage:** every installable stack ships `ai-local-overlay.mdc` (Cursor) and `ai-local-overlay.md` (Claude) with `MANDATORY` + acknowledgement format + `docs/LOCAL-OVERLAY.md` pointer; Claude twin listed in `claude/<stack>/rules/README.md` mapping table. Run `packages/ai-rules/scripts/check-local-overlay.sh`.
23
24
  - [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
24
25
  - [ ] **Hook-only lifecycle:** `status.json` / `metrics.json` writes happen only inside `hooks/`; agents read but never rewrite lifecycle fields. Run `packages/ai-rules/scripts/check-hook-only-lifecycle.sh`.
25
- - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` across the 10 stacks × 2 platforms (20 hooks) holds. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
26
+ - [ ] **Chain fork:** the byte-wise MD5 uniqueness of `chain-team-phases.sh` holds pairwise among the 10 stacks × Cursor/Claude platforms, and each released Mavis/OpenCode stack hook must also differ from the Cursor and Claude twins of the same stack. Run `packages/ai-rules/scripts/check-chain-hook-coverage.sh` and `packages/ai-rules/scripts/test-chain-team-phases-coverage.mjs`.
26
27
  - [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
27
28
  - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
28
29
  - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
29
30
  - [ ] **i18n anchors:** kept-marked Cyrillic fragments in `tests-unit.md(c)` stay consistent with their English counterparts. Run `packages/ai-rules/scripts/check-preset-i18n.sh`.
30
- - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (or document intentional skip) when maintaining this monorepo
31
+ - [ ] **Dogfood:** run `packages/ai-rules/scripts/sync-dogfood-cursor.sh` (and `sync-dogfood-mavis.sh` / `sync-dogfood-opencode.sh` when those platforms changed), or document an intentional skip, when maintaining this monorepo
31
32
  - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
32
33
 
33
34
  ## Pointers
@@ -37,6 +38,6 @@ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.curso
37
38
  - Budget: `preset-token-budget`
38
39
  - Leakage: `preset-no-cross-stack-leakage`
39
40
  - Validation: stack `agents/build-verifier.md` → preset-structure section
40
- - Dogfood script: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`
41
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
41
42
  - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
42
43
  - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -17,6 +17,8 @@ Invariants for rule loading in an **installed** preset (consumer app).
17
17
  |----------|-----------|-----|
18
18
  | Cursor | `alwaysApply: true` | **≤ 4** |
19
19
  | Claude | rules **without** `paths:` | **exactly 3** |
20
+ | Mavis | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
21
+ | OpenCode | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
20
22
 
21
23
  **Cursor 4th slot is reserved for `ai-local-overlay`** (consumer-owned `.ai.local/` rules). If you do not need local overlay, demote that rule to `globs: ["**/.ai.local/**"]` and revert to ≤3.
22
24
 
@@ -25,6 +27,7 @@ Invariants for rule loading in an **installed** preset (consumer app).
25
27
  Session-start body budget:
26
28
  - Claude trio: ≤140 lines total (stretch ≤120).
27
29
  - Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
30
+ - Mavis / OpenCode: ≤4 root-entry rule files; combined root `AGENTS.md` + platform entry ≤170 nonempty lines. Do not dump the full rule catalog into `AGENTS.md`.
28
31
 
29
32
  ## Meta / author rules
30
33
 
@@ -40,6 +40,20 @@ _shared/core → cursor/<stack> → mavis/<stack>
40
40
 
41
41
  Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
42
42
 
43
+ ## OpenCode derivation (not a Claude twin)
44
+
45
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
46
+ |-------|------------|-----------------|----------|
47
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
48
+
49
+ OpenCode is a **fourth platform adapter** with a **native** install root (`.opencode/`), not a Claude-style topic twin and not an owned overlay like `.mavis/`:
50
+
51
+ ```text
52
+ _shared/core → cursor/<stack> → opencode/<stack>
53
+ ```
54
+
55
+ Regenerate with `node packages/ai-rules/scripts/generate-opencode-next.mjs`; validate with `node packages/ai-rules/scripts/check-opencode-adapter-map.mjs`. Do not derive OpenCode sources from Claude.
56
+
43
57
  ## Same-PR checklist
44
58
 
45
59
  1. Edit Cursor rule first (body + frontmatter).
@@ -47,6 +61,7 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
47
61
  3. Update mapping table row if stem/path changed.
48
62
  4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
49
63
  5. When mapped `cursor/<stack>/` sources change, regenerate `mavis/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-mavis-next.mjs` + `check-mavis-adapter-map.mjs` for `next`).
64
+ 6. When mapped `cursor/<stack>/` sources change, regenerate `opencode/<stack>/` and refresh `adapter-map.json` `sourceRevision` in the **same PR** (run `generate-opencode-next.mjs` + `check-opencode-adapter-map.mjs` for `next`).
50
65
 
51
66
  ## Twin depth
52
67
 
@@ -68,5 +83,6 @@ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; valida
68
83
  - **php-laravel:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-hexagonal; mapping table required).
69
84
  - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
70
85
  - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
86
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
71
87
 
72
88
  Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.