@bonesofspring/ai-rules 0.2.23 → 0.2.24

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 (285) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +5 -1
  3. package/bin/cli.js +32 -9
  4. package/bin/opencode-install.js +531 -0
  5. package/package.json +10 -3
  6. package/presets/_shared/core/agent-team/agent-team-orchestrator.md +2 -2
  7. package/presets/_shared/core/meta/preset-layering.md +3 -3
  8. package/presets/_shared/core/meta/preset-no-cross-stack-leakage.md +1 -1
  9. package/presets/_shared/core/meta/preset-pr-checklist.md +4 -3
  10. package/presets/_shared/core/meta/preset-token-budget.md +3 -0
  11. package/presets/_shared/core/meta/preset-twin-sync.md +16 -0
  12. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-layering.md +3 -3
  13. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  14. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  15. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-token-budget.md +3 -0
  16. package/presets/claude/android-kotlin/rules/tooling-and-review/preset-twin-sync.md +16 -0
  17. package/presets/claude/go/rules/tooling-and-review/preset-layering.md +3 -3
  18. package/presets/claude/go/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  19. package/presets/claude/go/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  20. package/presets/claude/go/rules/tooling-and-review/preset-token-budget.md +3 -0
  21. package/presets/claude/go/rules/tooling-and-review/preset-twin-sync.md +16 -0
  22. package/presets/claude/ios-swift/rules/tooling-and-review/preset-layering.md +3 -3
  23. package/presets/claude/ios-swift/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  24. package/presets/claude/ios-swift/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  25. package/presets/claude/ios-swift/rules/tooling-and-review/preset-token-budget.md +3 -0
  26. package/presets/claude/ios-swift/rules/tooling-and-review/preset-twin-sync.md +16 -0
  27. package/presets/claude/java/rules/tooling-and-review/preset-layering.md +3 -3
  28. package/presets/claude/java/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  29. package/presets/claude/java/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  30. package/presets/claude/java/rules/tooling-and-review/preset-token-budget.md +3 -0
  31. package/presets/claude/java/rules/tooling-and-review/preset-twin-sync.md +16 -0
  32. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-layering.md +3 -3
  33. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  34. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  35. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-token-budget.md +3 -0
  36. package/presets/claude/mcp-ts/rules/tooling-and-review/preset-twin-sync.md +16 -0
  37. package/presets/claude/next/REPO_AGENTS.md +10 -5
  38. package/presets/claude/next/agents/build-verifier.md +3 -1
  39. package/presets/claude/next/rules/tooling-and-review/ai-local-overlay.md +1 -1
  40. package/presets/claude/next/rules/tooling-and-review/preset-layering.md +3 -3
  41. package/presets/claude/next/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  42. package/presets/claude/next/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  43. package/presets/claude/next/rules/tooling-and-review/preset-token-budget.md +3 -0
  44. package/presets/claude/next/rules/tooling-and-review/preset-twin-sync.md +16 -0
  45. package/presets/claude/nuxt/rules/tooling-and-review/preset-layering.md +3 -3
  46. package/presets/claude/nuxt/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  47. package/presets/claude/nuxt/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  48. package/presets/claude/nuxt/rules/tooling-and-review/preset-token-budget.md +3 -0
  49. package/presets/claude/nuxt/rules/tooling-and-review/preset-twin-sync.md +16 -0
  50. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-layering.md +3 -3
  51. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  52. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  53. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-token-budget.md +3 -0
  54. package/presets/claude/php-hexagonal/rules/tooling-and-review/preset-twin-sync.md +16 -0
  55. package/presets/claude/php-laravel/rules/tooling-and-review/preset-layering.md +3 -3
  56. package/presets/claude/php-laravel/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  57. package/presets/claude/php-laravel/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  58. package/presets/claude/php-laravel/rules/tooling-and-review/preset-token-budget.md +3 -0
  59. package/presets/claude/php-laravel/rules/tooling-and-review/preset-twin-sync.md +16 -0
  60. package/presets/claude/svelte/rules/tooling-and-review/preset-layering.md +3 -3
  61. package/presets/claude/svelte/rules/tooling-and-review/preset-no-cross-stack-leakage.md +1 -1
  62. package/presets/claude/svelte/rules/tooling-and-review/preset-pr-checklist.md +4 -3
  63. package/presets/claude/svelte/rules/tooling-and-review/preset-token-budget.md +3 -0
  64. package/presets/claude/svelte/rules/tooling-and-review/preset-twin-sync.md +16 -0
  65. package/presets/cursor/android-kotlin/rules/preset-layering.mdc +3 -3
  66. package/presets/cursor/android-kotlin/rules/preset-no-cross-stack-leakage.mdc +1 -1
  67. package/presets/cursor/android-kotlin/rules/preset-pr-checklist.mdc +4 -3
  68. package/presets/cursor/android-kotlin/rules/preset-token-budget.mdc +3 -0
  69. package/presets/cursor/android-kotlin/rules/preset-twin-sync.mdc +16 -0
  70. package/presets/cursor/go/rules/preset-layering.mdc +3 -3
  71. package/presets/cursor/go/rules/preset-no-cross-stack-leakage.mdc +1 -1
  72. package/presets/cursor/go/rules/preset-pr-checklist.mdc +4 -3
  73. package/presets/cursor/go/rules/preset-token-budget.mdc +3 -0
  74. package/presets/cursor/go/rules/preset-twin-sync.mdc +16 -0
  75. package/presets/cursor/ios-swift/rules/preset-layering.mdc +3 -3
  76. package/presets/cursor/ios-swift/rules/preset-no-cross-stack-leakage.mdc +1 -1
  77. package/presets/cursor/ios-swift/rules/preset-pr-checklist.mdc +4 -3
  78. package/presets/cursor/ios-swift/rules/preset-token-budget.mdc +3 -0
  79. package/presets/cursor/ios-swift/rules/preset-twin-sync.mdc +16 -0
  80. package/presets/cursor/java/rules/preset-layering.mdc +3 -3
  81. package/presets/cursor/java/rules/preset-no-cross-stack-leakage.mdc +1 -1
  82. package/presets/cursor/java/rules/preset-pr-checklist.mdc +4 -3
  83. package/presets/cursor/java/rules/preset-token-budget.mdc +3 -0
  84. package/presets/cursor/java/rules/preset-twin-sync.mdc +16 -0
  85. package/presets/cursor/mcp-ts/rules/preset-layering.mdc +3 -3
  86. package/presets/cursor/mcp-ts/rules/preset-no-cross-stack-leakage.mdc +1 -1
  87. package/presets/cursor/mcp-ts/rules/preset-pr-checklist.mdc +4 -3
  88. package/presets/cursor/mcp-ts/rules/preset-token-budget.mdc +3 -0
  89. package/presets/cursor/mcp-ts/rules/preset-twin-sync.mdc +16 -0
  90. package/presets/cursor/next/REPO_AGENTS.md +10 -5
  91. package/presets/cursor/next/agents/build-verifier.md +3 -1
  92. package/presets/cursor/next/rules/ai-local-overlay.mdc +1 -1
  93. package/presets/cursor/next/rules/preset-layering.mdc +3 -3
  94. package/presets/cursor/next/rules/preset-no-cross-stack-leakage.mdc +1 -1
  95. package/presets/cursor/next/rules/preset-pr-checklist.mdc +4 -3
  96. package/presets/cursor/next/rules/preset-token-budget.mdc +3 -0
  97. package/presets/cursor/next/rules/preset-twin-sync.mdc +16 -0
  98. package/presets/cursor/nuxt/rules/preset-layering.mdc +3 -3
  99. package/presets/cursor/nuxt/rules/preset-no-cross-stack-leakage.mdc +1 -1
  100. package/presets/cursor/nuxt/rules/preset-pr-checklist.mdc +4 -3
  101. package/presets/cursor/nuxt/rules/preset-token-budget.mdc +3 -0
  102. package/presets/cursor/nuxt/rules/preset-twin-sync.mdc +16 -0
  103. package/presets/cursor/php-hexagonal/rules/preset-layering.mdc +3 -3
  104. package/presets/cursor/php-hexagonal/rules/preset-no-cross-stack-leakage.mdc +1 -1
  105. package/presets/cursor/php-hexagonal/rules/preset-pr-checklist.mdc +4 -3
  106. package/presets/cursor/php-hexagonal/rules/preset-token-budget.mdc +3 -0
  107. package/presets/cursor/php-hexagonal/rules/preset-twin-sync.mdc +16 -0
  108. package/presets/cursor/php-laravel/rules/preset-layering.mdc +3 -3
  109. package/presets/cursor/php-laravel/rules/preset-no-cross-stack-leakage.mdc +1 -1
  110. package/presets/cursor/php-laravel/rules/preset-pr-checklist.mdc +4 -3
  111. package/presets/cursor/php-laravel/rules/preset-token-budget.mdc +3 -0
  112. package/presets/cursor/php-laravel/rules/preset-twin-sync.mdc +16 -0
  113. package/presets/cursor/svelte/rules/preset-layering.mdc +3 -3
  114. package/presets/cursor/svelte/rules/preset-no-cross-stack-leakage.mdc +1 -1
  115. package/presets/cursor/svelte/rules/preset-pr-checklist.mdc +4 -3
  116. package/presets/cursor/svelte/rules/preset-token-budget.mdc +3 -0
  117. package/presets/cursor/svelte/rules/preset-twin-sync.mdc +16 -0
  118. package/presets/mavis/next/REPO_AGENTS.md +9 -7
  119. package/presets/mavis/next/adapter-map.json +1 -1
  120. package/presets/mavis/next/agents/build-verifier.md +3 -1
  121. package/presets/mavis/next/rules/agent-team-orchestrator.md +2 -2
  122. package/presets/mavis/next/rules/ai-local-overlay.md +1 -1
  123. package/presets/mavis/next/rules/preset-layering.md +3 -3
  124. package/presets/mavis/next/rules/preset-no-cross-stack-leakage.md +1 -1
  125. package/presets/mavis/next/rules/preset-pr-checklist.md +4 -3
  126. package/presets/mavis/next/rules/preset-token-budget.md +3 -0
  127. package/presets/mavis/next/rules/preset-twin-sync.md +16 -0
  128. package/presets/opencode/README.md +61 -0
  129. package/presets/opencode/next/MCP.md +36 -0
  130. package/presets/opencode/next/OPENCODE.md +65 -0
  131. package/presets/opencode/next/README.md +16 -0
  132. package/presets/opencode/next/REPO_AGENTS.md +97 -0
  133. package/presets/opencode/next/adapter-map.json +959 -0
  134. package/presets/opencode/next/agents/README.md +201 -0
  135. package/presets/opencode/next/agents/accessibility-reviewer.md +73 -0
  136. package/presets/opencode/next/agents/api-contract-reviewer.md +69 -0
  137. package/presets/opencode/next/agents/build-verifier.md +124 -0
  138. package/presets/opencode/next/agents/ci-investigator.md +71 -0
  139. package/presets/opencode/next/agents/code-reviewer.md +73 -0
  140. package/presets/opencode/next/agents/codebase-analyzer.md +33 -0
  141. package/presets/opencode/next/agents/debugger.md +88 -0
  142. package/presets/opencode/next/agents/feature-developer.md +109 -0
  143. package/presets/opencode/next/agents/migration-specialist.md +79 -0
  144. package/presets/opencode/next/agents/mockup-reviewer.md +65 -0
  145. package/presets/opencode/next/agents/openspec-author.md +169 -0
  146. package/presets/opencode/next/agents/performance-auditor.md +80 -0
  147. package/presets/opencode/next/agents/playwright-test-generator.md +36 -0
  148. package/presets/opencode/next/agents/playwright-test-healer.md +36 -0
  149. package/presets/opencode/next/agents/playwright-test-planner.md +33 -0
  150. package/presets/opencode/next/agents/qa-tester.md +60 -0
  151. package/presets/opencode/next/agents/security-reviewer.md +66 -0
  152. package/presets/opencode/next/agents/solution-architect.md +80 -0
  153. package/presets/opencode/next/agents/task-analyst.md +178 -0
  154. package/presets/opencode/next/agents/task-router.md +190 -0
  155. package/presets/opencode/next/agents/tech-writer.md +69 -0
  156. package/presets/opencode/next/agents/unit-test-generator.md +39 -0
  157. package/presets/opencode/next/agents/unit-test-healer.md +40 -0
  158. package/presets/opencode/next/agents/unit-test-planner.md +66 -0
  159. package/presets/opencode/next/commands/README.md +49 -0
  160. package/presets/opencode/next/commands/spec-start.md +32 -0
  161. package/presets/opencode/next/commands/task-continue.md +58 -0
  162. package/presets/opencode/next/commands/task.md +58 -0
  163. package/presets/opencode/next/commands/technical-retro.md +88 -0
  164. package/presets/opencode/next/hooks/README.md +22 -0
  165. package/presets/opencode/next/hooks/chain-team-phases.sh +845 -0
  166. package/presets/opencode/next/opencode.json +33 -0
  167. package/presets/opencode/next/rules/README.md +20 -0
  168. package/presets/opencode/next/rules/agent-team-intake.md +11 -0
  169. package/presets/opencode/next/rules/agent-team-orchestrator.md +214 -0
  170. package/presets/opencode/next/rules/ai-local-overlay.md +37 -0
  171. package/presets/opencode/next/rules/anti-sycophancy-discipline.md +23 -0
  172. package/presets/opencode/next/rules/api-services.md +72 -0
  173. package/presets/opencode/next/rules/architecture-boundaries-ui.md +9 -0
  174. package/presets/opencode/next/rules/architecture-boundaries.md +86 -0
  175. package/presets/opencode/next/rules/arrow-functions.md +25 -0
  176. package/presets/opencode/next/rules/code-quality-and-refactoring.md +40 -0
  177. package/presets/opencode/next/rules/code-review-mr.md +40 -0
  178. package/presets/opencode/next/rules/css-property-order-stylelint.md +5 -0
  179. package/presets/opencode/next/rules/design-guidance.md +99 -0
  180. package/presets/opencode/next/rules/feature-delivery-workflow.md +49 -0
  181. package/presets/opencode/next/rules/http-client.md +55 -0
  182. package/presets/opencode/next/rules/layer-barrel-exports.md +68 -0
  183. package/presets/opencode/next/rules/mcp-usage.md +86 -0
  184. package/presets/opencode/next/rules/mockup-review.md +107 -0
  185. package/presets/opencode/next/rules/navigation-router-stack.md +56 -0
  186. package/presets/opencode/next/rules/navigation-router-ui.md +10 -0
  187. package/presets/opencode/next/rules/next-app-core.md +29 -0
  188. package/presets/opencode/next/rules/next-app-router.md +44 -0
  189. package/presets/opencode/next/rules/no-props-spread.md +56 -0
  190. package/presets/opencode/next/rules/no-type-assertion-as-import-export.md +51 -0
  191. package/presets/opencode/next/rules/package-manager.md +11 -0
  192. package/presets/opencode/next/rules/playwright-agents.md +67 -0
  193. package/presets/opencode/next/rules/post-change-lint.md +35 -0
  194. package/presets/opencode/next/rules/preset-layering.md +27 -0
  195. package/presets/opencode/next/rules/preset-no-cross-stack-leakage.md +90 -0
  196. package/presets/opencode/next/rules/preset-pr-checklist.md +36 -0
  197. package/presets/opencode/next/rules/preset-token-budget.md +39 -0
  198. package/presets/opencode/next/rules/preset-twin-sync.md +81 -0
  199. package/presets/opencode/next/rules/product-specs-authoring.md +112 -0
  200. package/presets/opencode/next/rules/product-specs.md +56 -0
  201. package/presets/opencode/next/rules/public-imports.md +50 -0
  202. package/presets/opencode/next/rules/react-a11y-coding.md +31 -0
  203. package/presets/opencode/next/rules/react-next-anti-hallucination.md +60 -0
  204. package/presets/opencode/next/rules/react-ui.md +105 -0
  205. package/presets/opencode/next/rules/reference-features.md +45 -0
  206. package/presets/opencode/next/rules/security-next.md +45 -0
  207. package/presets/opencode/next/rules/store-rtk.md +78 -0
  208. package/presets/opencode/next/rules/technical-retro.md +11 -0
  209. package/presets/opencode/next/rules/tests-e2e-structure.md +72 -0
  210. package/presets/opencode/next/rules/tests-unit.md +72 -0
  211. package/presets/opencode/next/rules/types-jsdoc.md +43 -0
  212. package/presets/opencode/next/rules/ux-design.md +99 -0
  213. package/presets/opencode/next/skills/README.md +21 -0
  214. package/presets/opencode/next/skills/ci-investigation/SKILL.md +44 -0
  215. package/presets/opencode/next/skills/code-review/SKILL.md +44 -0
  216. package/presets/opencode/next/skills/debug-investigation/SKILL.md +59 -0
  217. package/presets/opencode/next/skills/feature-delivery/SKILL.md +39 -0
  218. package/presets/opencode/next/skills/mockup-review/SKILL.md +29 -0
  219. package/presets/opencode/next/skills/playwright-e2e/SKILL.md +33 -0
  220. package/presets/opencode/next/skills/react-performance/SKILL.md +44 -0
  221. package/presets/opencode/next/skills/spec-authoring/SKILL.md +26 -0
  222. package/presets/opencode/next/skills/spec-discovery/SKILL.md +58 -0
  223. package/presets/opencode/next/skills/technical-retro/SKILL.md +54 -0
  224. package/presets/opencode/next/skills/unit-testing/SKILL.md +34 -0
  225. package/presets/opencode/next/skills/ux-design/SKILL.md +36 -0
  226. package/presets/opencode/next/skills/write-adr/SKILL.md +41 -0
  227. package/presets/opencode/next/team/README.md +148 -0
  228. package/presets/opencode/next/team/conventions.md +21 -0
  229. package/presets/opencode/next/team/fixtures/artifact-manifest.example.json +79 -0
  230. package/presets/opencode/next/team/fixtures/bugfix-standard.json +25 -0
  231. package/presets/opencode/next/team/fixtures/feature-full.json +29 -0
  232. package/presets/opencode/next/team/fixtures/feature-light.json +27 -0
  233. package/presets/opencode/next/team/fixtures/feature-with-figma-url.json +17 -0
  234. package/presets/opencode/next/team/fixtures/feature-with-ux-no-figma.json +17 -0
  235. package/presets/opencode/next/team/fixtures/memlog.example.md +9 -0
  236. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/human-gate/metrics.json +69 -0
  237. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/missing-ledger/status.json +5 -0
  238. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/parallel-receipts/metrics.json +79 -0
  239. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/serial-retry/metrics.json +124 -0
  240. package/presets/opencode/next/team/fixtures/metrics-scenarios/tasks/validation-failed/metrics.json +124 -0
  241. package/presets/opencode/next/team/fixtures/metrics.example.json +54 -0
  242. package/presets/opencode/next/team/fixtures/mockup-review-fail-embedded-status.json +8 -0
  243. package/presets/opencode/next/team/fixtures/mockup-review-standalone.json +14 -0
  244. package/presets/opencode/next/team/fixtures/ux-design-standalone.json +15 -0
  245. package/presets/opencode/next/team/tasks/.gitkeep +0 -0
  246. package/presets/opencode/platform-contract.json +131 -0
  247. package/scripts/capture-cli-golden.mjs +5 -1
  248. package/scripts/check-chain-hook-coverage.sh +1 -0
  249. package/scripts/check-opencode-adapter-map.mjs +294 -0
  250. package/scripts/check-opencode-local-overlay.mjs +56 -0
  251. package/scripts/check-opencode-platform-contract.mjs +388 -0
  252. package/scripts/check-opencode-token-budget.mjs +48 -0
  253. package/scripts/check-preset-leakage.sh +30 -1
  254. package/scripts/check-preset-structure.sh +45 -0
  255. package/scripts/check-task-router-intents.sh +4 -4
  256. package/scripts/fixtures/cli-golden/claude/next.json +8 -8
  257. package/scripts/fixtures/cli-golden/cursor/next.json +8 -8
  258. package/scripts/fixtures/cli-golden/mavis/next.json +9 -9
  259. package/scripts/fixtures/cli-golden/opencode/next.json +125 -0
  260. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/AGENTS.md +1 -0
  261. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/rules/extra.mdc +1 -0
  262. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/cursor/rules/sample.mdc +2 -0
  263. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/OPENCODE.md +1 -0
  264. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/adapter-map.json +26 -0
  265. package/scripts/fixtures/opencode-adapter-map/invalid-unmapped/opencode/rules/sample.md +2 -0
  266. package/scripts/fixtures/opencode-adapter-map/valid/cursor/AGENTS.md +1 -0
  267. package/scripts/fixtures/opencode-adapter-map/valid/cursor/rules/sample.mdc +2 -0
  268. package/scripts/fixtures/opencode-adapter-map/valid/opencode/OPENCODE.md +1 -0
  269. package/scripts/fixtures/opencode-adapter-map/valid/opencode/adapter-map.json +26 -0
  270. package/scripts/fixtures/opencode-adapter-map/valid/opencode/rules/sample.md +2 -0
  271. package/scripts/fixtures/opencode-platform-contract/invalid-home-destination.json +131 -0
  272. package/scripts/fixtures/opencode-platform-contract/invalid-missing-capability.json +126 -0
  273. package/scripts/fixtures/opencode-platform-contract/invalid-released-unknown-stack.json +133 -0
  274. package/scripts/fixtures/opencode-platform-contract/invalid-unknown-native-path.json +131 -0
  275. package/scripts/fixtures/opencode-platform-contract/invalid-version-pin.json +132 -0
  276. package/scripts/fixtures/opencode-platform-contract/valid.json +131 -0
  277. package/scripts/generate-mavis-next.mjs +9 -7
  278. package/scripts/generate-opencode-next.mjs +831 -0
  279. package/scripts/lib/discover-hooks.mjs +23 -1
  280. package/scripts/sync-dogfood-mavis.sh +90 -0
  281. package/scripts/sync-dogfood-opencode.sh +85 -0
  282. package/scripts/test-agent-task-metrics-hooks.mjs +4 -1
  283. package/scripts/test-chain-team-phases-coverage.mjs +6 -1
  284. package/scripts/test-cli-init-clean.mjs +111 -0
  285. package/scripts/test-opencode-context-budget.mjs +53 -0
