@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,738 @@
1
+ #!/usr/bin/env node
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // CATALOG: arc42 is twelve enumerable slots, not twelve paragraphs. This gate turns the
4
+ // CATALOG: architecture document into an addressable structure: it parses the arc42 doc into
5
+ // CATALOG: ARC-01..ARC-12, reports which slots the project's document actually carries, and fails when
6
+ // CATALOG: a project has LOST a slot its own skeleton provides. The stub count — a slot whose body
7
+ // CATALOG: is nothing but the skeleton's prompt comment — rides a monotone ratchet, so a project
8
+ // CATALOG: may leave sections unfilled but may never add an unfilled one.
9
+ // CATALOG: rejected a keyword scan for TODO/TBD markers, which was the first design: run over
10
+ // CATALOG: arbiter's own arc42 it produced three false positives, all of them prose ABOUT todo
11
+ // CATALOG: gates and a technical-debt count. A stub is recognised structurally instead — the body,
12
+ // CATALOG: with HTML comments and whitespace removed, is empty or is exactly one placeholder token.
13
+ // CATALOG: rejected inventing a per-tier list of required sections: src/generators/doc-set.ts
14
+ // CATALOG: already decides which skeleton a tier receives (canvas for solo/small, full for
15
+ // CATALOG: enterprise). The required set is READ from that skeleton, so this gate can never hold a
16
+ // CATALOG: second opinion about what a tier owes, and adding a section to a skeleton automatically
17
+ // CATALOG: makes it required of the projects that receive it. The converse is guarded by a second
18
+ // CATALOG: ratchet over the skeleton's OWN gaps against canonical ARC-01..ARC-12: without it, deleting a
19
+ // CATALOG: section from a skeleton would quietly lower the bar for every project that receives it,
20
+ // CATALOG: and the gate would report the weakened bar as a pass.
21
+ // CATALOG: rejected fold-in into check-doc-set.mjs because that gate answers "does the
22
+ // CATALOG: architecture document exist and is it fresh" — a presence question over 55 rows. This
23
+ // CATALOG: one answers "is the document structurally complete", for exactly one row, and folding
24
+ // CATALOG: them would make a missing file and a hollow file the same failure.
25
+ //
26
+ // scripts/check-arc42-slots.mjs
27
+ // L1 gate (INV-144): the architecture document is a filled structure, not a surviving skeleton.
28
+ //
29
+ // Usage: node scripts/check-arc42-slots.mjs [--dir <repo>] [--json] [--update-baseline]
30
+ // --dir names the tree to AUDIT; the arc42 skeletons are read from this script's own install root
31
+ // (override with --skeleton-root, which exists so the split is an explicit seam rather than an
32
+ // implicit one), so auditing a governed project holds it to the skeleton it was generated from.
33
+ // There is deliberately no --allow-increase: a rise in the stub count is legitimised by
34
+ // hand-editing scripts/data/arc42-baseline.json in the same PR as the section that caused it.
35
+ // Exit: 0 pass, 1 violation, 2 error (INV-53).
36
+ //
37
+ // Exports for unit tests: SLOTS, normalizeHeading, slotForHeading, splitSections, isStub,
38
+ // analyzeDocument, skeletonSlots, skeletonGaps
39
+
40
+ import { readRegularFileSync } from './lib/run-helpers.mjs'
41
+ import { existsSync, mkdirSync, writeFileSync } from 'node:fs'
42
+ import { dirname, join, resolve } from 'node:path'
43
+ import { fileURLToPath } from 'node:url'
44
+ import { parse as parseYaml } from 'yaml'
45
+ import {
46
+ loadOverlays,
47
+ loadTierColumn,
48
+ resolveEffectiveColumn,
49
+ resolvePresentPaths,
50
+ } from './lib/doc-set-resolve.mjs'
51
+
52
+ const scriptDir = dirname(fileURLToPath(import.meta.url))
53
+ const SELF_ROOT = resolve(scriptDir, '..')
54
+ const MANIFEST_REL = join('standards', 'gold-doc-set.yml')
55
+ const BASELINE_REL = join('scripts', 'data', 'arc42-baseline.json')
56
+ const SKELETON_FILE_FOR_COLUMN = {
57
+ solo: 'arc42-canvas.md.ejs',
58
+ small: 'arc42-canvas.md.ejs',
59
+ enterprise: 'arc42-full.md.ejs',
60
+ }
61
+ // Two layouts, and the gate must read the right one in each. A dev checkout has `src/templates`
62
+ // (the source of truth) AND a `dist/templates` copy that `npm run build` refreshes — reading dist
63
+ // there would grade an edited skeleton against a stale build. The published package has only
64
+ // `dist/`, because `npm run build` does `cp -r src/templates dist/templates` and `src/` is not in
65
+ // package.json `files` — which is why a constant pointing at `src/templates/...` resolved in this
66
+ // checkout and NOWHERE else, a silent permanent SKIP for every consumer. Source first, shipped
67
+ // second: correct in both, and the fallback is what makes the consumer case work at all.
68
+ const SKELETON_ROOTS = [join('src', 'templates'), join('dist', 'templates')]
69
+ /** Formats the arc42 doc-set row admits that are NOT arc42 and must not be graded as one. */
70
+ const NON_ARC42_ALIASES = /(^|\/)(blueprint|c4-model)\.md$/i
71
+
72
+ /**
73
+ * The twelve arc42 slots. `names` are anchored patterns matched against a NORMALIZED heading,
74
+ * so a document may number its sections, use `&`, or use the short form, and still resolve.
75
+ * A heading matching no slot is an ADDITION, which arc42 explicitly permits and this gate ignores.
76
+ */
77
+ export const SLOTS = [
78
+ {
79
+ id: 'ARC-01',
80
+ title: 'Introduction and Goals',
81
+ // `goals` and `purpose` are deliberately NOT standalone aliases: arc42's own subsection 1.2
82
+ // is "Quality goals", and a `## 1.2 Quality goals` has its numbering stripped and would then
83
+ // satisfy a slot, letting a filled subsection mask a hollow parent section.
84
+ names:
85
+ /^(introduction|introduction and goals|about|introduzione e obiettivi|requisiti e obiettivi)$/,
86
+ },
87
+ {
88
+ id: 'ARC-02',
89
+ title: 'Constraints',
90
+ names: /^(((architecture|architectural|technical) )?constraints|vincoli( architetturali)?)$/,
91
+ },
92
+ {
93
+ id: 'ARC-03',
94
+ title: 'Context and Scope',
95
+ // arc42 v8 splits section 3 into "Business Context" and "Technical Context"; both are the
96
+ // same slot. Bare `scope` is dropped — it is a common subsection heading inside section 1.
97
+ names:
98
+ /^(context|context and scope|scope and context|system context|system scope|business context|technical context|contesto e ambito)$/,
99
+ },
100
+ {
101
+ id: 'ARC-04',
102
+ title: 'Solution Strategy',
103
+ names: /^(solution strategy|strategy|strategia di soluzione)$/,
104
+ },
105
+ {
106
+ id: 'ARC-05',
107
+ title: 'Building Block View',
108
+ names: /^(building blocks?|building blocks? view|vista a blocchi)$/,
109
+ },
110
+ {
111
+ id: 'ARC-06',
112
+ title: 'Runtime View',
113
+ names: /^(runtime|runtime view|runtime scenarios|vista di runtime)$/,
114
+ },
115
+ {
116
+ id: 'ARC-07',
117
+ title: 'Deployment View',
118
+ names: /^(deployment|deployment view|infrastructure|vista di dispiegamento)$/,
119
+ },
120
+ {
121
+ id: 'ARC-08',
122
+ title: 'Crosscutting Concepts',
123
+ names: /^(cross ?cutting( concepts)?|concetti trasversali)$/,
124
+ },
125
+ {
126
+ id: 'ARC-09',
127
+ title: 'Architecture Decisions',
128
+ names: /^(((architecture|architectural|design) )?decisions|decisioni architetturali)$/,
129
+ },
130
+ {
131
+ id: 'ARC-10',
132
+ title: 'Quality Requirements',
133
+ // `quality goals` dropped for the same reason as ARC-01's: it is arc42's subsection 1.2.
134
+ names: /^(quality|quality requirements|quality scenarios|quality tree|requisiti di qualità)$/,
135
+ },
136
+ {
137
+ id: 'ARC-11',
138
+ title: 'Risks and Technical Debt',
139
+ // Plural `debts` is the official arc42 v8 EN title; a document copied verbatim from
140
+ // arc42.org failed this gate until it was added.
141
+ names: /^(risks?|risks? and technical debts?|technical debts?|rischi e debito tecnico)$/,
142
+ },
143
+ { id: 'ARC-12', title: 'Glossary', names: /^(glossary|terminology|glossario)$/ },
144
+ ]
145
+
146
+ /** A body that is exactly one of these, and nothing else, is a placeholder rather than content. */
147
+ const PLACEHOLDER_BODY =
148
+ /^(tbd|todo|t\.b\.d|n\/a|na|none|nothing|xxx|to be determined|to be defined|\?+|[\u2010-\u2015-]+|_+)$/
149
+
150
+ /**
151
+ * Heading text -> comparable token: drop leading section numbering (`3.`, `3.1`, `ARC-03 —`),
152
+ * spell `&` as `and`, drop trailing punctuation, lowercase, collapse whitespace.
153
+ */
154
+ export function normalizeHeading(raw) {
155
+ return (
156
+ raw
157
+ .replace(/^\s*(?:(?:ARC-)?[Aa]?\d+(?:\.\d+)*)\s*[.):—–-]*\s*/i, '')
158
+ .replace(/&/g, ' and ')
159
+ // Hyphens are a typographic choice, not a semantic one: `Cross-cutting`, `Cross cutting` and
160
+ // `Crosscutting` are the same arc42 slot, and a slot matcher that disagreed would be a bug
161
+ // that reads as a missing section.
162
+ .replace(/[\u2010-\u2015-]+/g, ' ')
163
+ .replace(/[.:;,]+\s*$/, '')
164
+ .trim()
165
+ .toLowerCase()
166
+ .replace(/\s+/g, ' ')
167
+ )
168
+ }
169
+
170
+ /** The slot id a heading fills, or null when the heading is an addition. */
171
+ export function slotForHeading(raw) {
172
+ // A numbered subsection cannot replace its parent, even at the same Markdown level.
173
+ if (/^\s*(?:ARC-)?[Aa]?\d+\.\d/i.test(raw)) return null
174
+ const norm = normalizeHeading(raw)
175
+ const hit = SLOTS.find((s) => s.names.test(norm))
176
+ return hit ? hit.id : null
177
+ }
178
+
179
+ /**
180
+ * Split markdown into sections. Three things this must get right, each of which was a live defeat:
181
+ *
182
+ * - HTML comments are stripped FIRST. A document wrapped entirely in `<!-- ... -->` renders as
183
+ * nothing, but slicing it into sections before stripping gave every slot a body containing the
184
+ * unbalanced `-->` residue, which `isStub` then read as content: a blank page scored 12/12.
185
+ * - The section level is DETECTED, not assumed. arc42's own single-file markdown template uses
186
+ * `# 1. Introduction and Goals`; assuming `##` scored such a document 0, which after the
187
+ * score-0 rule became a hard failure on a textbook-correct file.
188
+ * - Fenced blocks are skipped so a `## ` inside an example is not a section, and an UNTERMINATED
189
+ * fence is ignored rather than swallowing every heading after it.
190
+ */
191
+ export function splitSections(markdown) {
192
+ const text = markdown.replace(/<!--[\s\S]*?-->/g, '')
193
+ const level = detectSectionLevel(text)
194
+ return sectionsAtLevel(text, level)
195
+ }
196
+
197
+ /** Headings at one level, fenced regions excluded. */
198
+ /** Fence state after a line: null when open text, else the open fence. CommonMark closes a fence
199
+ * only with a run of the SAME char at least as long as the opener, so a ``` cannot close a ````. */
200
+ function nextFenceState(fence, line, i) {
201
+ const hit = /^\s*(```+|~~~+)/.exec(line)
202
+ if (!hit) return { fence, isFenceLine: false }
203
+ if (fence === null)
204
+ return { fence: { char: hit[1][0], len: hit[1].length, at: i }, isFenceLine: true }
205
+ const closes = hit[1][0] === fence.char && hit[1].length >= fence.len
206
+ return { fence: closes ? null : fence, isFenceLine: true }
207
+ }
208
+
209
+ function headingsAtLevel(text, level) {
210
+ const re = new RegExp(`^ {0,3}#{${level}}\\s+(.*\\S?)\\s*$`)
211
+ const lines = text.split('\n')
212
+ const readHeading = (i) => {
213
+ const m = re.exec(lines[i])
214
+ return m ? { line: i, heading: m[1].replace(/\s+#+\s*$/, '') } : null
215
+ }
216
+ const out = []
217
+ let fence = null
218
+ for (let i = 0; i < lines.length; i += 1) {
219
+ const step = nextFenceState(fence, lines[i], i)
220
+ fence = step.fence
221
+ if (step.isFenceLine || fence !== null) continue
222
+ const h = readHeading(i)
223
+ if (h) out.push(h)
224
+ }
225
+ // An unterminated fence must not swallow the rest of the document: re-scan from its opener as
226
+ // ordinary text rather than reporting every later section as absent.
227
+ if (fence !== null) {
228
+ for (let i = fence.at + 1; i < lines.length; i += 1) {
229
+ const h = readHeading(i)
230
+ if (h) out.push(h)
231
+ }
232
+ out.sort((a, b) => a.line - b.line)
233
+ }
234
+ return out
235
+ }
236
+
237
+ /** The heading level this document actually uses for its arc42 sections. */
238
+ function detectSectionLevel(text) {
239
+ // `##` is the default and the tie-breaker: it is what both arbiter skeletons and the great
240
+ // majority of arc42 documents use. Another level wins only by matching STRICTLY more slots, so
241
+ // a document whose headings match nothing (or match equally) is still read at `##` rather than
242
+ // silently reinterpreted at a level that happens to find nothing.
243
+ const scoreAt = (level) =>
244
+ headingsAtLevel(text, level).filter((h) => slotForHeading(h.heading) !== null).length
245
+ let best = 2
246
+ let bestScore = scoreAt(2)
247
+ for (const level of [1, 3]) {
248
+ const score = scoreAt(level)
249
+ if (score > bestScore) {
250
+ bestScore = score
251
+ best = level
252
+ }
253
+ }
254
+ return best
255
+ }
256
+
257
+ function sectionsAtLevel(text, level) {
258
+ const lines = text.split('\n')
259
+ const heads = headingsAtLevel(text, level)
260
+ return heads.map((h, i) => ({
261
+ heading: h.heading,
262
+ body: lines
263
+ .slice(h.line + 1, i + 1 < heads.length ? heads[i + 1].line : lines.length)
264
+ .join('\n'),
265
+ }))
266
+ }
267
+
268
+ /** A section is a stub when nothing but the skeleton's own prompt comment survives stripping. */
269
+ export function isStub(body) {
270
+ const stripped = body
271
+ .replace(/<!--[\s\S]*?-->/g, '')
272
+ .replace(/^\s*#{3,}\s.*$/gm, '')
273
+ .trim()
274
+ const bare = stripped.toLowerCase().replace(/[.!]+$/, '')
275
+ return stripped === '' || PLACEHOLDER_BODY.test(bare)
276
+ }
277
+
278
+ /** Slot ids a markdown document carries, and which of those are stubs. */
279
+ export function analyzeDocument(markdown) {
280
+ const present = new Map()
281
+ for (const section of splitSections(markdown)) {
282
+ const slot = slotForHeading(section.heading)
283
+ if (slot === null) continue
284
+ // A slot claimed twice (e.g. `## Risks` and `## Technical debt`) counts as filled if EITHER
285
+ // half carries content — splitting a slot across two headings is a formatting choice, not a gap.
286
+ const stub = isStub(section.body)
287
+ if (!present.has(slot) || present.get(slot) === true) present.set(slot, stub)
288
+ }
289
+ return {
290
+ slots: [...present.keys()].sort(),
291
+ stubs: [...present.entries()]
292
+ .filter(([, stub]) => stub)
293
+ .map(([id]) => id)
294
+ .sort(),
295
+ }
296
+ }
297
+
298
+ /** The slot ids the skeleton for a tier column provides — the required set, read not invented. */
299
+ export function skeletonSlots(root, column) {
300
+ const file = SKELETON_FILE_FOR_COLUMN[column] ?? SKELETON_FILE_FOR_COLUMN.enterprise
301
+ for (const base of SKELETON_ROOTS) {
302
+ const rel = join(base, 'docs', 'skeletons', file)
303
+ if (existsSync(join(root, rel))) {
304
+ return { rel, slots: analyzeDocument(readRegularFileSync(join(root, rel), 'utf-8')).slots }
305
+ }
306
+ }
307
+ return { rel: join(SKELETON_ROOTS[0], 'docs', 'skeletons', file), slots: null }
308
+ }
309
+
310
+ /** Every skeleton, not just this repo's column — ratchet #2 must protect the ones we do not run. */
311
+ export function allSkeletonSlots(root) {
312
+ const out = {}
313
+ for (const column of Object.keys(SKELETON_FILE_FOR_COLUMN)) {
314
+ out[column] = skeletonSlots(root, column).slots
315
+ }
316
+ return out
317
+ }
318
+
319
+ /**
320
+ * Canonical slots a skeleton does NOT provide. A gap is legitimate — the Canvas column drops
321
+ * Crosscutting and Glossary on purpose — but it is RATCHETED, so dropping one more is a decision
322
+ * that has to be written down rather than a side effect of editing a template.
323
+ */
324
+ export function skeletonGaps(slots) {
325
+ return SLOTS.filter((s) => !slots.includes(s.id)).map((s) => s.id)
326
+ }
327
+
328
+ /**
329
+ * Gaps for EVERY column, not just the one this repo audits under. A single scalar keyed nothing:
330
+ * it was measured on enterprise (0 gaps) while the Canvas really drops two, so a solo/small repo
331
+ * was told a slot "was dropped" that never was, and arbiter's own CI never evaluated the Canvas at
332
+ * all — leaving ratchet #2 inert for exactly the skeleton it exists to protect.
333
+ */
334
+ export function gapsByColumn(perColumnSlots) {
335
+ const out = {}
336
+ for (const [column, slots] of Object.entries(perColumnSlots)) {
337
+ // A MISSING skeleton is every slot gapped, not a column to quietly drop. Omitting it removed
338
+ // that column from the ratchet entirely, so deleting a skeleton file did not lower the bar —
339
+ // it deleted the bar.
340
+ out[column] = slots === null ? SLOTS.map((x) => x.id) : skeletonGaps(slots)
341
+ }
342
+ return out
343
+ }
344
+
345
+ function loadObject(path, label, parse = JSON.parse) {
346
+ try {
347
+ const value = parse(readRegularFileSync(path, 'utf-8'))
348
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
349
+ throw new Error('expected an object')
350
+ }
351
+ return { value }
352
+ } catch (err) {
353
+ process.stderr.write(`check-arc42-slots: ERROR — ${label}: ${err.message}\n`)
354
+ return { code: 2 }
355
+ }
356
+ }
357
+
358
+ function resolveArc42Path(root) {
359
+ const manifestPath = join(root, MANIFEST_REL)
360
+ if (!existsSync(manifestPath)) return { skip: `no manifest at ${MANIFEST_REL}` }
361
+ const loaded = loadObject(manifestPath, MANIFEST_REL, parseYaml)
362
+ if (loaded.code !== undefined) return loaded
363
+ const manifest = loaded.value
364
+ // The path list is READ from the arc42 row rather than restated here, so this gate and
365
+ // check-doc-set.mjs can never disagree about where a project's architecture document lives.
366
+ const row = (manifest.checks || []).find((c) => c.template === 'arc42')
367
+ if (!row) return { skip: `no arc42 row in ${MANIFEST_REL}` }
368
+ const found = resolvePresentPaths(row, root)
369
+ if (found.length === 0)
370
+ return { skip: 'no architecture document present (check-doc-set owns absence)' }
371
+ // accept_any is an unordered set of aliases, so the first entry is NOT the arc42 — in arbiter's
372
+ // own tree it resolves to a reading-order hub page. Score every present candidate and take the
373
+ // one carrying the most slots: the document that is most arc42-shaped IS the arc42.
374
+ const scored = found
375
+ .map((rel) => ({
376
+ rel,
377
+ slots: analyzeDocument(readRegularFileSync(join(root, rel), 'utf-8')).slots,
378
+ }))
379
+ .sort((a, b) => b.slots.length - a.slots.length || a.rel.localeCompare(b.rel))
380
+ // The manifest's arc42 row deliberately admits non-arc42 formats too — `blueprint.md` and
381
+ // `**/c4-model.md` are listed in its accept_any. Grading a C4 model against arc42's twelve slots
382
+ // would hard-fail a project that legitimately chose C4, so those resolve to a SKIP: presence is
383
+ // check-doc-set's business, and this gate has nothing to say about a format it does not model.
384
+ if (NON_ARC42_ALIASES.test(scored[0].rel) && scored[0].slots.length === 0) {
385
+ return {
386
+ skip:
387
+ `${scored[0].rel} is a non-arc42 architecture format the manifest admits ` +
388
+ `(blueprint / c4-model) — check-doc-set owns its presence`,
389
+ }
390
+ }
391
+ // Otherwise a zero-scoring candidate is NOT a skip. Replacing an arc42 with "# Architecture /
392
+ // See the wiki." scored 0, skipped, exited 0 — and check-doc-set stayed green because the file
393
+ // exists, so the two gates together certified "architecture documented" for a document with no
394
+ // architecture in it. Report the score and let the caller turn it into a violation.
395
+ return {
396
+ path: scored[0].rel,
397
+ score: scored[0].slots.length,
398
+ candidates: scored.map((c) => `${c.rel}:${c.slots.length}`),
399
+ }
400
+ }
401
+
402
+ function report(violations, summary, json) {
403
+ if (json) {
404
+ process.stdout.write(`${JSON.stringify({ ...summary, violations }, null, 2)}\n`)
405
+ } else if (violations.length > 0) {
406
+ process.stderr.write(`check-arc42-slots: FAIL — ${violations.length} violation(s)\n`)
407
+ for (const v of violations) process.stderr.write(` - ${v}\n`)
408
+ } else {
409
+ process.stdout.write(
410
+ `check-arc42-slots: PASS — ${summary.doc}: ${summary.filled}/${summary.required} required ` +
411
+ `slots filled, ${summary.stubs.length} stub(s) (baseline ${summary.baseline})\n`,
412
+ )
413
+ }
414
+ return violations.length > 0 ? 1 : 0
415
+ }
416
+
417
+ /**
418
+ * The required slot set, and where it came from. Inside arbiter the EJS skeleton is authoritative;
419
+ * a governed project does not ship the skeletons, so the emitted `required` list in the baseline
420
+ * is. When both exist they must agree — a divergence means the set governed projects are held to
421
+ * has drifted from the skeleton they were built from, and that is reported, not reconciled.
422
+ */
423
+ function resolveRequired(fromSkeleton, fromBaseline, skeletonRel) {
424
+ const drift =
425
+ fromSkeleton !== null && fromBaseline !== null && fromSkeleton.join() !== fromBaseline.join()
426
+ ? [
427
+ `${BASELINE_REL}: \`required\` is [${fromBaseline.join(', ')}] but ${skeletonRel} provides ` +
428
+ `[${fromSkeleton.join(', ')}] — the set governed projects are held to has drifted from ` +
429
+ `the skeleton they receive. Run --update-baseline.`,
430
+ ]
431
+ : []
432
+ return { required: fromSkeleton ?? fromBaseline, drift }
433
+ }
434
+
435
+ /** The two ratchet verdicts: hollow slots in the document, canonical gaps in the skeleton. */
436
+ function ratchetViolations({ docPath, stubs, allowed, gapsByCol, allowedByCol }) {
437
+ const out = []
438
+ if (stubs.length > allowed) {
439
+ out.push(
440
+ `${docPath}: ${stubs.length} hollow slot(s) (${stubs.join(', ')}), baseline allows ` +
441
+ `${allowed} — a section may be left unfilled, but a new unfilled one may not be added.`,
442
+ )
443
+ }
444
+ // Every column, not just this repo's: a scalar keyed to the auditing column left the Canvas
445
+ // skeleton — which arbiter's own CI never resolves — completely unguarded.
446
+ for (const [col, gaps] of Object.entries(gapsByCol)) {
447
+ const permitted = allowedByCol[col]
448
+ if (typeof permitted !== 'number') {
449
+ out.push(`${BASELINE_REL}: skeletonGaps has no entry for the "${col}" column`)
450
+ continue
451
+ }
452
+ if (gaps.length > permitted) {
453
+ out.push(
454
+ `the "${col}" arc42 skeleton omits ${gaps.length} canonical slot(s) (${gaps.join(', ')}), ` +
455
+ `baseline allows ${permitted} — a slot dropped from a skeleton lowers the bar for every ` +
456
+ `project that receives it, so the drop lands in the baseline diff or not at all.`,
457
+ )
458
+ }
459
+ }
460
+ return out
461
+ }
462
+
463
+ /** Slots the document owes its skeleton and does not carry. */
464
+ function missingSlotViolations(required, carried, docPath, column, source) {
465
+ return required
466
+ .filter((id) => !carried.has(id))
467
+ .map((id) => {
468
+ const slot = SLOTS.find((s) => s.id === id) ?? { title: 'unknown slot id' }
469
+ return (
470
+ `${docPath}: slot ${id} (${slot.title}) is absent, but ${source} — the skeleton this ` +
471
+ `project's "${column}" column receives — provides it. Either the section was removed from ` +
472
+ `the document, or the column rose (a promoted collaborationMode or tier_floor raises the ` +
473
+ `bar and does not backfill the document). Both are real gaps; add the section.`
474
+ )
475
+ })
476
+ }
477
+
478
+ /**
479
+ * Write the baseline, creating `scripts/data/` if absent — a generated project has `scripts/` but
480
+ * not `scripts/data/`, so the unguarded write was an ENOENT reported as a document violation.
481
+ */
482
+ function persistBaseline(baselinePath, next) {
483
+ mkdirSync(dirname(baselinePath), { recursive: true })
484
+ writeFileSync(baselinePath, `${JSON.stringify(next, null, 2)}\n`)
485
+ }
486
+
487
+ function updateBaseline(baselinePath, baseline, required, stubs, gapsByCol, allowed, allowedByCol) {
488
+ const risen = []
489
+ if (stubs > allowed) risen.push(`stubs ${allowed} -> ${stubs}`)
490
+ const nextGaps = {}
491
+ for (const [col, gaps] of Object.entries(gapsByCol)) {
492
+ nextGaps[col] = gaps.length
493
+ const permitted = allowedByCol[col]
494
+ if (typeof permitted === 'number' && gaps.length > permitted) {
495
+ risen.push(`skeletonGaps.${col} ${permitted} -> ${gaps.length}`)
496
+ }
497
+ }
498
+ if (risen.length > 0) {
499
+ process.stderr.write(
500
+ `check-arc42-slots: refusing --update-baseline — ${risen.join(', ')}. ` +
501
+ `Raise the number by hand, in the same PR as the section that needs it.\n`,
502
+ )
503
+ return 1
504
+ }
505
+ persistBaseline(baselinePath, { ...baseline, required, stubs, skeletonGaps: nextGaps })
506
+ process.stdout.write(
507
+ `check-arc42-slots: baseline updated — stubs ${stubs}, skeletonGaps ${JSON.stringify(nextGaps)}\n`,
508
+ )
509
+ return 0
510
+ }
511
+
512
+ /**
513
+ * The four things argv decides. `--dir` is the tree to AUDIT and defaults to cwd, exactly as
514
+ * check-doc-set.mjs is run by `arbiter doc-set`; `--skeleton-root` is where the arc42 skeletons
515
+ * come from and defaults to arbiter's own install — the two are separate because in production
516
+ * they ARE separate, and conflating them would hold a governed project to a skeleton it carries.
517
+ */
518
+ function parseArgs(argv) {
519
+ const dirIdx = argv.indexOf('--dir')
520
+ const skelIdx = argv.indexOf('--skeleton-root')
521
+ return {
522
+ root: dirIdx === -1 ? process.cwd() : resolve(argv[dirIdx + 1]),
523
+ skeletonRoot: skelIdx === -1 ? SELF_ROOT : resolve(argv[skelIdx + 1]),
524
+ updateBaseline: argv.includes('--update-baseline'),
525
+ json: argv.includes('--json'),
526
+ }
527
+ }
528
+
529
+ /**
530
+ * What the ratchet currently permits. With NO baseline file the gate records where the tree is
531
+ * rather than failing it: a freshly generated project's arc42 is hollow by construction, and a
532
+ * gate that made `arbiter init` produce a red repo would only teach people to delete the gate.
533
+ * Deleting the baseline later to reset is possible and deliberate — it lands in the diff.
534
+ */
535
+ /** A ratchet counter is a finite, non-negative integer — never Infinity, a float, or a string. */
536
+ function isCount(v) {
537
+ return typeof v === 'number' && Number.isInteger(v) && v >= 0
538
+ }
539
+
540
+ /** Validate a DECLARED skeletonGaps map: right shape, every shipped column, no unknown column. */
541
+ function validateDeclaredGaps(declared, gapCount) {
542
+ if (declared === undefined) return null
543
+ if (typeof declared !== 'object' || declared === null || Array.isArray(declared)) {
544
+ return (
545
+ `${BASELINE_REL}: "skeletonGaps" is ${JSON.stringify(declared)}, not a per-column object ` +
546
+ `— a scalar or array here left every column but the auditing one unguarded`
547
+ )
548
+ }
549
+ for (const col of Object.keys(declared)) {
550
+ // Object.hasOwn, not `in`: `'__proto__' in obj` is true for every object, so `in` let an
551
+ // unknown key named __proto__ straight through.
552
+ if (!Object.hasOwn(gapCount, col)) {
553
+ return `${BASELINE_REL}: skeletonGaps names unknown column "${col}"`
554
+ }
555
+ }
556
+ for (const col of Object.keys(gapCount)) {
557
+ if (!isCount(declared[col])) {
558
+ return (
559
+ `${BASELINE_REL}: skeletonGaps."${col}" is ${JSON.stringify(declared[col])}, not a whole ` +
560
+ `count — every shipped column must be pinned, or the unpinned one is unguarded`
561
+ )
562
+ }
563
+ }
564
+ return null
565
+ }
566
+
567
+ function allowancesFrom(baseline, stubCount, gapCount) {
568
+ // A COUNT, not merely a number. `"0"` is a string; `1e999` is Infinity and would permit any
569
+ // number of hollow slots forever; a float is not a count. Each looks innocuous in a diff and
570
+ // each disabled the ratchet permanently while --json kept reporting health.
571
+ if (baseline.stubs !== undefined && !isCount(baseline.stubs)) {
572
+ return {
573
+ error: `${BASELINE_REL}: "stubs" is ${JSON.stringify(baseline.stubs)}, not a whole count`,
574
+ }
575
+ }
576
+ const declared = baseline.skeletonGaps
577
+ const gapsError = validateDeclaredGaps(declared, gapCount)
578
+ if (gapsError !== null) return { error: gapsError }
579
+
580
+ const allowedByCol = {}
581
+ for (const [col, gaps] of Object.entries(gapCount)) {
582
+ // With no baseline at all, bootstrap from what we measured — the ONLY backfill allowed. A
583
+ // DECLARED map is complete by the check above, so a missing key can never re-permit today's
584
+ // count silently, which was the same laundering as a non-numeric counter one level down.
585
+ allowedByCol[col] = declared === undefined ? gaps.length : declared[col]
586
+ }
587
+ return {
588
+ allowed: typeof baseline.stubs === 'number' ? baseline.stubs : stubCount,
589
+ allowedByCol,
590
+ }
591
+ }
592
+
593
+ /** The document exists but carries no arc42 at all — check-doc-set cannot see this. */
594
+ function emptyDocumentViolation(located) {
595
+ if (located.score !== 0) return []
596
+ return [
597
+ `${located.path}: carries none of the twelve arc42 slots (candidates scored: ` +
598
+ `${located.candidates.join(', ')}) — the document exists, so check-doc-set is green, but ` +
599
+ `there is no architecture in it. A file that answers no arc42 question is not an arc42.`,
600
+ ]
601
+ }
602
+
603
+ /**
604
+ * Arm the ratchet on a clean first run. Tolerating the count only in memory meant no governed
605
+ * project ever grew a baseline, so `allowed` was recomputed as "whatever it is today" every run
606
+ * and the ratchet was inert everywhere except this repo.
607
+ *
608
+ * No `required` in the seed: it is column-SPECIFIC, so seeding it under one column and later
609
+ * promoting the tier reported a "drift" when only the column had changed. And a write failure is
610
+ * a warning, never a failure — an audit gate must not need write access to reach a verdict it has
611
+ * already computed (read-only checkouts, hardened containers).
612
+ */
613
+ function seedBaselineIfAbsent(baselinePath, stubs, gapsByCol) {
614
+ if (existsSync(baselinePath)) return
615
+ const seeded = {}
616
+ for (const [col, gaps] of Object.entries(gapsByCol)) seeded[col] = gaps.length
617
+ try {
618
+ persistBaseline(baselinePath, { stubs, skeletonGaps: seeded })
619
+ // stderr, not stdout: under --json stdout must stay a single parseable document.
620
+ process.stderr.write(`check-arc42-slots: seeded ${BASELINE_REL} — the ratchet is now armed\n`)
621
+ } catch (err) {
622
+ process.stderr.write(
623
+ `check-arc42-slots: could not seed ${BASELINE_REL} (${err.message}) — verdict stands, but ` +
624
+ `the ratchet stays unarmed until this file exists and is committed\n`,
625
+ )
626
+ }
627
+ }
628
+
629
+ function skip(why) {
630
+ process.stdout.write(`check-arc42-slots: SKIP — ${why}\n`)
631
+ // #2052: recognized marker so runCheck surfaces SKIP, not PASS, in the gate summary.
632
+ process.stdout.write(`[SKIP] ${why}\n`)
633
+ return 0
634
+ }
635
+
636
+ /** The tier column, the skeleton it names, and the baseline — or an exit code saying why not. */
637
+ function loadContext(root, skeletonRoot) {
638
+ // The EFFECTIVE column, floor included — check-doc-set.mjs resolves it the same way, and a gate
639
+ // that read the derived column alone would demand the Canvas of a repo the doc-set treats as
640
+ // enterprise.
641
+ const { tierFloor } = loadOverlays(root, join('standards', 'doc-profile'))
642
+ const column = resolveEffectiveColumn(loadTierColumn(root), tierFloor)
643
+ const { rel: skeletonRel, slots: fromSkeleton } = skeletonSlots(skeletonRoot, column)
644
+
645
+ const baselinePath = join(root, BASELINE_REL)
646
+ const loaded = existsSync(baselinePath) ? loadObject(baselinePath, BASELINE_REL) : { value: {} }
647
+ if (loaded.code !== undefined) return { code: loaded.code }
648
+ return {
649
+ column,
650
+ skeletonRel,
651
+ fromSkeleton,
652
+ baselinePath,
653
+ baseline: loaded.value,
654
+ fromBaseline: Array.isArray(loaded.value.required) ? loaded.value.required : null,
655
+ }
656
+ }
657
+
658
+ function main() {
659
+ const { root, skeletonRoot, updateBaseline: doUpdate, json } = parseArgs(process.argv.slice(2))
660
+
661
+ const located = resolveArc42Path(root)
662
+ if (located.code !== undefined) return located.code
663
+ if (located.skip) return skip(located.skip)
664
+
665
+ const ctx = loadContext(root, skeletonRoot)
666
+ if (ctx.code !== undefined) return ctx.code
667
+ const { column, skeletonRel, fromSkeleton, baselinePath, baseline, fromBaseline } = ctx
668
+
669
+ const { required, drift } = resolveRequired(fromSkeleton, fromBaseline, skeletonRel)
670
+ if (required === null) {
671
+ return skip(`neither ${skeletonRel} nor a \`required\` list in ${BASELINE_REL} is present`)
672
+ }
673
+
674
+ const doc = analyzeDocument(readRegularFileSync(join(root, located.path), 'utf-8'))
675
+ const carried = new Set(doc.slots)
676
+ // Every skeleton this arbiter ships, so a column nobody audits still cannot lose a slot.
677
+ const gapsByCol = gapsByColumn(allSkeletonSlots(skeletonRoot))
678
+ const allowances = allowancesFrom(baseline, doc.stubs.length, gapsByCol)
679
+ if (allowances.error !== undefined) {
680
+ process.stderr.write(`check-arc42-slots: ERROR — ${allowances.error}\n`)
681
+ return 2
682
+ }
683
+ const { allowed, allowedByCol } = allowances
684
+ const requiredSource = fromSkeleton !== null ? skeletonRel : BASELINE_REL
685
+
686
+ if (doUpdate) {
687
+ return updateBaseline(
688
+ baselinePath,
689
+ baseline,
690
+ required,
691
+ doc.stubs.length,
692
+ gapsByCol,
693
+ allowed,
694
+ allowedByCol,
695
+ )
696
+ }
697
+
698
+ const violations = [
699
+ ...drift,
700
+ ...missingSlotViolations(required, carried, located.path, column, requiredSource),
701
+ ...ratchetViolations({
702
+ docPath: located.path,
703
+ stubs: doc.stubs,
704
+ allowed,
705
+ gapsByCol,
706
+ allowedByCol,
707
+ }),
708
+ ]
709
+ violations.unshift(...emptyDocumentViolation(located))
710
+
711
+ const summary = {
712
+ doc: located.path,
713
+ column,
714
+ requiredFrom: requiredSource,
715
+ required: required.length,
716
+ filled: required.filter((id) => carried.has(id) && !doc.stubs.includes(id)).length,
717
+ present: doc.slots,
718
+ stubs: doc.stubs,
719
+ skeletonGaps: gapsByCol,
720
+ baseline: allowed,
721
+ baselineSkeletonGaps: allowedByCol,
722
+ }
723
+
724
+ if (violations.length === 0) seedBaselineIfAbsent(baselinePath, doc.stubs.length, gapsByCol)
725
+
726
+ return report(violations, summary, json)
727
+ }
728
+
729
+ if (import.meta.url === `file://${process.argv[1]}`) {
730
+ try {
731
+ process.exit(main())
732
+ } catch (err) {
733
+ process.stderr.write(`check-arc42-slots: ERROR — unexpected: ${err.message}\n`)
734
+ // INV-53: an error is exit 2. Exiting 1 misfiled every EACCES/EISDIR/ENOENT as a document
735
+ // gap — the gate accusing the architecture doc of a defect in the gate's own plumbing.
736
+ process.exit(2)
737
+ }
738
+ }