@getarbiter/cli 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (989) hide show
  1. package/CHANGELOG.md +713 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +31 -0
  4. package/PRIVACY.md +111 -0
  5. package/README.md +237 -0
  6. package/THIRD_PARTY_LICENSES.md +472 -0
  7. package/dist/.src-manifest.json +1 -0
  8. package/dist/capabilities/host-probe.js +3 -0
  9. package/dist/cli.d.ts +2 -0
  10. package/dist/cli.js +87 -0
  11. package/dist/commands/adopt-policy.js +3 -0
  12. package/dist/commands/configure-interactive.js +3 -0
  13. package/dist/commands/configure.js +5 -0
  14. package/dist/commands/cross-model-review.js +3 -0
  15. package/dist/commands/diff.js +20 -0
  16. package/dist/commands/doc-set.js +3 -0
  17. package/dist/commands/doctor/clean.js +2 -0
  18. package/dist/commands/doctor/fail-open-census.js +12 -0
  19. package/dist/commands/doctor/health.js +11 -0
  20. package/dist/commands/doctor/prove-gates.js +13 -0
  21. package/dist/commands/doctor/recover-lock.js +12 -0
  22. package/dist/commands/doctor/repair-state.js +6 -0
  23. package/dist/commands/doctor/tool-pin-extract.js +4 -0
  24. package/dist/commands/doctor/tool-pins.js +9 -0
  25. package/dist/commands/doctor-interactive.js +2 -0
  26. package/dist/commands/doctor.js +2 -0
  27. package/dist/commands/explain.js +19 -0
  28. package/dist/commands/gate-exec.js +4 -0
  29. package/dist/commands/gold-audit.js +14 -0
  30. package/dist/commands/graph.js +5 -0
  31. package/dist/commands/init/build-arbiter-config.js +1 -0
  32. package/dist/commands/init/generate.js +42 -0
  33. package/dist/commands/init/github-setup.js +5 -0
  34. package/dist/commands/init/maturity-gates.js +10 -0
  35. package/dist/commands/init/resolve-config.js +3 -0
  36. package/dist/commands/init/toolchain.js +10 -0
  37. package/dist/commands/init/types.js +1 -0
  38. package/dist/commands/init.js +17 -0
  39. package/dist/commands/method-interactive.js +4 -0
  40. package/dist/commands/method.js +11 -0
  41. package/dist/commands/obsidian.js +2 -0
  42. package/dist/commands/plugin.js +8 -0
  43. package/dist/commands/pr-merged.js +2 -0
  44. package/dist/commands/retire-policy.js +3 -0
  45. package/dist/commands/review-diff.js +3 -0
  46. package/dist/commands/settings.js +7 -0
  47. package/dist/commands/ship-config.js +2 -0
  48. package/dist/commands/ship-profile.js +2 -0
  49. package/dist/commands/ship-review.js +1 -0
  50. package/dist/commands/ship-tier.js +2 -0
  51. package/dist/commands/ship-train.js +2 -0
  52. package/dist/commands/task-mark.js +2 -0
  53. package/dist/commands/task-note.js +3 -0
  54. package/dist/commands/task-record-red.js +2 -0
  55. package/dist/commands/task-record-tech-debt.js +4 -0
  56. package/dist/commands/task-ship.js +3 -0
  57. package/dist/commands/task-state.js +6 -0
  58. package/dist/commands/task.js +59 -0
  59. package/dist/commands/update.js +60 -0
  60. package/dist/commands/upgrade-level-interactive.js +2 -0
  61. package/dist/commands/upgrade-level.js +7 -0
  62. package/dist/commands/verify-plan.js +8 -0
  63. package/dist/commands/verify-tdd.js +2 -0
  64. package/dist/commands/verify.js +7 -0
  65. package/dist/commands/wizard/coherence.js +1 -0
  66. package/dist/commands/worktree-prune.js +4 -0
  67. package/dist/commands/worktree.js +39 -0
  68. package/dist/compatibility/cross-language-matrix.json +540 -0
  69. package/dist/compatibility/index.d.ts +4 -0
  70. package/dist/compatibility/index.js +2 -0
  71. package/dist/compatibility/matcher.js +1 -0
  72. package/dist/compatibility/matrix.json +27 -0
  73. package/dist/compatibility/parsers.d.ts +38 -0
  74. package/dist/compatibility/parsers.js +1 -0
  75. package/dist/compatibility/probe.d.ts +41 -0
  76. package/dist/compatibility/probe.js +4 -0
  77. package/dist/compatibility/report.js +2 -0
  78. package/dist/compatibility/schema.d.ts +80 -0
  79. package/dist/compatibility/schema.js +1 -0
  80. package/dist/compatibility/skills-matrix.json +98 -0
  81. package/dist/compatibility/skills-validator.d.ts +30 -0
  82. package/dist/compatibility/skills-validator.js +4 -0
  83. package/dist/compatibility/tooling-proposals.json +5 -0
  84. package/dist/config/arbiter-ignore.js +3 -0
  85. package/dist/config/collaboration-mode-defaults.js +1 -0
  86. package/dist/config/diff.js +1 -0
  87. package/dist/config/env-overrides.js +3 -0
  88. package/dist/config/env-registry.js +2 -0
  89. package/dist/config/levels.js +1 -0
  90. package/dist/config/migrations/index.js +2 -0
  91. package/dist/config/migrations/v0-to-v1.js +2 -0
  92. package/dist/config/migrations/v1-to-v2.js +2 -0
  93. package/dist/config/migrations/v2-to-v3.js +2 -0
  94. package/dist/config/migrations/v3-to-v4.js +2 -0
  95. package/dist/config/override-resolver.js +2 -0
  96. package/dist/config/resolve-project-config.js +2 -0
  97. package/dist/config/resolve-project-name.js +2 -0
  98. package/dist/config/schema.d.ts +480 -0
  99. package/dist/config/schema.js +1 -0
  100. package/dist/config/test-pyramid-profiles.js +1 -0
  101. package/dist/config/thresholds.js +2 -0
  102. package/dist/conformance/dimensions.js +3 -0
  103. package/dist/conformance/engine.js +7 -0
  104. package/dist/conformance/gate-proofs.js +4 -0
  105. package/dist/conformance/shared.js +2 -0
  106. package/dist/detectors/axis.js +1 -0
  107. package/dist/detectors/build.js +2 -0
  108. package/dist/detectors/existing.js +2 -0
  109. package/dist/detectors/external-model.js +2 -0
  110. package/dist/detectors/framework.js +2 -0
  111. package/dist/detectors/git.js +11 -0
  112. package/dist/detectors/github.js +2 -0
  113. package/dist/detectors/lanes.js +5 -0
  114. package/dist/detectors/language-hooks.js +117 -0
  115. package/dist/detectors/language.js +2 -0
  116. package/dist/detectors/package-manager.js +2 -0
  117. package/dist/detectors/package.js +2 -0
  118. package/dist/detectors/scaffold-wiring.js +2 -0
  119. package/dist/detectors/workflow-collision.js +4 -0
  120. package/dist/evidence/gate-binding.js +4 -0
  121. package/dist/evidence/git-checks.js +3 -0
  122. package/dist/evidence/load.js +2 -0
  123. package/dist/evidence/provenance.js +2 -0
  124. package/dist/evidence/summary.js +2 -0
  125. package/dist/evidence/tdd-reexecute.js +2 -0
  126. package/dist/evidence/tdd.js +4 -0
  127. package/dist/experimental/index.js +2 -0
  128. package/dist/experimental/parse-argv.js +2 -0
  129. package/dist/experimental/registry.js +2 -0
  130. package/dist/generators/agents-claude.js +2 -0
  131. package/dist/generators/agents-md.js +2 -0
  132. package/dist/generators/anti-drift-validators.js +3 -0
  133. package/dist/generators/anti-proforma.js +2 -0
  134. package/dist/generators/api-e2e.js +2 -0
  135. package/dist/generators/api-middleware.js +2 -0
  136. package/dist/generators/archunit.js +2 -0
  137. package/dist/generators/audit-toolchain.js +2 -0
  138. package/dist/generators/auth.js +2 -0
  139. package/dist/generators/behavioral-tests.js +2 -0
  140. package/dist/generators/boundaries.js +2 -0
  141. package/dist/generators/check-all.js +2 -0
  142. package/dist/generators/check-stack-conformity.js +2 -0
  143. package/dist/generators/ci-five-lane.js +2 -0
  144. package/dist/generators/ci-tier.js +2 -0
  145. package/dist/generators/claude.js +3 -0
  146. package/dist/generators/codex-hooks.js +2 -0
  147. package/dist/generators/codex-known-limitations.js +2 -0
  148. package/dist/generators/codex.js +15 -0
  149. package/dist/generators/commit-footer.js +2 -0
  150. package/dist/generators/compliance-menu.js +2 -0
  151. package/dist/generators/compliance.js +2 -0
  152. package/dist/generators/conformance.js +2 -0
  153. package/dist/generators/contract-testing.js +2 -0
  154. package/dist/generators/coverage.js +2 -0
  155. package/dist/generators/debt-gates.js +24 -0
  156. package/dist/generators/debt-ratchet.js +2 -0
  157. package/dist/generators/derived-class.js +2 -0
  158. package/dist/generators/doc-set.js +4 -0
  159. package/dist/generators/docs.js +2 -0
  160. package/dist/generators/duplication.js +2 -0
  161. package/dist/generators/e2e-constitution.js +2 -0
  162. package/dist/generators/env-template.js +2 -0
  163. package/dist/generators/evidence-retention.js +2 -0
  164. package/dist/generators/feature-matrix.js +2 -0
  165. package/dist/generators/frontend-governance.js +2 -0
  166. package/dist/generators/frontend-quality.js +2 -0
  167. package/dist/generators/gap.js +2 -0
  168. package/dist/generators/gdpr.js +2 -0
  169. package/dist/generators/githooks.js +2 -0
  170. package/dist/generators/github-setup.js +2 -0
  171. package/dist/generators/github.js +2 -0
  172. package/dist/generators/gitignore.js +2 -0
  173. package/dist/generators/global-invariants.js +3 -0
  174. package/dist/generators/go-boundaries.js +2 -0
  175. package/dist/generators/gold-kit.js +2 -0
  176. package/dist/generators/infra.js +2 -0
  177. package/dist/generators/integration-testing.js +7 -0
  178. package/dist/generators/iso27001.js +2 -0
  179. package/dist/generators/iso9001.js +2 -0
  180. package/dist/generators/labels.js +2 -0
  181. package/dist/generators/local-wrapper.js +2 -0
  182. package/dist/generators/modulith.js +2 -0
  183. package/dist/generators/mutation.js +2 -0
  184. package/dist/generators/observability.js +2 -0
  185. package/dist/generators/operations.js +2 -0
  186. package/dist/generators/perf-k6.js +2 -0
  187. package/dist/generators/pharma.js +2 -0
  188. package/dist/generators/playwright-python.js +2 -0
  189. package/dist/generators/playwright-ts.js +2 -0
  190. package/dist/generators/pr-tooling.js +2 -0
  191. package/dist/generators/python-boundaries.js +2 -0
  192. package/dist/generators/quality.js +2 -0
  193. package/dist/generators/registry.js +2 -0
  194. package/dist/generators/regulated.js +2 -0
  195. package/dist/generators/resilience.js +2 -0
  196. package/dist/generators/risk-register.js +2 -0
  197. package/dist/generators/root.js +2 -0
  198. package/dist/generators/rust-boundaries.js +2 -0
  199. package/dist/generators/safety-class.js +2 -0
  200. package/dist/generators/security.js +2 -0
  201. package/dist/generators/seed.js +2 -0
  202. package/dist/generators/self-validation.js +2 -0
  203. package/dist/generators/ship-driver.js +2 -0
  204. package/dist/generators/skill-names.json +17 -0
  205. package/dist/generators/skills.js +2 -0
  206. package/dist/generators/smoke-journeys.js +2 -0
  207. package/dist/generators/solo-exception.js +2 -0
  208. package/dist/generators/ssot.js +2 -0
  209. package/dist/generators/stride-enforcement.js +2 -0
  210. package/dist/generators/suppressions.js +2 -0
  211. package/dist/generators/test-pyramid-manifest.js +3 -0
  212. package/dist/generators/test-taxonomy.js +2 -0
  213. package/dist/generators/wiki.js +2 -0
  214. package/dist/github/branch-protection.js +2 -0
  215. package/dist/github/classify-gh-error.js +2 -0
  216. package/dist/github/labels.js +2 -0
  217. package/dist/github/project-board.js +2 -0
  218. package/dist/graph/builders/adr.js +4 -0
  219. package/dist/graph/builders/ast.js +3 -0
  220. package/dist/graph/builders/canon.js +2 -0
  221. package/dist/graph/builders/evidence.js +2 -0
  222. package/dist/graph/builders/inv.js +1 -0
  223. package/dist/graph/builders/req.js +3 -0
  224. package/dist/graph/builders/test-nodes.js +3 -0
  225. package/dist/graph/builders/utils.js +2 -0
  226. package/dist/graph/load.js +2 -0
  227. package/dist/graph/model.js +2 -0
  228. package/dist/graph/query.js +3 -0
  229. package/dist/graph/store.js +1 -0
  230. package/dist/i18n/en.json +293 -0
  231. package/dist/i18n/index.js +4 -0
  232. package/dist/i18n/types.js +2 -0
  233. package/dist/integrations/companions.js +2 -0
  234. package/dist/integrations/external-review.js +10 -0
  235. package/dist/integrations/plugin-schema.js +2 -0
  236. package/dist/integrations/skill-detector.js +7 -0
  237. package/dist/integrations/skills-matrix.js +2 -0
  238. package/dist/integrations/types.d.ts +23 -0
  239. package/dist/integrations/types.js +2 -0
  240. package/dist/internal/cli-deprecation-registry.js +2 -0
  241. package/dist/internal/deprecate.js +3 -0
  242. package/dist/internal/experimental-warn.js +3 -0
  243. package/dist/invariants/catalog.d.ts +2 -0
  244. package/dist/invariants/catalog.js +1 -0
  245. package/dist/invariants/filter.d.ts +28 -0
  246. package/dist/invariants/filter.js +1 -0
  247. package/dist/invariants/index.d.ts +4 -0
  248. package/dist/invariants/index.js +2 -0
  249. package/dist/invariants/tiers.js +1 -0
  250. package/dist/invariants/types.d.ts +1 -0
  251. package/dist/invariants/types.js +1 -0
  252. package/dist/kit/applicability.js +3 -0
  253. package/dist/kit/audit-report.js +3 -0
  254. package/dist/kit/brownfield-detect.js +4 -0
  255. package/dist/kit/canonical-mapping.json +1 -0
  256. package/dist/kit/catalog.js +2 -0
  257. package/dist/kit/catalog.json +1 -0
  258. package/dist/kit/derived.json +1 -0
  259. package/dist/kit/emit-issues.js +8 -0
  260. package/dist/kit/measure.js +5 -0
  261. package/dist/kit/redaction.js +3 -0
  262. package/dist/kit/schema.js +2 -0
  263. package/dist/kit/taxonomy.js +2 -0
  264. package/dist/kit/thresholds.d.ts +12 -0
  265. package/dist/kit/thresholds.js +2 -0
  266. package/dist/kit/wave-engine.js +1 -0
  267. package/dist/recipes/loader.js +6 -0
  268. package/dist/recipes/schema.js +2 -0
  269. package/dist/risk/classifier.js +2 -0
  270. package/dist/risk/sha-check.js +2 -0
  271. package/dist/state/backups.js +2 -0
  272. package/dist/state/envelope.js +2 -0
  273. package/dist/state/generated-manifest.js +3 -0
  274. package/dist/state/manifest-key.js +2 -0
  275. package/dist/state/migrations/index.js +1 -0
  276. package/dist/state/migrations/v0-to-v1.js +2 -0
  277. package/dist/state/retired-renders.js +2 -0
  278. package/dist/templates/.nvmrc.ejs +1 -0
  279. package/dist/templates/HANDOFF.template.md +45 -0
  280. package/dist/templates/__tests__/contract/error-shape.contract.test.ts.ejs +47 -0
  281. package/dist/templates/agents-md/AGENTS.md.ejs +517 -0
  282. package/dist/templates/api-e2e/README.md.ejs +33 -0
  283. package/dist/templates/api-e2e/go-httptest.go.ejs +43 -0
  284. package/dist/templates/api-e2e/java-restassured.java.ejs +28 -0
  285. package/dist/templates/api-e2e/kotlin-restassured.kt.ejs +30 -0
  286. package/dist/templates/api-e2e/manifest.json.ejs +8 -0
  287. package/dist/templates/api-e2e/postman.collection.json.ejs +30 -0
  288. package/dist/templates/api-e2e/python-httpx.py.ejs +17 -0
  289. package/dist/templates/api-e2e/run.sh.ejs +61 -0
  290. package/dist/templates/api-e2e/ts-supertest.test.ts.ejs +18 -0
  291. package/dist/templates/archunit/AntiCyclicTest.java.ejs +29 -0
  292. package/dist/templates/archunit/AntiProformaExempt.java.ejs +35 -0
  293. package/dist/templates/archunit/AntiProformaTest.java.ejs +104 -0
  294. package/dist/templates/archunit/ArchitectureTest.java.ejs +87 -0
  295. package/dist/templates/archunit/DependencyFlowTest.java.ejs +55 -0
  296. package/dist/templates/archunit/DomainPurityTest.java.ejs +47 -0
  297. package/dist/templates/archunit/NamingConventionsTest.java.ejs +54 -0
  298. package/dist/templates/archunit/NoH2ArchTest.java.ejs +30 -0
  299. package/dist/templates/archunit/NoMockMvcTest.java.ejs +71 -0
  300. package/dist/templates/archunit/PortsIndependenceTest.java.ejs +55 -0
  301. package/dist/templates/archunit/RestAssuredArchTest.java.ejs +32 -0
  302. package/dist/templates/archunit/RestAssuredBaseIT.java.ejs +66 -0
  303. package/dist/templates/archunit/TestCoverageArchTest.java.ejs +29 -0
  304. package/dist/templates/archunit/arch-test-deps-maven.md.ejs +42 -0
  305. package/dist/templates/archunit/arch-test-deps.gradle.ejs +14 -0
  306. package/dist/templates/audit/gdpr/check-gdpr-controls.mjs.ejs +102 -0
  307. package/dist/templates/audit/gdpr/controls-to-gates.md.ejs +42 -0
  308. package/dist/templates/audit/gdpr/data-flow-map.md.ejs +30 -0
  309. package/dist/templates/audit/gdpr/dpia.md.ejs +45 -0
  310. package/dist/templates/audit/generic/audit-gate-rules.md.ejs +24 -0
  311. package/dist/templates/audit/generic/audit-trail-policy.md.ejs +38 -0
  312. package/dist/templates/audit/iso27001/iso27001-controls-gate-map.md.ejs +60 -0
  313. package/dist/templates/auth/setup.md.ejs +661 -0
  314. package/dist/templates/behavioral-tests/ExampleBehavioralTest.java.ejs +67 -0
  315. package/dist/templates/behavioral-tests/TESTING_POLICY.md.ejs +116 -0
  316. package/dist/templates/behavioral-tests/bdd/ExampleBddIT.java.ejs +19 -0
  317. package/dist/templates/behavioral-tests/bdd/ExampleSteps.java.ejs +61 -0
  318. package/dist/templates/behavioral-tests/bdd/example.feature.ejs +14 -0
  319. package/dist/templates/behavioral-tests/bdd/example.steps.ts.ejs +37 -0
  320. package/dist/templates/behavioral-tests/bdd/example_bdd_test.rs.ejs +64 -0
  321. package/dist/templates/behavioral-tests/bdd/example_test.go.ejs +80 -0
  322. package/dist/templates/behavioral-tests/bdd/test_example_bdd.py.ejs +47 -0
  323. package/dist/templates/behavioral-tests/eslint-playwright.json.ejs +10 -0
  324. package/dist/templates/behavioral-tests/eslint.config.playwright.mjs.ejs +29 -0
  325. package/dist/templates/behavioral-tests/example.behavioral.test.ts.ejs +47 -0
  326. package/dist/templates/behavioral-tests/example_behavioral_test.go.ejs +51 -0
  327. package/dist/templates/behavioral-tests/example_behavioral_test.rs.ejs +47 -0
  328. package/dist/templates/behavioral-tests/test_example_behavioral.py.ejs +40 -0
  329. package/dist/templates/boundaries/.eslintrc-boundaries.cjs.ejs +81 -0
  330. package/dist/templates/boundaries/.eslintrc-frontend-spa.cjs.ejs +79 -0
  331. package/dist/templates/boundaries/.importlinter.ejs +48 -0
  332. package/dist/templates/boundaries/check-boundaries-go.mjs.ejs +94 -0
  333. package/dist/templates/boundaries/check-boundaries-python.mjs.ejs +118 -0
  334. package/dist/templates/boundaries/check-boundaries-rust.mjs.ejs +111 -0
  335. package/dist/templates/boundaries/check-boundaries.mjs.ejs +34 -0
  336. package/dist/templates/boundaries/clippy.toml.ejs +50 -0
  337. package/dist/templates/boundaries/deny.toml.ejs +56 -0
  338. package/dist/templates/boundaries/eslint.config.boundaries.mjs.ejs +112 -0
  339. package/dist/templates/boundaries/eslint.config.frontend-spa.mjs.ejs +93 -0
  340. package/dist/templates/boundaries/golangci-boundaries.yml.ejs +70 -0
  341. package/dist/templates/boundaries/ruff-boundaries.toml.ejs +32 -0
  342. package/dist/templates/claude/CLAUDE.md.ejs +78 -0
  343. package/dist/templates/claude/agents/agent-write-classes.json +30 -0
  344. package/dist/templates/claude/agents/bridge-reviewer.md.ejs +68 -0
  345. package/dist/templates/claude/agents/codebase-scanner.md.ejs +69 -0
  346. package/dist/templates/claude/agents/context-checker.md.ejs +73 -0
  347. package/dist/templates/claude/agents/red-team.md.ejs +134 -0
  348. package/dist/templates/claude/commands/close-gold-gap.md.ejs +43 -0
  349. package/dist/templates/claude/commands/drain.md.ejs +81 -0
  350. package/dist/templates/claude/commands/gold-audit.md.ejs +43 -0
  351. package/dist/templates/claude/commands/impact.md.ejs +39 -0
  352. package/dist/templates/claude/commands/levelup.md.ejs +61 -0
  353. package/dist/templates/claude/commands/ship.md.ejs +902 -0
  354. package/dist/templates/claude/commands/tabletop.md.ejs +46 -0
  355. package/dist/templates/claude/commands/task.md.ejs +87 -0
  356. package/dist/templates/claude/commands/wt-close.md.ejs +58 -0
  357. package/dist/templates/claude/commands/wt-list.md.ejs +48 -0
  358. package/dist/templates/claude/commands/wt-open.md.ejs +61 -0
  359. package/dist/templates/claude/commands/wt-prune.md.ejs +38 -0
  360. package/dist/templates/claude/hooks/check-circular-deps.mjs.ejs +56 -0
  361. package/dist/templates/claude/hooks/check-no-orphan-todo.mjs.ejs +45 -0
  362. package/dist/templates/claude/hooks/check-no-pii.mjs.ejs +121 -0
  363. package/dist/templates/claude/hooks/check-no-placeholders.mjs.ejs +71 -0
  364. package/dist/templates/claude/hooks/check-no-skipped-tests.mjs +80 -0
  365. package/dist/templates/claude/hooks/check-no-unused-exports.mjs +62 -0
  366. package/dist/templates/claude/hooks/closer-mode-guard.mjs.ejs +102 -0
  367. package/dist/templates/claude/hooks/debug-state-on-failure.mjs.ejs +98 -0
  368. package/dist/templates/claude/hooks/enforce-gate-before-pr.mjs +142 -0
  369. package/dist/templates/claude/hooks/enforce-read-only.mjs +28 -0
  370. package/dist/templates/claude/hooks/exitplanmode-banner.mjs.ejs +43 -0
  371. package/dist/templates/claude/hooks/guard-done-evidence.mjs.ejs +85 -0
  372. package/dist/templates/claude/hooks/guard-task-completion.mjs.ejs +56 -0
  373. package/dist/templates/claude/hooks/hooks.mjs.ejs +127 -0
  374. package/dist/templates/claude/hooks/lib.mjs.ejs +523 -0
  375. package/dist/templates/claude/hooks/post-brainstorm-stop.mjs +48 -0
  376. package/dist/templates/claude/hooks/post-commit-check.mjs.ejs +65 -0
  377. package/dist/templates/claude/hooks/post-commit-checklists/go/backend.ejs +4 -0
  378. package/dist/templates/claude/hooks/post-commit-checklists/go/docs.ejs +4 -0
  379. package/dist/templates/claude/hooks/post-commit-checklists/go/frontend.ejs +4 -0
  380. package/dist/templates/claude/hooks/post-commit-checklists/java/backend.ejs +4 -0
  381. package/dist/templates/claude/hooks/post-commit-checklists/java/docs.ejs +4 -0
  382. package/dist/templates/claude/hooks/post-commit-checklists/java/frontend.ejs +4 -0
  383. package/dist/templates/claude/hooks/post-commit-checklists/python/backend.ejs +4 -0
  384. package/dist/templates/claude/hooks/post-commit-checklists/python/docs.ejs +4 -0
  385. package/dist/templates/claude/hooks/post-commit-checklists/python/frontend.ejs +4 -0
  386. package/dist/templates/claude/hooks/post-commit-checklists/rust/backend.ejs +5 -0
  387. package/dist/templates/claude/hooks/post-commit-checklists/rust/docs.ejs +4 -0
  388. package/dist/templates/claude/hooks/post-commit-checklists/rust/frontend.ejs +4 -0
  389. package/dist/templates/claude/hooks/post-commit-checklists/ts/backend.ejs +4 -0
  390. package/dist/templates/claude/hooks/post-commit-checklists/ts/docs.ejs +4 -0
  391. package/dist/templates/claude/hooks/post-commit-checklists/ts/frontend.ejs +5 -0
  392. package/dist/templates/claude/hooks/post-edit-dispatch.mjs.ejs +73 -0
  393. package/dist/templates/claude/hooks/post-subagent-release.mjs +80 -0
  394. package/dist/templates/claude/hooks/pre-compact.mjs.ejs +79 -0
  395. package/dist/templates/claude/hooks/pre-edit-plan-anchor.mjs.ejs +225 -0
  396. package/dist/templates/claude/hooks/pre-edit-ssot-guard.mjs +204 -0
  397. package/dist/templates/claude/hooks/pre-spawn-worktree-guard.mjs +129 -0
  398. package/dist/templates/claude/hooks/skill-forced-eval.mjs.ejs +281 -0
  399. package/dist/templates/claude/hooks/stop-dangerous.mjs +86 -0
  400. package/dist/templates/claude/hooks/stop-evidence-guard.mjs.ejs +245 -0
  401. package/dist/templates/claude/hooks/stop-finding-loss.mjs.ejs +168 -0
  402. package/dist/templates/claude/hooks/wiki-on-commit.mjs.ejs +38 -0
  403. package/dist/templates/claude/knowledge-map.json.ejs +26 -0
  404. package/dist/templates/claude/rules/05-agent-lifecycle.md +7 -0
  405. package/dist/templates/claude/rules/25-todo-folder-policy.md +5 -0
  406. package/dist/templates/claude/rules/40-context-economy.md +32 -0
  407. package/dist/templates/claude/rules/45-mcp-fallback.md +25 -0
  408. package/dist/templates/claude/rules/50-batch-execution.md +75 -0
  409. package/dist/templates/claude/rules/55-brainstorm-terminal-state.md +44 -0
  410. package/dist/templates/claude/rules/60-incidental-capture.md +43 -0
  411. package/dist/templates/claude/rules/75-impact-vault-reading.md +43 -0
  412. package/dist/templates/claude/rules/90-exec-protocol.md.ejs +40 -0
  413. package/dist/templates/claude/rules/95-closer-mode.md +45 -0
  414. package/dist/templates/claude/settings.json.ejs +165 -0
  415. package/dist/templates/claude/skills/architect-review/SKILL.md.ejs +82 -0
  416. package/dist/templates/claude/skills/brainstorming/SKILL.md.ejs +86 -0
  417. package/dist/templates/claude/skills/clean-code/SKILL.md.ejs +39 -0
  418. package/dist/templates/claude/skills/close-gold-gap/SKILL.md.ejs +58 -0
  419. package/dist/templates/claude/skills/codebase-audit/SKILL.md.ejs +88 -0
  420. package/dist/templates/claude/skills/configure/SKILL.md.ejs +72 -0
  421. package/dist/templates/claude/skills/epic-decompose/SKILL.md.ejs +86 -0
  422. package/dist/templates/claude/skills/gold-audit/SKILL.md.ejs +91 -0
  423. package/dist/templates/claude/skills/impact/SKILL.md.ejs +104 -0
  424. package/dist/templates/claude/skills/levelup/SKILL.md.ejs +146 -0
  425. package/dist/templates/claude/skills/tabletop/SKILL.md.ejs +118 -0
  426. package/dist/templates/claude/skills/tdd/SKILL.md.ejs +157 -0
  427. package/dist/templates/claude/skills/understand-code/SKILL.md.ejs +93 -0
  428. package/dist/templates/claude/skills/verification/SKILL.md.ejs +68 -0
  429. package/dist/templates/claude/skills/wave-drain/SKILL.md.ejs +491 -0
  430. package/dist/templates/codex/CODEX.md.ejs +140 -0
  431. package/dist/templates/codex/codex-adapter.mjs +132 -0
  432. package/dist/templates/codex/config.toml.ejs +189 -0
  433. package/dist/templates/compliance/compliance-mapping.md.ejs +124 -0
  434. package/dist/templates/compliance/compliance-menu.md.ejs +89 -0
  435. package/dist/templates/contract-testing/CONTRACTS_POLICY.md.ejs +30 -0
  436. package/dist/templates/contract-testing/api-snapshots/config-keys-baseline.json.ejs +1 -0
  437. package/dist/templates/contract-testing/api-snapshots/config-response-baseline.json.ejs +1 -0
  438. package/dist/templates/contract-testing/api-snapshots/enum-values-baseline.json.ejs +1 -0
  439. package/dist/templates/contract-testing/api-snapshots/error-shape-baseline.json.ejs +6 -0
  440. package/dist/templates/contract-testing/api-snapshots/openapi-baseline.json.ejs +12 -0
  441. package/dist/templates/contract-testing/api-snapshots/openapi-content-types-baseline.json.ejs +3 -0
  442. package/dist/templates/contract-testing/api-snapshots/openapi-paths-baseline.json.ejs +1 -0
  443. package/dist/templates/contract-testing/api-snapshots/openapi-required-fields-baseline.json.ejs +1 -0
  444. package/dist/templates/contract-testing/api-snapshots/openapi-response-status-baseline.json.ejs +3 -0
  445. package/dist/templates/contract-testing/api-snapshots/test-snapshot.json.ejs +4 -0
  446. package/dist/templates/contract-testing/env/.env.pact.ejs +4 -0
  447. package/dist/templates/contract-testing/graphql/GraphqlSchemaTest.java.ejs +29 -0
  448. package/dist/templates/contract-testing/graphql/graphql-inspector.test.ts.ejs +20 -0
  449. package/dist/templates/contract-testing/graphql/graphql_schema_test.go.ejs +27 -0
  450. package/dist/templates/contract-testing/graphql/graphql_schema_test.rs.ejs +27 -0
  451. package/dist/templates/contract-testing/graphql/test_graphql_schema.py.ejs +21 -0
  452. package/dist/templates/contract-testing/grpc/GrpcContractTest.java.ejs +23 -0
  453. package/dist/templates/contract-testing/grpc/buf-breaking.yml.ejs +6 -0
  454. package/dist/templates/contract-testing/grpc/buf.yaml.ejs +11 -0
  455. package/dist/templates/contract-testing/grpc/grpc-contract.test.ts.ejs +16 -0
  456. package/dist/templates/contract-testing/grpc/grpc_contract_test.go.ejs +22 -0
  457. package/dist/templates/contract-testing/grpc/grpc_contract_test.rs.ejs +22 -0
  458. package/dist/templates/contract-testing/grpc/test_grpc_contract.py.ejs +18 -0
  459. package/dist/templates/contract-testing/message-queue/SchemaRegistryCheckIT.java.ejs +44 -0
  460. package/dist/templates/contract-testing/message-queue/schema-registry-check.ts.ejs +42 -0
  461. package/dist/templates/contract-testing/message-queue/schema_registry_test.go.ejs +71 -0
  462. package/dist/templates/contract-testing/message-queue/schema_registry_test.rs.ejs +61 -0
  463. package/dist/templates/contract-testing/message-queue/test_schema_registry.py.ejs +31 -0
  464. package/dist/templates/contract-testing/pact-samples/assignment-response.json.ejs +7 -0
  465. package/dist/templates/contract-testing/pact-samples/availability-response.json.ejs +13 -0
  466. package/dist/templates/contract-testing/pact-samples/availability-rule-response.json.ejs +8 -0
  467. package/dist/templates/contract-testing/pact-samples/capacity-response.json.ejs +11 -0
  468. package/dist/templates/contract-testing/pact-samples/fully-booked-response.json.ejs +6 -0
  469. package/dist/templates/contract-testing/pact-samples/schedule-override-response.json.ejs +7 -0
  470. package/dist/templates/contract-testing/rest-owned/PactVerificationIT.java.ejs +31 -0
  471. package/dist/templates/contract-testing/rest-owned/pact-consumer.test.ts.ejs +36 -0
  472. package/dist/templates/contract-testing/rest-owned/pact-deps.gradle.ejs +15 -0
  473. package/dist/templates/contract-testing/rest-owned/pact_consumer_test.go.ejs +48 -0
  474. package/dist/templates/contract-testing/rest-owned/pact_consumer_test.rs.ejs +23 -0
  475. package/dist/templates/contract-testing/rest-owned/test_pact_consumer.py.ejs +35 -0
  476. package/dist/templates/contract-testing/rest-public/OpenApiDiffIT.java.ejs +44 -0
  477. package/dist/templates/contract-testing/rest-public/export-openapi-java.gradle.ejs +13 -0
  478. package/dist/templates/contract-testing/rest-public/export-openapi.mjs.ejs +21 -0
  479. package/dist/templates/contract-testing/rest-public/export_openapi.go.ejs +30 -0
  480. package/dist/templates/contract-testing/rest-public/export_openapi.py.ejs +27 -0
  481. package/dist/templates/contract-testing/rest-public/export_openapi.rs.ejs +32 -0
  482. package/dist/templates/contract-testing/rest-public/openapi-diff.ts.ejs +42 -0
  483. package/dist/templates/contract-testing/rest-public/openapi_diff_test.go.ejs +35 -0
  484. package/dist/templates/contract-testing/rest-public/openapi_diff_test.rs.ejs +36 -0
  485. package/dist/templates/contract-testing/rest-public/test_openapi_diff.py.ejs +32 -0
  486. package/dist/templates/coverage/.coveragerc.ejs +26 -0
  487. package/dist/templates/coverage/.tarpaulin.toml.ejs +30 -0
  488. package/dist/templates/coverage/Cargo.toml.profile.release.ejs +24 -0
  489. package/dist/templates/coverage/jacoco-maven-setup.md.ejs +72 -0
  490. package/dist/templates/coverage/jacoco.gradle.ejs +49 -0
  491. package/dist/templates/coverage/kover.gradle.ejs +35 -0
  492. package/dist/templates/coverage/vitest.browser.config.ts.ejs +47 -0
  493. package/dist/templates/coverage/vitest.config.ts.ejs +47 -0
  494. package/dist/templates/docs/CODING_STANDARDS.md.ejs +81 -0
  495. package/dist/templates/docs/FEATURE_MATRIX.md.ejs +84 -0
  496. package/dist/templates/docs/GAP.md.ejs +58 -0
  497. package/dist/templates/docs/ISO27001_ANNEX_A.md.ejs +144 -0
  498. package/dist/templates/docs/MASTER_TEST_PLAN.md.ejs +52 -0
  499. package/dist/templates/docs/POST_MERGE_REVIEW_TEMPLATE.md.ejs +63 -0
  500. package/dist/templates/docs/SECURE_CODING_CHECKLIST.md.ejs +61 -0
  501. package/dist/templates/docs/adr/ADR-000_template.md.ejs +28 -0
  502. package/dist/templates/docs/bugs/bug-analysis.md.ejs +47 -0
  503. package/dist/templates/docs/bugs/bug-report.md.ejs +51 -0
  504. package/dist/templates/docs/bugs/bug-verification.md.ejs +42 -0
  505. package/dist/templates/docs/runbooks/deployment.md.ejs +119 -0
  506. package/dist/templates/docs/runbooks/prod-checklist.md.ejs +90 -0
  507. package/dist/templates/docs/runbooks/rollback.md.ejs +124 -0
  508. package/dist/templates/docs/runbooks/troubleshooting.md.ejs +130 -0
  509. package/dist/templates/docs/skeletons/arc42-canvas.md.ejs +46 -0
  510. package/dist/templates/docs/skeletons/arc42-full.md.ejs +59 -0
  511. package/dist/templates/docs/skeletons/decision-registry.md.ejs +38 -0
  512. package/dist/templates/docs/skeletons/er-model.md.ejs +19 -0
  513. package/dist/templates/docs/skeletons/glossary.md.ejs +8 -0
  514. package/dist/templates/docs/skeletons/governance.md.ejs +13 -0
  515. package/dist/templates/docs/skeletons/slo.md.ejs +21 -0
  516. package/dist/templates/docs/skeletons/technical-debt.md.ejs +8 -0
  517. package/dist/templates/docs/skeletons/test-strategy.md.ejs +14 -0
  518. package/dist/templates/docs/skeletons/threat-model-4q.md.ejs +20 -0
  519. package/dist/templates/docs/skeletons/threat-model-stride.md.ejs +22 -0
  520. package/dist/templates/docs/specs/atomic-task-list.md.ejs +57 -0
  521. package/dist/templates/docs/steering/product.md.ejs +44 -0
  522. package/dist/templates/docs/steering/structure.md.ejs +49 -0
  523. package/dist/templates/docs/steering/tech.md.ejs +53 -0
  524. package/dist/templates/documentation/cli-catalog.md.ejs +21 -0
  525. package/dist/templates/e2e/E2E_CONSTITUTION.md.ejs +77 -0
  526. package/dist/templates/e2e/playwright-python/conftest.py.ejs +22 -0
  527. package/dist/templates/e2e/playwright-python/run_axe.py.ejs +99 -0
  528. package/dist/templates/e2e/playwright-python/test_a11y.py.ejs +38 -0
  529. package/dist/templates/e2e/playwright-python/test_smoke.py.ejs +28 -0
  530. package/dist/templates/e2e/playwright-ts/a11y.spec.ts.ejs +20 -0
  531. package/dist/templates/e2e/playwright-ts/render-smoke.spec.ts.ejs +90 -0
  532. package/dist/templates/e2e/playwright-ts/run-axe.ts.ejs +74 -0
  533. package/dist/templates/e2e/smoke-journeys/journeys.spec.ts.ejs +53 -0
  534. package/dist/templates/evidence-files.json.ejs +13 -0
  535. package/dist/templates/frontend/FE_DESIGN_PRINCIPLES.md.ejs +115 -0
  536. package/dist/templates/frontend/FRONTEND_CONSTITUTION.md.ejs +170 -0
  537. package/dist/templates/frontend/design-tokens.json.ejs +107 -0
  538. package/dist/templates/frontend/vrt-setup.md.ejs +83 -0
  539. package/dist/templates/githooks/commit-msg.ejs +60 -0
  540. package/dist/templates/githooks/pre-commit.ejs +95 -0
  541. package/dist/templates/githooks/pre-push.ejs +251 -0
  542. package/dist/templates/githooks/setup-hooks.sh.ejs +8 -0
  543. package/dist/templates/github/PULL_REQUEST_TEMPLATE.md +37 -0
  544. package/dist/templates/github/PULL_REQUEST_TEMPLATE.md.ejs +52 -0
  545. package/dist/templates/github/actions/build-cache/action.yml.ejs +84 -0
  546. package/dist/templates/github/actions/nas-ssh/action.yml.ejs +53 -0
  547. package/dist/templates/github/actions/setup-java-maven/action.yml.ejs +53 -0
  548. package/dist/templates/github/actions/setup-node-pnpm/action.yml.ejs +39 -0
  549. package/dist/templates/github/actions/sign-and-attest/action.yml.ejs +53 -0
  550. package/dist/templates/github/dependabot.yml.ejs +66 -0
  551. package/dist/templates/github/extended-ci-paths.txt.ejs +38 -0
  552. package/dist/templates/github/issue-templates/bug-report.yml +72 -0
  553. package/dist/templates/github/issue-templates/compliance-item.yml.ejs +75 -0
  554. package/dist/templates/github/issue-templates/config.yml +2 -0
  555. package/dist/templates/github/issue-templates/epic.yml +66 -0
  556. package/dist/templates/github/issue-templates/feature-request.yml +24 -0
  557. package/dist/templates/github/issue-templates/task-brief.yml.ejs +125 -0
  558. package/dist/templates/github/labels.yml.ejs +161 -0
  559. package/dist/templates/github/scripts/sticky-failure-issue.sh.ejs +61 -0
  560. package/dist/templates/github/workflows/01-pr-fast.yml.ejs +1089 -0
  561. package/dist/templates/github/workflows/02-pr-extended.yml.ejs +512 -0
  562. package/dist/templates/github/workflows/03-human-approval.yml.ejs +76 -0
  563. package/dist/templates/github/workflows/04-deploy-test.yml.ejs +425 -0
  564. package/dist/templates/github/workflows/05-release.yml.ejs +813 -0
  565. package/dist/templates/github/workflows/06-nightly-lite.yml.ejs +125 -0
  566. package/dist/templates/github/workflows/06-nightly.yml.ejs +25 -0
  567. package/dist/templates/github/workflows/07-weekly-lite.yml.ejs +221 -0
  568. package/dist/templates/github/workflows/07-weekly.yml.ejs +23 -0
  569. package/dist/templates/github/workflows/08-monthly.yml.ejs +23 -0
  570. package/dist/templates/github/workflows/09-heartbeat.yml.ejs +268 -0
  571. package/dist/templates/github/workflows/10-deploy-prod.yml.ejs +144 -0
  572. package/dist/templates/github/workflows/11-k6-on-demand.yml.ejs +43 -0
  573. package/dist/templates/github/workflows/12-mutation-scheduled.yml.ejs +100 -0
  574. package/dist/templates/github/workflows/13-archunit-extended.yml.ejs +33 -0
  575. package/dist/templates/github/workflows/14-license-scan.yml.ejs +45 -0
  576. package/dist/templates/github/workflows/15-codeql.yml.ejs +117 -0
  577. package/dist/templates/github/workflows/16-frontend-quality.yml.ejs +154 -0
  578. package/dist/templates/github/workflows/17-ossf-scorecard.yml.ejs +46 -0
  579. package/dist/templates/github/workflows/18-frontend-lane.yml.ejs +50 -0
  580. package/dist/templates/github/workflows/_ai-draft-check.yml.ejs +44 -0
  581. package/dist/templates/github/workflows/_contract-postman.yml.ejs +93 -0
  582. package/dist/templates/github/workflows/_cosign-copy/aws-ecs.ejs +90 -0
  583. package/dist/templates/github/workflows/_cosign-copy/azure-container-app.ejs +97 -0
  584. package/dist/templates/github/workflows/_cosign-copy/gcp-cloud-run.ejs +102 -0
  585. package/dist/templates/github/workflows/_cosign-copy/ghcr.ejs +76 -0
  586. package/dist/templates/github/workflows/_cosign-copy/nas-compose.ejs +69 -0
  587. package/dist/templates/github/workflows/_deploy/aws-ecs.ejs +78 -0
  588. package/dist/templates/github/workflows/_deploy/azure-container-app.ejs +59 -0
  589. package/dist/templates/github/workflows/_deploy/gcp-cloud-run.ejs +71 -0
  590. package/dist/templates/github/workflows/_deploy/ghcr.ejs +19 -0
  591. package/dist/templates/github/workflows/_deploy/nas-compose.ejs +45 -0
  592. package/dist/templates/github/workflows/_k6-runner.yml.ejs +107 -0
  593. package/dist/templates/github/workflows/_label-on-approve.yml.ejs +44 -0
  594. package/dist/templates/github/workflows/_label-sync.yml.ejs +58 -0
  595. package/dist/templates/github/workflows/_monthly.yml.ejs +343 -0
  596. package/dist/templates/github/workflows/_nightly.yml.ejs +826 -0
  597. package/dist/templates/github/workflows/_notify.yml.ejs +96 -0
  598. package/dist/templates/github/workflows/_partials/macos-keychain-bypass.ejs +6 -0
  599. package/dist/templates/github/workflows/_partials/macos-keychain-restore.ejs +6 -0
  600. package/dist/templates/github/workflows/_partials/scheduled-heavy-jobs.ejs +117 -0
  601. package/dist/templates/github/workflows/_partials/sigstore-preflight.ejs +8 -0
  602. package/dist/templates/github/workflows/_partials/trivy-fs-java.ejs +27 -0
  603. package/dist/templates/github/workflows/_post-merge-notify.yml.ejs +228 -0
  604. package/dist/templates/github/workflows/_pr-staleness.yml.ejs +85 -0
  605. package/dist/templates/github/workflows/_shared-security.yml.ejs +132 -0
  606. package/dist/templates/github/workflows/_sigstore-retry-sign.yml.ejs +102 -0
  607. package/dist/templates/github/workflows/_weekly.yml.ejs +313 -0
  608. package/dist/templates/github/workflows/drift-shadow.yml.ejs +51 -0
  609. package/dist/templates/github/workflows/five-lane/ci.yml.ejs +54 -0
  610. package/dist/templates/github/workflows/five-lane/nightly.yml.ejs +70 -0
  611. package/dist/templates/github/workflows/five-lane/release.yml.ejs +53 -0
  612. package/dist/templates/github/workflows/five-lane/weekly.yml.ejs +72 -0
  613. package/dist/templates/github/workflows/issue-state.yml.ejs +93 -0
  614. package/dist/templates/global-invariants/GLOBAL_INVARIANTS.md.ejs +34 -0
  615. package/dist/templates/governance/RACI.md.ejs +21 -0
  616. package/dist/templates/governance/ci-mental-model.md.ejs +268 -0
  617. package/dist/templates/governance/contract-integrity-policy.md.ejs +116 -0
  618. package/dist/templates/governance/enterprise-compliance-baseline.md.ejs +111 -0
  619. package/dist/templates/governance/evidence-retention.md.ejs +43 -0
  620. package/dist/templates/governance/gdpr-erasure-runbook.md.ejs +165 -0
  621. package/dist/templates/governance/qa-audit-phases.md.ejs +129 -0
  622. package/dist/templates/governance/risk-assessment-template.md.ejs +105 -0
  623. package/dist/templates/governance/risk-register.md.ejs +76 -0
  624. package/dist/templates/governance/solo-dev-exception.md.ejs +96 -0
  625. package/dist/templates/governance/validation-evidence.md.ejs +131 -0
  626. package/dist/templates/infra/azure/containerapp.tpl.yaml.ejs +74 -0
  627. package/dist/templates/infra/nas-compose/deploy.sh.ejs +114 -0
  628. package/dist/templates/integration-testing/AbstractIntegrationTest.java.ejs +36 -0
  629. package/dist/templates/integration-testing/NoH2ArchTest.java.ejs +24 -0
  630. package/dist/templates/integration-testing/conftest.py.ejs +20 -0
  631. package/dist/templates/integration-testing/db_fixture.rs.ejs +48 -0
  632. package/dist/templates/integration-testing/eslint-no-fake-db.json.ejs +19 -0
  633. package/dist/templates/integration-testing/eslint.config.no-fake-db.mjs.ejs +46 -0
  634. package/dist/templates/integration-testing/main_test.go.ejs +53 -0
  635. package/dist/templates/integration-testing/main_test_sqlite.go.ejs +37 -0
  636. package/dist/templates/integration-testing/test-setup.ts.ejs +26 -0
  637. package/dist/templates/integration-testing/testcontainers-deps.gradle.ejs +9 -0
  638. package/dist/templates/java/DeprecationInterceptor.java.ejs +50 -0
  639. package/dist/templates/java/archunit-hexagonal.ejs +69 -0
  640. package/dist/templates/java/modulith/ApplicationModulesTest.java.ejs +21 -0
  641. package/dist/templates/java/modulith/modulith-deps.gradle.ejs +13 -0
  642. package/dist/templates/java/modulith/modulith-maven-setup.md.ejs +21 -0
  643. package/dist/templates/java/pharma/AuditEvent.java.ejs +138 -0
  644. package/dist/templates/java/pharma/AuditMapper.java.ejs +60 -0
  645. package/dist/templates/java/pharma/archunit-pharma.ejs +128 -0
  646. package/dist/templates/kit/GLOBAL_KIT.md.ejs +11 -0
  647. package/dist/templates/kit/dim.md.ejs +33 -0
  648. package/dist/templates/llms-txt.config.json.ejs +22 -0
  649. package/dist/templates/local-wrapper/.env.example.ejs +15 -0
  650. package/dist/templates/local-wrapper/Makefile.ejs +44 -0
  651. package/dist/templates/local-wrapper/run.sh.ejs +5 -0
  652. package/dist/templates/middleware/410-gone-handler.ts.ejs +41 -0
  653. package/dist/templates/middleware/correlation-id.ts.ejs +32 -0
  654. package/dist/templates/middleware/deprecation.ts.ejs +45 -0
  655. package/dist/templates/middleware/error-handler.ts.ejs +73 -0
  656. package/dist/templates/middleware/payload-size-limit.ts.ejs +51 -0
  657. package/dist/templates/mutation/README.md.ejs +67 -0
  658. package/dist/templates/mutation/cargo-mutants.toml.ejs +9 -0
  659. package/dist/templates/mutation/mutmut-config.toml.ejs +7 -0
  660. package/dist/templates/mutation/parse-mutants.mjs.ejs +44 -0
  661. package/dist/templates/mutation/parse-mutmut.py.ejs +44 -0
  662. package/dist/templates/mutation/pitest-l2-setup.md.ejs +66 -0
  663. package/dist/templates/mutation/pitest-maven-setup.md.ejs +64 -0
  664. package/dist/templates/mutation/pitest.gradle.ejs +23 -0
  665. package/dist/templates/mutation/stryker.conf.json.ejs +17 -0
  666. package/dist/templates/observability/setup.md.ejs +495 -0
  667. package/dist/templates/operations/handbook.md.ejs +217 -0
  668. package/dist/templates/perf/bundle-budget.json.ejs +29 -0
  669. package/dist/templates/perf/k6/reports/csv-report.py.ejs +91 -0
  670. package/dist/templates/perf/k6/reports/html-report.py.ejs +114 -0
  671. package/dist/templates/perf/k6/reports/json-report.py.ejs +74 -0
  672. package/dist/templates/perf/k6/scenarios/breakpoint.js.ejs +26 -0
  673. package/dist/templates/perf/k6/scenarios/burst.js.ejs +43 -0
  674. package/dist/templates/perf/k6/scenarios/endurance.js.ejs +36 -0
  675. package/dist/templates/perf/k6/scenarios/load.js.ejs +26 -0
  676. package/dist/templates/perf/k6/scenarios/ramp-down.js.ejs +29 -0
  677. package/dist/templates/perf/k6/scenarios/ramp-up.js.ejs +32 -0
  678. package/dist/templates/perf/k6/scenarios/smoke.js.ejs +23 -0
  679. package/dist/templates/perf/k6/scenarios/soak.js.ejs +26 -0
  680. package/dist/templates/perf/k6/scenarios/spike.js.ejs +29 -0
  681. package/dist/templates/perf/k6/scenarios/steady-state.js.ejs +31 -0
  682. package/dist/templates/perf/k6/scenarios/stress.js.ejs +29 -0
  683. package/dist/templates/perf/k6/scenarios/volume.js.ejs +36 -0
  684. package/dist/templates/perf/k6/seed/test-data.sql.ejs +59 -0
  685. package/dist/templates/perf/lighthouserc.json.ejs +41 -0
  686. package/dist/templates/quality/iso9001/CAPA_LOG.md.ejs +36 -0
  687. package/dist/templates/quality/iso9001/DOCUMENT_CONTROL.md.ejs +36 -0
  688. package/dist/templates/quality/iso9001/REQUIREMENTS_TRACEABILITY.md.ejs +61 -0
  689. package/dist/templates/regulated/overlay.json.ejs +26 -0
  690. package/dist/templates/regulated/regulated-overlay.md.ejs +40 -0
  691. package/dist/templates/resilience/RESILIENCE.md.ejs +310 -0
  692. package/dist/templates/root/.gitignore.ejs +85 -0
  693. package/dist/templates/root/CODEOWNERS.ejs +18 -0
  694. package/dist/templates/root/CONTRIBUTING.md.ejs +62 -0
  695. package/dist/templates/root/SECURITY.md.ejs +19 -0
  696. package/dist/templates/root/TEST_TAXONOMY.md.ejs +100 -0
  697. package/dist/templates/root/commitlint.config.js.ejs +4 -0
  698. package/dist/templates/root/docs/METHOD/CANONICAL_PATHS.md.ejs +24 -0
  699. package/dist/templates/root/docs/METHOD/ENGINEERING_DEFAULTS.md.ejs +136 -0
  700. package/dist/templates/root/docs/METHOD/KNOWLEDGE_MAP.md.ejs +90 -0
  701. package/dist/templates/root/docs/METHOD/PATTERNS_CATALOG.md.ejs +51 -0
  702. package/dist/templates/root/docs/METHOD/REUSE_REGISTRY.md.ejs +26 -0
  703. package/dist/templates/root/docs/METHOD/REUSE_REGISTRY_SPEC.md.ejs +80 -0
  704. package/dist/templates/root/docs/METHOD/SSOT_CORE_SET.md.ejs +62 -0
  705. package/dist/templates/root/docs/METHOD/TRACK_ROUTER.md.ejs +39 -0
  706. package/dist/templates/root/docs/SYSTEM/CANON.md.ejs +359 -0
  707. package/dist/templates/root/docs/SYSTEM/FAIL_CLOSED.md.ejs +171 -0
  708. package/dist/templates/root/editorconfig.ejs +39 -0
  709. package/dist/templates/root/tsconfig.json.ejs +21 -0
  710. package/dist/templates/rust/clippy.toml.ejs +14 -0
  711. package/dist/templates/schemas/milestone.schema.json.ejs +164 -0
  712. package/dist/templates/schemas/rtm-verdict.schema.json.ejs +52 -0
  713. package/dist/templates/schemas/source-record.schema.json.ejs +91 -0
  714. package/dist/templates/schemas/tabletop-evidence.schema.json.ejs +53 -0
  715. package/dist/templates/schemas/use-case.schema.json.ejs +59 -0
  716. package/dist/templates/scripts/apply-branch-protection.mjs.ejs +70 -0
  717. package/dist/templates/scripts/audit-toolchain.mjs.ejs +112 -0
  718. package/dist/templates/scripts/bg-run.sh.ejs +59 -0
  719. package/dist/templates/scripts/capacity-probe.mjs.ejs +147 -0
  720. package/dist/templates/scripts/capture-debt-baseline.mjs.ejs +99 -0
  721. package/dist/templates/scripts/check-acceptance.mjs.ejs +298 -0
  722. package/dist/templates/scripts/check-action-pins.mjs.ejs +215 -0
  723. package/dist/templates/scripts/check-agent-return.mjs.ejs +177 -0
  724. package/dist/templates/scripts/check-all.mjs.ejs +1746 -0
  725. package/dist/templates/scripts/check-anti-fake-green.mjs.ejs +80 -0
  726. package/dist/templates/scripts/check-anti-proforma.mjs.ejs +547 -0
  727. package/dist/templates/scripts/check-api-e2e.mjs.ejs +106 -0
  728. package/dist/templates/scripts/check-arc42-slots.mjs.ejs +25 -0
  729. package/dist/templates/scripts/check-assertion-delta.mjs.ejs +287 -0
  730. package/dist/templates/scripts/check-audit-dry-pass.mjs.ejs +176 -0
  731. package/dist/templates/scripts/check-bundle-size.mjs.ejs +151 -0
  732. package/dist/templates/scripts/check-canonical-paths.mjs.ejs +39 -0
  733. package/dist/templates/scripts/check-ci-tiers.mjs.ejs +111 -0
  734. package/dist/templates/scripts/check-claude-md-lint.mjs.ejs +142 -0
  735. package/dist/templates/scripts/check-collab-mode-wired.mjs.ejs +60 -0
  736. package/dist/templates/scripts/check-commit-footer-rationale.mjs.ejs +170 -0
  737. package/dist/templates/scripts/check-constraint-scan.mjs.ejs +681 -0
  738. package/dist/templates/scripts/check-consumer-audit.mjs.ejs +414 -0
  739. package/dist/templates/scripts/check-continue-on-error.mjs.ejs +227 -0
  740. package/dist/templates/scripts/check-cross-model-review.mjs.ejs +458 -0
  741. package/dist/templates/scripts/check-decision-registry.mjs.ejs +101 -0
  742. package/dist/templates/scripts/check-doc-freshness.mjs.ejs +17 -0
  743. package/dist/templates/scripts/check-doc-links.mjs.ejs +98 -0
  744. package/dist/templates/scripts/check-doc-set.mjs.ejs +18 -0
  745. package/dist/templates/scripts/check-docs.mjs.ejs +71 -0
  746. package/dist/templates/scripts/check-domain-api-surface.mjs.ejs +80 -0
  747. package/dist/templates/scripts/check-drift.mjs.ejs +167 -0
  748. package/dist/templates/scripts/check-duplication.mjs.ejs +45 -0
  749. package/dist/templates/scripts/check-e2e-escalation.mjs.ejs +199 -0
  750. package/dist/templates/scripts/check-e2e-quarantine.mjs.ejs +68 -0
  751. package/dist/templates/scripts/check-emission-parity.mjs.ejs +91 -0
  752. package/dist/templates/scripts/check-exit-code-contract.mjs.ejs +138 -0
  753. package/dist/templates/scripts/check-fail-closed-audit.mjs.ejs +389 -0
  754. package/dist/templates/scripts/check-fe-boundaries.mjs.ejs +184 -0
  755. package/dist/templates/scripts/check-feature-matrix.mjs.ejs +835 -0
  756. package/dist/templates/scripts/check-frontend-lane.mjs.ejs +73 -0
  757. package/dist/templates/scripts/check-grace-window.mjs.ejs +102 -0
  758. package/dist/templates/scripts/check-handoff-doc.mjs.ejs +192 -0
  759. package/dist/templates/scripts/check-hook-routing.mjs.ejs +224 -0
  760. package/dist/templates/scripts/check-image-pins.mjs.ejs +90 -0
  761. package/dist/templates/scripts/check-inline-suppressions.mjs.ejs +153 -0
  762. package/dist/templates/scripts/check-iso9001.mjs.ejs +146 -0
  763. package/dist/templates/scripts/check-knowledge-map.mjs.ejs +49 -0
  764. package/dist/templates/scripts/check-local-ci-parity.mjs.ejs +382 -0
  765. package/dist/templates/scripts/check-m16-handoff.mjs.ejs +112 -0
  766. package/dist/templates/scripts/check-merge-method.mjs.ejs +92 -0
  767. package/dist/templates/scripts/check-milestones.mjs.ejs +678 -0
  768. package/dist/templates/scripts/check-min-test-execution.mjs.ejs +225 -0
  769. package/dist/templates/scripts/check-muted-test.mjs.ejs +270 -0
  770. package/dist/templates/scripts/check-no-stub-redirects.mjs.ejs +154 -0
  771. package/dist/templates/scripts/check-no-tracked-artifacts.mjs.ejs +134 -0
  772. package/dist/templates/scripts/check-oracle-discrimination.mjs.ejs +244 -0
  773. package/dist/templates/scripts/check-pii-scan.mjs.ejs +67 -0
  774. package/dist/templates/scripts/check-pipe-tee-hazard.mjs.ejs +85 -0
  775. package/dist/templates/scripts/check-pr-size-gate.mjs.ejs +85 -0
  776. package/dist/templates/scripts/check-refutation-verdicts.mjs.ejs +256 -0
  777. package/dist/templates/scripts/check-regulated-overlay.mjs.ejs +158 -0
  778. package/dist/templates/scripts/check-render-smoke.mjs.ejs +100 -0
  779. package/dist/templates/scripts/check-reuse-registry.mjs.ejs +44 -0
  780. package/dist/templates/scripts/check-review-completion.mjs.ejs +708 -0
  781. package/dist/templates/scripts/check-safety-adopt-ratchet.mjs.ejs +142 -0
  782. package/dist/templates/scripts/check-secret-presence.mjs.ejs +191 -0
  783. package/dist/templates/scripts/check-secret-scan.mjs.ejs +82 -0
  784. package/dist/templates/scripts/check-skip-critical-e2e.mjs.ejs +142 -0
  785. package/dist/templates/scripts/check-smoke-journeys.mjs.ejs +272 -0
  786. package/dist/templates/scripts/check-solo-reactivation.mjs.ejs +102 -0
  787. package/dist/templates/scripts/check-sources.mjs.ejs +245 -0
  788. package/dist/templates/scripts/check-ssot-core.mjs.ejs +45 -0
  789. package/dist/templates/scripts/check-stack-conformity.mjs.ejs +160 -0
  790. package/dist/templates/scripts/check-stride-traceability.mjs.ejs +101 -0
  791. package/dist/templates/scripts/check-suppression-expiry.mjs.ejs +79 -0
  792. package/dist/templates/scripts/check-suppression-rationale.mjs.ejs +76 -0
  793. package/dist/templates/scripts/check-suppressions.mjs.ejs +150 -0
  794. package/dist/templates/scripts/check-tabletop-evidence.mjs.ejs +499 -0
  795. package/dist/templates/scripts/check-tdd-evidence.mjs.ejs +381 -0
  796. package/dist/templates/scripts/check-test-naming.mjs.ejs +151 -0
  797. package/dist/templates/scripts/check-test-pyramid.mjs.ejs +170 -0
  798. package/dist/templates/scripts/check-test-scope-tier.mjs.ejs +208 -0
  799. package/dist/templates/scripts/check-tier-coverage.mjs.ejs +71 -0
  800. package/dist/templates/scripts/check-todo-max-age.mjs.ejs +205 -0
  801. package/dist/templates/scripts/check-touched-vs-manifest.mjs.ejs +179 -0
  802. package/dist/templates/scripts/check-unwired-guards.mjs.ejs +367 -0
  803. package/dist/templates/scripts/check-use-cases.mjs.ejs +345 -0
  804. package/dist/templates/scripts/check-validator-helptext.mjs.ejs +80 -0
  805. package/dist/templates/scripts/check-wiki-lint.mjs.ejs +162 -0
  806. package/dist/templates/scripts/check-workflow-docs-sync.mjs.ejs +91 -0
  807. package/dist/templates/scripts/check-workflow-job-naming.mjs.ejs +102 -0
  808. package/dist/templates/scripts/check-workflow-perms.mjs.ejs +54 -0
  809. package/dist/templates/scripts/check-workflow-runners.mjs.ejs +87 -0
  810. package/dist/templates/scripts/check-workflow-sha-pinning.mjs.ejs +89 -0
  811. package/dist/templates/scripts/check-workflow-test-integrity.mjs.ejs +235 -0
  812. package/dist/templates/scripts/checks/check-rust-no-unsafe.mjs.ejs +58 -0
  813. package/dist/templates/scripts/checks/check-rust-no-unwrap.mjs.ejs +61 -0
  814. package/dist/templates/scripts/ci-classify-changes.mjs.ejs +119 -0
  815. package/dist/templates/scripts/conformance.mjs.ejs +37 -0
  816. package/dist/templates/scripts/constraint-map.json.ejs +25 -0
  817. package/dist/templates/scripts/debt-lib.mjs.ejs +1015 -0
  818. package/dist/templates/scripts/debt-report.mjs.ejs +199 -0
  819. package/dist/templates/scripts/domain-api-surface.json.ejs +23 -0
  820. package/dist/templates/scripts/done-evidence.mjs.ejs +359 -0
  821. package/dist/templates/scripts/evidence-collect.mjs.ejs +264 -0
  822. package/dist/templates/scripts/evidence-prune.mjs.ejs +96 -0
  823. package/dist/templates/scripts/evidence-rotate.mjs.ejs +53 -0
  824. package/dist/templates/scripts/evidence-writer.sh.ejs +220 -0
  825. package/dist/templates/scripts/gate-registry.yml.ejs +286 -0
  826. package/dist/templates/scripts/gen-doc-index.mjs.ejs +19 -0
  827. package/dist/templates/scripts/gen-gap.mjs.ejs +153 -0
  828. package/dist/templates/scripts/gen-llms-txt.mjs.ejs +18 -0
  829. package/dist/templates/scripts/gen-wiki.mjs.ejs +196 -0
  830. package/dist/templates/scripts/gh-cleanup-expired-artifacts.mjs.ejs +134 -0
  831. package/dist/templates/scripts/gold-audit.mjs.ejs +19 -0
  832. package/dist/templates/scripts/i18n-literal-scanner.mjs.ejs +175 -0
  833. package/dist/templates/scripts/ingest-zap-report.mjs.ejs +107 -0
  834. package/dist/templates/scripts/inject-pact-samples.sh.ejs +96 -0
  835. package/dist/templates/scripts/issue-readiness.mjs.ejs +84 -0
  836. package/dist/templates/scripts/knowledge-map-update.mjs.ejs +32 -0
  837. package/dist/templates/scripts/lib/acceptance-criteria.mjs.ejs +213 -0
  838. package/dist/templates/scripts/lib/agent-return-validate.mjs.ejs +481 -0
  839. package/dist/templates/scripts/lib/coverage-gate.mjs.ejs +54 -0
  840. package/dist/templates/scripts/lib/e2e-reliability.mjs.ejs +207 -0
  841. package/dist/templates/scripts/lib/ephemeral-server.mjs.ejs +148 -0
  842. package/dist/templates/scripts/lib/evidence-binding.mjs.ejs +140 -0
  843. package/dist/templates/scripts/lib/exact-sha-policy.mjs.ejs +233 -0
  844. package/dist/templates/scripts/lib/gate-args.mjs.ejs +20 -0
  845. package/dist/templates/scripts/lib/gate-evidence.mjs.ejs +622 -0
  846. package/dist/templates/scripts/lib/gate-mutex.mjs.ejs +340 -0
  847. package/dist/templates/scripts/lib/glob-walk.mjs.ejs +148 -0
  848. package/dist/templates/scripts/lib/run-helpers.mjs.ejs +416 -0
  849. package/dist/templates/scripts/lib/seed-common.sh.ejs +105 -0
  850. package/dist/templates/scripts/lib/waiter-count.mjs.ejs +62 -0
  851. package/dist/templates/scripts/muted-tests-baseline.json.ejs +4 -0
  852. package/dist/templates/scripts/optional-emissions.json.ejs +117 -0
  853. package/dist/templates/scripts/oracle-discrimination-baseline.json.ejs +6 -0
  854. package/dist/templates/scripts/pid-watch.sh.ejs +78 -0
  855. package/dist/templates/scripts/pii-scan.mjs.ejs +125 -0
  856. package/dist/templates/scripts/pr-merge-watch.mjs.ejs +445 -0
  857. package/dist/templates/scripts/record-agent-return.mjs.ejs +279 -0
  858. package/dist/templates/scripts/record-journey-evidence.mjs.ejs +69 -0
  859. package/dist/templates/scripts/rework-log.mjs.ejs +172 -0
  860. package/dist/templates/scripts/run-postman-tests.sh.ejs +112 -0
  861. package/dist/templates/scripts/schemas/agent-return-external.schema.json +74 -0
  862. package/dist/templates/scripts/schemas/agent-return.schema.json.ejs +181 -0
  863. package/dist/templates/scripts/schemas/cross-model-dispatch.schema.json +95 -0
  864. package/dist/templates/scripts/seed-test-data.sh.ejs +99 -0
  865. package/dist/templates/scripts/self-validation.mjs.ejs +126 -0
  866. package/dist/templates/scripts/setup-repo.sh.ejs +78 -0
  867. package/dist/templates/scripts/spotbugs-baseline.json.ejs +4 -0
  868. package/dist/templates/scripts/test-gate-layering.mjs.ejs +92 -0
  869. package/dist/templates/scripts/validate-api-snapshots.mjs.ejs +86 -0
  870. package/dist/templates/scripts/validate-k6-scenarios.mjs.ejs +96 -0
  871. package/dist/templates/scripts/validate-openapi-field-types.mjs.ejs +124 -0
  872. package/dist/templates/scripts/validate-postman-collection.mjs.ejs +159 -0
  873. package/dist/templates/scripts/verify-fe-coverage.mjs.ejs +138 -0
  874. package/dist/templates/scripts/verify-i18n-parity.mjs.ejs +114 -0
  875. package/dist/templates/scripts/verify-module-coverage.mjs.ejs +207 -0
  876. package/dist/templates/scripts/verify-mutation-baseline.mjs.ejs +209 -0
  877. package/dist/templates/scripts/verify-spotbugs.mjs.ejs +216 -0
  878. package/dist/templates/scripts/verify-tokens.mjs.ejs +177 -0
  879. package/dist/templates/security/RISK_ASSESSMENT.md.ejs +35 -0
  880. package/dist/templates/security/STRIDE.md.ejs +24 -0
  881. package/dist/templates/security/gitleaks.toml.ejs +21 -0
  882. package/dist/templates/security/zap/baseline-auth.context.ejs +58 -0
  883. package/dist/templates/security/zap/rules.tsv.ejs +100 -0
  884. package/dist/templates/ship/TICK_PROMPT.md.ejs +55 -0
  885. package/dist/templates/ship/supervisor.sh.ejs +46 -0
  886. package/dist/templates/smoke-journeys/manifest.json.ejs +1 -0
  887. package/dist/templates/sonar-project.properties.ejs +25 -0
  888. package/dist/templates/standards/doc-profile.ejs +27 -0
  889. package/dist/templates/standards/gold-doc-set.yml.ejs +528 -0
  890. package/dist/templates/standards/gold-registry.java.yml.ejs +266 -0
  891. package/dist/templates/standards/gold-registry.typescript.yml.ejs +104 -0
  892. package/dist/templates/standards/gold-registry.yml.ejs +119 -0
  893. package/dist/templates/standards/thresholds.yml.ejs +86 -0
  894. package/dist/templates/static-analysis/.dependency-cruiser.cjs.ejs +78 -0
  895. package/dist/templates/static-analysis/.golangci.yml.ejs +70 -0
  896. package/dist/templates/static-analysis/.shellcheckrc.ejs +13 -0
  897. package/dist/templates/static-analysis/.yamllint.yml.ejs +41 -0
  898. package/dist/templates/static-analysis/checkstyle.xml.ejs +83 -0
  899. package/dist/templates/static-analysis/detekt.yml.ejs +26 -0
  900. package/dist/templates/static-analysis/eslint.config.mjs.ejs +54 -0
  901. package/dist/templates/static-analysis/eslint.config.static.mjs.ejs +38 -0
  902. package/dist/templates/static-analysis/eslintrc-static.json.ejs +30 -0
  903. package/dist/templates/static-analysis/jscpd.json.ejs +25 -0
  904. package/dist/templates/static-analysis/knip.json.ejs +26 -0
  905. package/dist/templates/static-analysis/pmd-ruleset.xml.ejs +92 -0
  906. package/dist/templates/static-analysis/prettierignore.ejs +59 -0
  907. package/dist/templates/static-analysis/prettierrc.json.ejs +10 -0
  908. package/dist/templates/static-analysis/requirements-dev.txt.ejs +11 -0
  909. package/dist/templates/static-analysis/ruff.toml.ejs +40 -0
  910. package/dist/templates/static-analysis/rustfmt.toml.ejs +3 -0
  911. package/dist/templates/static-analysis/spotbugs-exclude.xml.ejs +120 -0
  912. package/dist/templates/static-analysis/spotbugs.gradle.ejs +18 -0
  913. package/dist/templates/static-analysis/spotless.gradle.ejs +38 -0
  914. package/dist/templates/static-analysis/stylelintrc.json.ejs +16 -0
  915. package/dist/templates/suppressions/archunit-baseline.json.ejs +1 -0
  916. package/dist/templates/suppressions/consumer-audit-allowlist.json.ejs +1 -0
  917. package/dist/templates/suppressions/gitleaksignore.ejs +20 -0
  918. package/dist/templates/suppressions/pii-allowlist.json.ejs +1 -0
  919. package/dist/templates/suppressions/suppressions-schema.json.ejs +39 -0
  920. package/dist/templates/suppressions/trivyignore.ejs +17 -0
  921. package/dist/templates/testing/test-taxonomy.md.ejs +120 -0
  922. package/dist/test/example.behavioral.test.js +2 -0
  923. package/dist/types/memory.d.ts +19 -0
  924. package/dist/types/memory.js +1 -0
  925. package/dist/types/plan.d.ts +102 -0
  926. package/dist/types/plan.js +2 -0
  927. package/dist/types/plugin.d.ts +45 -0
  928. package/dist/types/plugin.js +1 -0
  929. package/dist/utils/canon-loader.js +2 -0
  930. package/dist/utils/channel.js +1 -0
  931. package/dist/utils/config.d.ts +79 -0
  932. package/dist/utils/config.js +5 -0
  933. package/dist/utils/confirm-downgrade.js +5 -0
  934. package/dist/utils/env.js +2 -0
  935. package/dist/utils/error-catalog.js +2 -0
  936. package/dist/utils/errors.js +2 -0
  937. package/dist/utils/evidence-log.js +3 -0
  938. package/dist/utils/file-lock.js +2 -0
  939. package/dist/utils/first-run.js +8 -0
  940. package/dist/utils/fs.js +3 -0
  941. package/dist/utils/github-issue-helper.js +4 -0
  942. package/dist/utils/gradle.js +21 -0
  943. package/dist/utils/json-output.js +2 -0
  944. package/dist/utils/logger-config.js +4 -0
  945. package/dist/utils/logger.js +3 -0
  946. package/dist/utils/maturity-check.js +2 -0
  947. package/dist/utils/pkg.js +3 -0
  948. package/dist/utils/platform.js +2 -0
  949. package/dist/utils/plugin-loader.js +2 -0
  950. package/dist/utils/plugin-worker.js +2 -0
  951. package/dist/utils/prettier-format.js +2 -0
  952. package/dist/utils/profiler.js +2 -0
  953. package/dist/utils/render.js +2 -0
  954. package/dist/utils/replay.js +3 -0
  955. package/dist/utils/run-cli.js +6 -0
  956. package/dist/utils/run-id.js +3 -0
  957. package/dist/utils/safe-read.js +2 -0
  958. package/dist/utils/task-id.js +2 -0
  959. package/dist/utils/today.js +2 -0
  960. package/dist/utils/tty.js +2 -0
  961. package/dist/utils/walk-dir.js +2 -0
  962. package/dist/verify/rules/drive-by-scope.js +1 -0
  963. package/dist/verify/rules/orphan-todos.js +1 -0
  964. package/dist/verify/rules/registry.js +1 -0
  965. package/dist/verify/rules/skip-patterns.js +1 -0
  966. package/dist/verify/rules/types.d.ts +15 -0
  967. package/dist/verify/rules/types.js +1 -0
  968. package/dist/verify/rules/ui-language.js +1 -0
  969. package/dist/verify/run.js +3 -0
  970. package/dist/wizard/archetype-defaults.js +1 -0
  971. package/dist/wizard/presets.js +1 -0
  972. package/dist/wizard/prompts.js +44 -0
  973. package/dist/wizard/types.d.ts +637 -0
  974. package/dist/wizard/types.js +1 -0
  975. package/dist/worktree/harvest.js +2 -0
  976. package/dist/worktree/links.js +2 -0
  977. package/dist/worktree/paths.js +2 -0
  978. package/dist/worktree/validate.js +3 -0
  979. package/package.json +124 -0
  980. package/scripts/check-arc42-slots.mjs +738 -0
  981. package/scripts/check-doc-freshness.mjs +236 -0
  982. package/scripts/check-doc-set.mjs +243 -0
  983. package/scripts/check-doc-style.mjs +228 -0
  984. package/scripts/gold-audit.mjs +319 -0
  985. package/scripts/lib/doc-gate-allowlist.mjs +123 -0
  986. package/scripts/lib/doc-set-resolve.mjs +274 -0
  987. package/scripts/lib/glob-walk.mjs +148 -0
  988. package/scripts/lib/gold-audit-lib.mjs +1260 -0
  989. package/scripts/lib/run-helpers.mjs +413 -0
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{resolveEffectiveThresholds}from"../config/thresholds.js";import{resolveCollaborationMode}from"../config/collaboration-mode-defaults.js";import{isSubtreeFrontendLane}from"../detectors/lanes.js";import{levelAtLeast,LEVEL_ORDER}from"../config/levels.js";import{parse as parseYaml}from"yaml";const VALID_LEVELS=new Set(["L1","L2","L3"]),VALID_KINDS=new Set(["check","warn","tool","inline"]);function deriveGateRegistryRenderData(data){const fe=data.frontend?.framework??"react",feGlob=fe==="vue"?"src/**/*.{ts,vue}":fe==="svelte"?"src/**/*.{ts,svelte}":"src/**/*.{ts,tsx,jsx}",govLevel=data.governanceLevel,isL3Plus=typeof govLevel=="string"&&LEVEL_ORDER.includes(govLevel)&&levelAtLeast(govLevel,"L3");return{...data,packageManager:data.packageManager??"npm",ratchetFlag:isL3Plus?"--require-improvement":"--gate",_feGlob:feGlob}}function parseGateRegistryYaml(rendered){let parsed;try{parsed=parseYaml(rendered)}catch(err){throw new Error(`gate registry: invalid YAML in gate-registry.yml.ejs \u2014 ${err instanceof Error?err.message:String(err)}`,{cause:err})}const raw=parsed?.gates;if(!Array.isArray(raw))throw new Error('gate registry: missing "gates" array');return raw}function validateGateEntryShape(entry,seen){const id=entry.id;if(typeof id!="string"||id.length===0)throw new Error("gate registry: every gate needs a string id");if(seen.has(id))throw new Error(`gate registry: duplicate gate id "${id}"`);seen.add(id);const level=entry.level;if(typeof level!="string"||!VALID_LEVELS.has(level))throw new Error(`gate registry: gate "${id}" has invalid level ${String(level)}`);const kind=entry.kind;if(typeof kind!="string"||!VALID_KINDS.has(kind))throw new Error(`gate registry: gate "${id}" has invalid kind ${String(kind)}`);if(kind!=="inline"&&!Array.isArray(entry.cmd))throw new Error(`gate registry: non-inline gate "${id}" needs a cmd array`);if(kind==="inline"&&entry.cmd!==void 0)throw new Error(`gate registry: inline gate "${id}" must not declare cmd (bodies live in the template)`);return{id,level,kind}}function flattenGateCmd(entry){const rawCmd=entry.cmd;if(rawCmd!==void 0)return[String(rawCmd[0]),...(rawCmd[1]??[]).map(String)]}function normalizeGateEntry(entry,seen){const{id,level,kind}=validateGateEntryShape(entry,seen),flatCmd=flattenGateCmd(entry);return{id,name:String(entry.name),level,kind,...flatCmd!==void 0?{cmd:flatCmd}:{},...typeof entry.language=="string"?{language:entry.language}:{},...typeof entry.emitIf=="string"?{emitIf:entry.emitIf}:{},...typeof entry.condition=="string"?{condition:entry.condition}:{},...typeof entry.else=="string"?{else:entry.else}:{},...entry.soft===!0?{soft:!0}:{},...typeof entry.promotes_to=="string"?{promotes_to:entry.promotes_to}:{},...entry.audit===!0?{audit:!0}:{}}}export function validatePromotions(entries){const ids=new Set(entries.map(e=>e.id));for(const entry of entries)if(entry.promotes_to!==void 0){if(!ids.has(entry.promotes_to))throw new Error(`gate registry: gate "${entry.id}" promotes_to unknown gate id "${entry.promotes_to}"`);if(entry.condition!==void 0||entry.else!==void 0)throw new Error(`gate registry: gate "${entry.id}" declares promotes_to and a runtime condition/else \u2014 a false condition would suppress both gates silently`);if(entry.kind==="inline")throw new Error(`gate registry: gate "${entry.id}" declares promotes_to and kind: inline \u2014 an inline gate with no matching template branch would suppress both gates silently`)}}export function loadGateRegistry(data){const registryData=deriveGateRegistryRenderData(data),rendered=renderTemplate("scripts/gate-registry.yml.ejs",registryData),raw=parseGateRegistryYaml(rendered),seen=new Set,entries=raw.map(entry=>normalizeGateEntry(entry,seen));return validatePromotions(entries),entries}function binarySizeBudget(archetype){return archetype==="cli"?10*1048576:archetype==="embedded"?5*1048576:0}function emitCoverageGate(base,data,opts){if(!(data.language==="typescript"&&data.enableDebtGates&&data.coverageEnabled))return[];const coverageGatePath=resolvedPath(base,"scripts","lib","coverage-gate.mjs");return[writeFile(coverageGatePath,renderTemplate("scripts/lib/coverage-gate.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}function emitTemplateFile(base,relPath,template,data,opts){return writeFile(resolvedPath(base,...relPath),renderTemplate(template,data),{skipIfExists:!0,dryRun:opts.dryRun})}const UNCONDITIONAL_EMISSIONS=[{rel:["scripts","check-all.mjs"],tpl:"scripts/check-all.mjs.ejs"},{rel:["scripts","test-gate-layering.mjs"],tpl:"scripts/test-gate-layering.mjs.ejs"},{rel:["scripts","optional-emissions.json"],tpl:"scripts/optional-emissions.json.ejs"},{rel:["scripts","lib","run-helpers.mjs"],tpl:"scripts/lib/run-helpers.mjs.ejs"},{rel:["scripts","lib","gate-evidence.mjs"],tpl:"scripts/lib/gate-evidence.mjs.ejs"},{rel:["scripts","lib","gate-mutex.mjs"],tpl:"scripts/lib/gate-mutex.mjs.ejs"},{rel:["scripts","lib","evidence-binding.mjs"],tpl:"scripts/lib/evidence-binding.mjs.ejs"},{rel:["scripts","check-collab-mode-wired.mjs"],tpl:"scripts/check-collab-mode-wired.mjs.ejs"},{rel:["scripts","check-hook-routing.mjs"],tpl:"scripts/check-hook-routing.mjs.ejs"},{rel:["scripts","check-emission-parity.mjs"],tpl:"scripts/check-emission-parity.mjs.ejs"},{rel:["scripts","check-constraint-scan.mjs"],tpl:"scripts/check-constraint-scan.mjs.ejs"},{rel:["scripts","constraint-map.json"],tpl:"scripts/constraint-map.json.ejs"},{rel:["scripts","check-no-tracked-artifacts.mjs"],tpl:"scripts/check-no-tracked-artifacts.mjs.ejs"},{rel:["scripts","check-image-pins.mjs"],tpl:"scripts/check-image-pins.mjs.ejs"},{rel:["scripts","lib","e2e-reliability.mjs"],tpl:"scripts/lib/e2e-reliability.mjs.ejs"},{rel:["scripts","check-e2e-quarantine.mjs"],tpl:"scripts/check-e2e-quarantine.mjs.ejs"},{rel:["scripts","check-tdd-evidence.mjs"],tpl:"scripts/check-tdd-evidence.mjs.ejs"},{rel:["scripts","check-tabletop-evidence.mjs"],tpl:"scripts/check-tabletop-evidence.mjs.ejs"},{rel:["schemas","tabletop-evidence.schema.json"],tpl:"schemas/tabletop-evidence.schema.json.ejs"},{rel:["scripts","check-sources.mjs"],tpl:"scripts/check-sources.mjs.ejs"},{rel:["schemas","source-record.schema.json"],tpl:"schemas/source-record.schema.json.ejs"},{rel:["scripts","check-use-cases.mjs"],tpl:"scripts/check-use-cases.mjs.ejs"},{rel:["schemas","use-case.schema.json"],tpl:"schemas/use-case.schema.json.ejs"},{rel:["scripts","check-milestones.mjs"],tpl:"scripts/check-milestones.mjs.ejs"},{rel:["schemas","milestone.schema.json"],tpl:"schemas/milestone.schema.json.ejs"},{rel:["scripts","check-todo-max-age.mjs"],tpl:"scripts/check-todo-max-age.mjs.ejs"},{rel:["scripts","check-test-pyramid.mjs"],tpl:"scripts/check-test-pyramid.mjs.ejs"},{rel:["scripts","verify-module-coverage.mjs"],tpl:"scripts/verify-module-coverage.mjs.ejs"},{rel:["scripts","verify-mutation-baseline.mjs"],tpl:"scripts/verify-mutation-baseline.mjs.ejs"},{rel:["scripts","check-api-e2e.mjs"],tpl:"scripts/check-api-e2e.mjs.ejs"},{rel:["scripts","check-render-smoke.mjs"],tpl:"scripts/check-render-smoke.mjs.ejs"},{rel:["scripts","check-smoke-journeys.mjs"],tpl:"scripts/check-smoke-journeys.mjs.ejs"},{rel:["scripts","check-e2e-escalation.mjs"],tpl:"scripts/check-e2e-escalation.mjs.ejs"},{rel:["scripts","check-m16-handoff.mjs"],tpl:"scripts/check-m16-handoff.mjs.ejs"},{rel:["scripts","lib","glob-walk.mjs"],tpl:"scripts/lib/glob-walk.mjs.ejs"},{rel:["scripts","issue-readiness.mjs"],tpl:"scripts/issue-readiness.mjs.ejs"},{rel:["scripts","check-acceptance.mjs"],tpl:"scripts/check-acceptance.mjs.ejs"},{rel:["scripts","rework-log.mjs"],tpl:"scripts/rework-log.mjs.ejs"},{rel:["scripts","lib","acceptance-criteria.mjs"],tpl:"scripts/lib/acceptance-criteria.mjs.ejs"},{rel:["scripts","check-doc-set.mjs"],tpl:"scripts/check-doc-set.mjs.ejs"},{rel:["scripts","check-arc42-slots.mjs"],tpl:"scripts/check-arc42-slots.mjs.ejs"},{rel:["scripts","check-doc-freshness.mjs"],tpl:"scripts/check-doc-freshness.mjs.ejs"},{rel:["scripts","check-anti-fake-green.mjs"],tpl:"scripts/check-anti-fake-green.mjs.ejs"},{rel:["scripts","check-decision-registry.mjs"],tpl:"scripts/check-decision-registry.mjs.ejs"},{rel:["scripts","check-muted-test.mjs"],tpl:"scripts/check-muted-test.mjs.ejs"},{rel:["muted-tests-baseline.json"],tpl:"scripts/muted-tests-baseline.json.ejs"},{rel:["scripts","check-skip-critical-e2e.mjs"],tpl:"scripts/check-skip-critical-e2e.mjs.ejs"},{rel:["scripts","check-no-stub-redirects.mjs"],tpl:"scripts/check-no-stub-redirects.mjs.ejs"},{rel:["scripts","check-grace-window.mjs"],tpl:"scripts/check-grace-window.mjs.ejs"},{rel:["scripts","check-assertion-delta.mjs"],tpl:"scripts/check-assertion-delta.mjs.ejs"},{rel:["scripts","check-safety-adopt-ratchet.mjs"],tpl:"scripts/check-safety-adopt-ratchet.mjs.ejs"},{rel:["scripts","check-touched-vs-manifest.mjs"],tpl:"scripts/check-touched-vs-manifest.mjs.ejs"},{rel:["scripts","record-agent-return.mjs"],tpl:"scripts/record-agent-return.mjs.ejs"},{rel:["scripts","lib","gate-args.mjs"],tpl:"scripts/lib/gate-args.mjs.ejs"},{rel:["scripts","lib","agent-return-validate.mjs"],tpl:"scripts/lib/agent-return-validate.mjs.ejs"},{rel:["schemas","agent-return.schema.json"],tpl:"scripts/schemas/agent-return.schema.json.ejs"},{rel:["schemas","agent-return-external.schema.json"],tpl:"scripts/schemas/agent-return-external.schema.json"},{rel:["scripts","check-cross-model-review.mjs"],tpl:"scripts/check-cross-model-review.mjs.ejs"},{rel:["schemas","cross-model-dispatch.schema.json"],tpl:"scripts/schemas/cross-model-dispatch.schema.json"},{rel:["scripts","gh-cleanup-expired-artifacts.mjs"],tpl:"scripts/gh-cleanup-expired-artifacts.mjs.ejs"}],DEBT_GATED_EMISSIONS=[{rel:["scripts","check-agent-return.mjs"],tpl:"scripts/check-agent-return.mjs.ejs"},{rel:["scripts","check-review-completion.mjs"],tpl:"scripts/check-review-completion.mjs.ejs"},{rel:["scripts","check-refutation-verdicts.mjs"],tpl:"scripts/check-refutation-verdicts.mjs.ejs"},{rel:["scripts","check-audit-dry-pass.mjs"],tpl:"scripts/check-audit-dry-pass.mjs.ejs"},{rel:["scripts","check-handoff-doc.mjs"],tpl:"scripts/check-handoff-doc.mjs.ejs"}];function emitUnconditional(base,data,opts){return UNCONDITIONAL_EMISSIONS.map(({rel,tpl})=>emitTemplateFile(base,rel,tpl,data,opts))}function emitDebtGated(base,data,opts){return data.enableDebtGates!==!0?[]:DEBT_GATED_EMISSIONS.map(({rel,tpl})=>emitTemplateFile(base,rel,tpl,data,opts))}const EXTENDED_GATED_EMISSIONS=[{rel:["scripts","check-reuse-registry.mjs"],tpl:"scripts/check-reuse-registry.mjs.ejs"}];function emitExtendedGated(base,data,opts){return data.includeExtendedInvariants!==!0?[]:EXTENDED_GATED_EMISSIONS.map(({rel,tpl})=>emitTemplateFile(base,rel,tpl,data,opts))}export function generateCheckAll(config,opts={dryRun:!1}){const results=[],base=config.targetDir,effective=resolveEffectiveThresholds(config),data={...config,coverageThreshold:effective.lineCoverage,coverageEnabled:effective.coverageEnabled,mutationEnabled:effective.mutationEnabled,mutationThreshold:effective.mutationScore,binarySizeBytes:binarySizeBudget(config.archetype)};data.gates=loadGateRegistry(data),results.push(...emitUnconditional(base,data,opts)),results.push(...emitDebtGated(base,data,opts)),results.push(...emitExtendedGated(base,data,opts)),results.push(...emitCoverageGate(base,data,opts)),typeof config.governanceLevel=="string"&&LEVEL_ORDER.includes(config.governanceLevel)&&levelAtLeast(config.governanceLevel,"L3")&&results.push(writeFile(resolvedPath(base,"scripts","evidence-collect.mjs"),renderTemplate("scripts/evidence-collect.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));const archetypesNeedingServer=new Set(["frontend-spa","backend-web-db"]);if(config.governanceLevel!=="L1"&&archetypesNeedingServer.has(config.archetype)){const ephemeralPath=resolvedPath(base,"scripts","lib","ephemeral-server.mjs");results.push(writeFile(ephemeralPath,renderTemplate("scripts/lib/ephemeral-server.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}))}return config.language==="rust"&&(results.push(writeFile(resolvedPath(base,"scripts","checks","check-rust-no-unwrap.mjs"),renderTemplate("scripts/checks/check-rust-no-unwrap.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"scripts","checks","check-rust-no-unsafe.mjs"),renderTemplate("scripts/checks/check-rust-no-unsafe.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}))),config.governanceLevel!=="L1"&&results.push(writeFile(resolvedPath(base,"scripts","check-docs.mjs"),renderTemplate("scripts/check-docs.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),resolveCollaborationMode(config)==="trunk-solo"&&results.push(writeFile(resolvedPath(base,"scripts","check-local-ci-parity.mjs"),renderTemplate("scripts/check-local-ci-parity.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(...emitDomainApiSurface(base,config,data,opts)),results.push(...emitOracleDiscrimination(base,config,data,opts)),results.push(...emitFrontendChecks(base,config,data,opts)),results.push(...emitConsumerAudit(base,config,data,opts)),{files:results}}function emitConsumerAudit(base,config,data,opts){return config.archetype!=="library"||config.language!=="typescript"||config.governanceLevel==="L1"?[]:[writeFile(resolvedPath(base,"scripts","check-consumer-audit.mjs"),renderTemplate("scripts/check-consumer-audit.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}function emitDomainApiSurface(base,config,data,opts){return config.hasPublicApi?[writeFile(resolvedPath(base,"scripts","check-domain-api-surface.mjs"),renderTemplate("scripts/check-domain-api-surface.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"domain-api-surface.json"),renderTemplate("scripts/domain-api-surface.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]:[]}function emitOracleDiscrimination(base,config,data,opts){return config.archetype==="frontend-spa"||config.archetype==="backend-web-db"?[writeFile(resolvedPath(base,"scripts","check-oracle-discrimination.mjs"),renderTemplate("scripts/check-oracle-discrimination.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"oracle-discrimination-baseline.json"),renderTemplate("scripts/oracle-discrimination-baseline.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]:[]}function emitFrontendChecks(base,config,data,opts){const out=[];return(config.archetype==="frontend-spa"||config.lanes.includes("frontend"))&&config.governanceLevel!=="L1"&&out.push(writeFile(resolvedPath(base,"scripts","check-fe-boundaries.mjs"),renderTemplate("scripts/check-fe-boundaries.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),isSubtreeFrontendLane(config)&&out.push(writeFile(resolvedPath(base,"scripts","check-frontend-lane.mjs"),renderTemplate("scripts/check-frontend-lane.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),out}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateStackConformity(config,opts={dryRun:!1}){const base=config.targetDir;return{files:[writeFile(resolvedPath(base,"scripts","check-stack-conformity.mjs"),renderTemplate("scripts/check-stack-conformity.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{chmodTranslated,resolvedPath,writeFile}from"../utils/fs.js";const SCRIPT_MODE=493;export function generateCiFiveLane(config,opts={dryRun:!1}){if(!config.enableFiveLaneCi||!(config.permitGitHub??config.useGitHub))return{files:[]};const data=config,githubDir=resolvedPath(config.targetDir,".github"),workflowsDir=join(githubDir,"workflows"),scriptsDir=join(githubDir,"scripts"),scriptPath=join(scriptsDir,"sticky-failure-issue.sh"),ciResult=writeFile(join(workflowsDir,"ci.yml"),renderTemplate("github/workflows/five-lane/ci.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),nightlyResult=writeFile(join(workflowsDir,"nightly.yml"),renderTemplate("github/workflows/five-lane/nightly.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),weeklyResult=writeFile(join(workflowsDir,"weekly.yml"),renderTemplate("github/workflows/five-lane/weekly.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),releaseResult=writeFile(join(workflowsDir,"release.yml"),renderTemplate("github/workflows/five-lane/release.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),scriptResult=writeFile(scriptPath,renderTemplate("github/scripts/sticky-failure-issue.sh.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun});return!opts.dryRun&&scriptResult.action!=="skipped"&&chmodTranslated(scriptPath,SCRIPT_MODE),{files:[ciResult,nightlyResult,weeklyResult,releaseResult,scriptResult]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateCiTier(config,opts={dryRun:!1}){if(!githubGenerationIsEnabled(config))return{files:[]};const data=config,githubDir=resolvedPath(config.targetDir,".github"),workflowsDir=join(githubDir,"workflows"),actionsDir=join(githubDir,"actions"),files=[writeFile(join(workflowsDir,"_notify.yml"),renderTemplate("github/workflows/_notify.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(workflowsDir,"_label-sync.yml"),renderTemplate("github/workflows/_label-sync.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(githubDir,"labels.yml"),renderTemplate("github/labels.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(actionsDir,"setup-node-pnpm","action.yml"),renderTemplate("github/actions/setup-node-pnpm/action.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})];return shouldGenerateCodeownersNotification(config)&&files.push(writeFile(join(workflowsDir,"_post-merge-notify.yml"),renderTemplate("github/workflows/_post-merge-notify.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),usesJavaBuildAction(config)&&files.push(writeFile(join(actionsDir,"setup-java-maven","action.yml"),renderTemplate("github/actions/setup-java-maven/action.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),supportsCrossJobBuildCache(config)&&files.push(writeFile(join(actionsDir,"build-cache","action.yml"),renderTemplate("github/actions/build-cache/action.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),config.deployTarget==="nas-compose"&&files.push(writeFile(join(actionsDir,"nas-ssh","action.yml"),renderTemplate("github/actions/nas-ssh/action.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),{files}}function githubGenerationIsEnabled(config){return config.permitGitHub??config.useGitHub}function shouldGenerateCodeownersNotification(config){return config.governanceLevel!=="L1"&&config.enableCodeownersNotify===!0}function usesJavaBuildAction(config){return config.language==="java"||config.language==="kotlin"}function supportsCrossJobBuildCache(config){return["typescript","python","java"].includes(config.language)}
@@ -0,0 +1,3 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{existsSync}from"node:fs";import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{ensureDir,mergeSettingsJson,resolvedPath,writeFile,readFileTranslated}from"../utils/fs.js";import{DEFAULT_TASK_TIERS}from"../config/schema.js";import{resolveCollaborationAxes}from"../config/collaboration-mode-defaults.js";export function buildRenderContext(config){const taskTiers=config.taskTiers??DEFAULT_TASK_TIERS,axes=resolveCollaborationAxes(config);return{...config,taskTiers,...axes}}export function generateClaude(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data=buildRenderContext(config);return results.push(writeFile(resolvedPath(base,".claude","CLAUDE.md"),renderTemplate("claude/CLAUDE.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),generateClaudeSettings(base,data,results,opts.dryRun),generateClaudeHooks(base,data,config,results,opts.dryRun),generateClaudeRules(base,data,config,results,opts.dryRun),generateClaudeCommands(base,data,results,opts.dryRun),results.push(writeFile(resolvedPath(base,".claude","knowledge-map.json"),renderTemplate("claude/knowledge-map.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),{files:results}}function isPlainObject(x){return typeof x=="object"&&x!==null&&!Array.isArray(x)}export function parseExistingSettings(settingsPath){const raw=readFileTranslated(settingsPath,"utf-8");let parsed;try{parsed=JSON.parse(raw)}catch(err){const msg=err instanceof Error?err.message:String(err);throw new Error(`Failed to parse existing .claude/settings.json: ${msg}. Fix or delete and re-run.`,{cause:err})}if(!isPlainObject(parsed)){const kind=Array.isArray(parsed)?"array":parsed===null?"null":typeof parsed;throw new Error(`Failed to parse existing .claude/settings.json: expected JSON object, got ${kind}. Fix or delete and re-run.`)}return parsed}function generateClaudeSettings(base,data,results,dryRun){const settingsPath=resolvedPath(base,".claude","settings.json");if(!existsSync(settingsPath)){results.push(writeFile(settingsPath,renderTemplate("claude/settings.json.ejs",data),{dryRun}));return}const existing=parseExistingSettings(settingsPath),incoming=JSON.parse(renderTemplate("claude/settings.json.ejs",data)),merged=mergeSettingsJson(existing,incoming),mergedText=JSON.stringify(merged,null,2)+`
3
+ `;results.push(writeFile(settingsPath,mergedText,{backup:!0,dryRun}))}const L2_ADVANCED_HOOKS=["post-edit-dispatch.mjs","debug-state-on-failure.mjs","skill-forced-eval.mjs","guard-task-completion.mjs","stop-evidence-guard.mjs","closer-mode-guard.mjs","exitplanmode-banner.mjs","stop-finding-loss.mjs"];export function planClaudeHooks(config){const isTs=config.language==="typescript"||config.language==="multi",entries=[],tpl=(file,template)=>{entries.push({file,template})};tpl("hooks.mjs","claude/hooks/hooks.mjs.ejs");for(const f of["stop-dangerous.mjs","enforce-read-only.mjs","pre-edit-ssot-guard.mjs","check-no-orphan-todo.mjs","check-no-placeholders.mjs","enforce-gate-before-pr.mjs","pre-spawn-worktree-guard.mjs","post-subagent-release.mjs"])tpl(f,`claude/hooks/${f}${f==="check-no-orphan-todo.mjs"||f==="check-no-placeholders.mjs"?".ejs":""}`);for(const f of["lib.mjs","post-commit-check.mjs"])tpl(f,`claude/hooks/${f}.ejs`);isTs&&tpl("check-no-unused-exports.mjs","claude/hooks/check-no-unused-exports.mjs"),config.enableNoSkippedTests!==!1&&tpl("check-no-skipped-tests.mjs","claude/hooks/check-no-skipped-tests.mjs");for(const hook of config.languageHooks)hook.name!=="check-no-orphan-todo.mjs"&&entries.push({file:hook.name,body:hook.body});if(tpl("pre-edit-plan-anchor.mjs","claude/hooks/pre-edit-plan-anchor.mjs.ejs"),tpl("pre-compact.mjs","claude/hooks/pre-compact.mjs.ejs"),config.governanceLevel!=="L1"){for(const f of L2_ADVANCED_HOOKS)tpl(f,`claude/hooks/${f}.ejs`);config.enableEvidenceHarness!==!1&&tpl("guard-done-evidence.mjs","claude/hooks/guard-done-evidence.mjs.ejs"),tpl("post-brainstorm-stop.mjs","claude/hooks/post-brainstorm-stop.mjs")}return isTs&&tpl("check-circular-deps.mjs","claude/hooks/check-circular-deps.mjs.ejs"),entries}function generateClaudeHooks(base,data,config,results,dryRun){const hooksDir=resolvedPath(base,".claude","hooks");dryRun||ensureDir(hooksDir);for(const entry of planClaudeHooks(config)){const content=entry.body??renderTemplate(entry.template,data);results.push(writeFile(join(hooksDir,entry.file),content,{skipIfExists:!0,dryRun}))}}export function planClaudeRules(config){const rules=[{file:"05-agent-lifecycle.md",template:"claude/rules/05-agent-lifecycle.md"},{file:"25-todo-folder-policy.md",template:"claude/rules/25-todo-folder-policy.md"},{file:"40-context-economy.md",template:"claude/rules/40-context-economy.md"},{file:"50-batch-execution.md",template:"claude/rules/50-batch-execution.md"},{file:"55-brainstorm-terminal-state.md",template:"claude/rules/55-brainstorm-terminal-state.md"},{file:"60-incidental-capture.md",template:"claude/rules/60-incidental-capture.md"},{file:"75-impact-vault-reading.md",template:"claude/rules/75-impact-vault-reading.md"},{file:"90-exec-protocol.md",template:"claude/rules/90-exec-protocol.md.ejs"},{file:"95-closer-mode.md",template:"claude/rules/95-closer-mode.md"}];return config.enableMcpFallback&&rules.push({file:"45-mcp-fallback.md",template:"claude/rules/45-mcp-fallback.md"}),rules}function generateClaudeRules(base,data,config,results,dryRun){const rulesDir=resolvedPath(base,".claude","rules");for(const rule of planClaudeRules(config))results.push(writeFile(join(rulesDir,rule.file),renderTemplate(rule.template,data),{skipIfExists:!0,dryRun}))}export const CLAUDE_COMMANDS=["task.md","ship.md","drain.md","impact.md","gold-audit.md","wt-open.md","wt-close.md","wt-list.md","wt-prune.md","close-gold-gap.md","levelup.md","tabletop.md"];function generateClaudeCommands(base,data,results,dryRun){const commandsDir=resolvedPath(base,".claude","commands");for(const cmd of CLAUDE_COMMANDS)results.push(writeFile(join(commandsDir,cmd),renderTemplate(`claude/commands/${cmd}.ejs`,data),{skipIfExists:!0,dryRun}))}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join,dirname}from"node:path";import{fileURLToPath}from"node:url";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath,readFileTranslated}from"../utils/fs.js";import{formatContent}from"../utils/prettier-format.js";const __dirname=dirname(fileURLToPath(import.meta.url));export const SHARED_GUARD_HOOKS=["stop-dangerous.mjs","enforce-read-only.mjs","pre-edit-ssot-guard.mjs","check-no-orphan-todo.mjs","check-no-placeholders.mjs"];export function generateCodexHooks(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data=config,hooksDir=resolvedPath(base,".claude","hooks");if(!config.tools.includes("claude")){results.push(writeFile(join(hooksDir,"lib.mjs"),renderTemplate("claude/hooks/lib.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));for(const hookFile of SHARED_GUARD_HOOKS){const templateFile=hookFile==="check-no-orphan-todo.mjs"||hookFile==="check-no-placeholders.mjs"?`${hookFile}.ejs`:hookFile;results.push(writeFile(join(hooksDir,hookFile),renderTemplate(`claude/hooks/${templateFile}`,data),{skipIfExists:!0,dryRun:opts.dryRun}))}config.enableNoSkippedTests!==!1&&results.push(writeFile(join(hooksDir,"check-no-skipped-tests.mjs"),renderTemplate("claude/hooks/check-no-skipped-tests.mjs",data),{skipIfExists:!0,dryRun:opts.dryRun}))}results.push(writeFile(resolvedPath(base,".codex","config.toml"),renderTemplate("codex/config.toml.ejs",data),{backup:!0,dryRun:opts.dryRun}));const adapterSrc=join(__dirname,"..","templates","codex","codex-adapter.mjs"),adapterDest=join(resolvedPath(base,".codex"),"codex-adapter.mjs"),adapterContent=formatContent(readFileTranslated(adapterSrc,"utf-8"),adapterDest,base);return results.push(writeFile(adapterDest,adapterContent,{skipIfExists:!0,dryRun:opts.dryRun})),{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{planClaudeHooks,planClaudeRules,CLAUDE_COMMANDS}from"./claude.js";import{AGENT_NAMES}from"./agents-claude.js";import{SKILL_NAMES}from"./skills.js";export const CODEX_DERIVED_RULES=[{file:"05-agent-lifecycle.md",template:"claude/rules/05-agent-lifecycle.md"},{file:"25-todo-folder-policy.md",template:"claude/rules/25-todo-folder-policy.md"},{file:"50-batch-execution.md",template:"claude/rules/50-batch-execution.md"},{file:"60-incidental-capture.md",template:"claude/rules/60-incidental-capture.md"},{file:"90-exec-protocol.md",template:"claude/rules/90-exec-protocol.md.ejs"}];const BRIDGED="Real-time: bridged via `.codex/config.toml` \u2192 `codex-adapter.mjs`",bridgedPlusGate=gate=>`${BRIDGED}; gate: ${gate}`,HOOK_DESCRIPTORS={"hooks.mjs":"infra","lib.mjs":"infra","stop-dangerous.mjs":{name:"stop-dangerous.mjs",enforces:"Blocks dangerous shell commands before execution",codexEquivalent:BRIDGED},"enforce-read-only.mjs":{name:"enforce-read-only.mjs",enforces:"Blocks edits to read-only / generated paths",codexEquivalent:BRIDGED},"pre-edit-ssot-guard.mjs":{name:"pre-edit-ssot-guard.mjs",enforces:"Warns on SSOT/governance file edits",codexEquivalent:BRIDGED},"check-no-orphan-todo.mjs":{name:"check-no-orphan-todo.mjs",enforces:"Blocks bare TODO without task ID (INV-06)",codexEquivalent:BRIDGED},"check-no-placeholders.mjs":{name:"check-no-placeholders.mjs",enforces:"Blocks stub content and unfinished scaffolding in edited files",codexEquivalent:BRIDGED},"check-no-skipped-tests.mjs":{name:"check-no-skipped-tests.mjs",enforces:"Blocks skipped/muted tests at edit time (INV-25)",codexEquivalent:BRIDGED},"check-no-pii.mjs":{name:"check-no-pii.mjs",enforces:"Blocks PII patterns in source (real-time)",codexEquivalent:BRIDGED},"enforce-gate-before-pr.mjs":{name:"enforce-gate-before-pr.mjs",enforces:"Blocks PR creation before the local gate passed",codexEquivalent:bridgedPlusGate("`node scripts/check-all.mjs L2` before push")},"post-commit-check.mjs":{name:"post-commit-check.mjs",enforces:"Post-commit checklist verification",codexEquivalent:BRIDGED},"check-no-unused-exports.mjs":{name:"check-no-unused-exports.mjs",enforces:"Blocks unused TypeScript exports (dead code)",codexEquivalent:bridgedPlusGate("dead-code check (`knip`) in `check-all.mjs`")},"check-no-any.mjs":{name:"check-no-any.mjs",enforces:"Blocks TypeScript `any` types (INV-04)",codexEquivalent:bridgedPlusGate("`tsc --strict`")},"check-no-unwrap.mjs":{name:"check-no-unwrap.mjs",enforces:"Blocks `.unwrap()` outside tests (Rust)",codexEquivalent:"Gate: clippy lint step in `check-all.mjs`"},"check-no-unchecked-err.mjs":{name:"check-no-unchecked-err.mjs",enforces:"Blocks unchecked `err` returns (Go)",codexEquivalent:"Gate: errcheck/vet step in `check-all.mjs`"},"check-no-bare-except.mjs":{name:"check-no-bare-except.mjs",enforces:"Blocks bare `except:` clauses (Python)",codexEquivalent:"Gate: ruff lint step in `check-all.mjs`"},"check-no-raw-types.mjs":{name:"check-no-raw-types.mjs",enforces:"Blocks raw generic types (Java)",codexEquivalent:"Gate: compiler lint step in `check-all.mjs`"},"check-no-mockmvc.mjs":{name:"check-no-mockmvc.mjs",enforces:"Blocks MockMvc in favour of real-server tests (Java)",codexEquivalent:"Gate: test-realism checks in `check-all.mjs`"},"pre-edit-plan-anchor.mjs":{name:"pre-edit-plan-anchor.mjs",enforces:"Requires plan file in implementation phase",codexEquivalent:"`.agents/plan/PLAN.json` protocol"},"pre-compact.mjs":{name:"pre-compact.mjs",enforces:"Snapshots task state before context compaction",codexEquivalent:BRIDGED},"post-edit-dispatch.mjs":{name:"post-edit-dispatch.mjs",enforces:"Runs post-edit agents for quality checks",codexEquivalent:"None \u2014 manual code review"},"debug-state-on-failure.mjs":{name:"debug-state-on-failure.mjs",enforces:"Persists debug state on gate failure",codexEquivalent:"None \u2014 manual logging"},"skill-forced-eval.mjs":{name:"skill-forced-eval.mjs",enforces:"Forces skill invocation before task start",codexEquivalent:BRIDGED},"guard-task-completion.mjs":{name:"guard-task-completion.mjs",enforces:"Blocks premature done claims",codexEquivalent:BRIDGED},"stop-evidence-guard.mjs":{name:"stop-evidence-guard.mjs",enforces:"Fail-closed completion backstop (INV-114)",codexEquivalent:"None \u2014 manual discipline"},"closer-mode-guard.mjs":{name:"closer-mode-guard.mjs",enforces:"CLOSER-mode enforcement in the close phase",codexEquivalent:BRIDGED},"exitplanmode-banner.mjs":{name:"exitplanmode-banner.mjs",enforces:"Plan-exit banner in the task lifecycle",codexEquivalent:"None \u2014 informational only"},"guard-done-evidence.mjs":{name:"guard-done-evidence.mjs",enforces:"Requires recorded evidence before done claims",codexEquivalent:bridgedPlusGate("`arbiter verify tdd` / evidence checks")},"post-brainstorm-stop.mjs":{name:"post-brainstorm-stop.mjs",enforces:"Brainstorm terminal-state guardrail (#1265)",codexEquivalent:BRIDGED},"check-circular-deps.mjs":{name:"check-circular-deps.mjs",enforces:"Detects circular deps per-edit (INV-01)",codexEquivalent:bridgedPlusGate("`madge --circular src` in `check-all.mjs`")},"wiki-on-commit.mjs":{name:"wiki-on-commit.mjs",enforces:"Regenerates the LLM wiki on commit (INV-116)",codexEquivalent:"Gate: wiki-lint check in `check-all.mjs`"},"pre-spawn-worktree-guard.mjs":{name:"pre-spawn-worktree-guard.mjs",enforces:"Refuses a second write-intent sub-agent spawn onto the main tree (E5 #1947)",codexEquivalent:"None \u2014 manual worktree discipline"},"post-subagent-release.mjs":{name:"post-subagent-release.mjs",enforces:"SubagentStop cleanup companion to pre-spawn-worktree-guard.mjs \u2014 releases the finished dispatch agents-active.json sidecar entry (#2403)",codexEquivalent:BRIDGED},"stop-finding-loss.mjs":{name:"stop-finding-loss.mjs",enforces:"Detects research dispatches with zero persisted findings (E6b #1948)",codexEquivalent:"None \u2014 manual discipline"}};export function planClaudeHookInventory(config){const names=planClaudeHooks(config).map(e=>e.file);return config.existing.aiRulez||(config.enableSecurityScanning&&names.push("check-no-pii.mjs"),config.governanceLevel!=="L1"&&config.tools.includes("claude")&&names.push("wiki-on-commit.mjs")),names}export function buildKnownLimitations(config){const hooks=[];for(const name of planClaudeHookInventory(config)){const descriptor=HOOK_DESCRIPTORS[name];if(descriptor===void 0)throw new Error(`codex-known-limitations: no descriptor for Claude hook "${name}" \u2014 add a row to HOOK_DESCRIPTORS (ADR-106: every emitted hook must be disclosed in the CODEX.md Known Limitations table)`);descriptor!=="infra"&&hooks.push(descriptor)}const codexRuleFiles=new Set(CODEX_DERIVED_RULES.map(r=>r.file)),claudeOnlyRules=planClaudeRules(config).map(r=>r.file).filter(f=>!codexRuleFiles.has(f));return{hooks,commands:CLAUDE_COMMANDS.map(c=>c.replace(/\.md$/,"")),agents:[...AGENT_NAMES],skills:[...SKILL_NAMES],claudeOnlyRules}}
@@ -0,0 +1,15 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{generateCodexHooks}from"./codex-hooks.js";import{buildKnownLimitations,CODEX_DERIVED_RULES}from"./codex-known-limitations.js";export function generateCodex(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data={...config,knownLimitations:buildKnownLimitations(config)};results.push(writeFile(resolvedPath(base,".agents","CODEX.md"),renderTemplate("codex/CODEX.md.ejs",data),{backup:!0,dryRun:opts.dryRun}));const rulesDir=resolvedPath(base,".agents","rules");for(const rule of CODEX_DERIVED_RULES)results.push(writeFile(join(rulesDir,rule.file),renderTemplate(rule.template,data),{skipIfExists:!0,dryRun:opts.dryRun}));const planDir=resolvedPath(base,".agents","plan");results.push(writeFile(join(planDir,"README.md"),PLAN_README,{skipIfExists:!0,dryRun:opts.dryRun}));const hookResult=generateCodexHooks(config,opts);return results.push(...hookResult.files),{files:results}}const PLAN_README=`# .agents/plan/
3
+
4
+ Task plan artifacts for Codex execution.
5
+
6
+ ## Files
7
+
8
+ - \`PLAN.json\` \u2014 current task plan (created by Codex before implementation)
9
+ - \`CONTEXT_PACK.md\` \u2014 context digest for the current task
10
+ - \`runs/\` \u2014 historical run snapshots
11
+
12
+ ## Plan Schema
13
+
14
+ See \`.agents/CODEX.md\` \xA7Plan Schema for the required format.
15
+ `;
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateCommitFooter(config,opts={dryRun:!1}){const base=config.targetDir,data=config;return{files:[writeFile(resolvedPath(base,"scripts","check-commit-footer-rationale.mjs"),renderTemplate("scripts/check-commit-footer-rationale.mjs.ejs",data),{dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateComplianceMenu(config,opts={dryRun:!1}){const path=resolvedPath(config.targetDir,"docs","COMPLIANCE_MENU.md"),content=renderTemplate("compliance/compliance-menu.md.ejs",config);return{files:[writeFile(path,content,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateCompliance(config,opts={dryRun:!1}){const path=resolvedPath(config.targetDir,"docs","COMPLIANCE_MAPPING.md"),content=renderTemplate("compliance/compliance-mapping.md.ejs",config);return{files:[writeFile(path,content,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{writeFile,resolvedPath}from"../utils/fs.js";import{renderTemplate}from"../utils/render.js";export function generateConformanceScript(config,opts={dryRun:!1}){const path=resolvedPath(config.targetDir,"scripts","conformance.mjs"),content=renderTemplate("scripts/conformance.mjs.ejs",config);return{files:[writeFile(path,content,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{mutatePackageJson}from"../utils/pkg.js";import{formatContent}from"../utils/prettier-format.js";import{getLogger}from"../utils/logger.js";import{isL3Allowed}from"../utils/maturity-check.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";const SPRINGDOC_OPENAPI_PLUGIN_VERSION="1.8.0";function injectPactPackageJson(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const devDeps=pkg.devDependencies??{};return devDeps["@pact-foundation/pact"]?!1:(devDeps["@pact-foundation/pact"]="^16.4.0",pkg.devDependencies=devDeps,!0)})}function javaContractsPkg(config){if(config.basePackage){if(!/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(config.basePackage))throw new Error(`Invalid basePackage identifier: ${config.basePackage}`);return`src/test/java/${config.basePackage.replace(/\./g,"/")}/contracts`}return"src/test/java/contracts"}function contractFile(cfOpts){const{base,config,data,templateDir,tsFile,javaFile,rustFile,goFile,pyFile,dryRun,tsPathSegments=["src","test","contracts"],formatTs=!1}=cfOpts,out=cfOpts.extraFiles??[],skip={skipIfExists:!0,dryRun};if(config.language==="typescript"||config.language==="multi"){const tsPath=resolvedPath(base,...tsPathSegments,tsFile),tsContent=renderTemplate(`contract-testing/${templateDir}/${tsFile}.ejs`,data);out.push(writeFile(tsPath,formatTs?formatContent(tsContent,tsPath,base):tsContent,skip))}if(config.language==="java"||config.language==="multi"){const pkg=javaContractsPkg(config);out.push(writeFile(resolvedPath(base,pkg,javaFile),renderTemplate(`contract-testing/${templateDir}/${javaFile}.ejs`,data),skip))}return config.language==="rust"?out.push(writeFile(resolvedPath(base,"tests",rustFile),renderTemplate(`contract-testing/${templateDir}/${rustFile}.ejs`,data),skip)):config.language==="go"?out.push(writeFile(resolvedPath(base,"tests",goFile),renderTemplate(`contract-testing/${templateDir}/${goFile}.ejs`,data),skip)):config.language==="python"&&out.push(writeFile(resolvedPath(base,"tests","contract",pyFile),renderTemplate(`contract-testing/${templateDir}/${pyFile}.ejs`,data),skip)),out}function generateApiContractBaselines(base,data,dryRun){const snapshotsBase=resolvedPath(base,"src","test","resources","api-snapshots"),pactSamplesBase=resolvedPath(base,"src","test","resources","pact-samples"),skip={skipIfExists:!0,dryRun},out=[],snapshotStubs=["openapi-baseline.json","openapi-paths-baseline.json","openapi-response-status-baseline.json","openapi-content-types-baseline.json","openapi-required-fields-baseline.json","config-response-baseline.json","config-keys-baseline.json","enum-values-baseline.json","error-shape-baseline.json","test-snapshot.json"];for(const name of snapshotStubs)out.push(writeFile(resolvedPath(snapshotsBase,name),renderTemplate(`contract-testing/api-snapshots/${name}.ejs`,data),skip));const pactStubs=["assignment-response.json","availability-response.json","availability-rule-response.json","capacity-response.json","fully-booked-response.json","schedule-override-response.json"];for(const name of pactStubs)out.push(writeFile(resolvedPath(pactSamplesBase,name),renderTemplate(`contract-testing/pact-samples/${name}.ejs`,data),skip));return out.push(writeFile(resolvedPath(base,"scripts","validate-api-snapshots.mjs"),renderTemplate("scripts/validate-api-snapshots.mjs.ejs",data),skip),writeFile(resolvedPath(base,"scripts","validate-openapi-field-types.mjs"),renderTemplate("scripts/validate-openapi-field-types.mjs.ejs",data),skip),writeFile(resolvedPath(base,"scripts","validate-postman-collection.mjs"),renderTemplate("scripts/validate-postman-collection.mjs.ejs",data),skip)),out}function generateRestOwned(base,config,data,dryRun){const extra=[writeFile(resolvedPath(base,".env.pact"),renderTemplate("contract-testing/env/.env.pact.ejs",data),{skipIfExists:!0,dryRun}),writeFile(resolvedPath(base,"pacts",".gitkeep"),"",{skipIfExists:!0,dryRun})];if((config.language==="java"||config.language==="multi")&&(extra.push(writeFile(resolvedPath(base,"config","pact-deps.gradle"),renderTemplate("contract-testing/rest-owned/pact-deps.gradle.ejs",data),{skipIfExists:!0,dryRun})),config.buildTool==="gradle")){const applyPactDeps=safeApplyFromSnippet(base,"config/pact-deps.gradle");applyPactDeps&&injectGradleWiring(base,dryRun,{snippets:[applyPactDeps]})}return(config.language==="java"||config.language==="multi")&&extra.push(writeFile(resolvedPath(base,"scripts","run-postman-tests.sh"),renderTemplate("scripts/run-postman-tests.sh.ejs",data),{skipIfExists:!0,dryRun}),writeFile(resolvedPath(base,"scripts","inject-pact-samples.sh"),renderTemplate("scripts/inject-pact-samples.sh.ejs",data),{skipIfExists:!0,dryRun}),writeFile(resolvedPath(base,".github","workflows","_contract-postman.yml"),renderTemplate("github/workflows/_contract-postman.yml.ejs",data),{skipIfExists:!0,dryRun})),(config.language==="java"||config.language==="multi")&&extra.push(...generateApiContractBaselines(base,data,dryRun)),(config.language==="typescript"||config.language==="multi")&&injectPactPackageJson(base,dryRun),contractFile({base,config,data,templateDir:"rest-owned",tsFile:"pact-consumer.test.ts",javaFile:"PactVerificationIT.java",rustFile:"pact_consumer_test.rs",goFile:"pact_consumer_test.go",pyFile:"test_pact_consumer.py",tsPathSegments:["__tests__","contract"],formatTs:!0,extraFiles:extra,dryRun})}function generateRestPublic(base,config,data,dryRun){const skip={skipIfExists:!0,dryRun},extra=[];if((config.language==="typescript"||config.language==="multi")&&extra.push(writeFile(resolvedPath(base,"export-openapi.mjs"),renderTemplate("contract-testing/rest-public/export-openapi.mjs.ejs",data),skip)),(config.language==="java"||config.language==="multi")&&(extra.push(writeFile(resolvedPath(base,"config","export-openapi-java.gradle"),renderTemplate("contract-testing/rest-public/export-openapi-java.gradle.ejs",data),skip)),config.buildTool==="gradle")){const applyExportOpenapi=safeApplyFromSnippet(base,"config/export-openapi-java.gradle");applyExportOpenapi&&injectGradleWiring(base,dryRun,{plugins:[{id:"org.springdoc.openapi-gradle-plugin",version:SPRINGDOC_OPENAPI_PLUGIN_VERSION}],snippets:[applyExportOpenapi]})}return config.language==="rust"?extra.push(writeFile(resolvedPath(base,"src","bin","export_openapi.rs"),renderTemplate("contract-testing/rest-public/export_openapi.rs.ejs",data),skip)):config.language==="go"?extra.push(writeFile(resolvedPath(base,"cmd","export-openapi","main.go"),renderTemplate("contract-testing/rest-public/export_openapi.go.ejs",data),skip)):config.language==="python"&&extra.push(writeFile(resolvedPath(base,"export_openapi.py"),renderTemplate("contract-testing/rest-public/export_openapi.py.ejs",data),skip)),contractFile({base,config,data,templateDir:"rest-public",tsFile:"openapi-diff.ts",javaFile:"OpenApiDiffIT.java",rustFile:"openapi_diff_test.rs",goFile:"openapi_diff_test.go",pyFile:"test_openapi_diff.py",extraFiles:extra,dryRun})}function generateGraphql(base,config,data,dryRun){return contractFile({base,config,data,templateDir:"graphql",tsFile:"graphql-inspector.test.ts",javaFile:"GraphqlSchemaTest.java",rustFile:"graphql_schema_test.rs",goFile:"graphql_schema_test.go",pyFile:"test_graphql_schema.py",dryRun})}function generateGrpc(base,config,data,dryRun){const skip={skipIfExists:!0,dryRun},shared=[writeFile(resolvedPath(base,"proto","buf.yaml"),renderTemplate("contract-testing/grpc/buf.yaml.ejs",data),skip),writeFile(resolvedPath(base,"proto","buf-breaking.yml"),renderTemplate("contract-testing/grpc/buf-breaking.yml.ejs",data),skip)];return contractFile({base,config,data,templateDir:"grpc",tsFile:"grpc-contract.test.ts",javaFile:"GrpcContractTest.java",rustFile:"grpc_contract_test.rs",goFile:"grpc_contract_test.go",pyFile:"test_grpc_contract.py",extraFiles:shared,dryRun})}function generateMessageQueue(base,config,data,dryRun){return contractFile({base,config,data,templateDir:"message-queue",tsFile:"schema-registry-check.ts",javaFile:"SchemaRegistryCheckIT.java",rustFile:"schema_registry_test.rs",goFile:"schema_registry_test.go",pyFile:"test_schema_registry.py",dryRun})}export function generateContractTesting(config,opts={dryRun:!1}){if(config.contractType==="none"||config.governanceLevel==="L1")return{files:[]};const dispatchers={"rest-owned":generateRestOwned,"rest-public":generateRestPublic,graphql:generateGraphql,grpc:generateGrpc,"message-queue":generateMessageQueue};if(!config.hasPublicApi)return{files:[]};const{language,acceptBetaTools=!1}=config;if(language!=="multi"&&!isL3Allowed(language,"contract",acceptBetaTools).allowed)return{files:[]};const handler=dispatchers[config.contractType];if(!handler)return getLogger().warn("contract_testing.unknown_contract_type",{contract_type:config.contractType},`Unknown contractType: ${config.contractType} \u2014 skipping`),{files:[]};const base=config.targetDir,data=config,results=[writeFile(resolvedPath(base,"CONTRACTS_POLICY.md"),renderTemplate("contract-testing/CONTRACTS_POLICY.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})];return results.push(...handler(base,config,data,opts.dryRun)),{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{resolveEffectiveThresholds}from"../config/thresholds.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";const KOVER_PLUGIN_VERSION="0.9.8";function binarySizeBudget(archetype){return archetype==="cli"?10*1048576:archetype==="embedded"?5*1048576:0}export function generateCoverage(config,opts={dryRun:!1}){if(!config.enableDebtGates)return{files:[]};const results=[],base=config.targetDir,effective=resolveEffectiveThresholds(config),data={...config,thresholds:{...config.thresholds,lineCoverage:effective.lineCoverage,branchCoverage:effective.branchCoverage},coverageThreshold:effective.lineCoverage,coverageEnabled:effective.coverageEnabled,binarySizeBytes:binarySizeBudget(config.archetype)};if((config.language==="typescript"||config.language==="multi")&&results.push(writeFile(resolvedPath(base,"vitest.config.ts"),renderTemplate("coverage/vitest.config.ts.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),(config.language==="java"||config.language==="multi")&&config.buildTool==="gradle"){results.push(writeFile(resolvedPath(base,"gradle","jacoco.gradle"),renderTemplate("coverage/jacoco.gradle.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));const applyJacoco=safeApplyFromSnippet(base,"gradle/jacoco.gradle",{rootBuildSignatures:[/(?:^|\n)[ \t]*jacoco\s*\{/]});applyJacoco&&injectGradleWiring(base,opts.dryRun,{snippets:[applyJacoco]})}return(config.language==="java"||config.language==="multi")&&config.buildTool==="maven"&&results.push(writeFile(resolvedPath(base,"docs","coverage","jacoco-maven-setup.md"),renderTemplate("coverage/jacoco-maven-setup.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),config.language==="rust"&&results.push(...emitRustCoverage(base,config,data,opts.dryRun)),results.push(...emitSingleFileCoverage(config.language,base,data,opts.dryRun)),{files:results}}function emitSingleFileCoverage(language,base,data,dryRun){return language==="python"?[writeFile(resolvedPath(base,".coveragerc"),renderTemplate("coverage/.coveragerc.ejs",data),{skipIfExists:!0,dryRun})]:language==="kotlin"?emitKotlinCoverage(base,data,dryRun):[]}function emitKotlinCoverage(base,data,dryRun){const result=writeFile(resolvedPath(base,"kover.gradle"),renderTemplate("coverage/kover.gradle.ejs",data),{skipIfExists:!0,dryRun}),applyKover=safeApplyFromSnippet(base,"kover.gradle",{rootBuildSignatures:[/(?:^|\n)[ \t]*kover\s*\{/]});return applyKover&&injectGradleWiring(base,dryRun,{plugins:[{id:"org.jetbrains.kotlinx.kover",version:KOVER_PLUGIN_VERSION}],snippets:[applyKover]}),[result]}function emitRustCoverage(base,config,data,dryRun){const out=[writeFile(resolvedPath(base,".tarpaulin.toml"),renderTemplate("coverage/.tarpaulin.toml.ejs",data),{skipIfExists:!0,dryRun})];return(config.archetype==="cli"||config.archetype==="embedded")&&out.push(writeFile(resolvedPath(base,"docs","coverage","Cargo.toml.profile.release"),renderTemplate("coverage/Cargo.toml.profile.release.ejs",data),{skipIfExists:!0,dryRun})),out}
@@ -0,0 +1,24 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{execFileSync}from"node:child_process";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{mutatePackageJson}from"../utils/pkg.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";function injectTestScripts(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const scripts=pkg.scripts??{},testScripts={"test:unit":"vitest run src","test:contract":"vitest run --passWithNoTests __tests__/contract","test:integration":"vitest run --passWithNoTests __tests__/integrations","test:behavioral":"vitest run --passWithNoTests __tests__/behavioral"};let changed=!1;for(const[key,value]of Object.entries(testScripts))scripts[key]||(scripts[key]=value,changed=!0);return changed&&(pkg.scripts=scripts),changed})}function injectTypeScriptGateScripts(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const scripts=pkg.scripts??{},gateScripts={typecheck:"tsc --noEmit",lint:"eslint .",build:"tsc -p tsconfig.json"};let changed=!1;for(const[key,value]of Object.entries(gateScripts))scripts[key]||(scripts[key]=value,changed=!0);return changed&&(pkg.scripts=scripts),changed})}function injectDepCruiserPackageJson(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const scripts=pkg.scripts??{},devDeps=pkg.devDependencies??{};let changed=!1;return scripts["check:arch"]||(scripts["check:arch"]="depcruise src",pkg.scripts=scripts,changed=!0),devDeps["dependency-cruiser"]||(devDeps["dependency-cruiser"]="^16.0.0",pkg.devDependencies=devDeps,changed=!0),changed})}const TS_GATE_DEVDEPS={typescript:"^5.6.0","@types/node":"^22.0.0",prettier:"^3.3.0",eslint:"^9.13.0","@eslint/js":"^9.13.0","typescript-eslint":"^8.10.0",vitest:"^3.0.0"},VITEST_COVERAGE="@vitest/coverage-v8",DEFAULT_VITEST_COVERAGE_SELECTOR="^3.0.0",ORDINARY_VITEST_SELECTOR=/^(?:\^|~)?\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;function coverageSelectorFor(vitestSelector){return vitestSelector!==void 0&&ORDINARY_VITEST_SELECTOR.test(vitestSelector)?vitestSelector:DEFAULT_VITEST_COVERAGE_SELECTOR}function injectTsGateToolchain(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const devDeps=pkg.devDependencies??{},dependencies=pkg.dependencies;let changed=!1;for(const[name,version]of Object.entries(TS_GATE_DEVDEPS))!devDeps[name]&&!dependencies?.[name]&&(devDeps[name]=version,changed=!0);return!devDeps[VITEST_COVERAGE]&&!dependencies?.[VITEST_COVERAGE]&&(devDeps[VITEST_COVERAGE]=coverageSelectorFor(devDeps.vitest??dependencies?.vitest),changed=!0),changed&&(pkg.devDependencies=devDeps),changed})}function injectFormatScript(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const scripts=pkg.scripts??{};return scripts.format?!1:(scripts.format="prettier --check .",pkg.scripts=scripts,!0)})}function emitTsGateScaffold(base,data,dryRun){return[["tsconfig.json","root/tsconfig.json.ejs"],[".prettierrc.json","static-analysis/prettierrc.json.ejs"],[".prettierignore","static-analysis/prettierignore.ejs"],["eslint.config.mjs","static-analysis/eslint.config.mjs.ejs"],["eslint.config.static.mjs","static-analysis/eslint.config.static.mjs.ejs"],[".eslintrc-static.json","static-analysis/eslintrc-static.json.ejs"]].map(([rel,tmpl])=>writeFile(resolvedPath(base,rel),renderTemplate(tmpl,data),{skipIfExists:!0,dryRun}))}const CHECKSTYLE_TOOL_VERSION="10.21.4",PMD_TOOL_VERSION="7.10.0",SPOTBUGS_PLUGIN_VERSION="6.0.18",SPOTLESS_PLUGIN_VERSION="7.0.3";function detectSpotlessRatchetRef(targetDir){for(const ref of["origin/main","origin/master"])try{return execFileSync("git",["-C",targetDir,"rev-parse","--verify","--quiet",`refs/remotes/${ref}`],{stdio:"ignore"}),ref}catch{}return null}function isJavaLike(config){return config.language==="java"||config.language==="multi"}function pushJavaGateEssentials(results,config,data,dryRun){if(!isJavaLike(config))return;const base=config.targetDir,javaData={...data,spotlessRatchetFrom:detectSpotlessRatchetRef(base)},files=[[resolvedPath(base,"config","checkstyle.xml"),"static-analysis/checkstyle.xml.ejs"],[resolvedPath(base,"spotless.gradle"),"static-analysis/spotless.gradle.ejs"]];for(const[path,tmpl]of files)results.push(writeFile(path,renderTemplate(tmpl,javaData),{skipIfExists:!0,dryRun}));if(config.buildTool!=="gradle")return;const snippets=[{signature:/(?:^|\n)[ \t]*checkstyle\s*\{/,kts:`checkstyle {
3
+ toolVersion = "${CHECKSTYLE_TOOL_VERSION}"
4
+ configFile = file("config/checkstyle.xml")
5
+ }`,groovy:`checkstyle {
6
+ toolVersion = '${CHECKSTYLE_TOOL_VERSION}'
7
+ configFile = file('config/checkstyle.xml')
8
+ }`}],applySpotless=safeApplyFromSnippet(base,"spotless.gradle",{rootBuildSignatures:[/(?:^|\n)[ \t]*spotless\s*\{/]});applySpotless&&snippets.push(applySpotless),injectGradleWiring(base,dryRun,{plugins:[{id:"checkstyle"},{id:"com.diffplug.spotless",version:SPOTLESS_PLUGIN_VERSION}],snippets})}function pushJavaDebtGates(results,config,data,dryRun){if(!isJavaLike(config))return;const base=config.targetDir,files=[[resolvedPath(base,"config","pmd-ruleset.xml"),"static-analysis/pmd-ruleset.xml.ejs"],[resolvedPath(base,"config","spotbugs-exclude.xml"),"static-analysis/spotbugs-exclude.xml.ejs"],[resolvedPath(base,"config","pitest-setup.md"),"mutation/pitest-l2-setup.md.ejs"],[resolvedPath(base,"spotbugs.gradle"),"static-analysis/spotbugs.gradle.ejs"],[resolvedPath(base,"scripts","verify-spotbugs.mjs"),"scripts/verify-spotbugs.mjs.ejs"],[resolvedPath(base,"spotbugs-baseline.json"),"scripts/spotbugs-baseline.json.ejs"]];for(const[path,tmpl]of files)results.push(writeFile(path,renderTemplate(tmpl,data),{skipIfExists:!0,dryRun}));if(config.buildTool!=="gradle")return;const spotbugsInlineSignature=/(?:^|\n)[ \t]*spotbugs\s*\{/,snippets=[{signature:/(?:^|\n)[ \t]*pmd\s*\{/,kts:`pmd {
9
+ toolVersion = "${PMD_TOOL_VERSION}"
10
+ ruleSetFiles = files("config/pmd-ruleset.xml")
11
+ ruleSets = listOf()
12
+ }`,groovy:`pmd {
13
+ toolVersion = '${PMD_TOOL_VERSION}'
14
+ ruleSetFiles = files('config/pmd-ruleset.xml')
15
+ ruleSets = []
16
+ }`},{signature:spotbugsInlineSignature,kts:`spotbugs {
17
+ effort.set(com.github.spotbugs.snom.Effort.MAX)
18
+ reportLevel.set(com.github.spotbugs.snom.Confidence.MEDIUM)
19
+ excludeFilter.set(file("config/spotbugs-exclude.xml"))
20
+ }`,groovy:`spotbugs {
21
+ effort = com.github.spotbugs.snom.Effort.valueOf('MAX')
22
+ reportLevel = com.github.spotbugs.snom.Confidence.valueOf('MEDIUM')
23
+ excludeFilter = file('config/spotbugs-exclude.xml')
24
+ }`}],applySpotbugs=safeApplyFromSnippet(base,"spotbugs.gradle",{rootBuildSignatures:[spotbugsInlineSignature]});applySpotbugs&&snippets.push(applySpotbugs),injectGradleWiring(base,dryRun,{plugins:[{id:"pmd"},{id:"com.github.spotbugs",version:SPOTBUGS_PLUGIN_VERSION}],snippets})}export function generateDebtGates(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data={...config,strictnessTier:config.strictnessTier??"practical"};for(const[rel,tmpl]of[[".yamllint.yml","static-analysis/.yamllint.yml.ejs"],[".shellcheckrc","static-analysis/.shellcheckrc.ejs"]])results.push(writeFile(resolvedPath(base,rel),renderTemplate(tmpl,data),{skipIfExists:!0,dryRun:opts.dryRun}));return(config.language==="typescript"||config.language==="multi")&&(injectTestScripts(base,opts.dryRun),injectTypeScriptGateScripts(base,opts.dryRun),results.push(...emitTsGateScaffold(base,data,opts.dryRun)),injectTsGateToolchain(base,opts.dryRun),injectFormatScript(base,opts.dryRun)),pushJavaGateEssentials(results,config,data,opts.dryRun),config.language==="python"&&(results.push(writeFile(resolvedPath(base,"ruff.toml"),renderTemplate("static-analysis/ruff.toml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"requirements-dev.txt"),renderTemplate("static-analysis/requirements-dev.txt.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}))),config.enableDebtGates?((config.language==="typescript"||config.language==="multi")&&(results.push(writeFile(resolvedPath(base,"knip.json"),renderTemplate("static-analysis/knip.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,".dependency-cruiser.cjs"),renderTemplate("static-analysis/.dependency-cruiser.cjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),injectDepCruiserPackageJson(base,opts.dryRun)),config.language==="rust"&&results.push(writeFile(resolvedPath(base,"rustfmt.toml"),renderTemplate("static-analysis/rustfmt.toml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),config.language==="go"&&results.push(writeFile(resolvedPath(base,".golangci.yml"),renderTemplate("static-analysis/.golangci.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),pushJavaDebtGates(results,config,data,opts.dryRun),config.language==="kotlin"&&pushKotlinDebtGates(results,base,data,opts.dryRun),{files:results}):{files:results}}function pushKotlinDebtGates(results,base,data,dryRun){results.push(writeFile(resolvedPath(base,"config","detekt","detekt.yml"),renderTemplate("static-analysis/detekt.yml.ejs",data),{skipIfExists:!0,dryRun}))}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function computeMetricsProfile(config){return{includeBundleSize:config.archetype==="frontend-spa"&&config.language==="typescript",includePublicApiSurface:config.archetype==="library"&&config.language==="typescript",includeBranchCoverage:config.archetype==="backend-web-db"||config.archetype==="library",spotbugsEnabled:config.language==="java"||config.language==="multi",archunitEnabled:(config.language==="java"||config.language==="multi")&&config.architectureStyle!=="none"}}export function generateDebtRatchet(config,opts={dryRun:!1}){if(!config.enableDebtGates)return{files:[]};const base=config.targetDir,metricsProfile=computeMetricsProfile(config),data={...config,metricsProfile};return{files:[writeFile(resolvedPath(base,"scripts","debt-lib.mjs"),renderTemplate("scripts/debt-lib.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","capture-debt-baseline.mjs"),renderTemplate("scripts/capture-debt-baseline.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","debt-report.mjs"),renderTemplate("scripts/debt-report.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{CODEX_DERIVED_RULES}from"./codex-known-limitations.js";import{SHARED_GUARD_HOOKS}from"./codex-hooks.js";export const DERIVED_TRACK_KEYS=[...CODEX_DERIVED_RULES.map(rule=>`.agents/rules/${rule.file}`),".claude/hooks/lib.mjs",...SHARED_GUARD_HOOKS.map(hook=>`.claude/hooks/${hook}`),".claude/hooks/check-no-skipped-tests.mjs",".codex/codex-adapter.mjs"];const DERIVED_TRACK_KEY_SET=new Set(DERIVED_TRACK_KEYS);export function isDerivedTrackKey(key){return DERIVED_TRACK_KEY_SET.has(key)}
@@ -0,0 +1,4 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{basename,resolve}from"node:path";import{existsSync}from"node:fs";import{writeFile,resolvedPath,readFileTranslated}from"../utils/fs.js";import{renderTemplate}from"../utils/render.js";import{formatContent}from"../utils/prettier-format.js";import{runDocSet}from"../commands/doc-set.js";import{isoToday}from"../utils/today.js";const SKELETON_CATALOG={arc42:{variants:{solo:"docs/skeletons/arc42-canvas.md.ejs",small:"docs/skeletons/arc42-canvas.md.ejs",enterprise:"docs/skeletons/arc42-full.md.ejs"}},"adr-seed":{variants:"docs/adr/ADR-000_template.md.ejs",targetOverride:"docs/ADR/ADR-000_template.md"},slo:{variants:"docs/skeletons/slo.md.ejs"},"threat-model":{variants:{solo:"docs/skeletons/threat-model-4q.md.ejs",small:"docs/skeletons/threat-model-4q.md.ejs",enterprise:"docs/skeletons/threat-model-stride.md.ejs"}},"er-model":{variants:"docs/skeletons/er-model.md.ejs"},glossary:{variants:"docs/skeletons/glossary.md.ejs"},"test-strategy":{variants:"docs/skeletons/test-strategy.md.ejs"},governance:{variants:"docs/skeletons/governance.md.ejs"},"technical-debt":{variants:"docs/skeletons/technical-debt.md.ejs"},"decision-registry":{variants:"docs/skeletons/decision-registry.md.ejs"}};function resolveTemplatePath(entry,column){return typeof entry.variants=="string"?entry.variants:entry.variants[column]}function frontmatter(title,today){return["---",`title: '${title}'`,"doc_version: '0.1.0'","status: draft",`last_review: '${today}'`,"owner: ''","canonical_id: ''","tags: ['audience/dev', 'kind/reference']","related: []","---",""].join(`
3
+ `)}function bannerStubFingerprint(path,purpose){const title=basename(path).replace(/\.md$/,""),banner=`> **STUB \u2014 fill me in.** Scaffolded by \`check-doc-set --generate\` to satisfy the gold doc-set. ${purpose??""}`.trim();return[frontmatter(title,"<DATE>"),`# ${title}`,"",banner,""].join(`
4
+ `)}function isUntouchedBannerStub(disk,path,purpose){return disk.replace(/^last_review: '.*'$/m,"last_review: '<DATE>'")===bannerStubFingerprint(path,purpose)}function scaffoldRow(item,entry,ctx){const templatePath=resolveTemplatePath(entry,ctx.tierColumn),targetRel=entry.targetOverride??item.path,targetAbs=resolvedPath(ctx.repo,targetRel),diskExists=existsSync(targetAbs),bannerDetected=item.path.endsWith(".md")&&diskExists&&isUntouchedBannerStub(readFileTranslated(targetAbs,"utf-8"),item.path,item.purpose);if(!(bannerDetected||item.isMissing&&!diskExists))return null;const title=basename(targetRel).replace(/\.md$/,""),body=renderTemplate(templatePath,{...ctx.config,projectName:ctx.projectName,title,today:ctx.today}),rendered=templatePath.startsWith("docs/skeletons/")?frontmatter(title,ctx.today)+body:body;return{result:writeFile(targetAbs,formatContent(rendered,targetAbs,ctx.repo),{skipIfExists:!bannerDetected,dryRun:ctx.dryRun}),targetRel}}export function generateDocSetSkeletons(config,opts={dryRun:!1}){const files=[],scaffolded=[],unbound=[],repo=config.targetDir,{payload}=runDocSet({repo,json:!0,quiet:!0,...opts.manifest!==void 0?{manifest:opts.manifest}:{},...opts.profile!==void 0?{profile:opts.profile}:{}});if(!payload)return{files,scaffolded,unbound};const ctx={repo,config,projectName:config.projectName??basename(resolve(repo)),today:isoToday(),tierColumn:payload.tierColumn,dryRun:opts.dryRun},rows=[...(payload.missing??[]).map(m=>({...m,isMissing:!0})),...(payload.present??[]).map(p=>({...p,isMissing:!1}))];for(const item of rows){const entry=item.template?SKELETON_CATALOG[item.template]:void 0;if(!entry){item.isMissing&&unbound.push(item.path);continue}const scaffoldedRow=scaffoldRow(item,entry,ctx);scaffoldedRow&&(files.push(scaffoldedRow.result),scaffolded.push({path:scaffoldedRow.targetRel,template:item.template,action:scaffoldedRow.result.action}))}return{files,scaffolded,unbound,tierColumn:payload.tierColumn}}export function runDocSetPlanApply(opts={}){const repo=opts.repo?resolve(opts.repo):process.cwd(),config={targetDir:repo,projectName:basename(repo)};return generateDocSetSkeletons(config,{dryRun:!opts.apply,...opts.manifest!==void 0?{manifest:opts.manifest}:{},...opts.profile!==void 0?{profile:opts.profile}:{}})}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{levelAtLeast}from"../config/levels.js";function emitSpecKitFamilies(config,opts){const base=config.targetDir,out=[];for(const steering of["structure","tech","product"])out.push(writeFile(resolvedPath(base,"docs","steering",`${steering}.md`),renderTemplate(`docs/steering/${steering}.md.ejs`,config),{skipIfExists:!0,dryRun:opts.dryRun}));out.push(writeFile(resolvedPath(base,"docs","specs","atomic-task-list.md"),renderTemplate("docs/specs/atomic-task-list.md.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}));for(const bug of["bug-report","bug-analysis","bug-verification"])out.push(writeFile(resolvedPath(base,"docs","bugs",`${bug}.md`),renderTemplate(`docs/bugs/${bug}.md.ejs`,config),{skipIfExists:!0,dryRun:opts.dryRun}));return out}function emitDocGenerationTools(config,opts){const base=config.targetDir;return[writeFile(resolvedPath(base,"scripts","gen-doc-index.mjs"),renderTemplate("scripts/gen-doc-index.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","gen-llms-txt.mjs"),renderTemplate("scripts/gen-llms-txt.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"llms-txt.config.json"),renderTemplate("llms-txt.config.json.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun})]}export function generateDocs(config,opts={dryRun:!1}){if(config.governanceLevel==="L1")return{files:[]};const results=[],base=config.targetDir,data=config,adrDir=resolvedPath(base,join("docs","adr"));results.push(writeFile(join(adrDir,"ADR-000_template.md"),renderTemplate("docs/adr/ADR-000_template.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"docs","SECURE_CODING_CHECKLIST.md"),renderTemplate("docs/SECURE_CODING_CHECKLIST.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"docs","CODING_STANDARDS.md"),renderTemplate("docs/CODING_STANDARDS.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"docs","MASTER_TEST_PLAN.md"),renderTemplate("docs/MASTER_TEST_PLAN.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"docs","testing","POST_MERGE_REVIEW_TEMPLATE.md"),renderTemplate("docs/POST_MERGE_REVIEW_TEMPLATE.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),levelAtLeast(config.governanceLevel,"L3")&&results.push(writeFile(resolvedPath(base,"docs","SECURITY","ISO27001_ANNEX_A.md"),renderTemplate("docs/ISO27001_ANNEX_A.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,"docs","COMMANDS.md"),renderTemplate("documentation/cli-catalog.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));const runbooksDir=resolvedPath(base,"docs","runbooks");for(const runbook of["rollback","troubleshooting","prod-checklist","deployment"])results.push(writeFile(resolvedPath(runbooksDir,`${runbook}.md`),renderTemplate(`docs/runbooks/${runbook}.md.ejs`,data),{skipIfExists:!0,dryRun:opts.dryRun}));return config.governanceLevel==="L3"&&results.push(writeFile(resolvedPath(base,"docs","SECURITY","RISK_ASSESSMENT.md"),renderTemplate("security/RISK_ASSESSMENT.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(...emitSpecKitFamilies(config,opts)),results.push(...emitDocGenerationTools(config,opts)),{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{injectDevDependency}from"../utils/pkg.js";function duplicationThresholdFor(level){return level==="L1"?10:level==="L2"?5:3}export function generateDuplication(config,opts={dryRun:!1}){if(config.language!=="typescript")return{files:[]};if(!config.enableDebtGates)return{files:[]};const data={...config,duplicationThreshold:duplicationThresholdFor(config.governanceLevel)},files=[writeFile(resolvedPath(config.targetDir,".jscpd.json"),renderTemplate("static-analysis/jscpd.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts/check-duplication.mjs"),renderTemplate("scripts/check-duplication.mjs.ejs",data),{skipIfExists:!1,dryRun:opts.dryRun})];return injectDevDependency(config.targetDir,"jscpd","5.0.6",opts.dryRun),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateE2eConstitution(config,opts={dryRun:!1}){if(!(config.archetype==="frontend-spa"||config.archetype==="backend-web-db"))return{files:[]};const constitution=renderTemplate("e2e/E2E_CONSTITUTION.md.ejs",config),base=config.targetDir;return{files:[writeFile(resolvedPath(base,"docs","GOVERNANCE","E2E_CONSTITUTION.md"),constitution,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateEnvTemplate(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data={projectName:config.projectName},envExamplePath=resolvedPath(base,".env.example");return results.push(writeFile(envExamplePath,renderTemplate("local-wrapper/.env.example.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateEvidenceRetention(config,opts={dryRun:!1}){const base=config.targetDir,data={...config,evidenceRetention:config.evidenceRetention??{mode:"local-last-N",count:5}},files=[writeFile(resolvedPath(base,"scripts","evidence-rotate.mjs"),renderTemplate("scripts/evidence-rotate.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","evidence-prune.mjs"),renderTemplate("scripts/evidence-prune.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"docs","METHOD","EVIDENCE_RETENTION.md"),renderTemplate("governance/evidence-retention.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})];return config.enableEvidenceHarness!==!1&&files.push(writeFile(resolvedPath(base,"scripts","done-evidence.mjs"),renderTemplate("scripts/done-evidence.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","record-journey-evidence.mjs"),renderTemplate("scripts/record-journey-evidence.mjs.ejs",data),{skipIfExists:!1,backup:!0,dryRun:opts.dryRun})),config.governanceLevel==="L4"&&files.push(writeFile(resolvedPath(base,"evidence-files.json"),renderTemplate("evidence-files.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateFeatureMatrix(config,opts={dryRun:!1}){if(config.governanceLevel==="L1")return{files:[]};const base=config.targetDir,data=config,result=writeFile(resolvedPath(base,"docs","FEATURE_MATRIX.md"),renderTemplate("docs/FEATURE_MATRIX.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),gate=writeFile(resolvedPath(base,"scripts","check-feature-matrix.mjs"),renderTemplate("scripts/check-feature-matrix.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),schema=writeFile(resolvedPath(base,"schemas","rtm-verdict.schema.json"),renderTemplate("schemas/rtm-verdict.schema.json.ejs",data),{dryRun:opts.dryRun});return{files:[result,gate,schema]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateFrontendGovernance(config,opts={dryRun:!1}){if(!(config.archetype==="frontend-spa"||config.lanes.includes("frontend")))return{files:[]};const templateData={...config,frontend:config.frontend??{}},base=config.targetDir,constitution=renderTemplate("frontend/FRONTEND_CONSTITUTION.md.ejs",templateData),principles=renderTemplate("frontend/FE_DESIGN_PRINCIPLES.md.ejs",templateData);return{files:[writeFile(resolvedPath(base,"docs","GOVERNANCE","FRONTEND_CONSTITUTION.md"),constitution,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"docs","GOVERNANCE","FE_DESIGN_PRINCIPLES.md"),principles,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{injectDevDependency}from"../utils/pkg.js";import{formatContent}from"../utils/prettier-format.js";export function generateFrontendQuality(config,opts={dryRun:!1}){if(!(config.archetype==="frontend-spa"||config.lanes.includes("frontend")))return{files:[]};const base=config.targetDir,templateData={...config,frontend:config.frontend??{}},tokensDef=renderTemplate("frontend/design-tokens.json.ejs",templateData),verifyTokens=renderTemplate("scripts/verify-tokens.mjs.ejs",templateData),i18nScanner=renderTemplate("scripts/i18n-literal-scanner.mjs.ejs",templateData),i18nParity=renderTemplate("scripts/verify-i18n-parity.mjs.ejs",templateData),feCoverage=renderTemplate("scripts/verify-fe-coverage.mjs.ejs",templateData),vitestBrowser=renderTemplate("coverage/vitest.browser.config.ts.ejs",templateData),vrtSetup=renderTemplate("frontend/vrt-setup.md.ejs",templateData),lighthouseRc=renderTemplate("perf/lighthouserc.json.ejs",templateData),bundleBudget=renderTemplate("perf/bundle-budget.json.ejs",templateData),checkBundleSize=renderTemplate("scripts/check-bundle-size.mjs.ejs",templateData),stylelintRc=renderTemplate("static-analysis/stylelintrc.json.ejs",templateData),renderSmokeSpec=config.language==="typescript"||config.language==="multi"?renderTemplate("e2e/playwright-ts/render-smoke.spec.ts.ejs",templateData):null,result={files:[writeFile(resolvedPath(base,"design-tokens.json"),tokensDef,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","verify-tokens.mjs"),verifyTokens,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","i18n-literal-scanner.mjs"),i18nScanner,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","verify-i18n-parity.mjs"),i18nParity,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","verify-fe-coverage.mjs"),feCoverage,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"vitest.browser.config.ts"),vitestBrowser,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"docs","GOVERNANCE","VRT_SETUP.md"),vrtSetup,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,".lighthouserc.json"),lighthouseRc,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"bundle-budget.json"),bundleBudget,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts","check-bundle-size.mjs"),checkBundleSize,{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,".stylelintrc.json"),stylelintRc,{skipIfExists:!0,dryRun:opts.dryRun}),...renderSmokeSpec!==null?[(()=>{const renderSmokePath=resolvedPath(base,"tests","e2e","render-smoke.spec.ts");return writeFile(renderSmokePath,formatContent(renderSmokeSpec,renderSmokePath,base),{skipIfExists:!0,dryRun:opts.dryRun})})()]:[]]};return injectDevDependency(base,"stylelint","^16.0.0",opts.dryRun),result}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateGap(config,opts={dryRun:!1}){if(config.governanceLevel==="L1")return{files:[]};const base=config.targetDir,data=config,result=writeFile(resolvedPath(base,"docs","GAP.md"),renderTemplate("docs/GAP.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),gate=writeFile(resolvedPath(base,"scripts","gen-gap.mjs"),renderTemplate("scripts/gen-gap.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun});return{files:[result,gate]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateGdprControls(config,opts={dryRun:!1}){const base=config.targetDir,data=config,skip={skipIfExists:!0,dryRun:opts.dryRun},docsDir="docs/compliance/gdpr";return[writeFile(resolvedPath(base,"scripts","check-gdpr-controls.mjs"),renderTemplate("audit/gdpr/check-gdpr-controls.mjs.ejs",data),skip),writeFile(resolvedPath(base,docsDir,"dpia.md"),renderTemplate("audit/gdpr/dpia.md.ejs",data),skip),writeFile(resolvedPath(base,docsDir,"data-flow-map.md"),renderTemplate("audit/gdpr/data-flow-map.md.ejs",data),skip),writeFile(resolvedPath(base,docsDir,"controls-to-gates.md"),renderTemplate("audit/gdpr/controls-to-gates.md.ejs",data),skip)]}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{chmodTranslated,resolvedPath,writeFile}from"../utils/fs.js";import{mutatePackageJson}from"../utils/pkg.js";const HOOK_MODE=493;function writeHook(filePath,content,dryRun){const result=writeFile(filePath,content,{skipIfExists:!0,dryRun});return!dryRun&&result.action!=="skipped"&&chmodTranslated(filePath,HOOK_MODE),result}function isTypeScript(config){return config.language==="typescript"||config.language==="multi"}function injectPrepareScript(targetDir,dryRun){mutatePackageJson(targetDir,dryRun,pkg=>{const hooksCmd="git config core.hooksPath .githooks",scripts=pkg.scripts??{},existing=scripts.prepare??"";return existing.includes(hooksCmd)?!1:(scripts.prepare=existing?`${existing} && ${hooksCmd}`:hooksCmd,pkg.scripts=scripts,!0)})}export function generateGithooks(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data=config,hooksDir=resolvedPath(base,".githooks");if(results.push(writeHook(resolvedPath(hooksDir,"pre-commit"),renderTemplate("githooks/pre-commit.ejs",data),opts.dryRun)),results.push(writeHook(resolvedPath(hooksDir,"pre-push"),renderTemplate("githooks/pre-push.ejs",data),opts.dryRun)),results.push(writeHook(resolvedPath(hooksDir,"commit-msg"),renderTemplate("githooks/commit-msg.ejs",data),opts.dryRun)),isTypeScript(config))injectPrepareScript(base,opts.dryRun);else{const setupPath=resolvedPath(base,"scripts","setup-hooks.sh"),setupResult=writeFile(setupPath,renderTemplate("githooks/setup-hooks.sh.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun});!opts.dryRun&&setupResult.action!=="skipped"&&chmodTranslated(setupPath,HOOK_MODE),results.push(setupResult)}return{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{chmodTranslated,resolvedPath,writeFile}from"../utils/fs.js";const SCRIPT_MODE=493;export function generateGithubSetup(config,opts={dryRun:!1}){if(!(config.permitGitHub??config.useGitHub))return{files:[]};const base=config.targetDir,data=config,files=[];if(config.governanceLevel!=="L1"){const setupScript=resolvedPath(base,"scripts","setup-repo.sh"),result=writeFile(setupScript,renderTemplate("scripts/setup-repo.sh.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun});!opts.dryRun&&result.action!=="skipped"&&chmodTranslated(setupScript,SCRIPT_MODE),files.push(result)}const bpScript=resolvedPath(base,"scripts","apply-branch-protection.mjs"),bpResult=writeFile(bpScript,renderTemplate("scripts/apply-branch-protection.mjs.ejs",data),{dryRun:opts.dryRun});!opts.dryRun&&bpResult.action!=="skipped"&&chmodTranslated(bpScript,SCRIPT_MODE),files.push(bpResult);for(const name of["check-ci-tiers.mjs","check-action-pins.mjs","check-workflow-perms.mjs","check-merge-method.mjs","ci-classify-changes.mjs"]){const scriptPath=resolvedPath(base,"scripts",name),result=writeFile(scriptPath,renderTemplate(`scripts/${name}.ejs`,data),{dryRun:opts.dryRun});!opts.dryRun&&result.action!=="skipped"&&chmodTranslated(scriptPath,SCRIPT_MODE),files.push(result)}return{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{levelAtLeast}from"../config/levels.js";import{resolvePipelineStyle,collaborationModeFromAnswers,resolveCollaborationMode,resolveDefaultBranchingStrategy}from"../config/collaboration-mode-defaults.js";import{isSubtreeFrontendLane}from"../detectors/lanes.js";export function resolveStyle(config){if(config.pipelineStyle)return config.pipelineStyle;if(config.collaborationMode)return resolvePipelineStyle(config.collaborationMode,config.governanceLevel);if(config.enableSoloDevMode){const mode=collaborationModeFromAnswers({soloDevMode:!0});return resolvePipelineStyle(mode,config.governanceLevel)}return config.ciTierMode==="baseline"?"starter":"standard"}export function releaseEnforcesMutation(config){return resolveStyle(config)!=="starter"}function generateIndustrialWorkflows(workflowsDir,data,dryRun){return[writeFile(join(workflowsDir,"12-mutation-scheduled.yml"),renderTemplate("github/workflows/12-mutation-scheduled.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"13-archunit-extended.yml"),renderTemplate("github/workflows/13-archunit-extended.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"14-license-scan.yml"),renderTemplate("github/workflows/14-license-scan.yml.ejs",data),{skipIfExists:!0,dryRun})]}const WEB_ARCHETYPES=new Set(["frontend-spa"]),PEER_REVIEW="peer-review",GATED_REVIEW="gated-review";function needsCodeql(cm,isL2Plus,language){return(cm===PEER_REVIEW&&isL2Plus||cm===GATED_REVIEW)&&language!=="rust"}function isReviewMode(cm){return cm===PEER_REVIEW||cm===GATED_REVIEW}function needsFrontendQuality(cm,isL2Plus,language,archetype){return isReviewMode(cm)&&isL2Plus&&language==="typescript"&&archetype!==void 0&&WEB_ARCHETYPES.has(archetype)}function needsFrontendLane(config,cm,isL2Plus){return isReviewMode(cm)&&isL2Plus&&isSubtreeFrontendLane(config)}function generateCiGapWorkflows(workflowsDir,config,dryRun){const files=[],cm=resolveCollaborationMode(config),gl=config.governanceLevel,isL2Plus=new Set(["L2","L3","L4"]).has(gl),isL3Plus=new Set(["L3","L4"]).has(gl);return cm==="trunk-solo"&&isL2Plus&&files.push(writeFile(join(workflowsDir,"06-nightly-lite.yml"),renderTemplate("github/workflows/06-nightly-lite.yml.ejs",config),{skipIfExists:!0,dryRun})),cm==="trunk-solo"&&isL3Plus&&files.push(writeFile(join(workflowsDir,"07-weekly-lite.yml"),renderTemplate("github/workflows/07-weekly-lite.yml.ejs",config),{skipIfExists:!0,dryRun})),needsCodeql(cm,isL2Plus,config.language)&&files.push(writeFile(join(workflowsDir,"15-codeql.yml"),renderTemplate("github/workflows/15-codeql.yml.ejs",config),{skipIfExists:!0,dryRun})),needsFrontendQuality(cm,isL2Plus,config.language,config.archetype)&&files.push(writeFile(join(workflowsDir,"16-frontend-quality.yml"),renderTemplate("github/workflows/16-frontend-quality.yml.ejs",config),{skipIfExists:!0,dryRun})),needsFrontendLane(config,cm,isL2Plus)&&files.push(writeFile(join(workflowsDir,"18-frontend-lane.yml"),renderTemplate("github/workflows/18-frontend-lane.yml.ejs",config),{skipIfExists:!0,dryRun})),cm===GATED_REVIEW&&isL3Plus&&files.push(writeFile(join(workflowsDir,"17-ossf-scorecard.yml"),renderTemplate("github/workflows/17-ossf-scorecard.yml.ejs",config),{skipIfExists:!0,dryRun})),files}function generateScheduledWorkflows(workflowsDir,data,dryRun){return[writeFile(join(workflowsDir,"_nightly.yml"),renderTemplate("github/workflows/_nightly.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_shared-security.yml"),renderTemplate("github/workflows/_shared-security.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_weekly.yml"),renderTemplate("github/workflows/_weekly.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_monthly.yml"),renderTemplate("github/workflows/_monthly.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"06-nightly.yml"),renderTemplate("github/workflows/06-nightly.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"07-weekly.yml"),renderTemplate("github/workflows/07-weekly.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"08-monthly.yml"),renderTemplate("github/workflows/08-monthly.yml.ejs",data),{skipIfExists:!0,dryRun})]}function generateCiWorkflows(workflowsDir,config,dryRun){const data=config,style=resolveStyle(config),cm=resolveCollaborationMode(config),files=[writeFile(join(workflowsDir,"01-pr-fast.yml"),renderTemplate("github/workflows/01-pr-fast.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"02-pr-extended.yml"),renderTemplate("github/workflows/02-pr-extended.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"03-human-approval.yml"),renderTemplate("github/workflows/03-human-approval.yml.ejs",data),{skipIfExists:!0,dryRun})];style!=="starter"&&files.push(writeFile(join(workflowsDir,"05-release.yml"),renderTemplate("github/workflows/05-release.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_sigstore-retry-sign.yml"),renderTemplate("github/workflows/_sigstore-retry-sign.yml.ejs",data),{skipIfExists:!0,dryRun}));const isL3Plus=levelAtLeast(config.governanceLevel,"L3");return style!=="starter"&&isL3Plus&&cm!=="trunk-solo"&&files.push(...generateScheduledWorkflows(workflowsDir,data,dryRun)),isL3Plus&&files.push(writeFile(join(workflowsDir,"09-heartbeat.yml"),renderTemplate("github/workflows/09-heartbeat.yml.ejs",data),{skipIfExists:!0,dryRun})),style==="industrial"&&files.push(...generateIndustrialWorkflows(workflowsDir,data,dryRun)),files.push(...generateCiGapWorkflows(workflowsDir,config,dryRun)),config.enableSoloDevMode&&files.push(writeFile(join(workflowsDir,"drift-shadow.yml"),renderTemplate("github/workflows/drift-shadow.yml.ejs",data),{skipIfExists:!0,dryRun})),(config.deployTarget??"none")!=="none"&&files.push(writeFile(join(workflowsDir,"04-deploy-test.yml"),renderTemplate("github/workflows/04-deploy-test.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"10-deploy-prod.yml"),renderTemplate("github/workflows/10-deploy-prod.yml.ejs",data),{skipIfExists:!0,dryRun})),files}function generateAgentGovernanceWorkflows(workflowsDir,config,dryRun){const data=config;return[writeFile(join(workflowsDir,"_label-on-approve.yml"),renderTemplate("github/workflows/_label-on-approve.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_ai-draft-check.yml"),renderTemplate("github/workflows/_ai-draft-check.yml.ejs",data),{skipIfExists:!0,dryRun}),writeFile(join(workflowsDir,"_pr-staleness.yml"),renderTemplate("github/workflows/_pr-staleness.yml.ejs",data),{skipIfExists:!0,dryRun})]}function generateIssueTemplates(issueTemplatesDir,config,dryRun){const data=config,files=[writeFile(join(issueTemplatesDir,"task-brief.yml"),renderTemplate("github/issue-templates/task-brief.yml.ejs",data),{skipIfExists:!0,dryRun})];for(const tpl of["bug-report.yml","feature-request.yml","epic.yml","config.yml"])files.push(writeFile(join(issueTemplatesDir,tpl),renderTemplate(`github/issue-templates/${tpl}`,data),{skipIfExists:!0,dryRun}));return config.governanceLevel!=="L1"&&files.push(writeFile(join(issueTemplatesDir,"compliance-item.yml"),renderTemplate("github/issue-templates/compliance-item.yml.ejs",data),{skipIfExists:!0,dryRun})),files}function resolveBranchingStrategy(config){return config.branchingStrategy?config.branchingStrategy:config.collaborationMode?resolveDefaultBranchingStrategy(config.collaborationMode):config.enableSoloDevMode?"trunk-direct":"github-flow"}export function generateGithub(config,opts={dryRun:!1}){const data={...config,branchingStrategy:resolveBranchingStrategy(config)},githubDir=resolvedPath(config.targetDir,".github"),workflowsDir=join(githubDir,"workflows"),issueTemplatesDir=join(githubDir,"ISSUE_TEMPLATE"),actionsDir=join(githubDir,"actions");return{files:[...generateCiWorkflows(workflowsDir,data,opts.dryRun),...generateAgentGovernanceWorkflows(workflowsDir,data,opts.dryRun),writeFile(join(githubDir,"PULL_REQUEST_TEMPLATE.md"),renderTemplate("github/PULL_REQUEST_TEMPLATE.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(githubDir,"extended-ci-paths.txt"),renderTemplate("github/extended-ci-paths.txt.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),...generateIssueTemplates(issueTemplatesDir,data,opts.dryRun),writeFile(join(workflowsDir,"issue-state.yml"),renderTemplate("github/workflows/issue-state.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(githubDir,"dependabot.yml"),renderTemplate("github/dependabot.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(join(actionsDir,"sign-and-attest","action.yml"),renderTemplate("github/actions/sign-and-attest/action.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateGitignore(config,opts={dryRun:!1}){const base=config.targetDir,data={...config,evidenceRetention:config.evidenceRetention??{mode:"local-last-N",count:5}};return{files:[writeFile(resolvedPath(base,".gitignore"),renderTemplate("root/.gitignore.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,3 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{getFilteredInvariants,getInvariantsByTier}from"../invariants/filter.js";import{TIER_LABELS}from"../invariants/tiers.js";const OPTIONAL_TIERS=["data","security","operational"];export function generateGlobalInvariants(config,opts={dryRun:!1}){if(!config.invariantTiers.some(t=>OPTIONAL_TIERS.includes(t)))return{action:"skipped",reason:"not-applicable",path:resolvedPath(config.targetDir,"GLOBAL_INVARIANTS.md")};const invariants=getFilteredInvariants({language:config.language,governanceLevel:config.governanceLevel,invariantTiers:config.invariantTiers,...config.includeExtendedInvariants?{includeExtendedInvariants:!0}:{},...config.projectInvariants!==void 0?{projectInvariants:config.projectInvariants}:{}}),invariantsByTier=getInvariantsByTier(invariants),data={...config,invariants,invariantsByTier,tierLabels:TIER_LABELS},content=renderTemplate("global-invariants/GLOBAL_INVARIANTS.md.ejs",data).trimEnd()+`
3
+ `;return writeFile(resolvedPath(config.targetDir,"GLOBAL_INVARIANTS.md"),content,{backup:!0,dryRun:opts.dryRun})}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateGoBoundaries(config,opts={dryRun:!1}){if(config.language!=="go")return{files:[]};if(config.architectureStyle!=="hexagonal")return{files:[]};const base=config.targetDir,data=config;return{files:[writeFile(resolvedPath(base,".golangci-boundaries.yml"),renderTemplate("boundaries/golangci-boundaries.yml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts/check-boundaries.mjs"),renderTemplate("boundaries/check-boundaries-go.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{writeFile,resolvedPath}from"../utils/fs.js";import{renderTemplate}from"../utils/render.js";const PER_STACK_REGISTRY={typescript:"gold-registry.typescript.yml",java:"gold-registry.java.yml",kotlin:"gold-registry.java.yml"},STANDARDS=[{rel:"gold-registry.yml",tpl:"standards/gold-registry.yml.ejs"},{rel:"thresholds.yml",tpl:"standards/thresholds.yml.ejs"},{rel:"gold-doc-set.yml",tpl:"standards/gold-doc-set.yml.ejs"},{rel:"doc-profile",tpl:"standards/doc-profile.ejs"}];export function generateGoldKit(config,opts={dryRun:!1}){const base=config.targetDir,files=[];files.push(writeFile(resolvedPath(base,"scripts","gold-audit.mjs"),renderTemplate("scripts/gold-audit.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}));for(const{rel,tpl}of STANDARDS)files.push(writeFile(resolvedPath(base,"standards",rel),renderTemplate(tpl,config),{skipIfExists:!0,dryRun:opts.dryRun}));const stackTpl=PER_STACK_REGISTRY[config.language];return stackTpl&&files.push(writeFile(resolvedPath(base,"standards",stackTpl.replace(/\.ejs$/,"")),renderTemplate(`standards/${stackTpl}.ejs`,config),{skipIfExists:!0,dryRun:opts.dryRun})),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{chmodTranslated,writeFile,resolvedPath}from"../utils/fs.js";const SCRIPT_MODE=493;export function generateInfra(config,opts={dryRun:!1}){if(config.deployTarget==="azure-container-app"){const infraDir=resolvedPath(config.targetDir,"infra","azure");return{files:[writeFile(join(infraDir,"containerapp.tpl.yaml"),renderTemplate("infra/azure/containerapp.tpl.yaml.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun})]}}if(config.deployTarget==="nas-compose"){const infraDir=resolvedPath(config.targetDir,"infra","nas-compose"),scriptPath=join(infraDir,"deploy.sh"),scriptResult=writeFile(scriptPath,renderTemplate("infra/nas-compose/deploy.sh.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun});return!opts.dryRun&&scriptResult.action!=="skipped"&&chmodTranslated(scriptPath,SCRIPT_MODE),{files:[scriptResult]}}return{files:[]}}
@@ -0,0 +1,7 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{existsSync}from"node:fs";import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{resolvedPath,writeFile,writeFileTranslated,readFileTranslated}from"../utils/fs.js";import{formatContent}from"../utils/prettier-format.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";function appendCargoDevDep(base,name,version,dryRun){if(dryRun)return;const cargoPath=join(base,"Cargo.toml");if(!existsSync(cargoPath))return;const content=readFileTranslated(cargoPath,"utf-8");if(content.includes(name))return;const section="[dev-dependencies]",entry=`${name} = "${version}"
3
+ `;content.includes(section)?writeFileTranslated(cargoPath,content.replace(section,`${section}
4
+ ${entry}`)):writeFileTranslated(cargoPath,`${content.trimEnd()}
5
+
6
+ ${section}
7
+ ${entry}`)}function emitJavaIntegrationTesting(config,base,data,dryRun){const supportPkg=config.basePackage?`src/test/java/${config.basePackage.replace(/\./g,"/")}/support`:"src/test/java/support",results=[writeFile(resolvedPath(base,supportPkg,"AbstractIntegrationTest.java"),renderTemplate("integration-testing/AbstractIntegrationTest.java.ejs",data),{skipIfExists:!0,dryRun}),writeFile(resolvedPath(base,supportPkg,"NoH2ArchTest.java"),renderTemplate("integration-testing/NoH2ArchTest.java.ejs",data),{skipIfExists:!0,dryRun}),writeFile(resolvedPath(base,"config","testcontainers-deps.gradle"),renderTemplate("integration-testing/testcontainers-deps.gradle.ejs",data),{skipIfExists:!0,dryRun})];if(config.buildTool==="gradle"){const applyTestcontainers=safeApplyFromSnippet(base,"config/testcontainers-deps.gradle");applyTestcontainers&&injectGradleWiring(base,dryRun,{snippets:[applyTestcontainers]})}return results}export function generateIntegrationTesting(config,opts={dryRun:!1}){if(!(config.databaseEngine!=null?config.databaseEngine!=="none":config.hasDatabase)||config.governanceLevel==="L1")return{files:[]};const base=config.targetDir,data=config,results=[];if((config.language==="java"||config.language==="multi")&&results.push(...emitJavaIntegrationTesting(config,base,data,opts.dryRun)),config.language==="typescript"||config.language==="multi"){const testSetupPath=resolvedPath(base,"__tests__","integrations","test-setup.ts");results.push(writeFile(testSetupPath,formatContent(renderTemplate("integration-testing/test-setup.ts.ejs",data),testSetupPath,base),{skipIfExists:!0,dryRun:opts.dryRun})),results.push(writeFile(resolvedPath(base,".eslintrc-no-fake-db.json"),renderTemplate("integration-testing/eslint-no-fake-db.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));const noFakeDbConfigPath=resolvedPath(base,"eslint.config.no-fake-db.mjs");results.push(writeFile(noFakeDbConfigPath,formatContent(renderTemplate("integration-testing/eslint.config.no-fake-db.mjs.ejs",data),noFakeDbConfigPath,base),{skipIfExists:!0,dryRun:opts.dryRun}))}if(config.language==="rust")results.push(writeFile(resolvedPath(base,"tests","db_fixture.rs"),renderTemplate("integration-testing/db_fixture.rs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),appendCargoDevDep(base,"testcontainers","0.23",opts.dryRun);else if(config.language==="go"){const goTemplate=config.databaseEngine==="sqlite"?"integration-testing/main_test_sqlite.go.ejs":"integration-testing/main_test.go.ejs";results.push(writeFile(resolvedPath(base,"tests","main_test.go"),renderTemplate(goTemplate,data),{skipIfExists:!0,dryRun:opts.dryRun}))}else config.language==="python"&&results.push(writeFile(resolvedPath(base,"tests","conftest.py"),renderTemplate("integration-testing/conftest.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));return{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateIso27001(config,opts={dryRun:!1}){if(config.industryOverlay!=="iso27001")return{files:[]};const skip={skipIfExists:!0,dryRun:opts.dryRun};return{files:[writeFile(resolvedPath(config.targetDir,"docs/compliance","iso27001-controls-gate-map.md"),renderTemplate("audit/iso27001/iso27001-controls-gate-map.md.ejs",config),skip)]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateIso9001(config,opts={dryRun:!1}){if(config.industryOverlay!=="iso9001")return{files:[]};const base=config.targetDir,data=config,skip={skipIfExists:!0,dryRun:opts.dryRun},qualityDir="docs/quality";return{files:[writeFile(resolvedPath(base,qualityDir,"REQUIREMENTS_TRACEABILITY.md"),renderTemplate("quality/iso9001/REQUIREMENTS_TRACEABILITY.md.ejs",data),skip),writeFile(resolvedPath(base,qualityDir,"DOCUMENT_CONTROL.md"),renderTemplate("quality/iso9001/DOCUMENT_CONTROL.md.ejs",data),skip),writeFile(resolvedPath(base,qualityDir,"CAPA_LOG.md"),renderTemplate("quality/iso9001/CAPA_LOG.md.ejs",data),skip),writeFile(resolvedPath(base,"scripts","check-iso9001.mjs"),renderTemplate("scripts/check-iso9001.mjs.ejs",data),skip)]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ export const TASK_SIZE_LABELS=[{name:"size:XS",description:"Tiny task \u2014 single file, minimal plan, 1 review agent",color:"c2e0c6"},{name:"size:S",description:"Small task \u2014 2\u20135 files, brief plan, 1 review agent",color:"fef2c0"},{name:"size:Standard",description:"Standard task \u2014 multi-file, full plan, 2 review agents",color:"fbca04"}];
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{chmodTranslated,resolvedPath,unlinkTranslated,writeFile}from"../utils/fs.js";export function generateLocalWrapper(config,opts={dryRun:!1}){const results=[],base=config.targetDir,data={projectName:config.projectName,enableEvidenceHarness:config.enableEvidenceHarness},makefilePath=resolvedPath(base,"Makefile");results.push(writeFile(makefilePath,renderTemplate("local-wrapper/Makefile.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}));const runShPath=resolvedPath(base,"run.sh"),runShResult=writeFile(runShPath,renderTemplate("local-wrapper/run.sh.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun});if(results.push(runShResult),!opts.dryRun&&runShResult.action!=="skipped")try{chmodTranslated(runShPath,493)}catch(err){try{unlinkTranslated(runShPath)}catch{}throw new Error(`chmod run.sh failed: ${err.message}. File removed to avoid partial state.`,{cause:err})}return{files:results}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{readFileSync,existsSync}from"node:fs";import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";function isSpringBootProject(targetDir){const pomPath=join(targetDir,"pom.xml");if(existsSync(pomPath))try{return readFileSync(pomPath,"utf8").includes("spring-boot-starter")}catch{return!1}const gradlePath=join(targetDir,"build.gradle"),gradleKtsPath=join(targetDir,"build.gradle.kts");for(const gPath of[gradlePath,gradleKtsPath])if(existsSync(gPath))try{if(readFileSync(gPath,"utf8").includes("spring-boot"))return!0}catch{continue}return!1}export function generateModulith(config,opts={dryRun:!1}){if(config.language!=="java"&&config.language!=="kotlin"&&config.language!=="multi")return{files:[]};if(!(isSpringBootProject(config.targetDir)||config.kitEnabled===!0))return{files:[]};const packagePath=config.basePackage?config.basePackage.replace(/\./g,"/")+"/modulith":"modulith",data={...config,basePackage:config.basePackage??"com.example"},files=[writeFile(resolvedPath(config.targetDir,"src","test","java",packagePath,"ApplicationModulesTest.java"),renderTemplate("java/modulith/ApplicationModulesTest.java.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})];return files.push(...emitAndWireModulithDeps(config,data,opts.dryRun)),{files}}function emitAndWireModulithDeps(config,data,dryRun){const base=config.targetDir;if(config.buildTool==="gradle"){const result=writeFile(resolvedPath(base,"gradle","modulith-deps.gradle"),renderTemplate("java/modulith/modulith-deps.gradle.ejs",data),{skipIfExists:!0,dryRun}),apply=safeApplyFromSnippet(base,"gradle/modulith-deps.gradle");return apply&&injectGradleWiring(base,dryRun,{snippets:[apply]}),[result]}return config.buildTool==="maven"?[writeFile(resolvedPath(base,"docs","modulith-maven-setup.md"),renderTemplate("java/modulith/modulith-maven-setup.md.ejs",data),{skipIfExists:!0,dryRun})]:[]}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{injectGradleWiring,safeApplyFromSnippet}from"../utils/gradle.js";import{resolveEffectiveThresholds}from"../config/thresholds.js";import{isL3Allowed}from"../utils/maturity-check.js";import{levelAtLeast}from"../config/levels.js";import{releaseEnforcesMutation}from"./github.js";const PITEST_PLUGIN_VERSION="1.15.0";function shouldEmit(target,language,acceptBeta){return language===target?!0:language!=="multi"?!1:isL3Allowed(target,"mutation",acceptBeta).allowed}function emitJavaMutation(targetDir,buildTool,data,dryRun){if(buildTool==="maven")return writeFile(resolvedPath(targetDir,"docs","mutation","pitest-maven-setup.md"),renderTemplate("mutation/pitest-maven-setup.md.ejs",data),{skipIfExists:!0,dryRun});const result=writeFile(resolvedPath(targetDir,"gradle","pitest.gradle"),renderTemplate("mutation/pitest.gradle.ejs",data),{skipIfExists:!0,dryRun}),apply=safeApplyFromSnippet(targetDir,"gradle/pitest.gradle");return injectGradleWiring(targetDir,dryRun,{plugins:[{id:"info.solidsoft.pitest",version:PITEST_PLUGIN_VERSION}],snippets:apply?[apply]:[]}),result}export function generateMutation(config,opts={dryRun:!1}){if(!levelAtLeast(config.governanceLevel,"L3")&&!releaseEnforcesMutation(config))return{files:[]};const{language,targetDir,acceptBetaTools=!1}=config;if(language!=="multi"&&!isL3Allowed(language,"mutation",acceptBetaTools).allowed)return{files:[]};const data={...config,mutationThreshold:resolveEffectiveThresholds(config).mutationScore,basePackage:config.basePackage??"com.example",modulePath:config.projectName.replace(/-/g,"_")},files=[writeFile(resolvedPath(targetDir,"docs","mutation","README.md"),renderTemplate("mutation/README.md.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})];return shouldEmit("java",language,acceptBetaTools)&&files.push(emitJavaMutation(targetDir,config.buildTool,data,opts.dryRun)),shouldEmit("typescript",language,acceptBetaTools)&&files.push(writeFile(resolvedPath(targetDir,"stryker.conf.json"),renderTemplate("mutation/stryker.conf.json.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),language==="rust"?files.push(writeFile(resolvedPath(targetDir,"cargo-mutants.toml"),renderTemplate("mutation/cargo-mutants.toml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(targetDir,"scripts","parse-mutants.mjs"),renderTemplate("mutation/parse-mutants.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})):language==="python"&&files.push(writeFile(resolvedPath(targetDir,"mutmut-config.toml"),renderTemplate("mutation/mutmut-config.toml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(targetDir,"scripts","parse-mutmut.py"),renderTemplate("mutation/parse-mutmut.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateObservability(config,opts={dryRun:!1}){return!config.observability||config.observability.provider==="none"?{files:[]}:{files:[writeFile(resolvedPath(config.targetDir,"docs","OBSERVABILITY.md"),renderTemplate("observability/setup.md.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generateOperations(config,opts={dryRun:!1}){const path=resolvedPath(config.targetDir,"docs","OPERATIONS_HANDBOOK.md"),content=renderTemplate("operations/handbook.md.ejs",config);return{files:[writeFile(path,content,{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{join}from"node:path";import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";const SCENARIO_NAMES=["load","stress","spike","soak","volume","breakpoint","smoke","ramp-up","ramp-down","steady-state","burst","endurance"],REPORT_NAMES=["html-report","json-report","csv-report"];export function generatePerfK6(config,opts={dryRun:!1}){if(!config.enablePerfTesting)return{files:[]};const base=config.targetDir,data=config,skip={skipIfExists:!0,dryRun:opts.dryRun},workflowsDir=resolvedPath(base,".github","workflows"),scenariosDir=resolvedPath(base,"perf","k6","scenarios"),reportsDir=resolvedPath(base,"perf","k6","reports"),seedDir=resolvedPath(base,"perf","k6","seed"),scriptsDir=resolvedPath(base,"scripts"),files=[];files.push(writeFile(join(workflowsDir,"11-k6-on-demand.yml"),renderTemplate("github/workflows/11-k6-on-demand.yml.ejs",data),skip)),files.push(writeFile(join(workflowsDir,"_k6-runner.yml"),renderTemplate("github/workflows/_k6-runner.yml.ejs",data),skip));for(const name of SCENARIO_NAMES)files.push(writeFile(join(scenariosDir,`${name}.js`),renderTemplate(`perf/k6/scenarios/${name}.js.ejs`,data),skip));for(const name of REPORT_NAMES)files.push(writeFile(join(reportsDir,`${name}.py`),renderTemplate(`perf/k6/reports/${name}.py.ejs`,data),skip));return files.push(writeFile(join(seedDir,"test-data.sql"),renderTemplate("perf/k6/seed/test-data.sql.ejs",data),skip)),files.push(writeFile(join(scriptsDir,"validate-k6-scenarios.mjs"),renderTemplate("scripts/validate-k6-scenarios.mjs.ejs",data),skip)),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{generateGdprControls}from"./gdpr.js";function auditMainPkg(config){return config.basePackage?`src/main/java/${config.basePackage.replace(/\./g,"/")}/audit`:"src/main/java/audit"}function archTestPkg(config){return config.basePackage?`src/test/java/${config.basePackage.replace(/\./g,"/")}/architecture`:"src/test/java/architecture"}function generatePharmaJava(config,opts){if(config.language!=="java")return[];const base=config.targetDir,data=config,skip={skipIfExists:!0,dryRun:opts.dryRun},mainPkg=auditMainPkg(config),testPkg=archTestPkg(config);return[writeFile(resolvedPath(base,mainPkg,"AuditEvent.java"),renderTemplate("java/pharma/AuditEvent.java.ejs",data),skip),writeFile(resolvedPath(base,mainPkg,"AuditMapper.java"),renderTemplate("java/pharma/AuditMapper.java.ejs",data),skip),writeFile(resolvedPath(base,testPkg,"PharmaArchUnitTest.java"),renderTemplate("java/pharma/archunit-pharma.ejs",data),skip)]}function generateGenericAudit(config,opts){const base=config.targetDir,data=config,skip={skipIfExists:!0,dryRun:opts.dryRun};return[writeFile(resolvedPath(base,"docs/compliance","audit-trail-policy.md"),renderTemplate("audit/generic/audit-trail-policy.md.ejs",data),skip),writeFile(resolvedPath(base,"docs/compliance","audit-gate-rules.md"),renderTemplate("audit/generic/audit-gate-rules.md.ejs",data),skip)]}export function generatePharma(config,opts={dryRun:!1}){const overlay=config.industryOverlay;if(!overlay||overlay==="none")return{files:[]};if(overlay==="iso9001")return{files:[]};let files;return overlay==="pharma"?files=generatePharmaJava(config,opts):overlay==="gdpr"?files=[...generateGenericAudit(config,opts),...generateGdprControls(config,opts)]:files=generateGenericAudit(config,opts),{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";const E2E_ARCHETYPES=new Set(["frontend-spa","backend-web-db"]);export function generatePlaywrightPython(config,opts={dryRun:!1}){if(config.language!=="python")return{files:[]};if(!E2E_ARCHETYPES.has(config.archetype))return{files:[]};const base=config.targetDir,data=config;return{files:[writeFile(resolvedPath(base,"tests","e2e","conftest.py"),renderTemplate("e2e/playwright-python/conftest.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"tests","e2e","test_smoke.py"),renderTemplate("e2e/playwright-python/test_smoke.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"tests","e2e","a11y","__init__.py"),"",{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"tests","e2e","a11y","run_axe.py"),renderTemplate("e2e/playwright-python/run_axe.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"tests","e2e","test_a11y.py"),renderTemplate("e2e/playwright-python/test_a11y.py.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";import{formatContent}from"../utils/prettier-format.js";const A11Y_ARCHETYPES=new Set(["frontend-spa","backend-web-db"]);export function generatePlaywrightTs(config,opts={dryRun:!1}){if(config.language!=="typescript"&&config.language!=="multi")return{files:[]};if(!A11Y_ARCHETYPES.has(config.archetype))return{files:[]};const base=config.targetDir,runAxePath=resolvedPath(base,"tests","e2e","a11y","run-axe.ts"),a11ySpecPath=resolvedPath(base,"tests","e2e","a11y.spec.ts");return{files:[writeFile(runAxePath,formatContent(renderTemplate("e2e/playwright-ts/run-axe.ts.ejs",config),runAxePath,base),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(a11ySpecPath,formatContent(renderTemplate("e2e/playwright-ts/a11y.spec.ts.ejs",config),a11ySpecPath,base),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{chmodTranslated,resolvedPath,writeFile}from"../utils/fs.js";import{renderTemplate}from"../utils/render.js";const SCRIPT_MODE=493;export function generatePrTooling(config,opts={dryRun:!1}){const files=[writeFile(resolvedPath(config.targetDir,"scripts","lib","exact-sha-policy.mjs"),renderTemplate("scripts/lib/exact-sha-policy.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts","lib","waiter-count.mjs"),renderTemplate("scripts/lib/waiter-count.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts","pr-merge-watch.mjs"),renderTemplate("scripts/pr-merge-watch.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts","capacity-probe.mjs"),renderTemplate("scripts/capacity-probe.mjs.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts","bg-run.sh"),renderTemplate("scripts/bg-run.sh.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(config.targetDir,"scripts","pid-watch.sh"),renderTemplate("scripts/pid-watch.sh.ejs",config),{skipIfExists:!0,dryRun:opts.dryRun})];if(!opts.dryRun)for(const rel of["scripts/bg-run.sh","scripts/pid-watch.sh"]){const scriptPath=resolvedPath(config.targetDir,rel);chmodTranslated(scriptPath,SCRIPT_MODE)}return{files}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";export function generatePythonBoundaries(config,opts={dryRun:!1}){if(config.language!=="python")return{files:[]};if(config.architectureStyle!=="hexagonal")return{files:[]};const base=config.targetDir,data=config;return{files:[writeFile(resolvedPath(base,".importlinter"),renderTemplate("boundaries/.importlinter.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"ruff-boundaries.toml"),renderTemplate("boundaries/ruff-boundaries.toml.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun}),writeFile(resolvedPath(base,"scripts/check-boundaries.mjs"),renderTemplate("boundaries/check-boundaries-python.mjs.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{renderTemplate}from"../utils/render.js";import{writeFile,resolvedPath}from"../utils/fs.js";const SONAR_SUPPORTED_LANGUAGES=new Set(["java","typescript","kotlin"]);export function generateQuality(config,opts={dryRun:!1}){if(config.governanceLevel==="L1")return{files:[]};if(!SONAR_SUPPORTED_LANGUAGES.has(config.language))return{files:[]};const base=config.targetDir,data=config;return{files:[writeFile(resolvedPath(base,"sonar-project.properties"),renderTemplate("sonar-project.properties.ejs",data),{skipIfExists:!0,dryRun:opts.dryRun})]}}