@@ -0,0 +1,56 @@
1
+ # Do not use prop spread when passing props to components
2
+
3
+ When calling **custom** React components (PascalCase names: `IconBox`, `TextField`, your `FooBar`), **pass props explicitly**, not via spread (`{...props}`, `{...obj}`).
4
+
5
+ **For agents and review:** do not “simplify” JSX by building an object and spreading it — that violates this rule. If prop branching is long, use two explicit JSX blocks (`condition ? <A … /> : <B … />`) or separate small components, not `{...mergedProps}`.
6
+
7
+ ## Why
8
+
9
+ - Explicit props make component dependencies obvious when reading code.
10
+ - Easier refactoring and usage search.
11
+ - Reduces the risk of accidentally passing extra or stale props.
12
+
13
+ ## Repo enforcement
14
+
15
+ - For `app/src/ui/**/*.tsx`, ESLint rule `react/jsx-props-no-spreading` is enabled (`app/eslint.config.mjs`): linter and CI will catch violations.
16
+ - A legitimate local exception — a **single-line** `eslint-disable-next-line react/jsx-props-no-spreading` with a brief “why” comment; for rare wrappers, a file-level disable is acceptable (as in `PromocodeInput`).
17
+
18
+ ## Examples
19
+
20
+ ```tsx
21
+ // ❌ Bad
22
+ const commonProps = { a, b, c }
23
+ return <Child {...commonProps} />
24
+
25
+ // ❌ Bad
26
+ return <Child {...props} />
27
+
28
+ // ❌ Bad (spread from a neighboring styles module is not an excuse)
29
+ const iconProps = cond ? { name, size: 'm' } : { name, size: 'm', ...styles.IconBoxAccent }
30
+ return <IconBox {...iconProps} />
31
+
32
+ // ✅ Good
33
+ return (
34
+ <Child
35
+ a={a}
36
+ b={b}
37
+ c={c}
38
+ />
39
+ )
40
+
41
+ // ✅ Good — explicit props per branch
42
+ return cond ? (
43
+ <IconBox name={name} size="m" variant="warning" />
44
+ ) : (
45
+ <IconBox
46
+ customColors={styles.IconBoxAccent.customColors}
47
+ name={name}
48
+ size="m"
49
+ />
50
+ )
51
+ ```
52
+
53
+ ## Exceptions
54
+
55
+ - Passing props to a **native** DOM element (`<div {...rest} />`) is allowed if `rest` contains only valid HTML attributes.
56
+ - Delegating props in a wrapper is allowed if explicitly documented and justified; mark the file or line via ESLint-disable as above when needed.
@@ -0,0 +1,51 @@
1
+ # Do not use `as` for type assertions on export and import (except necessary cases)
2
+
3
+ ## Scope
4
+
5
+ This covers **type assertion** in TypeScript: an expression like `value as Type`.
6
+
7
+ **Out of scope** (module syntax, not assertion):
8
+
9
+ - rename on export: `export { foo as bar }`, `export { default as Baz } from '...'`;
10
+ - rename on import: `import { foo as bar } from '...'`;
11
+ - `import type { Foo as Bar }` — type alias in a type-only import.
12
+
13
+ ## Requirement
14
+
15
+ - On the **public module boundary** (what is **exported** from a file / barrel, and what is immediately **assigned to imported symbols** with forced casting) **do not use** `as Type` to “fit” types when normal typing suffices.
16
+
17
+ ## Prefer instead of `as`
18
+
19
+ - explicit annotation: `const x: T = ...` / `function f(): T`;
20
+ - **generics** on functions and classes;
21
+ - **`satisfies`** (when you need compatibility check without narrowing to `any`);
22
+ - narrowing **`unknown`** after checks (type guards, `zod`, etc.);
23
+ - fixing **source types/DTO/mappers**, not assertion at the output.
24
+
25
+ ## When `as` is allowed
26
+
27
+ - interaction with **untyped** or incorrectly typed external modules where there is no reasonable alternative;
28
+ - narrow spots after **validation** when a type guard is still too noisy (prefer guard/`satisfies`);
29
+ - **`as const`** — when literal types are needed and wide inference breaks the contract (separate mechanism; use as needed, not as a substitute for API typing).
30
+ - **`catch (error)`** block after HTTP via the shared client: prefer narrowing via **`instanceof`** on the **transport error class** from `@/types` (which one — per existing implementation) and work with the narrowed type; bare **`as`** to the same type — only if `instanceof` is unavailable (different throw source) and intentional.
31
+
32
+ ## Examples
33
+
34
+ ```typescript
35
+ // ❌ Bad: assertion on exported API
36
+ export const config = loadRaw() as AppConfig
37
+
38
+ // ✅ Better: annotation + check or mapper
39
+ export const config: AppConfig = mapToAppConfig(loadRaw())
40
+
41
+ // ❌ Bad: immediately after import “breaks” the type
42
+ import { getData } from './api'
43
+ export const data = getData() as MyDto[]
44
+
45
+ // ✅ Better: type getData / wrap in a type-safe function
46
+ ```
47
+
48
+ ## Agent requirement
49
+
50
+ When reviewing and generating code **do not add** new `as Type` on exported entities and on import → export chains without explicit need; fix the type contract at the source when possible.
51
+ - In slices and services when handling API errors, consider **`instanceof`** on the transport error class from `@/types` first, following existing code (`http-client.md`, `store-rtk.md`).
@@ -0,0 +1,11 @@
1
+ # Package manager (terminal)
2
+
3
+ Before **`npm install` / `yarn` / `pnpm` / `bun`** and **`… run …`**, detect the repository package manager and **use only that one**.
4
+
5
+ ## How to detect
6
+
7
+ 1. **`packageManager`** in `package.json` (root or `app/package.json`).
8
+ 2. **Lockfile** nearby: `yarn.lock` → yarn; `pnpm-lock.yaml` → pnpm; `package-lock.json` → npm; `bun.lock(b)` → bun.
9
+ 3. If ambiguous — where `node_modules` lives and which lockfile CI uses.
10
+
11
+ Working directory for scripts — **`app/`**. Examples: `yarn lint`, `pnpm run test`. Do not guess — check the files.
@@ -0,0 +1,67 @@
1
+ # Playwright Agents in this project
2
+
3
+ In this repository, Playwright Agents (planner, generator, healer) **must follow the existing e2e structure**:
4
+
5
+ - **Test directory**: `app/__tests__/e2e`
6
+ - **Test plans (specs)**: `*.cases.md` files under `app/__tests__/e2e/**`
7
+ - **Executable tests**: `*.spec.ts` files under `app/__tests__/e2e/**`
8
+ - **Seed test**: `app/__tests__/e2e/seed.spec.ts`
9
+
10
+ Do **not** introduce separate top-level `specs/` and `tests/` folders for real test coverage. Those may be used only as temporary sandboxes if explicitly requested.
11
+
12
+ ## Planner (test plans)
13
+
14
+ When acting as a **Planner** (or working with the Playwright planner agent):
15
+
16
+ - **Treat `*.cases.md` as the canonical test plan files**, equivalent to Playwright's `specs/*.md`.
17
+ - **Location**:
18
+ - For a feature/domain, use the corresponding `*.cases.md` file under `app/__tests__/e2e`, e.g.:
19
+ - `app/__tests__/e2e/OrderHistory/order-history.cases.md`
20
+ - `app/__tests__/e2e/BillingReport/invoice-list.cases.md`
21
+ - **Content requirements**:
22
+ - Group scenarios by feature and subfeature using headings.
23
+ - For each scenario include:
24
+ - clear title,
25
+ - preconditions,
26
+ - ordered steps,
27
+ - expected results.
28
+ - Write in concise business language, but precise enough for automatic test generation.
29
+ - **Seed**:
30
+ - Assume environment is prepared by `app/__tests__/e2e/seed.spec.ts` (login, baseURL, mocks, etc.).
31
+
32
+ When asked to "generate a test plan" for a feature, **create or update the appropriate `*.cases.md` file in `app/__tests__/e2e/**`**, not in a separate `specs/` folder.
33
+
34
+ ## Generator (tests from plans)
35
+
36
+ When acting as a **Generator** (or working with the Playwright generator agent):
37
+
38
+ - **Source of truth for scenarios**:
39
+ - Use the relevant `*.cases.md` file under `app/__tests__/e2e/**` as the test plan.
40
+ - **Target for tests**:
41
+ - Generate or update `*.spec.ts` files under the same folder, e.g.:
42
+ - plan: `app/__tests__/e2e/OrderHistory/order-history.cases.md`
43
+ - tests: `app/__tests__/e2e/OrderHistory/order-history.spec.ts` (or additional `*.spec.ts` in that folder if needed).
44
+ - **Structure**:
45
+ - Use `test.describe` to group by top-level plan sections (feature / user flow).
46
+ - Use `test(...)` titles that match scenario names from the plan.
47
+ - Prefer Page Object and fluent interfaces that already exist in this project, for example:
48
+ - `app/__tests__/e2e/OrderHistory/OrderHistoryPage.ts`
49
+ - shared helpers under `app/__tests__/e2e/_shared/`.
50
+ - **Seed**:
51
+ - If a seed test is needed, use `app/__tests__/e2e/seed.spec.ts` as the reference for environment setup.
52
+
53
+ Do **not** generate Playwright tests into a separate `tests/` folder by default. Keep all e2e tests under `app/__tests__/e2e/**` to respect project conventions.
54
+
55
+ ## Healer (fixing tests)
56
+
57
+ When acting as a **Healer** (or working with the Playwright healer agent):
58
+
59
+ - Operate only on `*.spec.ts` files under `app/__tests__/e2e/**`.
60
+ - Use `*.cases.md` in the same folder as **documentation of the intended behavior**:
61
+ - Do not weaken or change business assertions in tests in a way that conflicts with the corresponding `*.cases.md`.
62
+ - Prefer updating locators, waits, and flow details to match the UI while keeping the scenario semantics intact.
63
+ - When multiple specs are involved, prioritize:
64
+ - the spec file in the same folder as the failing test,
65
+ - then shared utilities in `app/__tests__/e2e/_shared/`.
66
+
67
+ Healer should keep tests aligned with the existing test plans (`*.cases.md`) and with the page objects and helpers already used in the project.
@@ -0,0 +1,35 @@
1
+ # Linters after code changes
2
+
3
+ **Requestable, but must run on code changes:** the rule is not always-on (saves context); after editing source files the agent **must** follow this checklist.
4
+
5
+ ## When to apply
6
+
7
+ After **any** change to source files in `app/**` (TS/TSX/JS/MJS, CSS, styled/Linaria in `.ts`/`.tsx`).
8
+
9
+ Exceptions: documentation edits outside `app/`, CI configs, `.opencode/rules/**`, if application executable code did not change.
10
+
11
+ **Pipeline exception:** if the task runs through the agent team and the next step is `build-verifier`, the developer may limit lint/type-check to **changed files**; full run is **`build-verifier`’s** responsibility. In single-agent mode (no pipeline) — always a full run.
12
+
13
+ ## Required commands
14
+
15
+ Working directory — **`app/`**. Package manager — **`package-manager.md`**.
16
+
17
+ 1. **`lint:js`** — full ESLint across the project.
18
+ 2. **`lint:css`** — full Stylelint (`**/*.{css,ts}`).
19
+
20
+ Targeted lint on one file **does not replace** a full run before completing the task (except the pipeline exception above).
21
+
22
+ ## Procedure
23
+
24
+ 1. Finish code edits.
25
+ 2. Run **`lint:js`** and **`lint:css`** from `app/`.
26
+ 3. Analyze full output; fix errors/warnings in changed files; for Stylelint — **`lint:css --fix`** if auto-fixable.
27
+ 4. Repeat until exit code 0 or record a blocker in the user response.
28
+ 5. **`type-check`** when TypeScript changed. CI level: **`lint`** (= `lint:js` + `lint:css` + `type-check`).
29
+
30
+ ## What to fix
31
+
32
+ - **Errors** — must fix.
33
+ - **Warnings** — must fix in task files; out of scope — mention if they block a zero exit code.
34
+
35
+ Configs: `app/eslint.config.mjs`, `app/.stylelintrc` (CSS order — `css-property-order-stylelint.md`).
@@ -0,0 +1,27 @@
1
+ <!-- shared-core: meta/preset-layering.md -->
2
+
3
+ # Preset layering
4
+
5
+ Rules for **preset authors** (`packages/ai-rules/presets/**`). Not always-on in consumer apps.
6
+
7
+ ## Layers
8
+
9
+ | Layer | Where | What to put |
10
+ |-------|-------|-------------|
11
+ | **Core** | `presets/_shared/core/**` | Stack-agnostic prose + checklists; no frontmatter; no paths `app/**`, `Features/**`, Playwright, xcodebuild |
12
+ | **Stack** | `presets/{cursor\|claude\|mavis\|opencode}/<stack>/` | Domain/tooling, stack always-on trio, stack examples in **Stack notes** |
13
+ | **Platform** | Cursor `.mdc` / Claude `.md` / Mavis `.md` / OpenCode `.md` | Frontmatter (`alwaysApply`/`globs` vs `paths:` vs OpenCode `mode`/`permission`), platform-only (`BUGBOT.md`, `CLAUDE.md`) |
14
+
15
+ ## Where to put a new rule
16
+
17
+ 1. Shared principles for all stacks → **core** + adapters with `<!-- shared-core: … -->`.
18
+ 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`).
19
+ 3. Only Cursor, Claude, Mavis, or OpenCode packaging → platform artifact / frontmatter; do not duplicate semantics.
20
+
21
+ ## SoT
22
+
23
+ - Packages path — SoT; root `.cursor/` — dogfood sync.
24
+ - Per stack: **Cursor** `presets/cursor/<stack>/` → Claude twin same PR.
25
+ - `_shared` is **not** a `--preset` and is not copied by CLI `init`.
26
+
27
+ See also: `preset-twin-sync`, `preset-token-budget`, `preset-pr-checklist`, `preset-no-cross-stack-leakage`.
@@ -0,0 +1,90 @@
1
+ <!-- shared-core: meta/preset-no-cross-stack-leakage.md -->
2
+
3
+ # Preset no cross-stack leakage
4
+
5
+ Ban leakage of stack-specific names, paths, and handoff stems across presets.
6
+
7
+ ## Principles
8
+
9
+ - `next` must not require iOS-only or Android-only agents/tooling (`xcuitest-*`, `instrumentation-test-*`, `xcodebuild` as required handoff, Keychain-only rules).
10
+ - `nuxt` must not require iOS-only or Android-only agents/tooling (`xcuitest-*`, `instrumentation-test-*`, `xcodebuild` as required handoff, Keychain-only rules).
11
+ - `svelte` must not require iOS-only or Android-only agents/tooling (`xcuitest-*`, `instrumentation-test-*`, `xcodebuild` as required handoff, Keychain-only rules).
12
+ - `ios-swift` must not ship Playwright handoffs, Android `instrumentation-test-*` handoffs, or Next lint recipes as required commands.
13
+ - `android-kotlin` must not ship Playwright, XCUITest, `xcodebuild`, or Next lint recipes as required handoffs.
14
+ - `go` / `java` / `php-hexagonal` / `php-laravel` / `mcp-ts` must not ship Playwright, XCUITest, Android instrumentation agents, Next lint recipes, or `xcodebuild`/`SwiftLint` as required handoffs.
15
+ - `mcp-ts` must not ship Go tool commands (`go test`, `go vet`, `golangci-lint`) or `integration-test-*` agents as required delivery gates.
16
+ - Shared core must not embed stack paths (`app/src/**`, `Features/**`, `playwright`, `xcodebuild`).
17
+ - Storybook / Chrome DevTools MCP must **not** be required handoffs or agent stems (`storybook-reviewer`) on backend or mobile stacks. Frontend overlay mentions in `MCP.md` / `mcp-usage` Stack notes are OK.
18
+
19
+ ## Forbidden in ios-swift hooks/agents (FAIL)
20
+
21
+ In ios-swift `chain-team-phases.sh` / agent handoffs (Cursor + Claude):
22
+
23
+ - `playwright-test-`, `playwright-agents`, `playwright-e2e`, `user-playwright`
24
+ - `instrumentation-test-` as required Android handoffs
25
+ - `app/__tests__/e2e` as a required path
26
+ - Positive yarn recipes `lint:js` / `lint:css` as commands to run (negation prose alone is weak — prefer zero occurrences)
27
+
28
+ Required instead: `xcuitest-test-*` stems; build-verifier mentions `xcodebuild` or `post-change-build` / `xcode-tooling`.
29
+
30
+ ## Forbidden in android-kotlin hooks/agents (FAIL)
31
+
32
+ In android-kotlin `chain-team-phases.sh` / agent handoffs (Cursor + Claude):
33
+
34
+ - `playwright-test-`, `playwright-agents`, `playwright-e2e`, `user-playwright`
35
+ - `app/__tests__/e2e` as a required path
36
+ - `xcuitest-test-`, positive `xcodebuild` / `SwiftLint` as required handoffs
37
+ - Positive yarn recipes `lint:js` / `lint:css` as commands to run
38
+
39
+ Required instead: `instrumentation-test-*` stems; build-verifier mentions `gradle-tooling` and/or `post-change-build` (Gradle wrapper discovery — not `xcodebuild` as the default gate).
40
+
41
+ ## Forbidden in next hooks/agents (FAIL when present as required)
42
+
43
+ - `xcuitest-test-` / `instrumentation-test-` as handoff stems
44
+ - Requiring `xcodebuild` / SwiftLint as the default post-change gate for Next app work
45
+
46
+ ## Forbidden in nuxt hooks/agents (FAIL when present as required)
47
+
48
+ - `xcuitest-test-` / `instrumentation-test-` as handoff stems
49
+ - Requiring `xcodebuild` / SwiftLint as the default post-change gate for Nuxt app work
50
+ - Frontend profile mirrors `next`: Playwright / `lint:js` / `lint:css` allowed
51
+
52
+ ## Forbidden in svelte hooks/agents (FAIL when present as required)
53
+
54
+ - `xcuitest-test-` / `instrumentation-test-` as handoff stems
55
+ - Requiring `xcodebuild` / SwiftLint as the default post-change gate for SvelteKit app work
56
+ - Frontend profile mirrors `next` / `nuxt`: Playwright / `lint:js` / `lint:css` allowed
57
+
58
+ ## Forbidden in go / java / php-hexagonal / php-laravel hooks/agents (FAIL)
59
+
60
+ Shared backend-stack bans (`go`, `java`, `php-hexagonal`, and `php-laravel`):
61
+
62
+ - `playwright-test-`, `playwright-e2e`, `user-playwright`, `app/__tests__/e2e`
63
+ - Positive yarn recipes `lint:js` / `lint:css`
64
+ - `xcuitest-test-`, `instrumentation-test-`, `xcodebuild`, `SwiftLint` as required handoffs
65
+ - Agent files `accessibility-reviewer`, `mockup-reviewer`, `ux-designer` (no UI surface)
66
+ - Required `skills/ux-design`, required `rules/ux-design`, or required pipeline handoff stem `ux-design`
67
+
68
+ Required instead: `integration-test-*`; build-verifier / `post-change-test` plus stack tooling — `go-tooling` (`go test`, `go vet`), `java-tooling` (`mvn test` / `./gradlew test`), or `php-tooling` (`php artisan test` / `composer test` / `vendor/bin/phpunit`).
69
+
70
+ ## Forbidden in mcp-ts hooks/agents (FAIL)
71
+
72
+ Same UI/mobile bans as backend stacks, plus:
73
+
74
+ - `playwright-test-`, `playwright-agents`, `playwright-e2e`, `user-playwright`, `app/__tests__/e2e`
75
+ - Positive yarn recipes `lint:js` / `lint:css` as required gates
76
+ - `xcuitest-test-`, `instrumentation-test-`, `xcodebuild`, `SwiftLint` as required handoffs
77
+ - Go tool commands as required MCP delivery gates: `go test`, `go vet`, `golangci-lint`
78
+ - Agent files: `playwright-test-*`, `xcuitest-test-*`, `instrumentation-test-*`, `integration-test-*`, `accessibility-reviewer`, `mockup-reviewer`, `ux-designer`
79
+ - Required `skills/ux-design`, required `rules/ux-design`, or required pipeline handoff stem `ux-design`
80
+
81
+ Required instead: package-manager–discovered typecheck/test (`mcp-ts-tooling`, `post-change-test`); Phase 1 gates `build-verifier` + `security-reviewer`.
82
+
83
+ ## Soft / document
84
+
85
+ - Mentioning the other stack in **docs** comparing presets is OK.
86
+ - `build-verifier` may reference other stacks when validating **preset packaging** (`scope: preset-structure-validation`).
87
+
88
+ ## Chain fork
89
+
90
+ `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.
@@ -0,0 +1,36 @@
1
+ <!-- shared-core: meta/preset-pr-checklist.md -->
2
+
3
+ # Preset PR checklist
4
+
5
+ Checklist for PRs that touch `packages/ai-rules/presets/**` (and dogfood `.cursor/` sync).
6
+
7
+ ## Before merge
8
+
9
+ - [ ] **SoT:** edits in `packages/…` (not only root `.cursor/`)
10
+ - [ ] **Core:** if `_shared/core/**` changed — all `<!-- shared-core: … -->` consumers updated (or documented intentional fork)
11
+ - [ ] **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`)
12
+ - [ ] **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)
13
+ - [ ] **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)
14
+ - [ ] **Mapping:** `claude/<stack>/rules/README.md` mapping table is current
15
+ - [ ] **Token budget:** Cursor `alwaysApply` ≤ 4 (4th slot reserved for `ai-local-overlay`); Claude session-start exactly 3; meta rules not always-on
16
+ - [ ] **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`.
17
+ - [ ] **Leakage:** no foreign stack agent stems / handoff strings (`preset-no-cross-stack-leakage`)
18
+ - [ ] **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`.
19
+ - [ ] **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`.
20
+ - [ ] **Twin depth:** domain ≥15 lines; thin aliases documented
21
+ - [ ] **README:** stack `rules/README.md` core→stack mapping / catalog updated if stems added
22
+ - [ ] **CHANGELOG / package README:** note when public preset paths or install surface change
23
+ - [ ] **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`.
24
+ - [ ] **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
25
+ - [ ] **shared-core drift:** for embed-mode stems, run `packages/ai-rules/scripts/check-shared-core-drift.sh` (or document intentional fork)
26
+
27
+ ## Pointers
28
+
29
+ - Layering: `preset-layering`
30
+ - Sync: `preset-twin-sync`
31
+ - Budget: `preset-token-budget`
32
+ - Leakage: `preset-no-cross-stack-leakage`
33
+ - Validation: stack `agents/build-verifier.md` → preset-structure section
34
+ - Dogfood scripts: `packages/ai-rules/scripts/sync-dogfood-cursor.sh`, `sync-dogfood-mavis.sh`, `sync-dogfood-opencode.sh`
35
+ - Drift script: `packages/ai-rules/scripts/check-shared-core-drift.sh`
36
+ - Orchestrator: when editing presets, load this checklist + twin-sync
@@ -0,0 +1,39 @@
1
+ <!-- shared-core: meta/preset-token-budget.md -->
2
+
3
+ # Preset token budget
4
+
5
+ Invariants for rule loading in an **installed** preset (consumer app).
6
+
7
+ ## Hard caps
8
+
9
+ | Platform | Always-on | Cap |
10
+ |----------|-----------|-----|
11
+ | Cursor | `alwaysApply: true` | **≤ 4** |
12
+ | Claude | rules **without** `paths:` | **exactly 3** |
13
+ | Mavis | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
14
+ | OpenCode | `adapter-map` rules with `loadMode: root-entry` | **≤ 4** |
15
+
16
+ **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.
17
+
18
+ **Claude Option A (README exclusion):** when counting Claude rules without `paths:` / session-start, **exclude `**/README.md`** (topic indexes are not session-start rules). The intended session-start trio remains **exactly 3**; body budget sums **only those 3** rules.
19
+
20
+ Session-start body budget:
21
+ - Claude trio: ≤140 lines total (stretch ≤120).
22
+ - Cursor 4-set: ≤170 lines total (4 rules including `ai-local-overlay`).
23
+ - 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`.
24
+
25
+ ## Meta / author rules
26
+
27
+ Rules for preset authors (`preset-layering`, `preset-twin-sync`, …):
28
+
29
+ - **Never** `alwaysApply: true` on consumer installs.
30
+ - Cursor: `globs` limited to `packages/ai-rules/presets/**` (and dogfood `.cursor/**` where useful).
31
+ - Claude: `paths:` limited to `packages/ai-rules/presets/**` (and `.claude/**` dogfood if present).
32
+
33
+ ## Heavy workflows
34
+
35
+ Orchestrator, feature-delivery, code-review, post-change gates, domain globs — **requestable / paths**, not always-on.
36
+
37
+ ## Verifier
38
+
39
+ build-verifier **FAIL** if Cursor `alwaysApply` count exceeds 4, Claude session-start count exceeds 3 (Claude count **excludes `**/README.md`**), or if a `preset-*` meta rule is marked always-on.
@@ -0,0 +1,81 @@
1
+ <!-- shared-core: meta/preset-twin-sync.md -->
2
+
3
+ # Preset twin sync
4
+
5
+ Cursor `.mdc` — **SoT per stack**. Claude topic `.md` — derived twin.
6
+
7
+ ## Matrix
8
+
9
+ | Stack | Cursor SoT | Claude derive | Mapping table |
10
+ |-------|------------|---------------|---------------|
11
+ | `next` | `presets/cursor/next/rules/*.mdc` | `presets/claude/next/rules/<topic>/` | **Required** in `claude/next/rules/README.md` |
12
+ | `nuxt` | `presets/cursor/nuxt/rules/*.mdc` | `presets/claude/nuxt/rules/<topic>/` | **Required** in `claude/nuxt/rules/README.md` |
13
+ | `svelte` | `presets/cursor/svelte/rules/*.mdc` | `presets/claude/svelte/rules/<topic>/` | **Required** in `claude/svelte/rules/README.md` |
14
+ | `ios-swift` | `presets/cursor/ios-swift/rules/*.mdc` | `presets/claude/ios-swift/rules/<topic>/` | Keep in `claude/ios-swift/rules/README.md` |
15
+ | `go` | `presets/cursor/go/rules/*.mdc` | `presets/claude/go/rules/<topic>/` | Keep in `claude/go/rules/README.md` |
16
+ | `java` | `presets/cursor/java/rules/*.mdc` | `presets/claude/java/rules/<topic>/` | Keep in `claude/java/rules/README.md` |
17
+ | `mcp-ts` | `presets/cursor/mcp-ts/rules/*.mdc` | `presets/claude/mcp-ts/rules/<topic>/` | Keep in `claude/mcp-ts/rules/README.md` |
18
+ | `php-hexagonal` | `presets/cursor/php-hexagonal/rules/*.mdc` | `presets/claude/php-hexagonal/rules/<topic>/` | Keep in `claude/php-hexagonal/rules/README.md` |
19
+ | `php-laravel` | `presets/cursor/php-laravel/rules/*.mdc` | `presets/claude/php-laravel/rules/<topic>/` | Keep in `claude/php-laravel/rules/README.md` |
20
+ | `android-kotlin` | `presets/cursor/android-kotlin/rules/*.mdc` | `presets/claude/android-kotlin/rules/<topic>/` | Keep in `claude/android-kotlin/rules/README.md` |
21
+
22
+ ## Mavis derivation (not a Claude twin)
23
+
24
+ | Stack | Cursor SoT | Mavis derive | Manifest |
25
+ |-------|------------|--------------|----------|
26
+ | `next` | `presets/cursor/next/**` | `presets/mavis/next/**` via `generate-mavis-next.mjs` | **Required** `adapter-map.json` |
27
+
28
+ Mavis is a **third platform adapter**, not a Claude-style topic twin:
29
+
30
+ ```text
31
+ _shared/core → cursor/<stack> → mavis/<stack>
32
+ ```
33
+
34
+ Regenerate with `node packages/ai-rules/scripts/generate-mavis-next.mjs`; validate with `node packages/ai-rules/scripts/check-mavis-adapter-map.mjs`.
35
+
36
+ ## OpenCode derivation (not a Claude twin)
37
+
38
+ | Stack | Cursor SoT | OpenCode derive | Manifest |
39
+ |-------|------------|-----------------|----------|
40
+ | `next` | `presets/cursor/next/**` | `presets/opencode/next/**` via `generate-opencode-next.mjs` | **Required** `adapter-map.json` |
41
+
42
+ 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/`:
43
+
44
+ ```text
45
+ _shared/core → cursor/<stack> → opencode/<stack>
46
+ ```
47
+
48
+ 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.
49
+
50
+ ## Same-PR checklist
51
+
52
+ 1. Edit Cursor rule first (body + frontmatter).
53
+ 2. Update Claude twin: body + `paths:` (from Cursor `globs:` / requestable triggers); drop `alwaysApply`.
54
+ 3. Update mapping table row if stem/path changed.
55
+ 4. If body embeds core (`<!-- shared-core: … -->`), sync core consumers across stacks when core changed.
56
+ 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`).
57
+ 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`).
58
+
59
+ ## Twin depth
60
+
61
+ - **Domain** rules: ≥15 body lines (FAIL if thin without documented alias reason).
62
+ - **Thin aliases** (`agent-team-intake`, `technical-retro`): may be shorter (soft) if they only point to a command/skill.
63
+ - **Slim-companion rules** (UI-edit bundle, slim app-cores, slim tooling): may be shorter than 15 lines **if and only if** the body is a pointer into shared-core / stack-prose (no standalone prose). Examples live in stack `rules/README.md` (e.g. `cursor/next/rules/README.md` "UI-edit bundle" intent).
64
+ - Mechanical enforcement lives in `packages/ai-rules/scripts/check-preset-token-budget.sh` — see `SLIM_COMPANION_ALLOWLIST` (the 53 stems accepted as slim pointers) and `MIN_SLIM_BODY_LINES` (5-line floor). Slim-companion rules with a body of 6–14 lines whose stem is **not** in the allowlist are reported as slim violations by the script.
65
+
66
+ ## Severity (build-verifier)
67
+
68
+ - **next:** missing Claude twin for a changed Cursor rule → **FAIL** (mapping table required).
69
+ - **nuxt:** missing Claude twin for a changed Cursor rule → **FAIL** (mapping table required).
70
+ - **svelte:** missing Claude twin for a changed Cursor rule → **FAIL** (mapping table required).
71
+ - **ios-swift:** missing Claude twin for a changed Cursor rule → **FAIL**.
72
+ - **go:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift; mapping table required).
73
+ - **java:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go; mapping table required).
74
+ - **mcp-ts:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java; mapping table required).
75
+ - **php-hexagonal:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts; mapping table required).
76
+ - **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).
77
+ - **android-kotlin:** missing Claude twin for a changed Cursor rule → **FAIL** (same as next / ios-swift / go / java / mcp-ts / php-*; mapping table required).
78
+ - **mavis/next:** `cursor/next` mapped source changed without mavis regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-mavis-adapter-map.mjs`).
79
+ - **opencode/next:** `cursor/next` mapped source changed without opencode regeneration / `adapter-map.json` `sourceRevision` drift → **FAIL** (`check-opencode-adapter-map.mjs`).
80
+
81
+ Dogfood: sync packages → root `.cursor/` after Cursor SoT changes (not the reverse). Use `packages/ai-rules/scripts/sync-dogfood-cursor.sh`.
@@ -0,0 +1,112 @@
1
+ <!-- shared-core: architecture/product-specs-authoring.md -->
2
+
3
+ # Product specs authoring
4
+
5
+ Load when **Generate** or **Bootstrap** is requested (`/spec-start`, router `spec-gen`, brief AC, or analyst author mode). Discovery-only work stays on **`product-specs`**.
6
+
7
+ **Optional prefix:** when the user or AC asks **research-before-spec**, load skill **`spec-discovery`** first (subset of methods; **claim-ledger** mandatory). Not the default `/task` consume path and not a new pipeline step.
8
+
9
+ ## Modes
10
+
11
+ 1. **Consume** — default; never invent INDEX/specs (see `product-specs`).
12
+ 2. **Generate** — create/update page/feature specs + INDEX rows from brief AC, user intent, Figma, or code archaeology. Inventing *product* behavior is forbidden without a stated source (AC / user / UI copy / code-observed behavior labeled `status: draft` or `inferred`).
13
+ 3. **Bootstrap** — create `INDEX.md` + `_templates/` copies + first domain spec under greenfield policy.
14
+
15
+ ## Greenfield policy
16
+
17
+ Agents **may** create INDEX + first specs **only when** one of:
18
+
19
+ 1. User runs `/spec-start` or explicitly asks to bootstrap `docs/specs`.
20
+ 2. Brief/AC includes generation or bootstrap language.
21
+ 3. Router detects `spec-gen` intent.
22
+
23
+ Otherwise: missing INDEX → optional tree; do **not** invent INDEX merely because discovery loaded.
24
+
25
+ ## Conflict precedence
26
+
27
+ 1. **Human gate** decision (approved brief/spec edits).
28
+ 2. **Current task `brief.md` AC** — if AC contradicts an existing spec, analyst must reconcile (update spec as `draft` or revise AC) before developer; no silent contradiction.
29
+ 3. **Approved `docs/specs/**`** — behavior SoT for feature-developer once gate passed.
30
+ 4. **Code / `.ai/context`** — discovery evidence only; never override approved spec without gate.
31
+
32
+ Label inferred-from-code lines with `status: draft` until human promotes.
33
+
34
+ ## INDEX.md contract (v1)
35
+
36
+ | Column | Required | Notes |
37
+ |--------|----------|-------|
38
+ | `id` | yes | Stable kebab/id matching frontmatter `id` |
39
+ | `type` | yes | `page` \| `feature` |
40
+ | `domain` | yes | Domain folder under `docs/specs/domains/<domain>/` |
41
+ | `title` | yes | Human label |
42
+ | `path` | yes | Repo-relative path to markdown file |
43
+ | `routes` | no | Summary; may duplicate frontmatter |
44
+ | `aliases` | no | Comma-separated PageName / deep-link aliases |
45
+ | `status` | no | `draft` \| `active` \| `deprecated` |
46
+
47
+ Layout: `docs/specs/domains/<domain>/<id>.md` (page) and optional `docs/specs/domains/<domain>/feature.md`. Adding/renaming/removing a linked file **must** update INDEX in the **same change set**.
48
+
49
+ ## Frontmatter v1
50
+
51
+ | Field | Type | Required | Notes |
52
+ |-------|------|----------|-------|
53
+ | `id` | string | yes | Unique; matches INDEX |
54
+ | `type` | enum `page` \| `feature` | yes | Backend/MCP: prefer `feature` |
55
+ | `domain` | string | yes | |
56
+ | `routes` | string[] | yes (may be `[]`) | Web: URL paths; mobile: deep links/screens; backend: HTTP paths; mcp-ts: tool names |
57
+ | `ui` | string[] | yes (may be `[]`) | Component/screen refs; empty on backend/mcp |
58
+ | `store` | string[] | yes (may be `[]`) | Slice/module refs; empty when N/A |
59
+ | `api` | string[] | yes (may be `[]`) | Services/ports/tools |
60
+ | `aliases` | string[] | yes (may be `[]`) | |
61
+ | `e2e` | string[] | yes (may be `[]`) | Stack-appropriate test paths |
62
+ | `status` | enum | no | default `draft` on agent generate |
63
+ | `owners` | string[] | no | |
64
+ | `related` | string[] | no | Spec ids or paths |
65
+
66
+ Arrays are **always present** (empty allowed). Do not omit keys for N/A stacks.
67
+
68
+ ## Body headings (minimum)
69
+
70
+ **`page` required:** Overview; Entry / actors; Primary flows; States (loading / empty / error / success as applicable — mark N/A explicitly); Acceptance criteria (links or bullets to brief AC / product source).
71
+
72
+ **`page` optional:** Analytics, Accessibility, Edge cases, Related specs.
73
+
74
+ **`feature` required:** Overview; Shared behavior / constraints; Related pages (links).
75
+
76
+ **`feature` optional:** Cross-cutting states, Analytics.
77
+
78
+ Compliant = valid frontmatter + all required headings present (non-empty prose or explicit `N/A`) + INDEX row with resolvable `path`.
79
+
80
+ ## Templates & assets
81
+
82
+ **Package SoT:** `packages/ai-rules/presets/_shared/assets/docs-specs/` (`INDEX.md` stub, `_templates/page.md`, `_templates/feature.md`; `schemas/frontmatter-v1.schema.json` is a documentation artifact — the checker does not evaluate it).
83
+
84
+ **CLI `init`:** when consumer `docs/specs/` is **absent**, copy INDEX stub + `_templates/*` (idempotent; **never overwrite** existing INDEX). When the tree already exists, skip seed entirely.
85
+
86
+ **Skill fallback:** if consumer `_templates/` missing during author mode, copy from package/skill assets before authoring.
87
+
88
+ ## Author roles
89
+
90
+ | Role | Responsibility |
91
+ |------|----------------|
92
+ | **task-analyst** | Primary author (Generate + Bootstrap); INDEX bootstrap; brief **Related specs** + **Spec gaps / generation requested**; loads this stem + skill `spec-authoring`; optional skill `spec-discovery` when research-before-spec |
93
+ | **tech-writer** | Post-delivery sync where present; never invent product behavior without AC/code source |
94
+ | **feature-developer** | Consumes approved specs as SoT; mechanical INDEX/frontmatter fixes only on renames |
95
+ | **mcp-ts** | No tech-writer — author + post-sync via **task-analyst** only |
96
+
97
+ ## Self-check before handoff (soft block)
98
+
99
+ Block handoff via `open_questions` until fixed:
100
+
101
+ - [ ] Required frontmatter keys present; arrays always present (may be `[]`)
102
+ - [ ] Required body headings present (or explicit `N/A`)
103
+ - [ ] INDEX row added/updated with resolvable `path` in the **same change set**
104
+ - [ ] Sources cited; invented product behavior absent (or labeled `draft` / `inferred`)
105
+ - [ ] Conflict with brief AC reconciled or flagged
106
+
107
+ ## Related
108
+
109
+ - `product-specs` — discovery / consume
110
+ - Skill `spec-authoring` — procedural checklist
111
+ - Skill `spec-discovery` — opt-in research-before-spec (not default)
112
+ - Optional consumer script `scripts/check-product-specs.sh` (ships in the npm package; WARN default; `--strict` FAIL). Bash checks INDEX links, required frontmatter keys, and body headings — it does **not** evaluate `frontmatter-v1.schema.json`