@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,480 @@
1
+ import type { AiTool, Archetype, ArchitectureStyle, AuthConfig, AutonomyLevel, BranchingStrategy, CollaborationMode, ConformanceThresholds, ContractType, CrossModelReviewConfig, DeployTarget, EvidenceRetentionConfig, FrontendConfig, GovernanceLevel, InvariantTier, Lane, Language, ObservabilityConfig, ProjectPreset, SoloMergeMode, StrictnessTier, TaskTiers, ThresholdProfile, ThresholdsV2, WorktreeConfig } from '../wizard/types.js';
2
+ import type { BrownfieldClass } from '../kit/thresholds.js';
3
+ import type { Invariant } from '../invariants/types.js';
4
+ export interface FeatureFlags {
5
+ contractTesting: boolean;
6
+ mutationTesting: boolean;
7
+ securityScanning: boolean;
8
+ evidenceHarness: boolean;
9
+ /** INV-138: acceptance-criteria anchor gate (scripts/check-acceptance.mjs). Opt-in — absent ⇒ false. */
10
+ acceptanceAnchor?: boolean;
11
+ selfValidationHarness?: boolean;
12
+ /** #1835: opt-in toolchain/workflow-inventory audit (scripts/audit-toolchain.mjs). */
13
+ auditToolchain?: boolean;
14
+ /** #1835 (Task B, #1825): opt-in collapsed 5-lane CI doctrine (see enableFiveLaneCi). */
15
+ fiveLaneCi?: boolean;
16
+ debtGates: boolean;
17
+ suppressions: boolean;
18
+ soloDevMode?: boolean;
19
+ /** #1887-A: persistence of enableMcpFallback (opt-in — omitted/absent ⇒ false). */
20
+ mcpFallback?: boolean;
21
+ /** #1887-A: persistence of enableNoSkippedTests (opt-out — absent ⇒ true). */
22
+ noSkippedTests?: boolean;
23
+ /**
24
+ * #1887-A: compliance doc-pack, set only by applyPreset('industrial-grade').
25
+ * Without persistence a preset-initialized project silently dropped these
26
+ * generators on the next `arbiter update`/`diff`. All opt-in — absent ⇒ false.
27
+ */
28
+ riskRegister?: boolean;
29
+ operationsHandbook?: boolean;
30
+ iso27001Mapping?: boolean;
31
+ nis2Mapping?: boolean;
32
+ gdprMapping?: boolean;
33
+ /**
34
+ * #1887-A: 3 more generators built + gated on the ProjectConfig field but with
35
+ * no public activation path at all — same round-trip-drop class. Opt-in,
36
+ * absent ⇒ false.
37
+ */
38
+ codeownersNotify?: boolean;
39
+ taxonomy25d?: boolean;
40
+ perfTesting?: boolean;
41
+ }
42
+ export type DecompositionBackendId = 'github' | 'markdown';
43
+ export declare const DEFAULT_TASK_TIERS: TaskTiers;
44
+ export declare const DEFAULT_CROSS_MODEL_REVIEW: CrossModelReviewConfig;
45
+ interface DecompositionConfig {
46
+ backend: DecompositionBackendId;
47
+ markdown?: {
48
+ dir: string;
49
+ };
50
+ github?: {
51
+ owner: string;
52
+ repo: string;
53
+ };
54
+ }
55
+ /**
56
+ * File-pattern to ADR mapping for CONTEXT_PACK generation (#254).
57
+ * Pattern supports `*` (non-slash wildcard) and `**` (any-path wildcard).
58
+ */
59
+ interface ContextPackAdrMapping {
60
+ pattern: string;
61
+ adr: string;
62
+ }
63
+ /**
64
+ * Configuration for the CONTEXT_PACK generator (#254).
65
+ * Stored under `contextPack` in `arbiter.json`.
66
+ */
67
+ export type { AutonomyLevel };
68
+ export declare const AUTONOMY_LEVELS: readonly AutonomyLevel[];
69
+ /**
70
+ * #1306 (ADR-094 §Decision.4) — the gate level `arbiter verify` runs by default.
71
+ * Deliberately ONLY L1/L2 (the runnable gate levels): a defaultGateLevel is a
72
+ * per-run gate selector, not a governance tier, so L3/L4 are not valid values.
73
+ */
74
+ export type GateLevel = 'L1' | 'L2';
75
+ export declare const VALID_GATE_LEVELS: readonly GateLevel[];
76
+ export interface AutomationConfig {
77
+ autonomy: AutonomyLevel;
78
+ /**
79
+ * #1306 (ADR-094 §Decision.4) — max wave worktrees that may run concurrently.
80
+ * Positive integer. Absent ⇒ derived per collaboration mode (1 for trunk-solo,
81
+ * which never uses worktrees; >1 for peer/gated). trunk-solo + >1 is incoherent.
82
+ */
83
+ maxParallelWorktrees?: number;
84
+ /** #1306 (ADR-094 §Decision.4) — default gate level for verification. Absent ⇒ derived from governance level. */
85
+ defaultGateLevel?: GateLevel;
86
+ }
87
+ /**
88
+ * #2043 (AC-2043.2): the per-project smoke-journey acceptance floor. Declared in
89
+ * arbiter.json so the generated check-smoke-journeys.mjs gate enforces a genuine
90
+ * login/CRUD/authz floor per project — not just the journeys a team happened to
91
+ * declare. Absent ⇒ the gate falls back to the login/CRUD/authz trio.
92
+ */
93
+ export interface SmokeJourneyPolicy {
94
+ /** Journey ids that must ALL be declared in smoke-journeys.json. Default: ['auth','crud','authz']. */
95
+ requiredJourneys?: string[];
96
+ /** Per-project floor: minimum number of DECLARED journeys (2..4). Default: 3. */
97
+ minJourneys?: number;
98
+ }
99
+ /**
100
+ * #2043 (AC-2043.4/5): the e2e escalation policy — the configurable
101
+ * consecutive-failure ladder replacing the hardcoded 2-strike rule. Absent ⇒ the
102
+ * ship tick prompt and the ledger gate (check-e2e-escalation.mjs) both fall back
103
+ * to the pre-#2043 2-strike default. Present ⇒ ship tick prompt renders off
104
+ * `escalation.maxStrikes`; the ledger gate consumes `escalation.strikes`
105
+ * per-rung when present (#2248), else falls back to the scalar `maxStrikes`
106
+ * check (legacy).
107
+ */
108
+ export interface E2eEscalationPolicy {
109
+ escalation: {
110
+ /**
111
+ * Consecutive-failure ladder — each entry widens the response (e.g. [2, 3, 5]:
112
+ * widen scope at 2, force the full suite at 3, hard-stop at 5). Validated
113
+ * (an array of numbers) and consumed per-rung by check-e2e-escalation.mjs
114
+ * (#2248, AC-2248.2): the highest rung the ledger's trailing consecutive-
115
+ * REGRESSION count crosses drives distinct exit messaging (widen /
116
+ * force-full-suite / hard-stop-to-needs-human).
117
+ */
118
+ strikes: number[];
119
+ /**
120
+ * Required once `escalation` is declared. Drives the ship tick prompt's
121
+ * within-run strike count unconditionally; drives check-e2e-escalation.mjs's
122
+ * escalate/no-escalate decision only when `strikes` above is absent/invalid
123
+ * (the pre-#2248 scalar path, kept for backward compatibility). No
124
+ * config-layer default: when the whole `e2ePolicy` key is ABSENT, both
125
+ * check-e2e-escalation.mjs and TICK_PROMPT.md.ejs fall back to 2 (the
126
+ * pre-#2043 hardcoded 2-strike rule) — see the interface doc above.
127
+ */
128
+ maxStrikes: number;
129
+ };
130
+ }
131
+ /**
132
+ * #2401 — `/ship` ceremony bounds. The train (one worktree/branch/gate/PR carrying N issues)
133
+ * is the DEFAULT unit of ceremony, so how far it may grow is a per-project decision rather
134
+ * than a constant. Absent ⇒ {@link DEFAULT_TRAIN_LIMITS} (maxChain 10, maxAgeMinutes 480).
135
+ */
136
+ export interface ShipConfig {
137
+ /** Sealed-train bounds, resolved by `resolveTrainLimits` (src/commands/ship-train.ts). */
138
+ train?: {
139
+ /** Total ids on the branch (primary + chained) at which the next append is refused. Absent ⇒ 10. */
140
+ maxChain?: number;
141
+ /** Age of the open train, in minutes, past which the next append is refused. Absent ⇒ 480. */
142
+ maxAgeMinutes?: number;
143
+ };
144
+ review?: {
145
+ /**
146
+ * Review rounds the `refactor` phase may spend before the change must land with its
147
+ * remaining findings parked. Absent ⇒ {@link DEFAULT_REVIEW_MAX_ROUNDS} (2). Enforced by
148
+ * `arbiter ship`: the round past the cap is refused unless `--force-review` is passed.
149
+ */
150
+ maxRounds?: number;
151
+ };
152
+ }
153
+ interface ContextPackConfig {
154
+ /** File-pattern to ADR mappings. Used by `arbiter context-pack` to annotate @source: citations. */
155
+ adrMappings?: ContextPackAdrMapping[];
156
+ }
157
+ /**
158
+ * Integer migration-routing version (#605 / R1.K7).
159
+ *
160
+ * `version` (string) remains the human-facing semver-ish marker
161
+ * ("0.1", "0.2", ...). `$schemaVersion` is the machine routing key the
162
+ * migration registry consults — bumped only on a config-shape change.
163
+ *
164
+ * Loading a config with `$schemaVersion > CURRENT_CONFIG_SCHEMA_VERSION`
165
+ * is a hard error (do not silently load); see `loadConfig`.
166
+ *
167
+ * #1524: kept in lock-step with the migration terminus. The chain ends at
168
+ * `migrateV3ToV4`, which stamps `$schemaVersion: 4`, so a freshly-migrated
169
+ * config is a `4`. There is no `v4-to-v5` migration, so advertising `5` here
170
+ * desynced the loader's ceiling from the highest version this build can emit.
171
+ * The `migration-terminus` invariant test guards this equality.
172
+ */
173
+ export declare const CURRENT_CONFIG_SCHEMA_VERSION = 4;
174
+ /**
175
+ * #257/#1524: domain-specific test-taxonomy configuration. Its `domainDims[]`
176
+ * flow into the TEST_TAXONOMY template. Declared here (the config SSOT) so the
177
+ * generator can read it through the type system instead of an untyped cast.
178
+ */
179
+ export interface TaxonomyConfig {
180
+ /** Project-specific taxonomy dimensions appended to the archetype defaults. */
181
+ domainDims?: string[];
182
+ }
183
+ export interface ArbiterConfigV2 {
184
+ version: string;
185
+ $schemaVersion?: number;
186
+ /**
187
+ * #1978: durable project name, resolved once at `init` time via
188
+ * {@link resolveProjectName} (stored name → package.json → git remote → cwd
189
+ * basename) and persisted here so `arbiter update`/`diff` never re-derive it
190
+ * from the cwd basename — which breaks every worktree-based invocation
191
+ * (a worktree dir like `1978-fix-cwd` would otherwise become the project
192
+ * name). Absent on configs written before this field existed; callers fall
193
+ * back through the same precedence chain in that case.
194
+ */
195
+ projectName?: string;
196
+ tools: AiTool[];
197
+ governanceLevel: GovernanceLevel;
198
+ useGitHub?: boolean;
199
+ permitGitHub?: boolean;
200
+ decomposition?: DecompositionConfig;
201
+ features: FeatureFlags;
202
+ thresholds: ThresholdsV2;
203
+ /**
204
+ * Project language. Persisted so it is authoritative over raw filesystem detection
205
+ * (#1343 `resolveLanguage`): a Go-primary repo with a frontend-lane package.json keeps
206
+ * `go`. It is re-detected only on a genuine on-disk migration — when this stored
207
+ * language's build-file signal is gone — so `arbiter update` still picks up language
208
+ * migrations and re-runs language-gated generators.
209
+ */
210
+ language?: Language;
211
+ /** JavaScript package manager used by generated package-script gate checks. */
212
+ packageManager?: 'npm' | 'pnpm' | 'yarn' | 'bun';
213
+ archetype?: Archetype;
214
+ architectureStyle?: ArchitectureStyle;
215
+ isMultiTenant?: boolean;
216
+ /**
217
+ * #1317: legacy/derived database flag. Kept for back-compat — derived from
218
+ * {@link databaseEngine} (`hasDatabase = databaseEngine != null && databaseEngine !== 'none'`).
219
+ * Persisting both is fine; the axis derivation in detectors/axis.ts keeps them in sync.
220
+ */
221
+ hasDatabase?: boolean;
222
+ /**
223
+ * #1317: database engine axis. Source of truth for integration-testing scaffolding
224
+ * (sqlite ⇒ containerless TestMain; none ⇒ no DB test; postgresql/mysql ⇒ testcontainers).
225
+ * Absent ⇒ derived from {@link hasDatabase} (legacy `hasDatabase:true` ⇒ 'postgresql').
226
+ */
227
+ databaseEngine?: 'postgresql' | 'mysql' | 'mongodb' | 'sqlite' | 'other' | 'none';
228
+ hasPublicApi?: boolean;
229
+ acceptBetaTools?: boolean;
230
+ evidenceRetention?: EvidenceRetentionConfig;
231
+ thresholdProfile?: ThresholdProfile;
232
+ strictnessTier?: StrictnessTier;
233
+ graceEndsAt?: string;
234
+ graceFromLevel?: GovernanceLevel;
235
+ contractType?: ContractType;
236
+ /**
237
+ * #1254: industry compliance overlay axis. Persisted so `arbiter doctor`
238
+ * can flag incoherent (overlay × governanceLevel) cells and `arbiter update`
239
+ * re-emits the overlay artefacts. Absent = 'none'.
240
+ */
241
+ industryOverlay?: 'pharma' | 'sox' | 'gdpr' | 'generic' | 'iso27001' | 'iso9001' | 'regulated' | 'none';
242
+ basePackage?: string;
243
+ /**
244
+ * #1616: deploy target axis. Consumed by the github (04-deploy-test/10-deploy-prod
245
+ * workflows) and infra (azure-container-app) generators. Persisted so `arbiter
246
+ * update`/`diff` re-emit deploy workflows + infra instead of silently coercing to
247
+ * 'none' on every backend-web-db project's round-trip.
248
+ */
249
+ deployTarget?: DeployTarget;
250
+ invariantTiers?: InvariantTier[];
251
+ worktree?: WorktreeConfig;
252
+ plugins?: string[];
253
+ /**
254
+ * #1730 — per-companion overrides for /ship companion-plugin activation, keyed by bare skill
255
+ * name or full skillId (e.g. "ponytail"). Absent ⇒ any installed companion auto-activates in
256
+ * its policy-default mode on product repos. `enabled:false` disables without uninstalling;
257
+ * `mode` forces lite|full. Never activates on arbiter-self regardless of this setting.
258
+ */
259
+ companions?: Record<string, {
260
+ enabled?: boolean;
261
+ mode?: 'lite' | 'full';
262
+ }>;
263
+ lanes?: Lane[];
264
+ taskTiers?: TaskTiers;
265
+ /**
266
+ * #257/#1524: domain-specific test-taxonomy dimensions. Consumed by the
267
+ * TEST_TAXONOMY generator (`generateTestTaxonomy`) and surfaced in
268
+ * docs/TEST_TAXONOMY.md. Declared on the SSOT type so a key typo or rename is
269
+ * a compile error rather than a silent fall-through to `[]`.
270
+ */
271
+ taxonomy?: TaxonomyConfig;
272
+ /** CONTEXT_PACK generator configuration (#254). */
273
+ contextPack?: ContextPackConfig;
274
+ /** #1291 — ship autonomy gating (ADR-093 §4). Absent ⇒ L0 (ask each step). */
275
+ automation?: AutomationConfig;
276
+ /** #2356 — opt-in external review and explicit code-egress consent. */
277
+ crossModelReview?: CrossModelReviewConfig;
278
+ /** Observability provider configuration. Absent = no observability files generated. */
279
+ observability?: ObservabilityConfig;
280
+ /** Auth provider configuration. Absent = no auth setup files generated. */
281
+ auth?: AuthConfig;
282
+ /** Frontend framework + tooling configuration. Absent = no framework-specific governance text. */
283
+ frontend?: FrontendConfig;
284
+ /** Active project preset for audit/drift detection. Absent = no preset applied. */
285
+ preset?: ProjectPreset;
286
+ /** Release channel preference. Controls `arbiter doctor` reporting + downgrade warnings. Default: latest. */
287
+ channel?: 'latest' | 'beta' | 'canary';
288
+ /** Governance policy overrides. Absent = default behaviour. */
289
+ governance?: GovernanceConfig;
290
+ /** KIT install state. Populated by `arbiter kit install` (not under --dry-run). */
291
+ kit?: {
292
+ measure: Record<string, {
293
+ status: 'present' | 'partial' | 'missing';
294
+ evidence: string[];
295
+ }>;
296
+ };
297
+ /** ADR-051: collaboration-mode axis. Absent = inferred from features.soloDevMode or defaults to 'peer-review'. */
298
+ collaborationMode?: CollaborationMode;
299
+ /**
300
+ * ADR-051: branching strategy. When absent, derived from collaborationMode defaults table.
301
+ * Persisted only when set via `arbiter configure --set branchingStrategy=…`.
302
+ */
303
+ branchingStrategy?: BranchingStrategy;
304
+ /**
305
+ * ADR-051: trunk-solo merge method override.
306
+ * 'direct' = push to trunk, no PR. 'pr-ff' = gh pr + ff-only merge.
307
+ * Persisted only when set via `arbiter configure --set solo.mergeMode=…`.
308
+ */
309
+ solo?: {
310
+ mergeMode: SoloMergeMode;
311
+ };
312
+ /**
313
+ * #1394/#1623: conformance scoring override. When present (and valid), it is merged
314
+ * over the level-default + brownfield overlay so a project can pin its own tier-1
315
+ * members / family weights / gold gate. validateConfig validates it; runConformance
316
+ * reads + applies it. Absent ⇒ the governance×brownfield default drives the bar.
317
+ */
318
+ conformanceThresholds?: ConformanceThresholds;
319
+ /**
320
+ * #1693 (ADR-101): runner profile axis, orthogonal to collaborationMode/pipelineStyle.
321
+ * 'fleet' (default) = current behavior: fuzz + soak-e2e heavy jobs run at nightly
322
+ * cadence, hard-gated by nightly-required.
323
+ * 'solo' = fuzz + soak-e2e move to weekly cadence instead (single self-hosted
324
+ * runner), preserving the same hard-gate + issue-filing semantics at weekly
325
+ * cadence. Absent field treated as 'fleet'.
326
+ */
327
+ runnerProfile?: 'solo' | 'fleet';
328
+ /** #2043 (AC-2043.2): per-project smoke-journey acceptance floor. Absent ⇒ {@link DEFAULT_SMOKE_JOURNEYS}. */
329
+ smokeJourneys?: SmokeJourneyPolicy;
330
+ /** #2043 (AC-2043.4/5): configurable e2e escalation ladder. Absent ⇒ {@link DEFAULT_E2E_ESCALATION}. */
331
+ e2ePolicy?: E2eEscalationPolicy;
332
+ /** #2401: `/ship` ceremony bounds — train size/age and the review round cap. */
333
+ ship?: ShipConfig;
334
+ }
335
+ interface GovernanceConfig {
336
+ /**
337
+ * Invariant catalog scope.
338
+ * 'core' (default): INV-01..INV-61 only.
339
+ * 'extended': also includes opt-in extended set (INV-62..INV-71).
340
+ */
341
+ invariants_catalog?: 'core' | 'extended';
342
+ /**
343
+ * INV-115 constraint-scan gate toggle (#2037).
344
+ * 'on' (default): fail-closed when scripts/constraint-map.json is missing.
345
+ * 'off': explicit, visible opt-out — the gate SKIPs instead of running.
346
+ */
347
+ constraintScan?: 'on' | 'off';
348
+ /**
349
+ * #2045: repo-relative substrings guarded by pre-edit-ssot-guard.mjs, read at hook
350
+ * runtime (not baked into the hook), ADDED to the hook's own DEFAULT_SSOT_PATTERNS
351
+ * (AGENTS.md, .claude/CLAUDE.md, .agents/CODEX.md, docs/METHOD/, docs/SYSTEM/DECISIONS,
352
+ * docs/SYSTEM/CANON.md, docs/ADR/). Additive only — cannot remove a default-guarded
353
+ * path, so a config typo or an empty list never silently weakens the guard.
354
+ */
355
+ ssotGuardPatterns?: string[];
356
+ /**
357
+ * #2035: project-declared invariants (PROJ-NN namespace). The project is the
358
+ * author of its own catalog additions — merged with the built-in catalog at
359
+ * getFilteredInvariants. Ids MUST be PROJ-NN (never INV-NN — the built-in
360
+ * namespace is reserved); duplicates and retired entries are rejected.
361
+ */
362
+ projectInvariants?: Invariant[];
363
+ /**
364
+ * #2044 (AC-2044.5/6): live-SSOT surfaces — the declared-live matrix/ledger
365
+ * files that a code change MUST update in the SAME commit. check-drift
366
+ * (--live-ssot) binds the commit to the declared surfaces; the obligation is
367
+ * LIMITED to these surfaces (not every commit).
368
+ */
369
+ liveSsot?: {
370
+ surfaces: {
371
+ path: string;
372
+ kind: 'matrix' | 'ledger';
373
+ keys?: string[];
374
+ }[];
375
+ };
376
+ }
377
+ export type ValidateResult = {
378
+ ok: true;
379
+ config: ArbiterConfigV2;
380
+ } | {
381
+ ok: false;
382
+ errors: string[];
383
+ };
384
+ export declare const DEFAULT_THRESHOLDS: Record<GovernanceLevel, ThresholdsV2>;
385
+ export declare function validateConformanceThresholds(raw: unknown): string[];
386
+ export declare function autoFillConformanceThresholds(level: GovernanceLevel, cls?: BrownfieldClass): ConformanceThresholds;
387
+ export declare const GOVERNANCE_LEVELS: ReadonlySet<string>;
388
+ export declare const INDUSTRY_OVERLAYS: ReadonlySet<string>;
389
+ export declare const VALID_COLLABORATION_MODES: ReadonlySet<string>;
390
+ export declare const VALID_SOLO_MERGE_MODES: ReadonlySet<string>;
391
+ export declare const VALID_BRANCHING_STRATEGIES: ReadonlySet<string>;
392
+ /**
393
+ * Canonical AI-tool allow-list — the single source of truth for tool validation.
394
+ * #1594: exported so the v1→v2 migration filter imports it instead of keeping a
395
+ * stale hand-copy that silently strips tools.
396
+ *
397
+ * #2367 (ADR-119): narrowed to the two tools arbiter actually emits for. The
398
+ * five retired experimental targets (cursor/copilot/gemini/windsurf/aider) are
399
+ * now unknown values — `sanitizeCoercibleFields` filters them out of an older
400
+ * `arbiter.json` and falls back to `['claude','codex']` (ADR-105 never-brick),
401
+ * so an existing config is coerced with a report line, never rejected outright.
402
+ * Must stay identical to `AiTool` and `SUPPORTED_AI_TOOLS` in wizard/types.ts.
403
+ */
404
+ export declare const AI_TOOLS: ReadonlySet<string>;
405
+ export declare const DATABASE_ENGINES: ReadonlySet<string>;
406
+ export declare const STRICTNESS_TIERS: ReadonlySet<string>;
407
+ export declare const RUNNER_PROFILES: ReadonlySet<string>;
408
+ export declare const PACKAGE_MANAGERS: ReadonlySet<string>;
409
+ export declare const THRESHOLD_PROFILES: ReadonlySet<string>;
410
+ export declare const CONTRACT_TYPES: ReadonlySet<string>;
411
+ export declare const AUTH_PROVIDERS: ReadonlySet<string>;
412
+ export declare const OBSERVABILITY_PROVIDERS: ReadonlySet<string>;
413
+ export declare const DEPLOY_TARGETS: ReadonlySet<string>;
414
+ /**
415
+ * #1677: type-narrowing validator for the `--deploy-target` non-interactive flag.
416
+ * Mirrors the `validateProviders` membership-check pattern; rejecting at the CLI cast
417
+ * site (no silent coercion) keeps an unknown value from reaching buildNonInteractiveConfig.
418
+ */
419
+ export declare function isDeployTarget(value: string): value is DeployTarget;
420
+ /**
421
+ * #1585: single source of truth for threshold range validity — coverage keys are
422
+ * 1..100, the positive keys are > 0. Exported so the env-override layer
423
+ * (env-overrides.ts) reuses the exact same bounds validateThresholds enforces and
424
+ * the two definitions cannot drift. An out-of-range env override is dropped+warned
425
+ * by the override layer instead of flowing through and bricking validateConfig.
426
+ */
427
+ export declare function isThresholdValueInRange(key: string, value: number): boolean;
428
+ export declare function validateConfig(raw: unknown): ValidateResult;
429
+ /** One field sanitizeCoercibleFields rewrote because its value failed validateConfig. */
430
+ export interface CoercedField {
431
+ /** Top-level field name that was coerced (e.g. "contractType"). */
432
+ field: string;
433
+ /** The original (invalid) value that was present. */
434
+ from: unknown;
435
+ /**
436
+ * The value substituted in its place. `undefined` means the field was
437
+ * dropped entirely — it becomes absent, which validateConfig already
438
+ * treats as "not configured" for every field in the coercible set.
439
+ */
440
+ to: unknown;
441
+ }
442
+ export interface SanitizeResult {
443
+ draft: Record<string, unknown>;
444
+ report: CoercedField[];
445
+ }
446
+ /**
447
+ * Never-brick fallback (T0 — total config migration).
448
+ *
449
+ * `loadConfig` calls this ONLY after a strict `validateConfig()` pass has
450
+ * already failed — a config that validates cleanly never reaches this
451
+ * function, so the happy path is byte-for-byte unchanged.
452
+ *
453
+ * Deliberately narrow: this repairs only the closed set of "axis/identity"
454
+ * fields that steer template/generator SELECTION. It does NOT touch
455
+ * `features`, `thresholds`, `decomposition`, `frontend`, `automation`,
456
+ * `contextPack`, `taskTiers`, `kit`, `companions`, `governance`,
457
+ * `conformanceThresholds` or `channel` — a bad shape in any of those
458
+ * controls gate strictness or CI composition directly, so silently
459
+ * defaulting it could mask a real misconfiguration instead of a stale
460
+ * migration. Those stay FATAL (loadConfig still throws E_CONFIG_INVALID).
461
+ *
462
+ * Coercible set, each with a safe, already-precedented default:
463
+ * - `contractType`, `databaseEngine`, `strictnessTier`, `thresholdProfile`,
464
+ * `runnerProfile`, `industryOverlay` — unknown/removed enum value → the
465
+ * field is dropped (becomes absent/"not configured").
466
+ * - `lanes` — invalid entries are filtered out; valid entries are kept.
467
+ * - `governanceLevel` — absent → defaults to `'L2'`. A present but invalid
468
+ * value is FATAL: this field defines what “green” means, so it must fail
469
+ * closed like a syntax error rather than silently weakening governance.
470
+ * - `tools` — unknown entries filtered to the known `AI_TOOLS` set;
471
+ * falls back to `['claude', 'codex']` if that would empty the array.
472
+ * - `useGitHub`/`permitGitHub` — neither present as a boolean → defaults
473
+ * `permitGitHub: false`.
474
+ *
475
+ * Never mutates its input; returns a fresh draft plus a `report` of every
476
+ * field it touched. An empty report means nothing here was coercible — the
477
+ * caller should treat the original validation failure as fatal.
478
+ */
479
+ export declare function sanitizeCoercibleFields(raw: Record<string, unknown>): SanitizeResult;
480
+ export declare const VALID_LANES: ReadonlySet<string>;
@@ -0,0 +1 @@
1
+ export const DEFAULT_TASK_TIERS={XS:{planDepth:"minimal",reviewAgentCount:1},S:{planDepth:"brief",reviewAgentCount:1},Standard:{planDepth:"full",reviewAgentCount:2}},DEFAULT_CROSS_MODEL_REVIEW={enabled:!1,diffEgressConsent:!1,providers:["codex"],slots:{codeReview:1,redTeamReview:0},timeoutMs:3e5,onUnavailable:"degrade"},AUTONOMY_LEVELS=["L0","L1","L2","L3"],VALID_GATE_LEVELS=["L1","L2"],CURRENT_CONFIG_SCHEMA_VERSION=4,DEFAULT_THRESHOLDS={L1:{lineCoverage:60,branchCoverage:50,mutationScore:70,cyclomaticComplexity:20,methodLength:100,maxParams:8},L2:{lineCoverage:80,branchCoverage:70,mutationScore:80,cyclomaticComplexity:15,methodLength:65,maxParams:7},L3:{lineCoverage:85,branchCoverage:88,mutationScore:85,cyclomaticComplexity:10,methodLength:40,maxParams:5},L4:{lineCoverage:85,branchCoverage:88,mutationScore:85,cyclomaticComplexity:10,methodLength:40,maxParams:5}};const TIER1_MEMBERS_DEFAULT=["D-TEST-LEVELS","D-GATE-GREEN","D-DONE-EVIDENCE","D-NO-OVERCLAIM","D-LIVE-E2E","D-FE-RENDER-GATE","D-DOMAIN-API","D-COVERAGE-THRESHOLDS","D-INVARIANTS-ENFORCED","D-COMMIT-HYGIENE","DISC-finding-hygiene"],DEFAULT_FAMILY_WEIGHTS={discipline:.15,"reality-contact":.35,"docs-convention":.2,"code-quality-gold":.3},DEFAULT_CONFORMANCE_THRESHOLDS={L1:{tier1Members:TIER1_MEMBERS_DEFAULT,familyWeights:DEFAULT_FAMILY_WEIGHTS,goldTier2Gate:.85},L2:{tier1Members:TIER1_MEMBERS_DEFAULT,familyWeights:DEFAULT_FAMILY_WEIGHTS,goldTier2Gate:.88},L3:{tier1Members:TIER1_MEMBERS_DEFAULT,familyWeights:DEFAULT_FAMILY_WEIGHTS,goldTier2Gate:.9},L4:{tier1Members:TIER1_MEMBERS_DEFAULT,familyWeights:DEFAULT_FAMILY_WEIGHTS,goldTier2Gate:.92}},BROWNFIELD_CONFORMANCE_OVERLAYS={gold:{goldTier2Gate:.9},light:{goldTier2Gate:.8},medium:{goldTier2Gate:.75},heavy:{goldTier2Gate:.7}};export function validateConformanceThresholds(raw){const errors=[];if(typeof raw!="object"||raw===null)return errors.push("conformanceThresholds must be an object"),errors;const t=raw;return Array.isArray(t.tier1Members)||errors.push("conformanceThresholds.tier1Members must be an array"),(typeof t.familyWeights!="object"||t.familyWeights===null)&&errors.push("conformanceThresholds.familyWeights must be an object"),typeof t.goldTier2Gate!="number"&&errors.push("conformanceThresholds.goldTier2Gate must be a number"),errors}export function autoFillConformanceThresholds(level,cls){const base={...DEFAULT_CONFORMANCE_THRESHOLDS[level]};if(cls!==void 0){const overlay=BROWNFIELD_CONFORMANCE_OVERLAYS[cls];return{...base,...overlay}}return base}export const GOVERNANCE_LEVELS=new Set(["L1","L2","L3","L4"]),INDUSTRY_OVERLAYS=new Set(["pharma","sox","gdpr","generic","iso27001","iso9001","regulated","none"]),VALID_COLLABORATION_MODES=new Set(["trunk-solo","peer-review","gated-review"]),VALID_SOLO_MERGE_MODES=new Set(["direct","pr-ff"]),VALID_BRANCHING_STRATEGIES=new Set(["trunk-direct","github-flow","github-flow-with-develop"]),AI_TOOLS=new Set(["claude","codex"]);const DATABASE_ENGINE_VALUES={postgresql:!0,mysql:!0,mongodb:!0,sqlite:!0,other:!0,none:!0},STRICTNESS_TIER_VALUES={practical:!0,pedantic:!0},RUNNER_PROFILE_VALUES={solo:!0,fleet:!0},PACKAGE_MANAGER_VALUES={npm:!0,pnpm:!0,yarn:!0,bun:!0},THRESHOLD_PROFILE_VALUES={scaled:!0,fixed:!0},CONTRACT_TYPE_VALUES={"rest-owned":!0,"rest-public":!0,graphql:!0,grpc:!0,"message-queue":!0,none:!0},AUTH_PROVIDER_VALUES={none:!0,"app-level-ts":!0,authelia:!0,authentik:!0,"ory-stack":!0,zitadel:!0,keycloak:!0,"saas-clerk":!0,"saas-auth0":!0,"saas-supabase-auth":!0,"saas-cognito":!0},OBSERVABILITY_PROVIDER_VALUES={none:!0,"stdout-minimal":!0,"victoria-vector-quickwit":!0,signoz:!0,openobserve:!0,"prom-grafana-loki-jaeger":!0,"saas-sentry":!0,"saas-datadog":!0,"saas-axiom":!0,"saas-betterstack":!0};export const DATABASE_ENGINES=new Set(Object.keys(DATABASE_ENGINE_VALUES)),STRICTNESS_TIERS=new Set(Object.keys(STRICTNESS_TIER_VALUES)),RUNNER_PROFILES=new Set(Object.keys(RUNNER_PROFILE_VALUES)),PACKAGE_MANAGERS=new Set(Object.keys(PACKAGE_MANAGER_VALUES)),THRESHOLD_PROFILES=new Set(Object.keys(THRESHOLD_PROFILE_VALUES)),CONTRACT_TYPES=new Set(Object.keys(CONTRACT_TYPE_VALUES)),AUTH_PROVIDERS=new Set(Object.keys(AUTH_PROVIDER_VALUES)),OBSERVABILITY_PROVIDERS=new Set(Object.keys(OBSERVABILITY_PROVIDER_VALUES));const DEPLOY_TARGET_VALUES={ghcr:!0,"azure-container-app":!0,"aws-ecs":!0,"gcp-cloud-run":!0,"nas-compose":!0,none:!0};export const DEPLOY_TARGETS=new Set(Object.keys(DEPLOY_TARGET_VALUES));export function isDeployTarget(value){return DEPLOY_TARGETS.has(value)}function isRecord(val){return typeof val=="object"&&val!==null&&!Array.isArray(val)}const THRESHOLD_COVERAGE_KEYS=["lineCoverage","branchCoverage","mutationScore"],THRESHOLD_POSITIVE_KEYS=["cyclomaticComplexity","methodLength","maxParams"];export function isThresholdValueInRange(key,value){return THRESHOLD_COVERAGE_KEYS.includes(key)?value>0&&value<=100:THRESHOLD_POSITIVE_KEYS.includes(key)?value>0:!0}function validateThresholds(raw,errors){if(!isRecord(raw)){errors.push("thresholds must be an object");return}for(const key of THRESHOLD_COVERAGE_KEYS){const v=raw[key];(typeof v!="number"||!isThresholdValueInRange(key,v))&&errors.push(`thresholds.${key} must be a number between 1 and 100`)}for(const key of THRESHOLD_POSITIVE_KEYS){const v=raw[key];(typeof v!="number"||!isThresholdValueInRange(key,v))&&errors.push(`thresholds.${key} must be a positive number`)}}const OPTIONAL_FEATURE_FLAGS=["selfValidationHarness","auditToolchain","fiveLaneCi","soloDevMode","mcpFallback","noSkippedTests","riskRegister","operationsHandbook","iso27001Mapping","nis2Mapping","gdprMapping","codeownersNotify","taxonomy25d","perfTesting","acceptanceAnchor"];function validateFeatures(raw,errors){if(!isRecord(raw)){errors.push("features must be an object");return}const flags=["contractTesting","mutationTesting","securityScanning","evidenceHarness","debtGates","suppressions"];for(const key of flags)typeof raw[key]!="boolean"&&errors.push(`features.${key} must be a boolean`);for(const key of OPTIONAL_FEATURE_FLAGS)key in raw&&typeof raw[key]!="boolean"&&errors.push(`features.${key} must be a boolean`)}function validateCollaborationAxes(raw,errors){if("collaborationMode"in raw&&raw.collaborationMode!==void 0){const cm=raw.collaborationMode;VALID_COLLABORATION_MODES.has(cm)||errors.push(`collaborationMode must be one of trunk-solo, peer-review, gated-review \u2014 got ${cm}`)}if("branchingStrategy"in raw&&raw.branchingStrategy!==void 0){const bs=raw.branchingStrategy;VALID_BRANCHING_STRATEGIES.has(bs)||errors.push(`branchingStrategy must be one of trunk-direct, github-flow, github-flow-with-develop \u2014 got ${bs}`)}if(isRecord(raw.solo)&&raw.solo.mergeMode!==void 0){const mm=raw.solo.mergeMode;VALID_SOLO_MERGE_MODES.has(mm)||errors.push(`solo.mergeMode must be one of direct, pr-ff \u2014 got ${mm}`)}}function autoFillThresholds(raw,level){raw.thresholds===void 0&&typeof level=="string"&&GOVERNANCE_LEVELS.has(level)&&(raw.thresholds={...DEFAULT_THRESHOLDS[level]})}function validateOptionalScalars(raw,errors){if("basePackage"in raw&&raw.basePackage!==void 0&&typeof raw.basePackage!="string"&&errors.push("basePackage must be a string"),"projectName"in raw&&raw.projectName!==void 0&&typeof raw.projectName!="string"&&errors.push("projectName must be a string"),"industryOverlay"in raw&&raw.industryOverlay!==void 0){const overlay=raw.industryOverlay;(typeof overlay!="string"||!INDUSTRY_OVERLAYS.has(overlay))&&errors.push(`industryOverlay must be one of ${[...INDUSTRY_OVERLAYS].join(", ")} \u2014 got ${typeof overlay=="string"?overlay:typeof overlay}`)}}function validateOptionalEnums(raw,errors){const checks=[["databaseEngine",DATABASE_ENGINES],["strictnessTier",STRICTNESS_TIERS],["thresholdProfile",THRESHOLD_PROFILES],["contractType",CONTRACT_TYPES],["runnerProfile",RUNNER_PROFILES],["packageManager",PACKAGE_MANAGERS]];for(const[field,allowed]of checks)if(field in raw&&raw[field]!==void 0){const v=raw[field];(typeof v!="string"||!allowed.has(v))&&errors.push(`${field} must be one of ${[...allowed].join(", ")} \u2014 got ${typeof v=="string"?v:typeof v}`)}}function validateProviders(raw,errors){const checks=[["auth",AUTH_PROVIDERS],["observability",OBSERVABILITY_PROVIDERS]];for(const[field,allowed]of checks){const block=raw[field];if(isRecord(block)&&block.provider!==void 0){const v=block.provider;(typeof v!="string"||!allowed.has(v))&&errors.push(`${field}.provider must be one of ${[...allowed].join(", ")} \u2014 got ${typeof v=="string"?v:typeof v}`)}}}function validateCompanions(raw,errors){const block=raw.companions;if(block!==void 0){if(!isRecord(block)||Array.isArray(block)){errors.push(`companions must be an object map of per-companion overrides \u2014 got ${Array.isArray(block)?"array":typeof block}`);return}for(const[name,override]of Object.entries(block))validateCompanionOverride(name,override,errors)}}function validateCompanionOverride(name,override,errors){if(!isRecord(override)){errors.push(`companions.${name} must be an object \u2014 got ${typeof override}`);return}override.enabled!==void 0&&typeof override.enabled!="boolean"&&errors.push(`companions.${name}.enabled must be a boolean`);const mode=override.mode;mode!==void 0&&mode!=="lite"&&mode!=="full"&&errors.push(`companions.${name}.mode must be one of lite, full \u2014 got ${typeof mode=="string"?mode:typeof mode}`)}export function validateConfig(raw){if(!isRecord(raw))return{ok:!1,errors:["config must be a non-null object"]};const draft=structuredClone(raw),errors=[];typeof draft.version!="string"&&errors.push("version must be a string"),validateOptionalScalars(draft,errors),validateOptionalEnums(draft,errors),validateProviders(draft,errors),validateCompanions(draft,errors);const rawLevel=draft.governanceLevel,level=typeof rawLevel=="string"?rawLevel.toUpperCase():rawLevel;typeof rawLevel=="string"&&(draft.governanceLevel=level),(typeof level!="string"||!GOVERNANCE_LEVELS.has(level))&&errors.push(`governanceLevel must be one of L1, L2, L3, L4 \u2014 got ${String(rawLevel)}`),(!Array.isArray(draft.tools)||draft.tools.some(t=>!AI_TOOLS.has(t)))&&errors.push("tools must be an array of valid AI tools");const hasUseGitHub=typeof draft.useGitHub=="boolean",hasPermitGitHub=typeof draft.permitGitHub=="boolean";if(!hasUseGitHub&&!hasPermitGitHub&&errors.push("useGitHub or permitGitHub must be a boolean"),validateCollaborationAxes(draft,errors),autoFillThresholds(draft,level),validateFeatures(draft.features,errors),validateThresholds(draft.thresholds,errors),validateDecomposition(draft.decomposition,errors),validateFrontend(draft.frontend,errors),validateLanes(draft.lanes,errors),validateTaskTiers(draft.taskTiers,errors),validateContextPack(draft.contextPack,errors),validateAutomation(draft.automation,errors),validateCrossModelReview(draft.crossModelReview,errors),validateChannel(draft.channel,errors),validateGovernance(draft.governance,errors),validateKit(draft.kit,errors),validateSmokeJourneys(draft.smokeJourneys,errors),validateE2ePolicy(draft.e2ePolicy,errors),validateShip(draft.ship,errors),draft.conformanceThresholds!==void 0){const ctErrors=validateConformanceThresholds(draft.conformanceThresholds);errors.push(...ctErrors)}return errors.length>0?{ok:!1,errors}:{ok:!0,config:draft}}export function sanitizeCoercibleFields(raw){const draft=structuredClone(raw),report=[],dropIfInvalidEnum=(field,allowed)=>{const v=draft[field];v!==void 0&&(typeof v=="string"&&allowed.has(v)||(report.push({field,from:v,to:void 0}),Reflect.deleteProperty(draft,field)))};if(dropIfInvalidEnum("contractType",CONTRACT_TYPES),dropIfInvalidEnum("databaseEngine",DATABASE_ENGINES),dropIfInvalidEnum("strictnessTier",STRICTNESS_TIERS),dropIfInvalidEnum("thresholdProfile",THRESHOLD_PROFILES),dropIfInvalidEnum("runnerProfile",RUNNER_PROFILES),dropIfInvalidEnum("industryOverlay",INDUSTRY_OVERLAYS),Array.isArray(draft.lanes)){const original=draft.lanes,filtered=original.filter(v=>VALID_LANES.has(v));filtered.length!==original.length&&(report.push({field:"lanes",from:original,to:filtered}),draft.lanes=filtered)}const rawLevel=draft.governanceLevel;rawLevel===void 0&&(report.push({field:"governanceLevel",from:rawLevel,to:"L2"}),draft.governanceLevel="L2");const rawTools=draft.tools;if(!Array.isArray(rawTools)||rawTools.some(t=>!AI_TOOLS.has(t))){const filtered=Array.isArray(rawTools)?rawTools.filter(t=>AI_TOOLS.has(t)):[],fallback=filtered.length>0?filtered:["claude","codex"];report.push({field:"tools",from:rawTools,to:fallback}),draft.tools=fallback}const hasUseGitHub=typeof draft.useGitHub=="boolean",hasPermitGitHub=typeof draft.permitGitHub=="boolean";return!hasUseGitHub&&!hasPermitGitHub&&(report.push({field:"permitGitHub",from:draft.permitGitHub,to:!1}),draft.permitGitHub=!1),{draft,report}}const VALID_FRONTEND_FRAMEWORKS=new Set(["vue","react","svelte"]),FRONTEND_IDENT_RE=/^[@a-zA-Z0-9][a-zA-Z0-9@/._-]{0,59}$/;function validateFrontend(raw,errors){if(raw!=null){if(!isRecord(raw)){errors.push("frontend must be an object");return}raw.framework!=null&&(typeof raw.framework!="string"?errors.push("frontend.framework must be a string"):VALID_FRONTEND_FRAMEWORKS.has(raw.framework)||errors.push(`frontend.framework must be one of vue, react, svelte \u2014 got ${raw.framework}`));for(const k of["stateManager","validationLib"])raw[k]!=null&&(typeof raw[k]!="string"?errors.push(`frontend.${k} must be a string`):FRONTEND_IDENT_RE.test(raw[k])||errors.push(`frontend.${k} must match [a-zA-Z0-9-], max 40 chars \u2014 got ${raw[k]}`))}}const DECOMPOSITION_BACKENDS=new Set(["github","markdown"]);export const VALID_LANES=new Set(["frontend","backend","docs"]);function validateLanes(raw,errors){if(raw!=null){if(!Array.isArray(raw)){errors.push("lanes must be an array");return}for(const v of raw)VALID_LANES.has(v)||errors.push(`lanes contains invalid value: ${String(v)}`)}}function validateAutomation(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("automation must be an object");return}const level=raw.autonomy;AUTONOMY_LEVELS.includes(level)||errors.push(`automation.autonomy must be one of ${AUTONOMY_LEVELS.join("|")}`),validateAutomationPrefs(raw,errors)}function validateAutomationPrefs(raw,errors){const mpw=raw.maxParallelWorktrees;mpw!==void 0&&(typeof mpw!="number"||!Number.isInteger(mpw)||mpw<1)&&errors.push("automation.maxParallelWorktrees must be a positive integer");const gate=raw.defaultGateLevel;gate!==void 0&&!VALID_GATE_LEVELS.includes(gate)&&errors.push(`automation.defaultGateLevel must be one of ${VALID_GATE_LEVELS.join("|")}`)}function validateContextPack(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("contextPack must be an object");return}const mappings=raw.adrMappings;if(mappings!=null){if(!Array.isArray(mappings)){errors.push("contextPack.adrMappings must be an array");return}for(let i=0;i<mappings.length;i++){const m=mappings[i];if(!isRecord(m)){errors.push(`contextPack.adrMappings[${i}] must be an object`);continue}(typeof m.pattern!="string"||m.pattern.length===0)&&errors.push(`contextPack.adrMappings[${i}].pattern must be a non-empty string`),(typeof m.adr!="string"||m.adr.length===0)&&errors.push(`contextPack.adrMappings[${i}].adr must be a non-empty string`)}}}const CROSS_MODEL_REVIEW_PROVIDERS=new Set(["codex"]),CROSS_MODEL_REVIEW_POLICIES=new Set(["degrade","fail"]);function validateCrossModelReview(raw,errors){if(raw!==void 0){if(!isRecord(raw)){errors.push("crossModelReview must be an object");return}validateCrossModelBooleans(raw,errors),validateCrossModelProviders(raw,errors),validateCrossModelSlots(raw,errors),validateCrossModelTimeout(raw,errors),validateCrossModelPolicy(raw,errors)}}function validateCrossModelBooleans(raw,errors){typeof raw.enabled!="boolean"&&errors.push("crossModelReview.enabled must be a boolean"),typeof raw.diffEgressConsent!="boolean"&&errors.push("crossModelReview.diffEgressConsent must be a boolean")}function validateCrossModelProviders(raw,errors){const providers=raw.providers;(!Array.isArray(providers)||providers.length===0||providers.some(provider=>!CROSS_MODEL_REVIEW_PROVIDERS.has(provider)))&&errors.push("crossModelReview.providers must be a non-empty array containing only codex")}function validateCrossModelSlots(raw,errors){const slots=raw.slots;if(!isRecord(slots)){errors.push("crossModelReview.slots must be an object");return}const codeReview=slots.codeReview;codeReview!==0&&codeReview!==1&&errors.push("crossModelReview.slots.codeReview must be 0 or 1 in v1"),slots.redTeamReview!==0&&errors.push("crossModelReview.slots.redTeamReview must be 0 until red-team support ships")}function validateCrossModelTimeout(raw,errors){const timeoutMs=raw.timeoutMs;(typeof timeoutMs!="number"||!Number.isInteger(timeoutMs)||timeoutMs<1)&&errors.push("crossModelReview.timeoutMs must be a positive integer")}function validateCrossModelPolicy(raw,errors){CROSS_MODEL_REVIEW_POLICIES.has(raw.onUnavailable)||errors.push("crossModelReview.onUnavailable must be degrade or fail")}const VALID_INVARIANTS_CATALOG_VALUES=new Set(["core","extended"]),VALID_CONSTRAINT_SCAN_VALUES=new Set(["on","off"]);function validateGovernance(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("governance must be an object");return}const catalog=raw.invariants_catalog;catalog!==void 0&&!VALID_INVARIANTS_CATALOG_VALUES.has(catalog)&&errors.push(`governance.invariants_catalog must be 'core' or 'extended' \u2014 got ${typeof catalog=="string"?catalog:JSON.stringify(catalog)}`);const constraintScan=raw.constraintScan;constraintScan!==void 0&&!VALID_CONSTRAINT_SCAN_VALUES.has(constraintScan)&&errors.push(`governance.constraintScan must be 'on' or 'off' \u2014 got ${typeof constraintScan=="string"?constraintScan:JSON.stringify(constraintScan)}`),validateSsotGuardPatterns(raw.ssotGuardPatterns,errors),validateProjectInvariants(raw.projectInvariants,errors),validateLiveSsot(raw.liveSsot,errors)}function validateLiveSsot(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("governance.liveSsot must be an object");return}const surfaces=raw.surfaces;if(!Array.isArray(surfaces)){errors.push("governance.liveSsot.surfaces must be an array");return}for(const entry of surfaces){if(!isRecord(entry)||typeof entry.path!="string"){errors.push("governance.liveSsot.surfaces entries must be objects with a string path");continue}const kind=entry.kind;kind!=="matrix"&&kind!=="ledger"&&errors.push(`governance.liveSsot.surfaces kind must be 'matrix' or 'ledger' \u2014 got ${String(kind)}`);const keys=entry.keys;keys!==void 0&&(!Array.isArray(keys)||keys.some(k=>typeof k!="string"))&&errors.push("governance.liveSsot.surfaces keys must be an array of strings")}}function validateProjectInvariantLanguages(id,entry,errors){const languages=entry.languages;if(languages===void 0)return;if(!Array.isArray(languages)||languages.some(l=>typeof l!="string")){errors.push(`governance.projectInvariants ${id} languages must be an array of strings`);return}const languageDetail=entry.languageDetail;if(isRecord(languageDetail))for(const lang of languages)lang in languageDetail||errors.push(`governance.projectInvariants ${id} languageDetail must cover every language in languages (missing ${String(lang)})`)}function validateProjectInvariantEntry(entry,seen,errors){if(!isRecord(entry)){errors.push("governance.projectInvariants entries must be objects");return}const id=entry.id;if(typeof id!="string"||!PROJ_INVARIANT_ID_RE.test(id)){errors.push(`governance.projectInvariants id must match /^PROJ-\\d+$/ (the INV-NN namespace is reserved) \u2014 got ${String(id)}`);return}if(seen.has(id)){errors.push(`governance.projectInvariants duplicate id: ${id}`);return}seen.add(id),entry.status==="retired"&&errors.push(`governance.projectInvariants ${id} must not be retired`),(entry.tier===void 0||entry.title===void 0||entry.description===void 0)&&errors.push(`governance.projectInvariants ${id} requires tier, title, and description`),typeof entry.alwaysActive!="boolean"&&errors.push(`governance.projectInvariants ${id} requires boolean alwaysActive`),validateProjectInvariantLanguages(id,entry,errors)}function validateProjectInvariants(raw,errors){if(raw==null)return;if(!Array.isArray(raw)){errors.push("governance.projectInvariants must be an array of invariant objects");return}const seen=new Set;for(const entry of raw)validateProjectInvariantEntry(entry,seen,errors)}const PROJ_INVARIANT_ID_RE=/^PROJ-\d+$/;function validateSsotGuardPatterns(raw,errors){raw!==void 0&&(!Array.isArray(raw)||raw.some(p=>typeof p!="string"))&&errors.push("governance.ssotGuardPatterns must be an array of strings")}const VALID_KIT_STATUSES=new Set(["present","partial","missing"]);function validateKit(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("kit must be an object");return}const measure=raw.measure;if(measure!=null){if(!isRecord(measure)){errors.push("kit.measure must be an object");return}for(const[dimId,entry]of Object.entries(measure)){if(!isRecord(entry)){errors.push(`kit.measure.${dimId} must be an object`);continue}VALID_KIT_STATUSES.has(entry.status)||errors.push(`kit.measure.${dimId}.status must be present, partial, or missing`),(!Array.isArray(entry.evidence)||entry.evidence.some(e=>typeof e!="string"))&&errors.push(`kit.measure.${dimId}.evidence must be an array of strings`);const known=new Set(["status","evidence"]),extra=Object.keys(entry).filter(k=>!known.has(k));extra.length>0&&errors.push(`kit.measure.${dimId} has unknown keys: ${extra.join(", ")}`)}}}const VALID_PLAN_DEPTHS=new Set(["minimal","brief","full"]);function validateOneTier(tierName,raw,errors){if(!isRecord(raw)){errors.push(`taskTiers.${tierName} must be an object`);return}const planDepth=raw.planDepth;(typeof planDepth!="string"||!VALID_PLAN_DEPTHS.has(planDepth))&&errors.push(`taskTiers.${tierName}.planDepth must be one of minimal, brief, full`);const count=raw.reviewAgentCount;(typeof count!="number"||!Number.isInteger(count)||count<=0)&&errors.push(`taskTiers.${tierName}.reviewAgentCount must be a positive integer`)}function validateTaskTiers(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("taskTiers must be an object");return}const required=["XS","S","Standard"];for(const tier of required){if(!(tier in raw)){errors.push(`taskTiers.${tier} is required`);continue}validateOneTier(tier,raw[tier],errors)}}function validateDecomposition(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("decomposition must be an object");return}const backend=raw.backend;backend!==void 0&&!DECOMPOSITION_BACKENDS.has(backend)&&errors.push(`decomposition.backend must be "github" or "markdown" \u2014 got ${typeof backend=="string"?backend:JSON.stringify(backend)}`)}const VALID_CHANNELS=new Set(["latest","beta","canary"]);function validateChannel(raw,errors){raw!=null&&(typeof raw!="string"||!VALID_CHANNELS.has(raw))&&errors.push(`channel must be one of latest, beta, canary \u2014 got ${JSON.stringify(raw)}`)}const SMOKE_JOURNEYS_MIN=2,SMOKE_JOURNEYS_MAX=4,E2E_MAX_STRIKES_MIN=2;function validateSmokeJourneys(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("smokeJourneys must be an object");return}const requiredJourneys=raw.requiredJourneys;requiredJourneys!==void 0&&(!Array.isArray(requiredJourneys)||requiredJourneys.some(j=>typeof j!="string"))&&errors.push("smokeJourneys.requiredJourneys must be an array of strings");const minJourneys=raw.minJourneys;minJourneys!==void 0&&(typeof minJourneys=="number"&&Number.isInteger(minJourneys)&&minJourneys>=SMOKE_JOURNEYS_MIN&&minJourneys<=SMOKE_JOURNEYS_MAX||errors.push(`smokeJourneys.minJourneys must be an integer between ${SMOKE_JOURNEYS_MIN} and ${SMOKE_JOURNEYS_MAX}`))}function validateShipBound(path,raw,errors){raw!==void 0&&(typeof raw!="number"||!Number.isInteger(raw)||raw<1)&&errors.push(`${path} must be an integer >= 1`)}function validateShipSection(path,raw,bounds,errors){if(raw!=null){if(!isRecord(raw)){errors.push(`${path} must be an object`);return}for(const bound of bounds)validateShipBound(`${path}.${bound}`,raw[bound],errors)}}function validateShip(raw,errors){if(raw!=null){if(!isRecord(raw)){errors.push("ship must be an object");return}validateShipSection("ship.train",raw.train,["maxChain","maxAgeMinutes"],errors),validateShipSection("ship.review",raw.review,["maxRounds"],errors)}}function validateE2ePolicy(raw,errors){if(raw==null)return;if(!isRecord(raw)){errors.push("e2ePolicy must be an object");return}const escalation=raw.escalation;if(escalation==null)return;if(!isRecord(escalation)){errors.push("e2ePolicy.escalation must be an object");return}const strikes=escalation.strikes;(!Array.isArray(strikes)||strikes.some(s=>typeof s!="number"))&&errors.push("e2ePolicy.escalation.strikes must be an array of numbers");const maxStrikes=escalation.maxStrikes;typeof maxStrikes=="number"&&Number.isInteger(maxStrikes)&&maxStrikes>=E2E_MAX_STRIKES_MIN||errors.push(`e2ePolicy.escalation.maxStrikes must be an integer >= ${E2E_MAX_STRIKES_MIN}`)}
@@ -0,0 +1 @@
1
+ const PROFILES={"backend-web-db":{archetype:"backend-web-db",hasUnitTests:!0,hasContainerIntegration:!0,hasPropertyTests:!1,hasE2ETests:!0,hasPerformanceTests:!0,hasContractTests:!0,levels:[{id:"L1",name:"L1 Unit",description:"Fast, isolated unit tests for business logic and domain models",tools:"JUnit/pytest/vitest/cargo test"},{id:"L2",name:"L2 Integration",description:"Service + DB integration using Testcontainers or Docker Compose",tools:"Testcontainers, RestAssured, TestClient"},{id:"L3",name:"L3 Contract",description:"Consumer-driven contract tests to verify API compatibility",tools:"Pact, Spring Cloud Contract"},{id:"L4",name:"L4 E2E",description:"End-to-end browser / API flows against a running environment",tools:"Playwright, Cypress, Postman"},{id:"L5",name:"L5 Performance",description:"Load and stress tests verifying SLAs under production-like load",tools:"k6, Gatling, Locust"}]},cli:{archetype:"cli",hasUnitTests:!0,hasContainerIntegration:!1,hasPropertyTests:!1,hasE2ETests:!1,hasPerformanceTests:!1,hasContractTests:!1,levels:[{id:"L1",name:"L1 Unit",description:"Unit tests for individual commands, parsers, and handlers",tools:"JUnit/pytest/vitest/cargo test"},{id:"L2",name:"L2 CLI Integration",description:"Integration tests invoking the CLI binary with real arguments",tools:"bats, pytest subprocess, assert_cmd"}]},library:{archetype:"library",hasUnitTests:!0,hasContainerIntegration:!1,hasPropertyTests:!0,hasE2ETests:!1,hasPerformanceTests:!1,hasContractTests:!1,levels:[{id:"L1",name:"L1 Unit",description:"Unit tests for all public API surface \u2014 every exported function/class",tools:"JUnit/pytest/vitest/cargo test"},{id:"L2",name:"L2 Property-Based",description:"Generative / property-based tests to find edge cases",tools:"fast-check, Hypothesis, proptest, QuickCheck"}]},"data-pipeline":{archetype:"data-pipeline",hasUnitTests:!0,hasContainerIntegration:!0,hasPropertyTests:!1,hasE2ETests:!1,hasPerformanceTests:!1,hasContractTests:!0,levels:[{id:"L1",name:"L1 Unit",description:"Unit tests for transforms, parsers, and aggregation logic",tools:"pytest/vitest/cargo test"},{id:"L2",name:"L2 Integration",description:"Pipeline integration with real or containerised data stores",tools:"Testcontainers, pytest-docker"},{id:"L3",name:"L3 Contract",description:"Schema / data contract tests ensuring upstream/downstream compatibility",tools:"Great Expectations, Pact, soda-core"}]},"frontend-spa":{archetype:"frontend-spa",hasUnitTests:!0,hasContainerIntegration:!1,hasPropertyTests:!1,hasE2ETests:!0,hasPerformanceTests:!1,hasContractTests:!1,levels:[{id:"L1",name:"L1 Unit",description:"Unit tests for utilities, hooks, and pure functions",tools:"vitest, jest"},{id:"L2",name:"L2 Component",description:"Component-level rendering and interaction tests",tools:"Testing Library, Storybook, Enzyme"},{id:"L3",name:"L3 E2E",description:"Full browser flows against a running or mocked backend",tools:"Playwright, Cypress"}]},embedded:{archetype:"embedded",hasUnitTests:!0,hasContainerIntegration:!1,hasPropertyTests:!1,hasE2ETests:!1,hasPerformanceTests:!1,hasContractTests:!1,levels:[{id:"L1",name:"L1 Unit",description:"Host-side unit tests for logic, state machines, and protocols",tools:"Unity, cargo test, pytest"},{id:"L2",name:"L2 Hardware Integration",description:"Tests against simulator, emulator, or real hardware in CI",tools:"QEMU, Renode, JTAG-based harness"}]}};export function getTestPyramidProfile(archetype){const profile=PROFILES[archetype];if(profile===void 0)throw new Error(`unknown archetype "${archetype}" \u2014 no test pyramid profile defined for it`);return profile}
@@ -0,0 +1,2 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{DEFAULT_THRESHOLDS}from"./schema.js";export function computeThresholds(linesOfCode,profile,governanceLevel){const levelDefaults=DEFAULT_THRESHOLDS[governanceLevel],mutationThreshold=levelDefaults.mutationScore;if(profile==="fixed")return{coverageEnabled:!0,mutationEnabled:!0,coverageThreshold:levelDefaults.lineCoverage,mutationThreshold};const coverageEnabled=linesOfCode>=1e3,mutationEnabled=linesOfCode>=5e3;let coverageThreshold;if(!coverageEnabled)coverageThreshold=60;else{const t=Math.min(1,(linesOfCode-1e3)/9e3);coverageThreshold=Math.round(60+t*25)}return{coverageEnabled,mutationEnabled,coverageThreshold,mutationThreshold}}export function resolveEffectiveThresholds(config){const profile=config.thresholdProfile??"fixed",computed=computeThresholds(config.linesOfCode??0,profile,config.governanceLevel),defaults=DEFAULT_THRESHOLDS[config.governanceLevel],lineCoverage=profile==="scaled"?computed.coverageThreshold:config.thresholds?.lineCoverage??computed.coverageThreshold,mutationScore=profile==="scaled"?computed.mutationThreshold:config.thresholds?.mutationScore??computed.mutationThreshold,branchCoverage=config.thresholds?.branchCoverage??defaults.branchCoverage;return{coverageEnabled:computed.coverageEnabled,mutationEnabled:computed.mutationEnabled,lineCoverage,branchCoverage,mutationScore}}
@@ -0,0 +1,3 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import{readdirSync}from"node:fs";import{join}from"node:path";import{safeResolve,readJson,readText,fileExists,globMatch,walkRepo}from"./shared.js";const RC_T1={family:"reality-contact",tier:1,weight:0,required_at:"L1"},DISC_T1={family:"discipline",tier:1,weight:0,required_at:"L1"},D_TEST_LEVELS_ID="D-TEST-LEVELS",D_TEST_LEVELS_TITLE="Declared test levels populated";function checkRequiredLevel(lvl,allFiles){if(typeof lvl!="object"||lvl===null)return null;const l=lvl;if((typeof l.status=="string"?l.status:"required")!=="required")return null;const matched=(Array.isArray(l.globs)?l.globs:[]).some(g=>allFiles.some(f=>globMatch(g,f))),levelName=typeof l.level=="string"?l.level:"unknown";return matched?null:levelName}export function probeDTestLevels(root){const pyramidPath=safeResolve(root,"test-pyramid.json");if(pyramidPath===null||!fileExists(pyramidPath))return{id:D_TEST_LEVELS_ID,title:D_TEST_LEVELS_TITLE,...RC_T1,verdict:"N",evidence:{file:"test-pyramid.json",detail:"missing \u2014 no test pyramid declared"}};const manifest=readJson(pyramidPath);if(manifest===null||typeof manifest!="object")return{id:D_TEST_LEVELS_ID,title:D_TEST_LEVELS_TITLE,...RC_T1,verdict:"N",evidence:{file:"test-pyramid.json",detail:"parse error"}};const m=manifest,levels=Array.isArray(m.levels)?m.levels:[];if(levels.length===0)return{id:D_TEST_LEVELS_ID,title:D_TEST_LEVELS_TITLE,...RC_T1,verdict:"N",evidence:{file:"test-pyramid.json",detail:"no levels declared"}};const allFiles=walkRepo(root),failures=levels.map(lvl=>checkRequiredLevel(lvl,allFiles)).filter(r=>r!==null);return failures.length>0?{id:D_TEST_LEVELS_ID,title:D_TEST_LEVELS_TITLE,...RC_T1,verdict:"N",evidence:{file:"test-pyramid.json",detail:`empty required levels: ${failures.join(", ")}`}}:{id:D_TEST_LEVELS_ID,title:D_TEST_LEVELS_TITLE,...RC_T1,verdict:"Y",evidence:{file:"test-pyramid.json",detail:"all required levels populated"}}}const SERVICE_ARCHETYPES=new Set(["backend","backend-web-db","backend-api","backend-service","service","fullstack","fullstack-web"]);export function probeDLiveE2e(root,archetype){if(!(archetype!==null&&(SERVICE_ARCHETYPES.has(archetype)||archetype.startsWith("backend")||archetype==="fullstack")))return{id:"D-LIVE-E2E",title:"Non-mocked live API e2e layer exists and runs",...RC_T1,verdict:"NA",evidence:{file:"arbiter.json",detail:`archetype "${archetype??"unset"}" is not a service type \u2014 not applicable`}};const manifestPath=safeResolve(root,"api-e2e.json");if(manifestPath===null||!fileExists(manifestPath))return{id:"D-LIVE-E2E",title:"Non-mocked live API e2e layer exists and runs",...RC_T1,verdict:"N",evidence:{file:"api-e2e.json",detail:"missing \u2014 no e2e manifest declared"}};const manifest=readJson(manifestPath);if(manifest===null||typeof manifest!="object")return{id:"D-LIVE-E2E",title:"Non-mocked live API e2e layer exists and runs",...RC_T1,verdict:"N",evidence:{file:"api-e2e.json",detail:"parse error"}};const m=manifest,suiteCount=typeof m.suiteCount=="number"?m.suiteCount:0;return suiteCount>0?{id:"D-LIVE-E2E",title:"Non-mocked live API e2e layer exists and runs",...RC_T1,verdict:"Y",evidence:{file:"api-e2e.json",detail:`suiteCount=${suiteCount}`}}:{id:"D-LIVE-E2E",title:"Non-mocked live API e2e layer exists and runs",...RC_T1,verdict:"N",evidence:{file:"api-e2e.json",detail:"suiteCount=0 \u2014 no e2e suites registered"}}}const D_FE_RENDER_GATE_ID="D-FE-RENDER-GATE",D_FE_RENDER_GATE_TITLE="FE archetypes have behavioural/visual gate",FE_ARCHETYPES=new Set(["frontend","frontend-web","frontend-spa","fullstack","fullstack-web"]),FE_RENDER_EVIDENCE_FILES=["playwright.config.ts","playwright.config.js","vitest.browser.config.ts","vitest.browser.config.js","chromatic.config.ts","chromatic.config.js"];export function probeDFeRenderGate(root,archetype){if(!(archetype!==null&&(FE_ARCHETYPES.has(archetype)||archetype.startsWith("frontend")||archetype==="fullstack")))return{id:D_FE_RENDER_GATE_ID,title:D_FE_RENDER_GATE_TITLE,...RC_T1,verdict:"NA",evidence:{file:"arbiter.json",detail:`archetype "${archetype??"unset"}" is not a frontend type \u2014 not applicable`}};for(const file of FE_RENDER_EVIDENCE_FILES){const abs=safeResolve(root,file);if(abs!==null&&fileExists(abs))return{id:D_FE_RENDER_GATE_ID,title:D_FE_RENDER_GATE_TITLE,...RC_T1,verdict:"Y",evidence:{file}}}return{id:D_FE_RENDER_GATE_ID,title:D_FE_RENDER_GATE_TITLE,...RC_T1,verdict:"N",evidence:{file:"arbiter.json",detail:"no playwright/vitest-browser/chromatic config found for frontend archetype"}}}export function probeDDomainApi(root){const manifestPath=safeResolve(root,"domain-api-surface.json");if(manifestPath!==null&&fileExists(manifestPath)){const manifest=readJson(manifestPath);if(manifest!==null&&typeof manifest=="object"){const m=manifest,checks=Array.isArray(m.checks)?m.checks:[];return checks.length>0?{id:"D-DOMAIN-API",title:"Domain-API surface completeness checked",...RC_T1,verdict:"Y",evidence:{file:"domain-api-surface.json",detail:`${checks.length} check(s) defined`}}:{id:"D-DOMAIN-API",title:"Domain-API surface completeness checked",...RC_T1,verdict:"N",evidence:{file:"domain-api-surface.json",detail:"checks array is empty"}}}}const legacyFiles=["openapi.yaml","openapi.yml","openapi.json","api/openapi.yaml","api/openapi.yml","api/openapi.json","pact.config.ts","pact.config.js",".pact"];for(const file of legacyFiles){const abs=safeResolve(root,file);if(abs!==null&&fileExists(abs))return{id:"D-DOMAIN-API",title:"Domain-API surface completeness checked",...RC_T1,verdict:"Y",evidence:{file}}}return{id:"D-DOMAIN-API",title:"Domain-API surface completeness checked",...RC_T1,verdict:"N",evidence:{file:"domain-api-surface.json",detail:"missing \u2014 no domain-api-surface.json or openapi/pact config found"}}}const D_DONE_EVIDENCE_ID="D-DONE-EVIDENCE",D_DONE_EVIDENCE_TITLE="Done-evidence requires reality-contact",LAST_DONE_EVIDENCE_PATH=".claude/.last-done-evidence.json";export function probeDDoneEvidence(root){const evidencePath=safeResolve(root,LAST_DONE_EVIDENCE_PATH);if(evidencePath===null||!fileExists(evidencePath))return{id:D_DONE_EVIDENCE_ID,title:D_DONE_EVIDENCE_TITLE,...RC_T1,verdict:"N",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"absent \u2014 no done-evidence recorded"}};const manifest=readJson(evidencePath);if(manifest===null||typeof manifest!="object")return{id:D_DONE_EVIDENCE_ID,title:D_DONE_EVIDENCE_TITLE,...RC_T1,verdict:"N",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"parse error"}};const rc=manifest.reality_contact;return typeof rc=="object"&&rc!==null&&rc.passed===!0?{id:D_DONE_EVIDENCE_ID,title:D_DONE_EVIDENCE_TITLE,...RC_T1,verdict:"Y",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"reality_contact.passed=true"}}:{id:D_DONE_EVIDENCE_ID,title:D_DONE_EVIDENCE_TITLE,...RC_T1,verdict:"N",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"reality_contact.passed is not true"}}}const GATE_RESULT_PATH=".arbiter/gate/local-result.json";export function probeGateGreen(root){const resultPath=safeResolve(root,GATE_RESULT_PATH);if(resultPath!==null&&fileExists(resultPath)){const manifest=readJson(resultPath);if(manifest!==null&&typeof manifest=="object"){const m=manifest;return m.pass===!0?{id:"D-GATE-GREEN",title:"Local gate most recently ran green",...DISC_T1,verdict:"Y",evidence:{file:GATE_RESULT_PATH,detail:"pass=true"}}:m.pass===!1?{id:"D-GATE-GREEN",title:"Local gate most recently ran green",...DISC_T1,verdict:"N",evidence:{file:GATE_RESULT_PATH,detail:"pass=false \u2014 gate ran, not green"}}:{id:"D-GATE-GREEN",title:"Local gate most recently ran green",...DISC_T1,verdict:"NV",evidence:{file:GATE_RESULT_PATH,detail:"gate result missing pass field (not verified)"}}}return{id:"D-GATE-GREEN",title:"Local gate most recently ran green",...DISC_T1,verdict:"NV",evidence:{file:GATE_RESULT_PATH,detail:"gate result unparseable (not verified)"}}}return{id:"D-GATE-GREEN",title:"Local gate most recently ran green",...DISC_T1,verdict:"NV",evidence:{file:GATE_RESULT_PATH,detail:"gate has not been run (not verified)"}}}const COVERAGE_SUMMARY_PATH="coverage/coverage-summary.json",COVERAGE_THRESHOLD=80;export function probeCoverageThresholds(root){const summaryPath=safeResolve(root,COVERAGE_SUMMARY_PATH);if(summaryPath===null||!fileExists(summaryPath))return{id:"D-COVERAGE-THRESHOLDS",title:`All coverage metrics >= ${COVERAGE_THRESHOLD}%`,...DISC_T1,verdict:"NV",evidence:{file:COVERAGE_SUMMARY_PATH,detail:"absent \u2014 coverage has not been collected"}};const manifest=readJson(summaryPath);if(manifest===null||typeof manifest!="object")return{id:"D-COVERAGE-THRESHOLDS",title:`All coverage metrics >= ${COVERAGE_THRESHOLD}%`,...DISC_T1,verdict:"NV",evidence:{file:COVERAGE_SUMMARY_PATH,detail:"parse error"}};const total=manifest.total;if(typeof total!="object"||total===null)return{id:"D-COVERAGE-THRESHOLDS",title:`All coverage metrics >= ${COVERAGE_THRESHOLD}%`,...DISC_T1,verdict:"NV",evidence:{file:COVERAGE_SUMMARY_PATH,detail:"total field missing"}};const t=total,metrics=["lines","branches","functions","statements"],below=[];for(const metric of metrics){const entry=t[metric];if(typeof entry=="object"&&entry!==null){const pct=entry.pct;typeof pct=="number"&&pct<COVERAGE_THRESHOLD&&below.push(`${metric}=${pct}%`)}}return below.length>0?{id:"D-COVERAGE-THRESHOLDS",title:`All coverage metrics >= ${COVERAGE_THRESHOLD}%`,...DISC_T1,verdict:"N",evidence:{file:COVERAGE_SUMMARY_PATH,detail:`below ${COVERAGE_THRESHOLD}%: ${below.join(", ")}`}}:{id:"D-COVERAGE-THRESHOLDS",title:`All coverage metrics >= ${COVERAGE_THRESHOLD}%`,...DISC_T1,verdict:"Y",evidence:{file:COVERAGE_SUMMARY_PATH,detail:`all metrics >= ${COVERAGE_THRESHOLD}%`}}}const INVARIANTS_CATALOG_PATH="src/invariants/catalog.ts",GLOBAL_INVARIANTS_PATH="GLOBAL_INVARIANTS.md",NON_TRIVIAL_INV=/##\s\S|INV-\d+/;export function probeInvariantsEnforced(root){const catalogPath=safeResolve(root,INVARIANTS_CATALOG_PATH);if(catalogPath!==null&&fileExists(catalogPath))return{id:"D-INVARIANTS-ENFORCED",title:"Invariants catalog is present",...DISC_T1,verdict:"Y",evidence:{file:INVARIANTS_CATALOG_PATH}};const arbiterInvPath=safeResolve(root,".arbiter/invariants.json");if(arbiterInvPath!==null&&fileExists(arbiterInvPath))return{id:"D-INVARIANTS-ENFORCED",title:"Invariants catalog is present",...DISC_T1,verdict:"Y",evidence:{file:".arbiter/invariants.json"}};const globalInvPath=safeResolve(root,GLOBAL_INVARIANTS_PATH);if(globalInvPath!==null){const content=readText(globalInvPath);if(content!==null&&NON_TRIVIAL_INV.test(content))return{id:"D-INVARIANTS-ENFORCED",title:"Invariants catalog is present",...DISC_T1,verdict:"Y",evidence:{file:GLOBAL_INVARIANTS_PATH}}}return invariantTierStatus(root)==="none"?{id:"D-INVARIANTS-ENFORCED",title:"Invariants catalog is present",...DISC_T1,verdict:"NA",evidence:{file:"arbiter.json",detail:"no optional invariant tiers (data/security/operational) \u2014 catalog not prescribed at this preset"}}:{id:"D-INVARIANTS-ENFORCED",title:"Invariants catalog is present",...DISC_T1,verdict:"NV",evidence:{file:INVARIANTS_CATALOG_PATH,detail:"no invariants catalog found"}}}function invariantTierStatus(root){const OPTIONAL_INV_TIERS=new Set(["data","security","operational"]),cfgPath=safeResolve(root,"arbiter.json");if(cfgPath===null)return"absent";const cfg=readJson(cfgPath);if(cfg===null||typeof cfg!="object")return"absent";const tiers=cfg.invariantTiers;return Array.isArray(tiers)?tiers.some(t=>OPTIONAL_INV_TIERS.has(String(t)))?"some":"none":"absent"}export function probeNoOverclaim(root){const evidencePath=safeResolve(root,LAST_DONE_EVIDENCE_PATH);if(evidencePath===null||!fileExists(evidencePath))return{id:"D-NO-OVERCLAIM",title:"Done-evidence explicitly asserts no overclaim",...DISC_T1,verdict:"NV",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"absent \u2014 no done-evidence recorded"}};const manifest=readJson(evidencePath);return manifest!==null&&typeof manifest=="object"&&manifest.no_overclaim===!0?{id:"D-NO-OVERCLAIM",title:"Done-evidence explicitly asserts no overclaim",...DISC_T1,verdict:"Y",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"no_overclaim=true"}}:{id:"D-NO-OVERCLAIM",title:"Done-evidence explicitly asserts no overclaim",...DISC_T1,verdict:"N",evidence:{file:LAST_DONE_EVIDENCE_PATH,detail:"no_overclaim is not true"}}}const HOOKS_DIRS=[".githooks",".husky"],COMMITLINT_CONFIGS=["commitlint.config.js",".commitlintrc.json",".commitlintrc.js"];function nonEmptyDir(abs){try{return readdirSync(abs).length>0}catch{return!1}}function nonEmptyFile(abs){const txt=readText(abs);return txt!==null&&txt.trim().length>0}export function probeCommitHygiene(root){const hooksDir=HOOKS_DIRS.find(d=>{const p=safeResolve(root,d);return p!==null&&fileExists(p)&&nonEmptyDir(p)}),commitlintConfig=COMMITLINT_CONFIGS.find(c=>{const p=safeResolve(root,c);return p!==null&&nonEmptyFile(p)});if(hooksDir&&commitlintConfig)return{id:"D-COMMIT-HYGIENE",title:"Commit message hygiene enforced",...DISC_T1,verdict:"Y",evidence:{file:commitlintConfig,detail:`${hooksDir}/ and ${commitlintConfig} present`}};const missing=[];return hooksDir||missing.push(".husky/ (or .githooks/)"),commitlintConfig||missing.push(".commitlintrc.json (or commitlint.config.js / .commitlintrc.js)"),{id:"D-COMMIT-HYGIENE",title:"Commit message hygiene enforced",...DISC_T1,verdict:"N",evidence:{file:".commitlintrc.json",detail:`missing: ${missing.join(", ")}`}}}const FINDING_HYGIENE_ID="DISC-finding-hygiene",FINDING_HYGIENE_TITLE="Incidental findings drained, not just filed",FINDINGS_DIR=".arbiter/findings",FINDING_HYGIENE_BASELINE=".arbiter/finding-hygiene-baseline.json",FINDING_STALE_DAYS=14,MS_PER_DAY=1440*60*1e3;function accumulateShard(text,acc){for(const line of text.split(`
3
+ `)){const trimmed=line.trim();if(trimmed.length===0)continue;let entry;try{entry=JSON.parse(trimmed)}catch{continue}if(typeof entry!="object"||entry===null)continue;const e=entry,fp=typeof e.fingerprint=="string"?e.fingerprint:trimmed;acc.fingerprints.add(fp);const ts=typeof e.ts=="string"?Date.parse(e.ts):NaN;!Number.isNaN(ts)&&(acc.oldestTs===null||ts<acc.oldestTs)&&(acc.oldestTs=ts)}}function readFindingsSpool(root){const dirAbs=safeResolve(root,FINDINGS_DIR);if(dirAbs===null||!fileExists(dirAbs))return null;let shards;try{shards=readdirSync(dirAbs).filter(f=>f.endsWith(".jsonl"))}catch{return{openCount:0,oldestAgeDays:0}}const acc={fingerprints:new Set,oldestTs:null};for(const shard of shards){const text=readText(join(dirAbs,shard));text!==null&&accumulateShard(text,acc)}const oldestAgeDays=acc.oldestTs===null?0:Math.max(0,Math.floor((Date.now()-acc.oldestTs)/MS_PER_DAY));return{openCount:acc.fingerprints.size,oldestAgeDays}}function readFindingHygienePrior(root){const abs=safeResolve(root,FINDING_HYGIENE_BASELINE);if(abs===null||!fileExists(abs))return null;const parsed=readJson(abs);if(parsed===null||typeof parsed!="object")return null;const v=parsed.openFindingsCount;return typeof v=="number"?v:null}export function probeFindingHygiene(root){const base={id:FINDING_HYGIENE_ID,title:FINDING_HYGIENE_TITLE,...DISC_T1},stats=readFindingsSpool(root);if(stats===null)return{...base,verdict:"NA",evidence:{file:FINDINGS_DIR,detail:"no findings spool \u2014 not governed for incidental-finding hygiene"}};const prior=readFindingHygienePrior(root);return prior!==null&&stats.openCount>prior?{...base,verdict:"N",evidence:{file:FINDINGS_DIR,detail:`openFindingsCount rose ${prior} \u2192 ${stats.openCount} \u2014 findings filed without draining`}}:stats.openCount>0&&stats.oldestAgeDays>FINDING_STALE_DAYS?{...base,verdict:"P",evidence:{file:FINDINGS_DIR,detail:`oldest open finding is ${stats.oldestAgeDays}d (> ${FINDING_STALE_DAYS}d) \u2014 promote or drain`}}:{...base,verdict:"Y",evidence:{file:FINDINGS_DIR,detail:stats.openCount===0?"spool drained \u2014 no open findings":`${stats.openCount} open finding(s), fresh and non-regressing`}}}const E2E_QUARANTINE_ID="DISC-e2e-quarantine",E2E_QUARANTINE_TITLE="E2E quarantine registry has no expired entries",E2E_QUARANTINE_PATH=".arbiter/e2e/quarantine.json",QUARANTINE_REQUIRED_FIELDS=["id","fingerprint","reason","owner","added","expires","issue"];function quarantineEntries(registry){return Array.isArray(registry)?registry:registry!==null&&typeof registry=="object"&&Array.isArray(registry.entries)?registry.entries:null}function findExpiredOrInvalid(entries,now){for(const[idx,e]of entries.entries()){if(e===null||typeof e!="object")return`entry[${idx}]: not an object`;const rec=e,rawId=rec.id,rawFp=rec.fingerprint,label=typeof rawId=="string"&&rawId?rawId:typeof rawFp=="string"&&rawFp?rawFp:`entry[${idx}]`;for(const f of QUARANTINE_REQUIRED_FIELDS)if(rec[f]===void 0||rec[f]===null||rec[f]==="")return`${label}: missing required field '${f}'`;const expMs=new Date(rec.expires).getTime();if(Number.isNaN(expMs))return`${label}: 'expires' is not a valid date`;if(expMs<now)return`${label}: quarantine expired on ${String(rec.expires)}`}return null}const E2E_CONSTITUTION_REF="See docs/GOVERNANCE/E2E_CONSTITUTION.md for the full E2E determinism rule set (#1817, A4).";export function probeE2eQuarantine(root){const base={id:E2E_QUARANTINE_ID,title:E2E_QUARANTINE_TITLE,...DISC_T1},abs=safeResolve(root,E2E_QUARANTINE_PATH);if(abs===null||!fileExists(abs))return{...base,verdict:"NA",evidence:{file:E2E_QUARANTINE_PATH,detail:`no quarantine registry \u2014 vacuous pass (INV-130). ${E2E_CONSTITUTION_REF}`}};const parsed=readJson(abs);if(parsed===null)return{...base,verdict:"N",evidence:{file:E2E_QUARANTINE_PATH,detail:"registry present but not valid JSON"}};const entries=quarantineEntries(parsed);if(entries===null)return{...base,verdict:"N",evidence:{file:E2E_QUARANTINE_PATH,detail:"registry must be an array or { entries: [...] }"}};const problem=findExpiredOrInvalid(entries,Date.now());return problem!==null?{...base,verdict:"N",evidence:{file:E2E_QUARANTINE_PATH,detail:problem}}:{...base,verdict:"Y",evidence:{file:E2E_QUARANTINE_PATH,detail:`${entries.length} quarantine entry(ies), all complete and unexpired. ${E2E_CONSTITUTION_REF}`}}}