@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.
- package/CHANGELOG.md +713 -0
- package/LICENSE +202 -0
- package/NOTICE +31 -0
- package/PRIVACY.md +111 -0
- package/README.md +237 -0
- package/THIRD_PARTY_LICENSES.md +472 -0
- package/dist/.src-manifest.json +1 -0
- package/dist/capabilities/host-probe.js +3 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +87 -0
- package/dist/commands/adopt-policy.js +3 -0
- package/dist/commands/configure-interactive.js +3 -0
- package/dist/commands/configure.js +5 -0
- package/dist/commands/cross-model-review.js +3 -0
- package/dist/commands/diff.js +20 -0
- package/dist/commands/doc-set.js +3 -0
- package/dist/commands/doctor/clean.js +2 -0
- package/dist/commands/doctor/fail-open-census.js +12 -0
- package/dist/commands/doctor/health.js +11 -0
- package/dist/commands/doctor/prove-gates.js +13 -0
- package/dist/commands/doctor/recover-lock.js +12 -0
- package/dist/commands/doctor/repair-state.js +6 -0
- package/dist/commands/doctor/tool-pin-extract.js +4 -0
- package/dist/commands/doctor/tool-pins.js +9 -0
- package/dist/commands/doctor-interactive.js +2 -0
- package/dist/commands/doctor.js +2 -0
- package/dist/commands/explain.js +19 -0
- package/dist/commands/gate-exec.js +4 -0
- package/dist/commands/gold-audit.js +14 -0
- package/dist/commands/graph.js +5 -0
- package/dist/commands/init/build-arbiter-config.js +1 -0
- package/dist/commands/init/generate.js +42 -0
- package/dist/commands/init/github-setup.js +5 -0
- package/dist/commands/init/maturity-gates.js +10 -0
- package/dist/commands/init/resolve-config.js +3 -0
- package/dist/commands/init/toolchain.js +10 -0
- package/dist/commands/init/types.js +1 -0
- package/dist/commands/init.js +17 -0
- package/dist/commands/method-interactive.js +4 -0
- package/dist/commands/method.js +11 -0
- package/dist/commands/obsidian.js +2 -0
- package/dist/commands/plugin.js +8 -0
- package/dist/commands/pr-merged.js +2 -0
- package/dist/commands/retire-policy.js +3 -0
- package/dist/commands/review-diff.js +3 -0
- package/dist/commands/settings.js +7 -0
- package/dist/commands/ship-config.js +2 -0
- package/dist/commands/ship-profile.js +2 -0
- package/dist/commands/ship-review.js +1 -0
- package/dist/commands/ship-tier.js +2 -0
- package/dist/commands/ship-train.js +2 -0
- package/dist/commands/task-mark.js +2 -0
- package/dist/commands/task-note.js +3 -0
- package/dist/commands/task-record-red.js +2 -0
- package/dist/commands/task-record-tech-debt.js +4 -0
- package/dist/commands/task-ship.js +3 -0
- package/dist/commands/task-state.js +6 -0
- package/dist/commands/task.js +59 -0
- package/dist/commands/update.js +60 -0
- package/dist/commands/upgrade-level-interactive.js +2 -0
- package/dist/commands/upgrade-level.js +7 -0
- package/dist/commands/verify-plan.js +8 -0
- package/dist/commands/verify-tdd.js +2 -0
- package/dist/commands/verify.js +7 -0
- package/dist/commands/wizard/coherence.js +1 -0
- package/dist/commands/worktree-prune.js +4 -0
- package/dist/commands/worktree.js +39 -0
- package/dist/compatibility/cross-language-matrix.json +540 -0
- package/dist/compatibility/index.d.ts +4 -0
- package/dist/compatibility/index.js +2 -0
- package/dist/compatibility/matcher.js +1 -0
- package/dist/compatibility/matrix.json +27 -0
- package/dist/compatibility/parsers.d.ts +38 -0
- package/dist/compatibility/parsers.js +1 -0
- package/dist/compatibility/probe.d.ts +41 -0
- package/dist/compatibility/probe.js +4 -0
- package/dist/compatibility/report.js +2 -0
- package/dist/compatibility/schema.d.ts +80 -0
- package/dist/compatibility/schema.js +1 -0
- package/dist/compatibility/skills-matrix.json +98 -0
- package/dist/compatibility/skills-validator.d.ts +30 -0
- package/dist/compatibility/skills-validator.js +4 -0
- package/dist/compatibility/tooling-proposals.json +5 -0
- package/dist/config/arbiter-ignore.js +3 -0
- package/dist/config/collaboration-mode-defaults.js +1 -0
- package/dist/config/diff.js +1 -0
- package/dist/config/env-overrides.js +3 -0
- package/dist/config/env-registry.js +2 -0
- package/dist/config/levels.js +1 -0
- package/dist/config/migrations/index.js +2 -0
- package/dist/config/migrations/v0-to-v1.js +2 -0
- package/dist/config/migrations/v1-to-v2.js +2 -0
- package/dist/config/migrations/v2-to-v3.js +2 -0
- package/dist/config/migrations/v3-to-v4.js +2 -0
- package/dist/config/override-resolver.js +2 -0
- package/dist/config/resolve-project-config.js +2 -0
- package/dist/config/resolve-project-name.js +2 -0
- package/dist/config/schema.d.ts +480 -0
- package/dist/config/schema.js +1 -0
- package/dist/config/test-pyramid-profiles.js +1 -0
- package/dist/config/thresholds.js +2 -0
- package/dist/conformance/dimensions.js +3 -0
- package/dist/conformance/engine.js +7 -0
- package/dist/conformance/gate-proofs.js +4 -0
- package/dist/conformance/shared.js +2 -0
- package/dist/detectors/axis.js +1 -0
- package/dist/detectors/build.js +2 -0
- package/dist/detectors/existing.js +2 -0
- package/dist/detectors/external-model.js +2 -0
- package/dist/detectors/framework.js +2 -0
- package/dist/detectors/git.js +11 -0
- package/dist/detectors/github.js +2 -0
- package/dist/detectors/lanes.js +5 -0
- package/dist/detectors/language-hooks.js +117 -0
- package/dist/detectors/language.js +2 -0
- package/dist/detectors/package-manager.js +2 -0
- package/dist/detectors/package.js +2 -0
- package/dist/detectors/scaffold-wiring.js +2 -0
- package/dist/detectors/workflow-collision.js +4 -0
- package/dist/evidence/gate-binding.js +4 -0
- package/dist/evidence/git-checks.js +3 -0
- package/dist/evidence/load.js +2 -0
- package/dist/evidence/provenance.js +2 -0
- package/dist/evidence/summary.js +2 -0
- package/dist/evidence/tdd-reexecute.js +2 -0
- package/dist/evidence/tdd.js +4 -0
- package/dist/experimental/index.js +2 -0
- package/dist/experimental/parse-argv.js +2 -0
- package/dist/experimental/registry.js +2 -0
- package/dist/generators/agents-claude.js +2 -0
- package/dist/generators/agents-md.js +2 -0
- package/dist/generators/anti-drift-validators.js +3 -0
- package/dist/generators/anti-proforma.js +2 -0
- package/dist/generators/api-e2e.js +2 -0
- package/dist/generators/api-middleware.js +2 -0
- package/dist/generators/archunit.js +2 -0
- package/dist/generators/audit-toolchain.js +2 -0
- package/dist/generators/auth.js +2 -0
- package/dist/generators/behavioral-tests.js +2 -0
- package/dist/generators/boundaries.js +2 -0
- package/dist/generators/check-all.js +2 -0
- package/dist/generators/check-stack-conformity.js +2 -0
- package/dist/generators/ci-five-lane.js +2 -0
- package/dist/generators/ci-tier.js +2 -0
- package/dist/generators/claude.js +3 -0
- package/dist/generators/codex-hooks.js +2 -0
- package/dist/generators/codex-known-limitations.js +2 -0
- package/dist/generators/codex.js +15 -0
- package/dist/generators/commit-footer.js +2 -0
- package/dist/generators/compliance-menu.js +2 -0
- package/dist/generators/compliance.js +2 -0
- package/dist/generators/conformance.js +2 -0
- package/dist/generators/contract-testing.js +2 -0
- package/dist/generators/coverage.js +2 -0
- package/dist/generators/debt-gates.js +24 -0
- package/dist/generators/debt-ratchet.js +2 -0
- package/dist/generators/derived-class.js +2 -0
- package/dist/generators/doc-set.js +4 -0
- package/dist/generators/docs.js +2 -0
- package/dist/generators/duplication.js +2 -0
- package/dist/generators/e2e-constitution.js +2 -0
- package/dist/generators/env-template.js +2 -0
- package/dist/generators/evidence-retention.js +2 -0
- package/dist/generators/feature-matrix.js +2 -0
- package/dist/generators/frontend-governance.js +2 -0
- package/dist/generators/frontend-quality.js +2 -0
- package/dist/generators/gap.js +2 -0
- package/dist/generators/gdpr.js +2 -0
- package/dist/generators/githooks.js +2 -0
- package/dist/generators/github-setup.js +2 -0
- package/dist/generators/github.js +2 -0
- package/dist/generators/gitignore.js +2 -0
- package/dist/generators/global-invariants.js +3 -0
- package/dist/generators/go-boundaries.js +2 -0
- package/dist/generators/gold-kit.js +2 -0
- package/dist/generators/infra.js +2 -0
- package/dist/generators/integration-testing.js +7 -0
- package/dist/generators/iso27001.js +2 -0
- package/dist/generators/iso9001.js +2 -0
- package/dist/generators/labels.js +2 -0
- package/dist/generators/local-wrapper.js +2 -0
- package/dist/generators/modulith.js +2 -0
- package/dist/generators/mutation.js +2 -0
- package/dist/generators/observability.js +2 -0
- package/dist/generators/operations.js +2 -0
- package/dist/generators/perf-k6.js +2 -0
- package/dist/generators/pharma.js +2 -0
- package/dist/generators/playwright-python.js +2 -0
- package/dist/generators/playwright-ts.js +2 -0
- package/dist/generators/pr-tooling.js +2 -0
- package/dist/generators/python-boundaries.js +2 -0
- package/dist/generators/quality.js +2 -0
- package/dist/generators/registry.js +2 -0
- package/dist/generators/regulated.js +2 -0
- package/dist/generators/resilience.js +2 -0
- package/dist/generators/risk-register.js +2 -0
- package/dist/generators/root.js +2 -0
- package/dist/generators/rust-boundaries.js +2 -0
- package/dist/generators/safety-class.js +2 -0
- package/dist/generators/security.js +2 -0
- package/dist/generators/seed.js +2 -0
- package/dist/generators/self-validation.js +2 -0
- package/dist/generators/ship-driver.js +2 -0
- package/dist/generators/skill-names.json +17 -0
- package/dist/generators/skills.js +2 -0
- package/dist/generators/smoke-journeys.js +2 -0
- package/dist/generators/solo-exception.js +2 -0
- package/dist/generators/ssot.js +2 -0
- package/dist/generators/stride-enforcement.js +2 -0
- package/dist/generators/suppressions.js +2 -0
- package/dist/generators/test-pyramid-manifest.js +3 -0
- package/dist/generators/test-taxonomy.js +2 -0
- package/dist/generators/wiki.js +2 -0
- package/dist/github/branch-protection.js +2 -0
- package/dist/github/classify-gh-error.js +2 -0
- package/dist/github/labels.js +2 -0
- package/dist/github/project-board.js +2 -0
- package/dist/graph/builders/adr.js +4 -0
- package/dist/graph/builders/ast.js +3 -0
- package/dist/graph/builders/canon.js +2 -0
- package/dist/graph/builders/evidence.js +2 -0
- package/dist/graph/builders/inv.js +1 -0
- package/dist/graph/builders/req.js +3 -0
- package/dist/graph/builders/test-nodes.js +3 -0
- package/dist/graph/builders/utils.js +2 -0
- package/dist/graph/load.js +2 -0
- package/dist/graph/model.js +2 -0
- package/dist/graph/query.js +3 -0
- package/dist/graph/store.js +1 -0
- package/dist/i18n/en.json +293 -0
- package/dist/i18n/index.js +4 -0
- package/dist/i18n/types.js +2 -0
- package/dist/integrations/companions.js +2 -0
- package/dist/integrations/external-review.js +10 -0
- package/dist/integrations/plugin-schema.js +2 -0
- package/dist/integrations/skill-detector.js +7 -0
- package/dist/integrations/skills-matrix.js +2 -0
- package/dist/integrations/types.d.ts +23 -0
- package/dist/integrations/types.js +2 -0
- package/dist/internal/cli-deprecation-registry.js +2 -0
- package/dist/internal/deprecate.js +3 -0
- package/dist/internal/experimental-warn.js +3 -0
- package/dist/invariants/catalog.d.ts +2 -0
- package/dist/invariants/catalog.js +1 -0
- package/dist/invariants/filter.d.ts +28 -0
- package/dist/invariants/filter.js +1 -0
- package/dist/invariants/index.d.ts +4 -0
- package/dist/invariants/index.js +2 -0
- package/dist/invariants/tiers.js +1 -0
- package/dist/invariants/types.d.ts +1 -0
- package/dist/invariants/types.js +1 -0
- package/dist/kit/applicability.js +3 -0
- package/dist/kit/audit-report.js +3 -0
- package/dist/kit/brownfield-detect.js +4 -0
- package/dist/kit/canonical-mapping.json +1 -0
- package/dist/kit/catalog.js +2 -0
- package/dist/kit/catalog.json +1 -0
- package/dist/kit/derived.json +1 -0
- package/dist/kit/emit-issues.js +8 -0
- package/dist/kit/measure.js +5 -0
- package/dist/kit/redaction.js +3 -0
- package/dist/kit/schema.js +2 -0
- package/dist/kit/taxonomy.js +2 -0
- package/dist/kit/thresholds.d.ts +12 -0
- package/dist/kit/thresholds.js +2 -0
- package/dist/kit/wave-engine.js +1 -0
- package/dist/recipes/loader.js +6 -0
- package/dist/recipes/schema.js +2 -0
- package/dist/risk/classifier.js +2 -0
- package/dist/risk/sha-check.js +2 -0
- package/dist/state/backups.js +2 -0
- package/dist/state/envelope.js +2 -0
- package/dist/state/generated-manifest.js +3 -0
- package/dist/state/manifest-key.js +2 -0
- package/dist/state/migrations/index.js +1 -0
- package/dist/state/migrations/v0-to-v1.js +2 -0
- package/dist/state/retired-renders.js +2 -0
- package/dist/templates/.nvmrc.ejs +1 -0
- package/dist/templates/HANDOFF.template.md +45 -0
- package/dist/templates/__tests__/contract/error-shape.contract.test.ts.ejs +47 -0
- package/dist/templates/agents-md/AGENTS.md.ejs +517 -0
- package/dist/templates/api-e2e/README.md.ejs +33 -0
- package/dist/templates/api-e2e/go-httptest.go.ejs +43 -0
- package/dist/templates/api-e2e/java-restassured.java.ejs +28 -0
- package/dist/templates/api-e2e/kotlin-restassured.kt.ejs +30 -0
- package/dist/templates/api-e2e/manifest.json.ejs +8 -0
- package/dist/templates/api-e2e/postman.collection.json.ejs +30 -0
- package/dist/templates/api-e2e/python-httpx.py.ejs +17 -0
- package/dist/templates/api-e2e/run.sh.ejs +61 -0
- package/dist/templates/api-e2e/ts-supertest.test.ts.ejs +18 -0
- package/dist/templates/archunit/AntiCyclicTest.java.ejs +29 -0
- package/dist/templates/archunit/AntiProformaExempt.java.ejs +35 -0
- package/dist/templates/archunit/AntiProformaTest.java.ejs +104 -0
- package/dist/templates/archunit/ArchitectureTest.java.ejs +87 -0
- package/dist/templates/archunit/DependencyFlowTest.java.ejs +55 -0
- package/dist/templates/archunit/DomainPurityTest.java.ejs +47 -0
- package/dist/templates/archunit/NamingConventionsTest.java.ejs +54 -0
- package/dist/templates/archunit/NoH2ArchTest.java.ejs +30 -0
- package/dist/templates/archunit/NoMockMvcTest.java.ejs +71 -0
- package/dist/templates/archunit/PortsIndependenceTest.java.ejs +55 -0
- package/dist/templates/archunit/RestAssuredArchTest.java.ejs +32 -0
- package/dist/templates/archunit/RestAssuredBaseIT.java.ejs +66 -0
- package/dist/templates/archunit/TestCoverageArchTest.java.ejs +29 -0
- package/dist/templates/archunit/arch-test-deps-maven.md.ejs +42 -0
- package/dist/templates/archunit/arch-test-deps.gradle.ejs +14 -0
- package/dist/templates/audit/gdpr/check-gdpr-controls.mjs.ejs +102 -0
- package/dist/templates/audit/gdpr/controls-to-gates.md.ejs +42 -0
- package/dist/templates/audit/gdpr/data-flow-map.md.ejs +30 -0
- package/dist/templates/audit/gdpr/dpia.md.ejs +45 -0
- package/dist/templates/audit/generic/audit-gate-rules.md.ejs +24 -0
- package/dist/templates/audit/generic/audit-trail-policy.md.ejs +38 -0
- package/dist/templates/audit/iso27001/iso27001-controls-gate-map.md.ejs +60 -0
- package/dist/templates/auth/setup.md.ejs +661 -0
- package/dist/templates/behavioral-tests/ExampleBehavioralTest.java.ejs +67 -0
- package/dist/templates/behavioral-tests/TESTING_POLICY.md.ejs +116 -0
- package/dist/templates/behavioral-tests/bdd/ExampleBddIT.java.ejs +19 -0
- package/dist/templates/behavioral-tests/bdd/ExampleSteps.java.ejs +61 -0
- package/dist/templates/behavioral-tests/bdd/example.feature.ejs +14 -0
- package/dist/templates/behavioral-tests/bdd/example.steps.ts.ejs +37 -0
- package/dist/templates/behavioral-tests/bdd/example_bdd_test.rs.ejs +64 -0
- package/dist/templates/behavioral-tests/bdd/example_test.go.ejs +80 -0
- package/dist/templates/behavioral-tests/bdd/test_example_bdd.py.ejs +47 -0
- package/dist/templates/behavioral-tests/eslint-playwright.json.ejs +10 -0
- package/dist/templates/behavioral-tests/eslint.config.playwright.mjs.ejs +29 -0
- package/dist/templates/behavioral-tests/example.behavioral.test.ts.ejs +47 -0
- package/dist/templates/behavioral-tests/example_behavioral_test.go.ejs +51 -0
- package/dist/templates/behavioral-tests/example_behavioral_test.rs.ejs +47 -0
- package/dist/templates/behavioral-tests/test_example_behavioral.py.ejs +40 -0
- package/dist/templates/boundaries/.eslintrc-boundaries.cjs.ejs +81 -0
- package/dist/templates/boundaries/.eslintrc-frontend-spa.cjs.ejs +79 -0
- package/dist/templates/boundaries/.importlinter.ejs +48 -0
- package/dist/templates/boundaries/check-boundaries-go.mjs.ejs +94 -0
- package/dist/templates/boundaries/check-boundaries-python.mjs.ejs +118 -0
- package/dist/templates/boundaries/check-boundaries-rust.mjs.ejs +111 -0
- package/dist/templates/boundaries/check-boundaries.mjs.ejs +34 -0
- package/dist/templates/boundaries/clippy.toml.ejs +50 -0
- package/dist/templates/boundaries/deny.toml.ejs +56 -0
- package/dist/templates/boundaries/eslint.config.boundaries.mjs.ejs +112 -0
- package/dist/templates/boundaries/eslint.config.frontend-spa.mjs.ejs +93 -0
- package/dist/templates/boundaries/golangci-boundaries.yml.ejs +70 -0
- package/dist/templates/boundaries/ruff-boundaries.toml.ejs +32 -0
- package/dist/templates/claude/CLAUDE.md.ejs +78 -0
- package/dist/templates/claude/agents/agent-write-classes.json +30 -0
- package/dist/templates/claude/agents/bridge-reviewer.md.ejs +68 -0
- package/dist/templates/claude/agents/codebase-scanner.md.ejs +69 -0
- package/dist/templates/claude/agents/context-checker.md.ejs +73 -0
- package/dist/templates/claude/agents/red-team.md.ejs +134 -0
- package/dist/templates/claude/commands/close-gold-gap.md.ejs +43 -0
- package/dist/templates/claude/commands/drain.md.ejs +81 -0
- package/dist/templates/claude/commands/gold-audit.md.ejs +43 -0
- package/dist/templates/claude/commands/impact.md.ejs +39 -0
- package/dist/templates/claude/commands/levelup.md.ejs +61 -0
- package/dist/templates/claude/commands/ship.md.ejs +902 -0
- package/dist/templates/claude/commands/tabletop.md.ejs +46 -0
- package/dist/templates/claude/commands/task.md.ejs +87 -0
- package/dist/templates/claude/commands/wt-close.md.ejs +58 -0
- package/dist/templates/claude/commands/wt-list.md.ejs +48 -0
- package/dist/templates/claude/commands/wt-open.md.ejs +61 -0
- package/dist/templates/claude/commands/wt-prune.md.ejs +38 -0
- package/dist/templates/claude/hooks/check-circular-deps.mjs.ejs +56 -0
- package/dist/templates/claude/hooks/check-no-orphan-todo.mjs.ejs +45 -0
- package/dist/templates/claude/hooks/check-no-pii.mjs.ejs +121 -0
- package/dist/templates/claude/hooks/check-no-placeholders.mjs.ejs +71 -0
- package/dist/templates/claude/hooks/check-no-skipped-tests.mjs +80 -0
- package/dist/templates/claude/hooks/check-no-unused-exports.mjs +62 -0
- package/dist/templates/claude/hooks/closer-mode-guard.mjs.ejs +102 -0
- package/dist/templates/claude/hooks/debug-state-on-failure.mjs.ejs +98 -0
- package/dist/templates/claude/hooks/enforce-gate-before-pr.mjs +142 -0
- package/dist/templates/claude/hooks/enforce-read-only.mjs +28 -0
- package/dist/templates/claude/hooks/exitplanmode-banner.mjs.ejs +43 -0
- package/dist/templates/claude/hooks/guard-done-evidence.mjs.ejs +85 -0
- package/dist/templates/claude/hooks/guard-task-completion.mjs.ejs +56 -0
- package/dist/templates/claude/hooks/hooks.mjs.ejs +127 -0
- package/dist/templates/claude/hooks/lib.mjs.ejs +523 -0
- package/dist/templates/claude/hooks/post-brainstorm-stop.mjs +48 -0
- package/dist/templates/claude/hooks/post-commit-check.mjs.ejs +65 -0
- package/dist/templates/claude/hooks/post-commit-checklists/go/backend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/go/docs.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/go/frontend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/java/backend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/java/docs.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/java/frontend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/python/backend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/python/docs.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/python/frontend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/rust/backend.ejs +5 -0
- package/dist/templates/claude/hooks/post-commit-checklists/rust/docs.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/rust/frontend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/ts/backend.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/ts/docs.ejs +4 -0
- package/dist/templates/claude/hooks/post-commit-checklists/ts/frontend.ejs +5 -0
- package/dist/templates/claude/hooks/post-edit-dispatch.mjs.ejs +73 -0
- package/dist/templates/claude/hooks/post-subagent-release.mjs +80 -0
- package/dist/templates/claude/hooks/pre-compact.mjs.ejs +79 -0
- package/dist/templates/claude/hooks/pre-edit-plan-anchor.mjs.ejs +225 -0
- package/dist/templates/claude/hooks/pre-edit-ssot-guard.mjs +204 -0
- package/dist/templates/claude/hooks/pre-spawn-worktree-guard.mjs +129 -0
- package/dist/templates/claude/hooks/skill-forced-eval.mjs.ejs +281 -0
- package/dist/templates/claude/hooks/stop-dangerous.mjs +86 -0
- package/dist/templates/claude/hooks/stop-evidence-guard.mjs.ejs +245 -0
- package/dist/templates/claude/hooks/stop-finding-loss.mjs.ejs +168 -0
- package/dist/templates/claude/hooks/wiki-on-commit.mjs.ejs +38 -0
- package/dist/templates/claude/knowledge-map.json.ejs +26 -0
- package/dist/templates/claude/rules/05-agent-lifecycle.md +7 -0
- package/dist/templates/claude/rules/25-todo-folder-policy.md +5 -0
- package/dist/templates/claude/rules/40-context-economy.md +32 -0
- package/dist/templates/claude/rules/45-mcp-fallback.md +25 -0
- package/dist/templates/claude/rules/50-batch-execution.md +75 -0
- package/dist/templates/claude/rules/55-brainstorm-terminal-state.md +44 -0
- package/dist/templates/claude/rules/60-incidental-capture.md +43 -0
- package/dist/templates/claude/rules/75-impact-vault-reading.md +43 -0
- package/dist/templates/claude/rules/90-exec-protocol.md.ejs +40 -0
- package/dist/templates/claude/rules/95-closer-mode.md +45 -0
- package/dist/templates/claude/settings.json.ejs +165 -0
- package/dist/templates/claude/skills/architect-review/SKILL.md.ejs +82 -0
- package/dist/templates/claude/skills/brainstorming/SKILL.md.ejs +86 -0
- package/dist/templates/claude/skills/clean-code/SKILL.md.ejs +39 -0
- package/dist/templates/claude/skills/close-gold-gap/SKILL.md.ejs +58 -0
- package/dist/templates/claude/skills/codebase-audit/SKILL.md.ejs +88 -0
- package/dist/templates/claude/skills/configure/SKILL.md.ejs +72 -0
- package/dist/templates/claude/skills/epic-decompose/SKILL.md.ejs +86 -0
- package/dist/templates/claude/skills/gold-audit/SKILL.md.ejs +91 -0
- package/dist/templates/claude/skills/impact/SKILL.md.ejs +104 -0
- package/dist/templates/claude/skills/levelup/SKILL.md.ejs +146 -0
- package/dist/templates/claude/skills/tabletop/SKILL.md.ejs +118 -0
- package/dist/templates/claude/skills/tdd/SKILL.md.ejs +157 -0
- package/dist/templates/claude/skills/understand-code/SKILL.md.ejs +93 -0
- package/dist/templates/claude/skills/verification/SKILL.md.ejs +68 -0
- package/dist/templates/claude/skills/wave-drain/SKILL.md.ejs +491 -0
- package/dist/templates/codex/CODEX.md.ejs +140 -0
- package/dist/templates/codex/codex-adapter.mjs +132 -0
- package/dist/templates/codex/config.toml.ejs +189 -0
- package/dist/templates/compliance/compliance-mapping.md.ejs +124 -0
- package/dist/templates/compliance/compliance-menu.md.ejs +89 -0
- package/dist/templates/contract-testing/CONTRACTS_POLICY.md.ejs +30 -0
- package/dist/templates/contract-testing/api-snapshots/config-keys-baseline.json.ejs +1 -0
- package/dist/templates/contract-testing/api-snapshots/config-response-baseline.json.ejs +1 -0
- package/dist/templates/contract-testing/api-snapshots/enum-values-baseline.json.ejs +1 -0
- package/dist/templates/contract-testing/api-snapshots/error-shape-baseline.json.ejs +6 -0
- package/dist/templates/contract-testing/api-snapshots/openapi-baseline.json.ejs +12 -0
- package/dist/templates/contract-testing/api-snapshots/openapi-content-types-baseline.json.ejs +3 -0
- package/dist/templates/contract-testing/api-snapshots/openapi-paths-baseline.json.ejs +1 -0
- package/dist/templates/contract-testing/api-snapshots/openapi-required-fields-baseline.json.ejs +1 -0
- package/dist/templates/contract-testing/api-snapshots/openapi-response-status-baseline.json.ejs +3 -0
- package/dist/templates/contract-testing/api-snapshots/test-snapshot.json.ejs +4 -0
- package/dist/templates/contract-testing/env/.env.pact.ejs +4 -0
- package/dist/templates/contract-testing/graphql/GraphqlSchemaTest.java.ejs +29 -0
- package/dist/templates/contract-testing/graphql/graphql-inspector.test.ts.ejs +20 -0
- package/dist/templates/contract-testing/graphql/graphql_schema_test.go.ejs +27 -0
- package/dist/templates/contract-testing/graphql/graphql_schema_test.rs.ejs +27 -0
- package/dist/templates/contract-testing/graphql/test_graphql_schema.py.ejs +21 -0
- package/dist/templates/contract-testing/grpc/GrpcContractTest.java.ejs +23 -0
- package/dist/templates/contract-testing/grpc/buf-breaking.yml.ejs +6 -0
- package/dist/templates/contract-testing/grpc/buf.yaml.ejs +11 -0
- package/dist/templates/contract-testing/grpc/grpc-contract.test.ts.ejs +16 -0
- package/dist/templates/contract-testing/grpc/grpc_contract_test.go.ejs +22 -0
- package/dist/templates/contract-testing/grpc/grpc_contract_test.rs.ejs +22 -0
- package/dist/templates/contract-testing/grpc/test_grpc_contract.py.ejs +18 -0
- package/dist/templates/contract-testing/message-queue/SchemaRegistryCheckIT.java.ejs +44 -0
- package/dist/templates/contract-testing/message-queue/schema-registry-check.ts.ejs +42 -0
- package/dist/templates/contract-testing/message-queue/schema_registry_test.go.ejs +71 -0
- package/dist/templates/contract-testing/message-queue/schema_registry_test.rs.ejs +61 -0
- package/dist/templates/contract-testing/message-queue/test_schema_registry.py.ejs +31 -0
- package/dist/templates/contract-testing/pact-samples/assignment-response.json.ejs +7 -0
- package/dist/templates/contract-testing/pact-samples/availability-response.json.ejs +13 -0
- package/dist/templates/contract-testing/pact-samples/availability-rule-response.json.ejs +8 -0
- package/dist/templates/contract-testing/pact-samples/capacity-response.json.ejs +11 -0
- package/dist/templates/contract-testing/pact-samples/fully-booked-response.json.ejs +6 -0
- package/dist/templates/contract-testing/pact-samples/schedule-override-response.json.ejs +7 -0
- package/dist/templates/contract-testing/rest-owned/PactVerificationIT.java.ejs +31 -0
- package/dist/templates/contract-testing/rest-owned/pact-consumer.test.ts.ejs +36 -0
- package/dist/templates/contract-testing/rest-owned/pact-deps.gradle.ejs +15 -0
- package/dist/templates/contract-testing/rest-owned/pact_consumer_test.go.ejs +48 -0
- package/dist/templates/contract-testing/rest-owned/pact_consumer_test.rs.ejs +23 -0
- package/dist/templates/contract-testing/rest-owned/test_pact_consumer.py.ejs +35 -0
- package/dist/templates/contract-testing/rest-public/OpenApiDiffIT.java.ejs +44 -0
- package/dist/templates/contract-testing/rest-public/export-openapi-java.gradle.ejs +13 -0
- package/dist/templates/contract-testing/rest-public/export-openapi.mjs.ejs +21 -0
- package/dist/templates/contract-testing/rest-public/export_openapi.go.ejs +30 -0
- package/dist/templates/contract-testing/rest-public/export_openapi.py.ejs +27 -0
- package/dist/templates/contract-testing/rest-public/export_openapi.rs.ejs +32 -0
- package/dist/templates/contract-testing/rest-public/openapi-diff.ts.ejs +42 -0
- package/dist/templates/contract-testing/rest-public/openapi_diff_test.go.ejs +35 -0
- package/dist/templates/contract-testing/rest-public/openapi_diff_test.rs.ejs +36 -0
- package/dist/templates/contract-testing/rest-public/test_openapi_diff.py.ejs +32 -0
- package/dist/templates/coverage/.coveragerc.ejs +26 -0
- package/dist/templates/coverage/.tarpaulin.toml.ejs +30 -0
- package/dist/templates/coverage/Cargo.toml.profile.release.ejs +24 -0
- package/dist/templates/coverage/jacoco-maven-setup.md.ejs +72 -0
- package/dist/templates/coverage/jacoco.gradle.ejs +49 -0
- package/dist/templates/coverage/kover.gradle.ejs +35 -0
- package/dist/templates/coverage/vitest.browser.config.ts.ejs +47 -0
- package/dist/templates/coverage/vitest.config.ts.ejs +47 -0
- package/dist/templates/docs/CODING_STANDARDS.md.ejs +81 -0
- package/dist/templates/docs/FEATURE_MATRIX.md.ejs +84 -0
- package/dist/templates/docs/GAP.md.ejs +58 -0
- package/dist/templates/docs/ISO27001_ANNEX_A.md.ejs +144 -0
- package/dist/templates/docs/MASTER_TEST_PLAN.md.ejs +52 -0
- package/dist/templates/docs/POST_MERGE_REVIEW_TEMPLATE.md.ejs +63 -0
- package/dist/templates/docs/SECURE_CODING_CHECKLIST.md.ejs +61 -0
- package/dist/templates/docs/adr/ADR-000_template.md.ejs +28 -0
- package/dist/templates/docs/bugs/bug-analysis.md.ejs +47 -0
- package/dist/templates/docs/bugs/bug-report.md.ejs +51 -0
- package/dist/templates/docs/bugs/bug-verification.md.ejs +42 -0
- package/dist/templates/docs/runbooks/deployment.md.ejs +119 -0
- package/dist/templates/docs/runbooks/prod-checklist.md.ejs +90 -0
- package/dist/templates/docs/runbooks/rollback.md.ejs +124 -0
- package/dist/templates/docs/runbooks/troubleshooting.md.ejs +130 -0
- package/dist/templates/docs/skeletons/arc42-canvas.md.ejs +46 -0
- package/dist/templates/docs/skeletons/arc42-full.md.ejs +59 -0
- package/dist/templates/docs/skeletons/decision-registry.md.ejs +38 -0
- package/dist/templates/docs/skeletons/er-model.md.ejs +19 -0
- package/dist/templates/docs/skeletons/glossary.md.ejs +8 -0
- package/dist/templates/docs/skeletons/governance.md.ejs +13 -0
- package/dist/templates/docs/skeletons/slo.md.ejs +21 -0
- package/dist/templates/docs/skeletons/technical-debt.md.ejs +8 -0
- package/dist/templates/docs/skeletons/test-strategy.md.ejs +14 -0
- package/dist/templates/docs/skeletons/threat-model-4q.md.ejs +20 -0
- package/dist/templates/docs/skeletons/threat-model-stride.md.ejs +22 -0
- package/dist/templates/docs/specs/atomic-task-list.md.ejs +57 -0
- package/dist/templates/docs/steering/product.md.ejs +44 -0
- package/dist/templates/docs/steering/structure.md.ejs +49 -0
- package/dist/templates/docs/steering/tech.md.ejs +53 -0
- package/dist/templates/documentation/cli-catalog.md.ejs +21 -0
- package/dist/templates/e2e/E2E_CONSTITUTION.md.ejs +77 -0
- package/dist/templates/e2e/playwright-python/conftest.py.ejs +22 -0
- package/dist/templates/e2e/playwright-python/run_axe.py.ejs +99 -0
- package/dist/templates/e2e/playwright-python/test_a11y.py.ejs +38 -0
- package/dist/templates/e2e/playwright-python/test_smoke.py.ejs +28 -0
- package/dist/templates/e2e/playwright-ts/a11y.spec.ts.ejs +20 -0
- package/dist/templates/e2e/playwright-ts/render-smoke.spec.ts.ejs +90 -0
- package/dist/templates/e2e/playwright-ts/run-axe.ts.ejs +74 -0
- package/dist/templates/e2e/smoke-journeys/journeys.spec.ts.ejs +53 -0
- package/dist/templates/evidence-files.json.ejs +13 -0
- package/dist/templates/frontend/FE_DESIGN_PRINCIPLES.md.ejs +115 -0
- package/dist/templates/frontend/FRONTEND_CONSTITUTION.md.ejs +170 -0
- package/dist/templates/frontend/design-tokens.json.ejs +107 -0
- package/dist/templates/frontend/vrt-setup.md.ejs +83 -0
- package/dist/templates/githooks/commit-msg.ejs +60 -0
- package/dist/templates/githooks/pre-commit.ejs +95 -0
- package/dist/templates/githooks/pre-push.ejs +251 -0
- package/dist/templates/githooks/setup-hooks.sh.ejs +8 -0
- package/dist/templates/github/PULL_REQUEST_TEMPLATE.md +37 -0
- package/dist/templates/github/PULL_REQUEST_TEMPLATE.md.ejs +52 -0
- package/dist/templates/github/actions/build-cache/action.yml.ejs +84 -0
- package/dist/templates/github/actions/nas-ssh/action.yml.ejs +53 -0
- package/dist/templates/github/actions/setup-java-maven/action.yml.ejs +53 -0
- package/dist/templates/github/actions/setup-node-pnpm/action.yml.ejs +39 -0
- package/dist/templates/github/actions/sign-and-attest/action.yml.ejs +53 -0
- package/dist/templates/github/dependabot.yml.ejs +66 -0
- package/dist/templates/github/extended-ci-paths.txt.ejs +38 -0
- package/dist/templates/github/issue-templates/bug-report.yml +72 -0
- package/dist/templates/github/issue-templates/compliance-item.yml.ejs +75 -0
- package/dist/templates/github/issue-templates/config.yml +2 -0
- package/dist/templates/github/issue-templates/epic.yml +66 -0
- package/dist/templates/github/issue-templates/feature-request.yml +24 -0
- package/dist/templates/github/issue-templates/task-brief.yml.ejs +125 -0
- package/dist/templates/github/labels.yml.ejs +161 -0
- package/dist/templates/github/scripts/sticky-failure-issue.sh.ejs +61 -0
- package/dist/templates/github/workflows/01-pr-fast.yml.ejs +1089 -0
- package/dist/templates/github/workflows/02-pr-extended.yml.ejs +512 -0
- package/dist/templates/github/workflows/03-human-approval.yml.ejs +76 -0
- package/dist/templates/github/workflows/04-deploy-test.yml.ejs +425 -0
- package/dist/templates/github/workflows/05-release.yml.ejs +813 -0
- package/dist/templates/github/workflows/06-nightly-lite.yml.ejs +125 -0
- package/dist/templates/github/workflows/06-nightly.yml.ejs +25 -0
- package/dist/templates/github/workflows/07-weekly-lite.yml.ejs +221 -0
- package/dist/templates/github/workflows/07-weekly.yml.ejs +23 -0
- package/dist/templates/github/workflows/08-monthly.yml.ejs +23 -0
- package/dist/templates/github/workflows/09-heartbeat.yml.ejs +268 -0
- package/dist/templates/github/workflows/10-deploy-prod.yml.ejs +144 -0
- package/dist/templates/github/workflows/11-k6-on-demand.yml.ejs +43 -0
- package/dist/templates/github/workflows/12-mutation-scheduled.yml.ejs +100 -0
- package/dist/templates/github/workflows/13-archunit-extended.yml.ejs +33 -0
- package/dist/templates/github/workflows/14-license-scan.yml.ejs +45 -0
- package/dist/templates/github/workflows/15-codeql.yml.ejs +117 -0
- package/dist/templates/github/workflows/16-frontend-quality.yml.ejs +154 -0
- package/dist/templates/github/workflows/17-ossf-scorecard.yml.ejs +46 -0
- package/dist/templates/github/workflows/18-frontend-lane.yml.ejs +50 -0
- package/dist/templates/github/workflows/_ai-draft-check.yml.ejs +44 -0
- package/dist/templates/github/workflows/_contract-postman.yml.ejs +93 -0
- package/dist/templates/github/workflows/_cosign-copy/aws-ecs.ejs +90 -0
- package/dist/templates/github/workflows/_cosign-copy/azure-container-app.ejs +97 -0
- package/dist/templates/github/workflows/_cosign-copy/gcp-cloud-run.ejs +102 -0
- package/dist/templates/github/workflows/_cosign-copy/ghcr.ejs +76 -0
- package/dist/templates/github/workflows/_cosign-copy/nas-compose.ejs +69 -0
- package/dist/templates/github/workflows/_deploy/aws-ecs.ejs +78 -0
- package/dist/templates/github/workflows/_deploy/azure-container-app.ejs +59 -0
- package/dist/templates/github/workflows/_deploy/gcp-cloud-run.ejs +71 -0
- package/dist/templates/github/workflows/_deploy/ghcr.ejs +19 -0
- package/dist/templates/github/workflows/_deploy/nas-compose.ejs +45 -0
- package/dist/templates/github/workflows/_k6-runner.yml.ejs +107 -0
- package/dist/templates/github/workflows/_label-on-approve.yml.ejs +44 -0
- package/dist/templates/github/workflows/_label-sync.yml.ejs +58 -0
- package/dist/templates/github/workflows/_monthly.yml.ejs +343 -0
- package/dist/templates/github/workflows/_nightly.yml.ejs +826 -0
- package/dist/templates/github/workflows/_notify.yml.ejs +96 -0
- package/dist/templates/github/workflows/_partials/macos-keychain-bypass.ejs +6 -0
- package/dist/templates/github/workflows/_partials/macos-keychain-restore.ejs +6 -0
- package/dist/templates/github/workflows/_partials/scheduled-heavy-jobs.ejs +117 -0
- package/dist/templates/github/workflows/_partials/sigstore-preflight.ejs +8 -0
- package/dist/templates/github/workflows/_partials/trivy-fs-java.ejs +27 -0
- package/dist/templates/github/workflows/_post-merge-notify.yml.ejs +228 -0
- package/dist/templates/github/workflows/_pr-staleness.yml.ejs +85 -0
- package/dist/templates/github/workflows/_shared-security.yml.ejs +132 -0
- package/dist/templates/github/workflows/_sigstore-retry-sign.yml.ejs +102 -0
- package/dist/templates/github/workflows/_weekly.yml.ejs +313 -0
- package/dist/templates/github/workflows/drift-shadow.yml.ejs +51 -0
- package/dist/templates/github/workflows/five-lane/ci.yml.ejs +54 -0
- package/dist/templates/github/workflows/five-lane/nightly.yml.ejs +70 -0
- package/dist/templates/github/workflows/five-lane/release.yml.ejs +53 -0
- package/dist/templates/github/workflows/five-lane/weekly.yml.ejs +72 -0
- package/dist/templates/github/workflows/issue-state.yml.ejs +93 -0
- package/dist/templates/global-invariants/GLOBAL_INVARIANTS.md.ejs +34 -0
- package/dist/templates/governance/RACI.md.ejs +21 -0
- package/dist/templates/governance/ci-mental-model.md.ejs +268 -0
- package/dist/templates/governance/contract-integrity-policy.md.ejs +116 -0
- package/dist/templates/governance/enterprise-compliance-baseline.md.ejs +111 -0
- package/dist/templates/governance/evidence-retention.md.ejs +43 -0
- package/dist/templates/governance/gdpr-erasure-runbook.md.ejs +165 -0
- package/dist/templates/governance/qa-audit-phases.md.ejs +129 -0
- package/dist/templates/governance/risk-assessment-template.md.ejs +105 -0
- package/dist/templates/governance/risk-register.md.ejs +76 -0
- package/dist/templates/governance/solo-dev-exception.md.ejs +96 -0
- package/dist/templates/governance/validation-evidence.md.ejs +131 -0
- package/dist/templates/infra/azure/containerapp.tpl.yaml.ejs +74 -0
- package/dist/templates/infra/nas-compose/deploy.sh.ejs +114 -0
- package/dist/templates/integration-testing/AbstractIntegrationTest.java.ejs +36 -0
- package/dist/templates/integration-testing/NoH2ArchTest.java.ejs +24 -0
- package/dist/templates/integration-testing/conftest.py.ejs +20 -0
- package/dist/templates/integration-testing/db_fixture.rs.ejs +48 -0
- package/dist/templates/integration-testing/eslint-no-fake-db.json.ejs +19 -0
- package/dist/templates/integration-testing/eslint.config.no-fake-db.mjs.ejs +46 -0
- package/dist/templates/integration-testing/main_test.go.ejs +53 -0
- package/dist/templates/integration-testing/main_test_sqlite.go.ejs +37 -0
- package/dist/templates/integration-testing/test-setup.ts.ejs +26 -0
- package/dist/templates/integration-testing/testcontainers-deps.gradle.ejs +9 -0
- package/dist/templates/java/DeprecationInterceptor.java.ejs +50 -0
- package/dist/templates/java/archunit-hexagonal.ejs +69 -0
- package/dist/templates/java/modulith/ApplicationModulesTest.java.ejs +21 -0
- package/dist/templates/java/modulith/modulith-deps.gradle.ejs +13 -0
- package/dist/templates/java/modulith/modulith-maven-setup.md.ejs +21 -0
- package/dist/templates/java/pharma/AuditEvent.java.ejs +138 -0
- package/dist/templates/java/pharma/AuditMapper.java.ejs +60 -0
- package/dist/templates/java/pharma/archunit-pharma.ejs +128 -0
- package/dist/templates/kit/GLOBAL_KIT.md.ejs +11 -0
- package/dist/templates/kit/dim.md.ejs +33 -0
- package/dist/templates/llms-txt.config.json.ejs +22 -0
- package/dist/templates/local-wrapper/.env.example.ejs +15 -0
- package/dist/templates/local-wrapper/Makefile.ejs +44 -0
- package/dist/templates/local-wrapper/run.sh.ejs +5 -0
- package/dist/templates/middleware/410-gone-handler.ts.ejs +41 -0
- package/dist/templates/middleware/correlation-id.ts.ejs +32 -0
- package/dist/templates/middleware/deprecation.ts.ejs +45 -0
- package/dist/templates/middleware/error-handler.ts.ejs +73 -0
- package/dist/templates/middleware/payload-size-limit.ts.ejs +51 -0
- package/dist/templates/mutation/README.md.ejs +67 -0
- package/dist/templates/mutation/cargo-mutants.toml.ejs +9 -0
- package/dist/templates/mutation/mutmut-config.toml.ejs +7 -0
- package/dist/templates/mutation/parse-mutants.mjs.ejs +44 -0
- package/dist/templates/mutation/parse-mutmut.py.ejs +44 -0
- package/dist/templates/mutation/pitest-l2-setup.md.ejs +66 -0
- package/dist/templates/mutation/pitest-maven-setup.md.ejs +64 -0
- package/dist/templates/mutation/pitest.gradle.ejs +23 -0
- package/dist/templates/mutation/stryker.conf.json.ejs +17 -0
- package/dist/templates/observability/setup.md.ejs +495 -0
- package/dist/templates/operations/handbook.md.ejs +217 -0
- package/dist/templates/perf/bundle-budget.json.ejs +29 -0
- package/dist/templates/perf/k6/reports/csv-report.py.ejs +91 -0
- package/dist/templates/perf/k6/reports/html-report.py.ejs +114 -0
- package/dist/templates/perf/k6/reports/json-report.py.ejs +74 -0
- package/dist/templates/perf/k6/scenarios/breakpoint.js.ejs +26 -0
- package/dist/templates/perf/k6/scenarios/burst.js.ejs +43 -0
- package/dist/templates/perf/k6/scenarios/endurance.js.ejs +36 -0
- package/dist/templates/perf/k6/scenarios/load.js.ejs +26 -0
- package/dist/templates/perf/k6/scenarios/ramp-down.js.ejs +29 -0
- package/dist/templates/perf/k6/scenarios/ramp-up.js.ejs +32 -0
- package/dist/templates/perf/k6/scenarios/smoke.js.ejs +23 -0
- package/dist/templates/perf/k6/scenarios/soak.js.ejs +26 -0
- package/dist/templates/perf/k6/scenarios/spike.js.ejs +29 -0
- package/dist/templates/perf/k6/scenarios/steady-state.js.ejs +31 -0
- package/dist/templates/perf/k6/scenarios/stress.js.ejs +29 -0
- package/dist/templates/perf/k6/scenarios/volume.js.ejs +36 -0
- package/dist/templates/perf/k6/seed/test-data.sql.ejs +59 -0
- package/dist/templates/perf/lighthouserc.json.ejs +41 -0
- package/dist/templates/quality/iso9001/CAPA_LOG.md.ejs +36 -0
- package/dist/templates/quality/iso9001/DOCUMENT_CONTROL.md.ejs +36 -0
- package/dist/templates/quality/iso9001/REQUIREMENTS_TRACEABILITY.md.ejs +61 -0
- package/dist/templates/regulated/overlay.json.ejs +26 -0
- package/dist/templates/regulated/regulated-overlay.md.ejs +40 -0
- package/dist/templates/resilience/RESILIENCE.md.ejs +310 -0
- package/dist/templates/root/.gitignore.ejs +85 -0
- package/dist/templates/root/CODEOWNERS.ejs +18 -0
- package/dist/templates/root/CONTRIBUTING.md.ejs +62 -0
- package/dist/templates/root/SECURITY.md.ejs +19 -0
- package/dist/templates/root/TEST_TAXONOMY.md.ejs +100 -0
- package/dist/templates/root/commitlint.config.js.ejs +4 -0
- package/dist/templates/root/docs/METHOD/CANONICAL_PATHS.md.ejs +24 -0
- package/dist/templates/root/docs/METHOD/ENGINEERING_DEFAULTS.md.ejs +136 -0
- package/dist/templates/root/docs/METHOD/KNOWLEDGE_MAP.md.ejs +90 -0
- package/dist/templates/root/docs/METHOD/PATTERNS_CATALOG.md.ejs +51 -0
- package/dist/templates/root/docs/METHOD/REUSE_REGISTRY.md.ejs +26 -0
- package/dist/templates/root/docs/METHOD/REUSE_REGISTRY_SPEC.md.ejs +80 -0
- package/dist/templates/root/docs/METHOD/SSOT_CORE_SET.md.ejs +62 -0
- package/dist/templates/root/docs/METHOD/TRACK_ROUTER.md.ejs +39 -0
- package/dist/templates/root/docs/SYSTEM/CANON.md.ejs +359 -0
- package/dist/templates/root/docs/SYSTEM/FAIL_CLOSED.md.ejs +171 -0
- package/dist/templates/root/editorconfig.ejs +39 -0
- package/dist/templates/root/tsconfig.json.ejs +21 -0
- package/dist/templates/rust/clippy.toml.ejs +14 -0
- package/dist/templates/schemas/milestone.schema.json.ejs +164 -0
- package/dist/templates/schemas/rtm-verdict.schema.json.ejs +52 -0
- package/dist/templates/schemas/source-record.schema.json.ejs +91 -0
- package/dist/templates/schemas/tabletop-evidence.schema.json.ejs +53 -0
- package/dist/templates/schemas/use-case.schema.json.ejs +59 -0
- package/dist/templates/scripts/apply-branch-protection.mjs.ejs +70 -0
- package/dist/templates/scripts/audit-toolchain.mjs.ejs +112 -0
- package/dist/templates/scripts/bg-run.sh.ejs +59 -0
- package/dist/templates/scripts/capacity-probe.mjs.ejs +147 -0
- package/dist/templates/scripts/capture-debt-baseline.mjs.ejs +99 -0
- package/dist/templates/scripts/check-acceptance.mjs.ejs +298 -0
- package/dist/templates/scripts/check-action-pins.mjs.ejs +215 -0
- package/dist/templates/scripts/check-agent-return.mjs.ejs +177 -0
- package/dist/templates/scripts/check-all.mjs.ejs +1746 -0
- package/dist/templates/scripts/check-anti-fake-green.mjs.ejs +80 -0
- package/dist/templates/scripts/check-anti-proforma.mjs.ejs +547 -0
- package/dist/templates/scripts/check-api-e2e.mjs.ejs +106 -0
- package/dist/templates/scripts/check-arc42-slots.mjs.ejs +25 -0
- package/dist/templates/scripts/check-assertion-delta.mjs.ejs +287 -0
- package/dist/templates/scripts/check-audit-dry-pass.mjs.ejs +176 -0
- package/dist/templates/scripts/check-bundle-size.mjs.ejs +151 -0
- package/dist/templates/scripts/check-canonical-paths.mjs.ejs +39 -0
- package/dist/templates/scripts/check-ci-tiers.mjs.ejs +111 -0
- package/dist/templates/scripts/check-claude-md-lint.mjs.ejs +142 -0
- package/dist/templates/scripts/check-collab-mode-wired.mjs.ejs +60 -0
- package/dist/templates/scripts/check-commit-footer-rationale.mjs.ejs +170 -0
- package/dist/templates/scripts/check-constraint-scan.mjs.ejs +681 -0
- package/dist/templates/scripts/check-consumer-audit.mjs.ejs +414 -0
- package/dist/templates/scripts/check-continue-on-error.mjs.ejs +227 -0
- package/dist/templates/scripts/check-cross-model-review.mjs.ejs +458 -0
- package/dist/templates/scripts/check-decision-registry.mjs.ejs +101 -0
- package/dist/templates/scripts/check-doc-freshness.mjs.ejs +17 -0
- package/dist/templates/scripts/check-doc-links.mjs.ejs +98 -0
- package/dist/templates/scripts/check-doc-set.mjs.ejs +18 -0
- package/dist/templates/scripts/check-docs.mjs.ejs +71 -0
- package/dist/templates/scripts/check-domain-api-surface.mjs.ejs +80 -0
- package/dist/templates/scripts/check-drift.mjs.ejs +167 -0
- package/dist/templates/scripts/check-duplication.mjs.ejs +45 -0
- package/dist/templates/scripts/check-e2e-escalation.mjs.ejs +199 -0
- package/dist/templates/scripts/check-e2e-quarantine.mjs.ejs +68 -0
- package/dist/templates/scripts/check-emission-parity.mjs.ejs +91 -0
- package/dist/templates/scripts/check-exit-code-contract.mjs.ejs +138 -0
- package/dist/templates/scripts/check-fail-closed-audit.mjs.ejs +389 -0
- package/dist/templates/scripts/check-fe-boundaries.mjs.ejs +184 -0
- package/dist/templates/scripts/check-feature-matrix.mjs.ejs +835 -0
- package/dist/templates/scripts/check-frontend-lane.mjs.ejs +73 -0
- package/dist/templates/scripts/check-grace-window.mjs.ejs +102 -0
- package/dist/templates/scripts/check-handoff-doc.mjs.ejs +192 -0
- package/dist/templates/scripts/check-hook-routing.mjs.ejs +224 -0
- package/dist/templates/scripts/check-image-pins.mjs.ejs +90 -0
- package/dist/templates/scripts/check-inline-suppressions.mjs.ejs +153 -0
- package/dist/templates/scripts/check-iso9001.mjs.ejs +146 -0
- package/dist/templates/scripts/check-knowledge-map.mjs.ejs +49 -0
- package/dist/templates/scripts/check-local-ci-parity.mjs.ejs +382 -0
- package/dist/templates/scripts/check-m16-handoff.mjs.ejs +112 -0
- package/dist/templates/scripts/check-merge-method.mjs.ejs +92 -0
- package/dist/templates/scripts/check-milestones.mjs.ejs +678 -0
- package/dist/templates/scripts/check-min-test-execution.mjs.ejs +225 -0
- package/dist/templates/scripts/check-muted-test.mjs.ejs +270 -0
- package/dist/templates/scripts/check-no-stub-redirects.mjs.ejs +154 -0
- package/dist/templates/scripts/check-no-tracked-artifacts.mjs.ejs +134 -0
- package/dist/templates/scripts/check-oracle-discrimination.mjs.ejs +244 -0
- package/dist/templates/scripts/check-pii-scan.mjs.ejs +67 -0
- package/dist/templates/scripts/check-pipe-tee-hazard.mjs.ejs +85 -0
- package/dist/templates/scripts/check-pr-size-gate.mjs.ejs +85 -0
- package/dist/templates/scripts/check-refutation-verdicts.mjs.ejs +256 -0
- package/dist/templates/scripts/check-regulated-overlay.mjs.ejs +158 -0
- package/dist/templates/scripts/check-render-smoke.mjs.ejs +100 -0
- package/dist/templates/scripts/check-reuse-registry.mjs.ejs +44 -0
- package/dist/templates/scripts/check-review-completion.mjs.ejs +708 -0
- package/dist/templates/scripts/check-safety-adopt-ratchet.mjs.ejs +142 -0
- package/dist/templates/scripts/check-secret-presence.mjs.ejs +191 -0
- package/dist/templates/scripts/check-secret-scan.mjs.ejs +82 -0
- package/dist/templates/scripts/check-skip-critical-e2e.mjs.ejs +142 -0
- package/dist/templates/scripts/check-smoke-journeys.mjs.ejs +272 -0
- package/dist/templates/scripts/check-solo-reactivation.mjs.ejs +102 -0
- package/dist/templates/scripts/check-sources.mjs.ejs +245 -0
- package/dist/templates/scripts/check-ssot-core.mjs.ejs +45 -0
- package/dist/templates/scripts/check-stack-conformity.mjs.ejs +160 -0
- package/dist/templates/scripts/check-stride-traceability.mjs.ejs +101 -0
- package/dist/templates/scripts/check-suppression-expiry.mjs.ejs +79 -0
- package/dist/templates/scripts/check-suppression-rationale.mjs.ejs +76 -0
- package/dist/templates/scripts/check-suppressions.mjs.ejs +150 -0
- package/dist/templates/scripts/check-tabletop-evidence.mjs.ejs +499 -0
- package/dist/templates/scripts/check-tdd-evidence.mjs.ejs +381 -0
- package/dist/templates/scripts/check-test-naming.mjs.ejs +151 -0
- package/dist/templates/scripts/check-test-pyramid.mjs.ejs +170 -0
- package/dist/templates/scripts/check-test-scope-tier.mjs.ejs +208 -0
- package/dist/templates/scripts/check-tier-coverage.mjs.ejs +71 -0
- package/dist/templates/scripts/check-todo-max-age.mjs.ejs +205 -0
- package/dist/templates/scripts/check-touched-vs-manifest.mjs.ejs +179 -0
- package/dist/templates/scripts/check-unwired-guards.mjs.ejs +367 -0
- package/dist/templates/scripts/check-use-cases.mjs.ejs +345 -0
- package/dist/templates/scripts/check-validator-helptext.mjs.ejs +80 -0
- package/dist/templates/scripts/check-wiki-lint.mjs.ejs +162 -0
- package/dist/templates/scripts/check-workflow-docs-sync.mjs.ejs +91 -0
- package/dist/templates/scripts/check-workflow-job-naming.mjs.ejs +102 -0
- package/dist/templates/scripts/check-workflow-perms.mjs.ejs +54 -0
- package/dist/templates/scripts/check-workflow-runners.mjs.ejs +87 -0
- package/dist/templates/scripts/check-workflow-sha-pinning.mjs.ejs +89 -0
- package/dist/templates/scripts/check-workflow-test-integrity.mjs.ejs +235 -0
- package/dist/templates/scripts/checks/check-rust-no-unsafe.mjs.ejs +58 -0
- package/dist/templates/scripts/checks/check-rust-no-unwrap.mjs.ejs +61 -0
- package/dist/templates/scripts/ci-classify-changes.mjs.ejs +119 -0
- package/dist/templates/scripts/conformance.mjs.ejs +37 -0
- package/dist/templates/scripts/constraint-map.json.ejs +25 -0
- package/dist/templates/scripts/debt-lib.mjs.ejs +1015 -0
- package/dist/templates/scripts/debt-report.mjs.ejs +199 -0
- package/dist/templates/scripts/domain-api-surface.json.ejs +23 -0
- package/dist/templates/scripts/done-evidence.mjs.ejs +359 -0
- package/dist/templates/scripts/evidence-collect.mjs.ejs +264 -0
- package/dist/templates/scripts/evidence-prune.mjs.ejs +96 -0
- package/dist/templates/scripts/evidence-rotate.mjs.ejs +53 -0
- package/dist/templates/scripts/evidence-writer.sh.ejs +220 -0
- package/dist/templates/scripts/gate-registry.yml.ejs +286 -0
- package/dist/templates/scripts/gen-doc-index.mjs.ejs +19 -0
- package/dist/templates/scripts/gen-gap.mjs.ejs +153 -0
- package/dist/templates/scripts/gen-llms-txt.mjs.ejs +18 -0
- package/dist/templates/scripts/gen-wiki.mjs.ejs +196 -0
- package/dist/templates/scripts/gh-cleanup-expired-artifacts.mjs.ejs +134 -0
- package/dist/templates/scripts/gold-audit.mjs.ejs +19 -0
- package/dist/templates/scripts/i18n-literal-scanner.mjs.ejs +175 -0
- package/dist/templates/scripts/ingest-zap-report.mjs.ejs +107 -0
- package/dist/templates/scripts/inject-pact-samples.sh.ejs +96 -0
- package/dist/templates/scripts/issue-readiness.mjs.ejs +84 -0
- package/dist/templates/scripts/knowledge-map-update.mjs.ejs +32 -0
- package/dist/templates/scripts/lib/acceptance-criteria.mjs.ejs +213 -0
- package/dist/templates/scripts/lib/agent-return-validate.mjs.ejs +481 -0
- package/dist/templates/scripts/lib/coverage-gate.mjs.ejs +54 -0
- package/dist/templates/scripts/lib/e2e-reliability.mjs.ejs +207 -0
- package/dist/templates/scripts/lib/ephemeral-server.mjs.ejs +148 -0
- package/dist/templates/scripts/lib/evidence-binding.mjs.ejs +140 -0
- package/dist/templates/scripts/lib/exact-sha-policy.mjs.ejs +233 -0
- package/dist/templates/scripts/lib/gate-args.mjs.ejs +20 -0
- package/dist/templates/scripts/lib/gate-evidence.mjs.ejs +622 -0
- package/dist/templates/scripts/lib/gate-mutex.mjs.ejs +340 -0
- package/dist/templates/scripts/lib/glob-walk.mjs.ejs +148 -0
- package/dist/templates/scripts/lib/run-helpers.mjs.ejs +416 -0
- package/dist/templates/scripts/lib/seed-common.sh.ejs +105 -0
- package/dist/templates/scripts/lib/waiter-count.mjs.ejs +62 -0
- package/dist/templates/scripts/muted-tests-baseline.json.ejs +4 -0
- package/dist/templates/scripts/optional-emissions.json.ejs +117 -0
- package/dist/templates/scripts/oracle-discrimination-baseline.json.ejs +6 -0
- package/dist/templates/scripts/pid-watch.sh.ejs +78 -0
- package/dist/templates/scripts/pii-scan.mjs.ejs +125 -0
- package/dist/templates/scripts/pr-merge-watch.mjs.ejs +445 -0
- package/dist/templates/scripts/record-agent-return.mjs.ejs +279 -0
- package/dist/templates/scripts/record-journey-evidence.mjs.ejs +69 -0
- package/dist/templates/scripts/rework-log.mjs.ejs +172 -0
- package/dist/templates/scripts/run-postman-tests.sh.ejs +112 -0
- package/dist/templates/scripts/schemas/agent-return-external.schema.json +74 -0
- package/dist/templates/scripts/schemas/agent-return.schema.json.ejs +181 -0
- package/dist/templates/scripts/schemas/cross-model-dispatch.schema.json +95 -0
- package/dist/templates/scripts/seed-test-data.sh.ejs +99 -0
- package/dist/templates/scripts/self-validation.mjs.ejs +126 -0
- package/dist/templates/scripts/setup-repo.sh.ejs +78 -0
- package/dist/templates/scripts/spotbugs-baseline.json.ejs +4 -0
- package/dist/templates/scripts/test-gate-layering.mjs.ejs +92 -0
- package/dist/templates/scripts/validate-api-snapshots.mjs.ejs +86 -0
- package/dist/templates/scripts/validate-k6-scenarios.mjs.ejs +96 -0
- package/dist/templates/scripts/validate-openapi-field-types.mjs.ejs +124 -0
- package/dist/templates/scripts/validate-postman-collection.mjs.ejs +159 -0
- package/dist/templates/scripts/verify-fe-coverage.mjs.ejs +138 -0
- package/dist/templates/scripts/verify-i18n-parity.mjs.ejs +114 -0
- package/dist/templates/scripts/verify-module-coverage.mjs.ejs +207 -0
- package/dist/templates/scripts/verify-mutation-baseline.mjs.ejs +209 -0
- package/dist/templates/scripts/verify-spotbugs.mjs.ejs +216 -0
- package/dist/templates/scripts/verify-tokens.mjs.ejs +177 -0
- package/dist/templates/security/RISK_ASSESSMENT.md.ejs +35 -0
- package/dist/templates/security/STRIDE.md.ejs +24 -0
- package/dist/templates/security/gitleaks.toml.ejs +21 -0
- package/dist/templates/security/zap/baseline-auth.context.ejs +58 -0
- package/dist/templates/security/zap/rules.tsv.ejs +100 -0
- package/dist/templates/ship/TICK_PROMPT.md.ejs +55 -0
- package/dist/templates/ship/supervisor.sh.ejs +46 -0
- package/dist/templates/smoke-journeys/manifest.json.ejs +1 -0
- package/dist/templates/sonar-project.properties.ejs +25 -0
- package/dist/templates/standards/doc-profile.ejs +27 -0
- package/dist/templates/standards/gold-doc-set.yml.ejs +528 -0
- package/dist/templates/standards/gold-registry.java.yml.ejs +266 -0
- package/dist/templates/standards/gold-registry.typescript.yml.ejs +104 -0
- package/dist/templates/standards/gold-registry.yml.ejs +119 -0
- package/dist/templates/standards/thresholds.yml.ejs +86 -0
- package/dist/templates/static-analysis/.dependency-cruiser.cjs.ejs +78 -0
- package/dist/templates/static-analysis/.golangci.yml.ejs +70 -0
- package/dist/templates/static-analysis/.shellcheckrc.ejs +13 -0
- package/dist/templates/static-analysis/.yamllint.yml.ejs +41 -0
- package/dist/templates/static-analysis/checkstyle.xml.ejs +83 -0
- package/dist/templates/static-analysis/detekt.yml.ejs +26 -0
- package/dist/templates/static-analysis/eslint.config.mjs.ejs +54 -0
- package/dist/templates/static-analysis/eslint.config.static.mjs.ejs +38 -0
- package/dist/templates/static-analysis/eslintrc-static.json.ejs +30 -0
- package/dist/templates/static-analysis/jscpd.json.ejs +25 -0
- package/dist/templates/static-analysis/knip.json.ejs +26 -0
- package/dist/templates/static-analysis/pmd-ruleset.xml.ejs +92 -0
- package/dist/templates/static-analysis/prettierignore.ejs +59 -0
- package/dist/templates/static-analysis/prettierrc.json.ejs +10 -0
- package/dist/templates/static-analysis/requirements-dev.txt.ejs +11 -0
- package/dist/templates/static-analysis/ruff.toml.ejs +40 -0
- package/dist/templates/static-analysis/rustfmt.toml.ejs +3 -0
- package/dist/templates/static-analysis/spotbugs-exclude.xml.ejs +120 -0
- package/dist/templates/static-analysis/spotbugs.gradle.ejs +18 -0
- package/dist/templates/static-analysis/spotless.gradle.ejs +38 -0
- package/dist/templates/static-analysis/stylelintrc.json.ejs +16 -0
- package/dist/templates/suppressions/archunit-baseline.json.ejs +1 -0
- package/dist/templates/suppressions/consumer-audit-allowlist.json.ejs +1 -0
- package/dist/templates/suppressions/gitleaksignore.ejs +20 -0
- package/dist/templates/suppressions/pii-allowlist.json.ejs +1 -0
- package/dist/templates/suppressions/suppressions-schema.json.ejs +39 -0
- package/dist/templates/suppressions/trivyignore.ejs +17 -0
- package/dist/templates/testing/test-taxonomy.md.ejs +120 -0
- package/dist/test/example.behavioral.test.js +2 -0
- package/dist/types/memory.d.ts +19 -0
- package/dist/types/memory.js +1 -0
- package/dist/types/plan.d.ts +102 -0
- package/dist/types/plan.js +2 -0
- package/dist/types/plugin.d.ts +45 -0
- package/dist/types/plugin.js +1 -0
- package/dist/utils/canon-loader.js +2 -0
- package/dist/utils/channel.js +1 -0
- package/dist/utils/config.d.ts +79 -0
- package/dist/utils/config.js +5 -0
- package/dist/utils/confirm-downgrade.js +5 -0
- package/dist/utils/env.js +2 -0
- package/dist/utils/error-catalog.js +2 -0
- package/dist/utils/errors.js +2 -0
- package/dist/utils/evidence-log.js +3 -0
- package/dist/utils/file-lock.js +2 -0
- package/dist/utils/first-run.js +8 -0
- package/dist/utils/fs.js +3 -0
- package/dist/utils/github-issue-helper.js +4 -0
- package/dist/utils/gradle.js +21 -0
- package/dist/utils/json-output.js +2 -0
- package/dist/utils/logger-config.js +4 -0
- package/dist/utils/logger.js +3 -0
- package/dist/utils/maturity-check.js +2 -0
- package/dist/utils/pkg.js +3 -0
- package/dist/utils/platform.js +2 -0
- package/dist/utils/plugin-loader.js +2 -0
- package/dist/utils/plugin-worker.js +2 -0
- package/dist/utils/prettier-format.js +2 -0
- package/dist/utils/profiler.js +2 -0
- package/dist/utils/render.js +2 -0
- package/dist/utils/replay.js +3 -0
- package/dist/utils/run-cli.js +6 -0
- package/dist/utils/run-id.js +3 -0
- package/dist/utils/safe-read.js +2 -0
- package/dist/utils/task-id.js +2 -0
- package/dist/utils/today.js +2 -0
- package/dist/utils/tty.js +2 -0
- package/dist/utils/walk-dir.js +2 -0
- package/dist/verify/rules/drive-by-scope.js +1 -0
- package/dist/verify/rules/orphan-todos.js +1 -0
- package/dist/verify/rules/registry.js +1 -0
- package/dist/verify/rules/skip-patterns.js +1 -0
- package/dist/verify/rules/types.d.ts +15 -0
- package/dist/verify/rules/types.js +1 -0
- package/dist/verify/rules/ui-language.js +1 -0
- package/dist/verify/run.js +3 -0
- package/dist/wizard/archetype-defaults.js +1 -0
- package/dist/wizard/presets.js +1 -0
- package/dist/wizard/prompts.js +44 -0
- package/dist/wizard/types.d.ts +637 -0
- package/dist/wizard/types.js +1 -0
- package/dist/worktree/harvest.js +2 -0
- package/dist/worktree/links.js +2 -0
- package/dist/worktree/paths.js +2 -0
- package/dist/worktree/validate.js +3 -0
- package/package.json +124 -0
- package/scripts/check-arc42-slots.mjs +738 -0
- package/scripts/check-doc-freshness.mjs +236 -0
- package/scripts/check-doc-set.mjs +243 -0
- package/scripts/check-doc-style.mjs +228 -0
- package/scripts/gold-audit.mjs +319 -0
- package/scripts/lib/doc-gate-allowlist.mjs +123 -0
- package/scripts/lib/doc-set-resolve.mjs +274 -0
- package/scripts/lib/glob-walk.mjs +148 -0
- package/scripts/lib/gold-audit-lib.mjs +1260 -0
- package/scripts/lib/run-helpers.mjs +413 -0
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{existsSync,lstatSync,readdirSync,readFileSync,statSync}from"node:fs";import{join,relative}from"node:path";import{toFsError}from"../utils/fs.js";let diagnosticErrors=0;const workflowCache=new Map,pkgCache=new Map;export function clearMeasureCache(){workflowCache.clear(),pkgCache.clear(),diagnosticErrors=0}const SKIP_DIRS=new Set(["node_modules",".git","dist","target","build",".gradle","vendor","__pycache__",".mypy_cache",".ruff_cache",".next","out","coverage",".nyc_output"]),EVIDENCE_CAP=20;function toPosixRelative(repoRoot,absPath){return relative(repoRoot,absPath).replace(/\\/g,"/")}function readPkgJson(repoRoot){const cached=pkgCache.get(repoRoot);if(cached!==void 0)return cached;const pkgPath=join(repoRoot,"package.json");if(!existsSync(pkgPath))return pkgCache.set(repoRoot,null),null;try{const raw=readFileSync(pkgPath,"utf8"),parsed=JSON.parse(raw);return pkgCache.set(repoRoot,parsed),parsed}catch{return pkgCache.set(repoRoot,null),null}}function hasDep(pkg,name){if(!pkg)return!1;const deps=pkg.dependencies??{},devDeps=pkg.devDependencies??{},peerDeps=pkg.peerDependencies??{};return name in deps||name in devDeps||name in peerDeps}function hasScript(pkg,key){if(!pkg)return!1;const scripts=pkg.scripts??{};return key in scripts}function fileContains(absPath,pattern){try{const st=statSync(absPath);if(!st.isFile()||st.size>1048576)return st.size>1048576&&process.stderr.write(`[measure] skipping large file: ${absPath}
|
|
3
|
+
`),!1;const content=readFileSync(absPath,"utf8");return typeof pattern=="string"?content.includes(pattern):pattern.test(content)}catch{return!1}}function visitEntry(full,entry,matchFn,remainingDepth,results){let st;try{st=lstatSync(full)}catch{return}st.isDirectory()?findRecursive(full,matchFn,remainingDepth-1,results):matchFn(entry)&&results.push(full)}function findRecursive(dir,matchFn,remainingDepth=12,results=[]){if(remainingDepth<0||results.length>=EVIDENCE_CAP)return results;let entries;try{entries=readdirSync(dir)}catch{return results}for(const entry of entries){if(results.length>=EVIDENCE_CAP)break;SKIP_DIRS.has(entry)||visitEntry(join(dir,entry),entry,matchFn,remainingDepth,results)}return results}function checkAny(repoRoot,relPaths){const found=[];for(const rel of relPaths){if(found.length>=EVIDENCE_CAP)break;const abs=join(repoRoot,rel);existsSync(abs)&&found.push(rel.replace(/\\/g,"/"))}return found.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:found}}function checkDir(repoRoot,relDir,extFilter){const abs=join(repoRoot,relDir);if(!existsSync(abs))return{status:"missing",evidence:[]};let entries;try{entries=readdirSync(abs)}catch{return{status:"missing",evidence:[]}}const matching=entries.filter(f=>extFilter?f.endsWith(extFilter):!0).filter(f=>{try{return statSync(join(abs,f)).isFile()}catch{return!1}}).slice(0,EVIDENCE_CAP).map(f=>toPosixRelative(repoRoot,join(abs,f)));return matching.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:matching}}function readWorkflowFile(abs){try{const st=statSync(abs);return!st.isFile()||st.size>1048576?null:readFileSync(abs,"utf8")}catch{return null}}function workflowsMatchingPattern(repoRoot,pattern){let repoMap=workflowCache.get(repoRoot);if(!repoMap){repoMap=new Map;const wfDir=join(repoRoot,".github","workflows");if(existsSync(wfDir)){let entries;try{entries=readdirSync(wfDir).filter(f=>f.endsWith(".yml")||f.endsWith(".yaml"))}catch{entries=[]}for(const f of entries){const content=readWorkflowFile(join(wfDir,f));content!==null&&repoMap.set(f,content)}}workflowCache.set(repoRoot,repoMap)}const results=[];for(const[filename,content]of repoMap)(typeof pattern=="string"?content.includes(pattern):pattern.test(content))&&results.push(`.github/workflows/${filename}`);return results.sort()}function globWorkflows(repoRoot){const dir=join(repoRoot,".github","workflows");if(!existsSync(dir))return[];try{return readdirSync(dir).filter(f=>f.endsWith(".yml")||f.endsWith(".yaml")).sort().map(f=>toPosixRelative(repoRoot,join(dir,f)))}catch(err){return process.stderr.write(`[measure] readdirSync failed for ${dir}: ${toFsError(err,dir).message}
|
|
4
|
+
`),[]}}function hasArchUnitDep(repoRoot){const pom=join(repoRoot,"pom.xml"),gradle=join(repoRoot,"build.gradle"),found=[];return fileContains(pom,"archunit")&&found.push("pom.xml"),fileContains(gradle,"archunit")&&found.push("build.gradle"),found}function findArchTestClasses(repoRoot){const testDir=join(repoRoot,"src","test");return existsSync(testDir)?findRecursive(testDir,name=>/ArchTest/i.test(name)&&name.endsWith(".java")).map(abs=>toPosixRelative(repoRoot,abs)):[]}function measureArchUnit(repoRoot){const depFiles=hasArchUnitDep(repoRoot);if(depFiles.length===0)return{status:"missing",evidence:[]};const testClasses=findArchTestClasses(repoRoot);return testClasses.length>0?{status:"present",evidence:[...depFiles,...testClasses].slice(0,EVIDENCE_CAP)}:{status:"partial",evidence:depFiles}}const DIM_HANDLERS={N01:measureArchUnit,N02:measureArchUnit,N03:measureArchUnit,N04:measureArchUnit,N05:measureArchUnit,N06:measureArchUnit,N07:r=>{const script=join(r,"scripts","check-circular-deps.mjs");if(existsSync(script))return{status:"present",evidence:["scripts/check-circular-deps.mjs"]};const pkg=readPkgJson(r);return hasDep(pkg,"madge")?{status:"partial",evidence:["package.json"]}:{status:"missing",evidence:[]}},N08:r=>{const abs=findRecursive(join(r,"src"),n=>/audit.*service|AuditEvent/i.test(n)).map(a=>toPosixRelative(r,a));return abs.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:abs.slice(0,EVIDENCE_CAP)}},N73:r=>{const dirs=[join(r,"db","migrations"),join(r,"src","main","resources","db")],found=[];for(const d of dirs)existsSync(d)&&found.push(...findRecursive(d,n=>/audit/i.test(n)).map(a=>toPosixRelative(r,a)));return found.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:found.slice(0,EVIDENCE_CAP)}},N74:r=>{const dirs=[join(r,"db","migrations"),join(r,"src","main","resources","db")],found=[];for(const d of dirs)existsSync(d)&&found.push(...findRecursive(d,n=>/trigger|audit_trigger/i.test(n)).map(a=>toPosixRelative(r,a)));return found.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:found.slice(0,EVIDENCE_CAP)}},N75:r=>{const found=findRecursive(join(r,"src"),n=>/AuditEvent.*Repository|AppendOnly/i.test(n)).map(a=>toPosixRelative(r,a));return found.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:found.slice(0,EVIDENCE_CAP)}},N09:r=>checkAny(r,[".eslintrc",".eslintrc.js",".eslintrc.cjs",".eslintrc.json",".eslintrc.yml",".eslintrc.yaml","eslint.config.js","eslint.config.mjs","eslint.config.cjs",".golangci.yml",".golangci.yaml","ruff.toml",".ruff.toml","setup.cfg",".clippy.toml"]),N10:r=>checkAny(r,[".prettierrc",".prettierrc.js",".prettierrc.cjs",".prettierrc.json",".prettierrc.yml",".prettierrc.yaml","prettier.config.js","prettier.config.cjs","prettier.config.mjs","spotless.gradle","rustfmt.toml"]),N11:r=>checkAny(r,["pmd.xml",".semgrep.yml",".semgrep.yaml","semgrep-rules"]),N12:r=>checkAny(r,["spotbugs.gradle","spotbugs-baseline.json"]),N13:()=>({status:"missing",evidence:[]}),N14:r=>{const fromFile=checkAny(r,["knip.json","scripts/check-no-unused-exports.mjs"]);if(fromFile.status==="present")return fromFile;const pkg=readPkgJson(r);return hasDep(pkg,"knip")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N15:r=>{const fromFile=checkAny(r,[".jscpd.json"]);if(fromFile.status==="present")return fromFile;const pkg=readPkgJson(r);return hasDep(pkg,"jscpd")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N16:r=>checkAny(r,["src/tokens","design-tokens.json","tailwind.config.js","tailwind.config.ts","tailwind.config.cjs","tailwind.config.mjs"]),N17:r=>checkAny(r,["vitest.config.ts","vitest.config.js","vitest.config.mjs","vitest.config.cjs","jest.config.ts","jest.config.js","jest.config.cjs","jest.config.mjs","pytest.ini","setup.cfg","Cargo.toml"]),N18:r=>{const candidates=["vitest.config.ts","vitest.config.js","vitest.config.mjs",".nycrc",".nycrc.json"],found=[];for(const rel of candidates){const abs=join(r,rel);existsSync(abs)&&fileContains(abs,/thresholds|coverage.*lines|branches|statements|functions/)&&found.push(rel)}return fileContains(join(r,"build.gradle"),"jacoco")&&found.push("build.gradle"),found.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:found.slice(0,EVIDENCE_CAP)}},N19:r=>checkAny(r,["scripts/coverage-baseline.json",".coverage-baseline"]),N20:r=>{const fromFile=checkAny(r,["stryker.config.js","stryker.config.ts","stryker.config.mjs","stryker.config.cjs","stryker.config.json","stryker.conf.json",".mutmut.toml"]);if(fromFile.status==="present")return fromFile;const pkg=readPkgJson(r);return hasDep(pkg,"@stryker-mutator/core")||hasDep(pkg,"stryker")?{status:"present",evidence:["package.json"]}:fileContains(join(r,"pom.xml"),"pitest")||fileContains(join(r,"build.gradle"),"pitest")?{status:"present",evidence:[fileContains(join(r,"pom.xml"),"pitest")?"pom.xml":"build.gradle"]}:{status:"missing",evidence:[]}},N21:r=>{const candidates=["vitest.config.ts","vitest.config.js","vitest.config.mjs"];for(const rel of candidates){const abs=join(r,rel);if(existsSync(abs)&&fileContains(abs,/pool|poolOptions|threads|forks/))return{status:"present",evidence:[rel]}}return{status:"missing",evidence:[]}},N22:r=>checkAny(r,["scripts/check-test-naming.mjs"]),N23:r=>checkDir(r,".arbiter/evidence/tdd"),N24:r=>{const pkg=readPkgJson(r);if(hasScript(pkg,"test:unit"))return{status:"present",evidence:["package.json"]};const vitestCandidates=["vitest.config.ts","vitest.config.js","vitest.config.mjs"];for(const rel of vitestCandidates){const abs=join(r,rel);if(existsSync(abs)&&fileContains(abs,/exclude|testPathIgnorePatterns/))return{status:"partial",evidence:[rel]}}return{status:"missing",evidence:[]}},N25:r=>{const pkg=readPkgJson(r);if(hasScript(pkg,"test:integration"))return{status:"present",evidence:["package.json"]};const wfs=workflowsMatchingPattern(r,"integration");return wfs.length>0?{status:"partial",evidence:wfs.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N26:r=>{const wfs=workflowsMatchingPattern(r,"schedule:");return wfs.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)}},N27:r=>{const fromDir=checkDir(r,"__tests__/integration");if(fromDir.status==="present")return fromDir;const javaTests=findRecursive(join(r,"src","test"),n=>n.endsWith("IT.java")).map(a=>toPosixRelative(r,a));return javaTests.length>0?{status:"present",evidence:javaTests.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N28:r=>{const fromDir=checkDir(r,"__tests__/contract");if(fromDir.status==="present")return fromDir;const pkg=readPkgJson(r);return hasDep(pkg,"@pact-foundation/pact")||hasDep(pkg,"pact")?{status:"present",evidence:["package.json"]}:fileContains(join(r,"pom.xml"),"spring-cloud-contract")||fileContains(join(r,"build.gradle"),"spring-cloud-contract")?{status:"present",evidence:[fileContains(join(r,"pom.xml"),"spring-cloud-contract")?"pom.xml":"build.gradle"]}:{status:"missing",evidence:[]}},N29:r=>{const fromBehavioral=checkDir(r,"__tests__/behavioral");if(fromBehavioral.status==="present")return fromBehavioral;const fromFeatures=checkDir(r,"features");if(fromFeatures.status==="present")return fromFeatures;const pkg=readPkgJson(r);return hasDep(pkg,"@cucumber/cucumber")||hasDep(pkg,"cucumber")||hasDep(pkg,"pytest-bdd")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N30:r=>{const depFiles=hasArchUnitDep(r);if(depFiles.length===0)return{status:"missing",evidence:[]};const testClasses=findArchTestClasses(r);return testClasses.length>0?{status:"present",evidence:[...depFiles,...testClasses].slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N31:r=>{const fromDir=checkDir(r,"fuzz");if(fromDir.status==="present")return fromDir;const fuzzFiles=findRecursive(join(r,"src","test"),n=>/Fuzz/i.test(n)).map(a=>toPosixRelative(r,a));return fuzzFiles.length>0?{status:"present",evidence:fuzzFiles.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N32:r=>{const pkg=readPkgJson(r);return hasDep(pkg,"fast-check")||hasDep(pkg,"hypothesis")||hasDep(pkg,"proptest")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N33:r=>{const fromSnapshots=checkDir(r,"__tests__/__snapshots__");if(fromSnapshots.status==="present")return fromSnapshots;const fromSrcSnapshots=checkDir(r,"src/__snapshots__");return fromSrcSnapshots.status==="present"?fromSrcSnapshots:checkAny(r,["scripts/check-api-snapshot.mjs"])},N34:r=>{const workflows=globWorkflows(r);return workflows.length<2?{status:"missing",evidence:[]}:{status:"present",evidence:workflows.slice(0,EVIDENCE_CAP)}},N35:r=>{const wfs=workflowsMatchingPattern(r,"pull_request");return wfs.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)}},N36:r=>{const wfs=workflowsMatchingPattern(r,/push[\s\S]*?tags|release:/);return wfs.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)}},N37:r=>{const matching=workflowsMatchingPattern(r,"schedule:").filter(f=>/nightly/i.test(f)||fileContains(join(r,f),/cron:.*"0 [0-5]/));return matching.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:matching.slice(0,EVIDENCE_CAP)}},N38:r=>{const matching=workflowsMatchingPattern(r,"schedule:").filter(f=>/weekly/i.test(f)||fileContains(join(r,f),/cron:.*"0 \d+ \* \* 0/));return matching.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:matching.slice(0,EVIDENCE_CAP)}},N39:r=>{const wfs=workflowsMatchingPattern(r,"CI_BUILD_RUNNER_LABEL");if(wfs.length>0)return{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)};const allWfs=globWorkflows(r);return allWfs.length>0?{status:"partial",evidence:allWfs.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N40:r=>{const wfs=workflowsMatchingPattern(r,/attest-build-provenance|cosign/);if(wfs.length>0)return{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)};const pkg=readPkgJson(r);return hasDep(pkg,"cosign")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N41:r=>checkAny(r,["playwright.config.ts","playwright.config.js","playwright.config.mjs","__tests__/e2e"]),N42:r=>checkAny(r,["k6","locustfile.py","gatling/simulations"]),N43:r=>{const wfs=workflowsMatchingPattern(r,/zap-|nuclei/);return wfs.length===0?{status:"missing",evidence:[]}:{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)}},N44:r=>{const pkg=readPkgJson(r);if(hasDep(pkg,"keycloak-js")||hasDep(pkg,"keycloak-connect"))return{status:"present",evidence:["package.json"]};const testFiles=findRecursive(join(r,"__tests__"),n=>/keycloak/i.test(n)).map(a=>toPosixRelative(r,a));return testFiles.length>0?{status:"present",evidence:testFiles.slice(0,EVIDENCE_CAP)}:fileContains(join(r,"pom.xml"),"keycloak")||fileContains(join(r,"build.gradle"),"keycloak")?{status:"present",evidence:[fileContains(join(r,"pom.xml"),"keycloak")?"pom.xml":"build.gradle"]}:{status:"missing",evidence:[]}},N45:r=>{const fromScript=checkAny(r,["scripts/check-format.mjs","scripts/check-format.sh"]);if(fromScript.status==="present")return fromScript;const pkg=readPkgJson(r);return hasScript(pkg,"format")||hasScript(pkg,"lint:format")||hasScript(pkg,"fmt")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N46:r=>checkAny(r,["scripts/check-spdx-headers.mjs"]),N47:r=>checkAny(r,["scripts/check-no-orphan-todo.mjs"]),N48:r=>checkAny(r,["scripts/check-no-placeholders.mjs"]),N49:r=>checkAny(r,["scripts/check-doc-links.mjs"]),N50:r=>checkAny(r,["scripts/check-bloat-ratchet.mjs"]),N51:r=>checkAny(r,["scripts/debt-report.mjs","debt-baseline.json"]),N52:r=>checkAny(r,["scripts/check-self-dogfood.mjs"]),N53:r=>checkAny(r,["scripts/check-api-snapshot.mjs","api-snapshot.json"]),N54:r=>{const fromScript=checkAny(r,["scripts/check-circular-deps.mjs"]);if(fromScript.status==="present")return fromScript;const pkg=readPkgJson(r);return hasDep(pkg,"madge")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N55:r=>{const fromConfig=checkAny(r,[".gitleaks.toml",".gitleaks.config.toml"]);if(fromConfig.status==="present")return fromConfig;const wfs=workflowsMatchingPattern(r,"gitleaks");return wfs.length>0?{status:"partial",evidence:wfs.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N56:r=>{const fromConfig=checkAny(r,[".trivyignore","owasp-suppressions.xml",".audit-ci.json"]);if(fromConfig.status==="present")return fromConfig;const wfs=workflowsMatchingPattern(r,"npm audit");return wfs.length>0?{status:"partial",evidence:wfs.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N57:r=>{const fromConfig=checkAny(r,[".trivyignore"]);if(fromConfig.status==="present")return fromConfig;const wfs=workflowsMatchingPattern(r,/trivy|aquasecurity/);return wfs.length>0?{status:"present",evidence:wfs.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N58:r=>{const fromFile=checkAny(r,[".fossa.yml",".fossa.yaml"]);if(fromFile.status==="present")return fromFile;const pkg=readPkgJson(r);return hasDep(pkg,"licensee")?{status:"present",evidence:["package.json"]}:{status:"missing",evidence:[]}},N59:r=>checkAny(r,["commitlint.config.js","commitlint.config.ts","commitlint.config.cjs","commitlint.config.mjs",".commitlintrc",".commitlintrc.js",".commitlintrc.json",".commitlintrc.yml",".commitlintrc.yaml"]),N60:r=>{const fromScript=checkAny(r,["scripts/check-branch-name.mjs"]);return fromScript.status==="present"?fromScript:fileContains(join(r,"AGENTS.md"),/branch.*convention|branch.*format|branch.*pattern/i)?{status:"partial",evidence:["AGENTS.md"]}:{status:"missing",evidence:[]}},N61:r=>checkAny(r,[".github/pull_request_template.md",".github/PULL_REQUEST_TEMPLATE.md"]),N62:r=>checkDir(r,".github/ISSUE_TEMPLATE"),N63:r=>checkAny(r,["AGENTS.md",".claude/CLAUDE.md"]),N64:r=>checkAny(r,["docs/REFERENCE/ci-developer-reference.md","docs/ci-reference.md","docs/ci-developer-reference.md"]),N65:r=>{const fromDirLower=checkDir(r,"docs/adr");if(fromDirLower.status==="present")return fromDirLower;const fromDirUpper=checkDir(r,"docs/ADR");return fromDirUpper.status==="present"?fromDirUpper:checkAny(r,["docs/SYSTEM/DECISIONS.md"])},N66:r=>checkAny(r,["openapi.yaml","openapi.json","swagger.yaml","swagger.json","api-spec.yaml","api-spec.json"]),N67:r=>{const fromDir=checkDir(r,"docs/runbooks");return fromDir.status==="present"?fromDir:checkAny(r,["RUNBOOK.md","docs/runbook.md","docs/RUNBOOK.md"])},N68:r=>checkAny(r,["docs/METHOD/KNOWLEDGE_MAP.md","scripts/check-knowledge-map.mjs"]),N69:r=>checkAny(r,[".nvmrc",".node-version",".tool-versions"]),N70:r=>{const abs=join(r,".env.example");if(existsSync(abs))return{status:"present",evidence:[".env.example"]};let entries;try{entries=readdirSync(r)}catch{return{status:"missing",evidence:[]}}const found=entries.filter(f=>f.startsWith(".env")&&f.includes("example"));return found.length>0?{status:"present",evidence:found.slice(0,EVIDENCE_CAP)}:{status:"missing",evidence:[]}},N71:r=>checkAny(r,["src/experimental/registry.ts","src/feature-flags.ts"]),N72:r=>checkAny(r,["docker-compose.staging.yml","docker-compose.staging.yaml","config/dev","config/prod"]),N76:r=>{const pkg=readPkgJson(r);return hasDep(pkg,"axe-core")||hasDep(pkg,"@axe-core/playwright")||hasDep(pkg,"pa11y")||hasDep(pkg,"pa11y-ci")?{status:"present",evidence:["package.json"]}:checkAny(r,[".lighthouserc.js",".lighthouserc.json",".lighthouserc.yml"])},N77:r=>{if(!(fileContains(join(r,"pom.xml"),"spring-modulith")||fileContains(join(r,"build.gradle"),"spring-modulith")))return{status:"missing",evidence:[]};const src=fileContains(join(r,"pom.xml"),"spring-modulith")?"pom.xml":"build.gradle",verifyFiles=findRecursive(join(r,"src","test"),n=>n.endsWith(".java")).filter(abs=>fileContains(abs,"ApplicationModules"));return verifyFiles.length>0?{status:"present",evidence:[src,...verifyFiles.map(a=>toPosixRelative(r,a))].slice(0,EVIDENCE_CAP)}:{status:"present",evidence:[src]}},N78:r=>{const fromGuide=checkAny(r,["docs/GOVERNANCE/RESILIENCE.md"]);if(fromGuide.status==="present")return fromGuide;const pkg=readPkgJson(r);return hasDep(pkg,"cockatiel")||hasDep(pkg,"opossum")?{status:"present",evidence:["package.json"]}:fileContains(join(r,"pom.xml"),"resilience4j")||fileContains(join(r,"build.gradle"),"resilience4j")?{status:"present",evidence:[fileContains(join(r,"pom.xml"),"resilience4j")?"pom.xml":"build.gradle"]}:fileContains(join(r,"requirements.txt"),"tenacity")?{status:"present",evidence:["requirements.txt"]}:{status:"missing",evidence:[]}}};export function measureDim(dim,repoRoot){if(!existsSync(repoRoot))return{status:"missing",evidence:[]};try{const handler=DIM_HANDLERS[dim.id];if(!handler)return{status:"missing",evidence:[]};const raw=handler(repoRoot),evidence=Array.from(new Set(raw.evidence)).sort();return{status:raw.status,evidence}}catch(err){return diagnosticErrors++,process.stderr.write(`[measure] measureDim failed for ${dim.id}: ${String(err)}
|
|
5
|
+
`),{status:"missing",evidence:[]}}}export function getMeasureDiagnosticErrors(){return diagnosticErrors}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
export function scanForRedactedTokens(text,lexicon){const matches=[],lines=text.split(`
|
|
3
|
+
`);for(let i=0;i<lines.length;i++){const lineContent=lines[i]??"";for(const entry of lexicon)lineContent.includes(entry.token)&&(entry.allowContext!==void 0&&lineContent.includes(entry.allowContext)||matches.push({token:entry.token,line:i+1,lineContent}))}return matches}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{z}from"zod";import{VALID_TML,VALID_GATES,VALID_STACKS}from"./taxonomy.js";export{VALID_STACKS}from"./taxonomy.js";const reasonSchema=z.string().min(40,"reason must be at least 40 characters"),KitOverlayCellSchema=z.discriminatedUnion("kind",[z.object({kind:z.literal("tool"),tool:z.string().min(1),matrixCategory:z.string().min(1)}),z.object({kind:z.literal("equivalent"),arbiterSlot:z.string().min(1),reason:reasonSchema}),z.object({kind:z.literal("na-by-archetype"),archetypes:z.array(z.string()).min(1),reason:reasonSchema}),z.object({kind:z.literal("na-by-paradigm"),reason:reasonSchema}),z.object({kind:z.literal("gap"),suggestedTool:z.string().optional(),suggestedGenerator:z.string().optional(),followupIssue:z.number().int().positive().optional(),reason:reasonSchema}).refine(v=>v.suggestedTool!==void 0||v.suggestedGenerator!==void 0||v.followupIssue!==void 0,{message:"gap cell must have at least one of: suggestedTool, suggestedGenerator, followupIssue"})]),DerivedCellSchema=z.union([KitOverlayCellSchema,z.object({kind:z.literal("gap")})]),KitDimensionSchema=z.object({id:z.string().regex(/^N(0[1-9]|[1-6]\d|7[0-8])$/,"id must be N01..N78"),name:z.string().min(1),tml:z.enum(VALID_TML),gate:z.enum(VALID_GATES),categoryRef:z.string().min(1),archetypeGating:z.object({applies:z.array(z.string()),excludes:z.array(z.string())}),conditionalFlag:z.string().optional(),invLink:z.string().optional(),generatorLink:z.string().optional(),kitThreshold:z.number().optional(),arbiterThreshold:z.number().optional(),requiresDbEngine:z.array(z.string()).optional(),status:z.enum(["covered","partial","missing-tracked","missing"]),followupIssue:z.number().int().positive().optional(),note:z.string().optional()});export const KitCatalogSchema=z.array(KitDimensionSchema);const DerivedKitDimSchema=KitDimensionSchema.extend({perStack:z.record(z.enum(VALID_STACKS),DerivedCellSchema)});export const DerivedKitSchema=z.array(DerivedKitDimSchema);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brownfield class: characterizes how mature a repository is.
|
|
3
|
+
* Determines which column of the threshold matrix to apply for existing code.
|
|
4
|
+
* New code always uses the `new_code` column (gold-grade), regardless of class.
|
|
5
|
+
*
|
|
6
|
+
* Classification heuristics (from brownfield-detect.ts):
|
|
7
|
+
* gold → greenfield or already-mature repo (< 50 source files)
|
|
8
|
+
* light → 50–500 source files, coverage > 30 %
|
|
9
|
+
* medium → 500–2 000 source files, coverage 5–30 %
|
|
10
|
+
* heavy → 2 000+ source files, coverage < 5 %
|
|
11
|
+
*/
|
|
12
|
+
export type BrownfieldClass = 'gold' | 'light' | 'medium' | 'heavy';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const WAVE_GOALS={W0:cls=>`Bootstrap \u2014 confirm existing coverage (brownfield: ${cls})`,W1:cls=>`Enforcement \u2014 close partial gaps (brownfield: ${cls})`,W2:()=>"Advanced \u2014 implement missing tooling",W3:()=>"Gold \u2014 achieve full quality-gate parity"};export function buildWavePlan(assessments,brownfieldClass){const applicable=assessments.filter(a=>(a.applicability??"applicable")!=="na"),byStatus={Y:[],P:[],N:[],NA:[]};for(const a of applicable)byStatus[a.status].push(a);const toEntries=list=>list.map(({dimId,status,category})=>({dimId,status,category})),waves=[{label:"W0",goal:WAVE_GOALS.W0(brownfieldClass),dimensions:toEntries(byStatus.Y)},{label:"W1",goal:WAVE_GOALS.W1(brownfieldClass),dimensions:toEntries(byStatus.P)},{label:"W2",goal:WAVE_GOALS.W2(brownfieldClass),dimensions:toEntries(byStatus.N)},{label:"W3",goal:WAVE_GOALS.W3(brownfieldClass),dimensions:[]}],totalDims=waves.reduce((s,w)=>s+w.dimensions.length,0),byWave={};for(const w of waves)byWave[w.label]=w.dimensions.length;return{brownfieldClass,waves,summary:{totalDims,byWave}}}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{statSync}from"node:fs";import{createHash}from"node:crypto";import{RecipeSchema}from"./schema.js";import{readFileTranslated}from"../utils/fs.js";const MAX_BYTES=256*1024;export async function loadRecipe(source,opts={}){if(source.startsWith("http://"))throw new Error(`Recipe URL must use https:// \u2014 plain http:// is not allowed (supply-chain risk). Got: ${source}`);const raw=source.startsWith("https://")?await fetchRecipe(source):readLocalRecipe(source);if(opts.sha256){const actual=createHash("sha256").update(raw).digest("hex");if(actual!==opts.sha256)throw new Error(`Recipe sha256 checksum mismatch.
|
|
3
|
+
expected: ${opts.sha256}
|
|
4
|
+
actual: ${actual}`)}let parsed;try{parsed=JSON.parse(raw.toString("utf-8"))}catch(err){const msg=err instanceof Error?err.message:String(err);throw new Error(`Recipe JSON parse error: ${msg}`,{cause:err})}const result=RecipeSchema.safeParse(parsed);if(!result.success){const issues=result.error.issues.map(i=>` ${i.path.join(".")}: ${i.message}`).join(`
|
|
5
|
+
`);throw new Error(`Recipe validation failed:
|
|
6
|
+
${issues}`)}return result.data}function readLocalRecipe(source){const filePath=source.startsWith("file://")?new URL(source).pathname:source,stat=statSync(filePath);if(stat.size>MAX_BYTES)throw new Error(`Recipe file size ${stat.size} bytes exceeds limit of ${MAX_BYTES} bytes (256 KB). Reduce the recipe file size.`);return readFileTranslated(filePath)}function assertResponseOk(response,url){if(response.status>=300&&response.status<400)throw new Error(`Recipe URL was redirected \u2014 supply the final HTTPS URL directly. Got redirect from: ${url}`);if(!response.ok)throw new Error(`Recipe fetch returned HTTP ${response.status}: ${url}`)}function wrapFetchError(err){if(err instanceof Error&&err.message.startsWith("Recipe"))throw err;const msg=err instanceof Error?err.message:String(err);throw new Error(`Recipe fetch failed: ${msg}`,{cause:err})}async function fetchRecipe(url){const controller=new AbortController,timeout=setTimeout(()=>{controller.abort()},1e4);try{const response=await fetch(url,{signal:controller.signal,redirect:"manual"});assertResponseOk(response,url);const contentLength=response.headers.get("content-length");if(contentLength!==null&&parseInt(contentLength,10)>MAX_BYTES)throw new Error(`Recipe response Content-Length ${contentLength} bytes exceeds limit of ${MAX_BYTES} bytes (256 KB).`);const buf=Buffer.from(await response.arrayBuffer());if(buf.length>MAX_BYTES)throw new Error(`Recipe response body size ${buf.length} bytes exceeds limit of ${MAX_BYTES} bytes (256 KB).`);return buf}catch(err){wrapFetchError(err)}finally{clearTimeout(timeout)}}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{z}from"zod";const AiToolSchema=z.enum(["claude","codex"]),GovernanceLevelSchema=z.enum(["L1","L2","L3","L4"]),LanguageSchema=z.enum(["typescript","java","kotlin","rust","python","go","multi"]),ArchetypeSchema=z.enum(["backend-web-db","cli","library","data-pipeline","frontend-spa","embedded"]),ArchitectureStyleSchema=z.enum(["hexagonal","layered","modular-monolith","none"]),DatabaseEngineSchema=z.enum(["postgresql","mysql","mongodb","sqlite","other","none"]),ContractTypeSchema=z.enum(["rest-owned","rest-public","graphql","grpc","message-queue","none"]),LaneSchema=z.enum(["frontend","backend","docs"]),DecompositionBackendSchema=z.enum(["github","markdown"]);export const RecipeSchema=z.object({tools:z.array(AiToolSchema).min(1).optional(),governanceLevel:GovernanceLevelSchema.optional(),language:LanguageSchema.optional(),framework:z.string().nullable().optional(),archetype:ArchetypeSchema.optional(),architectureStyle:ArchitectureStyleSchema.optional(),useGitHub:z.boolean().optional(),isMultiTenant:z.boolean().optional(),hasDatabase:z.boolean().optional(),hasPublicApi:z.boolean().optional(),databaseEngine:DatabaseEngineSchema.optional(),contractType:ContractTypeSchema.optional(),lanes:z.array(LaneSchema).optional(),evidenceHarness:z.boolean().optional(),decomposition:z.object({backend:DecompositionBackendSchema}).optional(),enableDebtGates:z.boolean().optional(),enableSuppressions:z.boolean().optional(),enableSecurityScanning:z.boolean().optional(),enableMutationTesting:z.boolean().optional(),enableContractTesting:z.boolean().optional(),enableSoloDevMode:z.boolean().optional(),enableMcpFallback:z.boolean().optional(),enableNoSkippedTests:z.boolean().optional(),enableAuditToolchain:z.boolean().optional(),enableFiveLaneCi:z.boolean().optional(),enableCodeownersNotify:z.boolean().optional(),enableTaxonomy25d:z.boolean().optional(),enablePerfTesting:z.boolean().optional(),enableRiskRegister:z.boolean().optional(),enableOperationsHandbook:z.boolean().optional(),enableIso27001Mapping:z.boolean().optional(),enableNis2Mapping:z.boolean().optional(),enableGdprMapping:z.boolean().optional(),automation:z.object({autonomy:z.enum(["L0","L1","L2","L3"]),maxParallelWorktrees:z.number().int().positive().optional(),defaultGateLevel:z.enum(["L1","L2"]).optional()}).strict().optional()});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
export const UNCLASSIFIED_LEVEL="R-unknown";const RULES={typescript:[{pattern:/(^|\/)migrations?\//i,level:"R0"},{pattern:/\.sql$/i,level:"R0"},{pattern:/(^|\/)auth\//i,level:"R1"},{pattern:/(^|\/)payment(s)?\//i,level:"R1"},{pattern:/(^|\/)api\//i,level:"R2"},{pattern:/(^|\/)server\//i,level:"R2"},{pattern:/(^|\/)components?\//i,level:"R3"},{pattern:/(^|\/)pages?\//i,level:"R3"},{pattern:/\.md$/i,level:"R4"},{pattern:/(^|\/)docs?\//i,level:"R4"},{pattern:/(^|\/)__tests__\//,level:"R4"}],python:[{pattern:/(^|\/)alembic\/versions\//i,level:"R0"},{pattern:/(^|\/)migrations?\//i,level:"R0"},{pattern:/(^|\/)auth\//i,level:"R1"},{pattern:/(^|\/)api\//i,level:"R2"},{pattern:/(^|\/)tests?\//i,level:"R4"},{pattern:/\.md$/i,level:"R4"}],rust:[{pattern:/unsafe/i,level:"R0"},{pattern:/(^|\/)migrations?\//i,level:"R0"},{pattern:/\.rs$/i,level:"R2"},{pattern:/\.md$/i,level:"R4"}],java:[{pattern:/(^|\/)migration(s)?\/.*\.sql$/i,level:"R0"},{pattern:/(^|\/)security\//i,level:"R1"},{pattern:/\.md$/i,level:"R4"}],go:[{pattern:/(^|\/)migrations?\//i,level:"R0"},{pattern:/(^|\/)auth\//i,level:"R1"},{pattern:/\.go$/i,level:"R2"},{pattern:/\.md$/i,level:"R4"}]};export function classifyPath(path,stack){try{if(typeof path!="string"||path.trim()==="")return UNCLASSIFIED_LEVEL;const rules=RULES[stack];if(!rules)return UNCLASSIFIED_LEVEL;const norm=path.replace(/\\/g,"/");for(const rule of rules)if(rule.pattern.test(norm))return rule.level;return UNCLASSIFIED_LEVEL}catch{return UNCLASSIFIED_LEVEL}}const RISK_ORDER=["R0","R1","R2","R3","R4"];export function highestRisk(levels){if(levels.length===0)return UNCLASSIFIED_LEVEL;let best=null;for(const l of levels){if(l===UNCLASSIFIED_LEVEL)return UNCLASSIFIED_LEVEL;(best===null||RISK_ORDER.indexOf(l)<RISK_ORDER.indexOf(best))&&(best=l)}return best??UNCLASSIFIED_LEVEL}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{createHash}from"node:crypto";function canonicalise(value){if(Array.isArray(value))return value.map(canonicalise);if(value!==null&&typeof value=="object"){const obj=value,sortedKeys=Object.keys(obj).sort(),out={};for(const k of sortedKeys)out[k]=canonicalise(obj[k]);return out}return value}export function computeSummarySha(body){const{sha:_ignored,...rest}=body,canonical=JSON.stringify(canonicalise(rest));return createHash("sha256").update(canonical).digest("hex")}export function verifySummarySha(body){const stored=body.sha;if(typeof stored!="string")return{ok:!1,reason:"missing or non-string sha field"};const expected=computeSummarySha(body);return expected!==stored?{ok:!1,expected,actual:stored,reason:"sha mismatch"}:{ok:!0,expected,actual:stored}}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{existsSync,readdirSync,statSync}from"node:fs";import{copyFileTranslated,unlinkTranslated}from"../utils/fs.js";import{basename,dirname,join}from"node:path";export const DEFAULT_BACKUP_CAP=10;function isoTimestamp(){return new Date().toISOString().replace(/[:.]/g,"-")}function backupSuffix(path){const base=basename(path).replace(/[.+*?^$()[\]{}|\\]/g,"\\$&");return new RegExp(`^${base}\\.bak\\.`)}export function listBackups(path){const dir=dirname(path);if(!existsSync(dir))return[];const re=backupSuffix(path);return readdirSync(dir).filter(f=>re.test(f)).map(f=>join(dir,f)).sort((a,b)=>statSync(a).mtimeMs-statSync(b).mtimeMs)}export function rotateBackup(path,opts={}){const cap=opts.cap??DEFAULT_BACKUP_CAP;if(!existsSync(path))return null;const backupPath=`${path}.bak.${isoTimestamp()}`;copyFileTranslated(path,backupPath);const all=listBackups(path);if(all.length>cap){const overflow=all.slice(0,all.length-cap);for(const old of overflow)try{unlinkTranslated(old)}catch{}}return backupPath}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{createHash}from"node:crypto";export const CURRENT_SNAPSHOT_VERSION=1;export function canonicalJson(value){return JSON.stringify(value,sortedReplacer,2)}function sortedReplacer(_key,value){if(value!==null&&typeof value=="object"&&!Array.isArray(value)){const entries=Object.entries(value).sort(([a],[b])=>a<b?-1:a>b?1:0);return Object.fromEntries(entries)}return value}export function computeChecksum(envelope){return createHash("sha256").update(canonicalJson(envelope)).digest("hex")}export function wrapSnapshot(config){const envelope={$schemaVersion:CURRENT_SNAPSHOT_VERSION,config};return{".checksum":computeChecksum(envelope),...envelope}}export class SnapshotChecksumError extends Error{expected;actual;constructor(expected,actual){super(`snapshot checksum mismatch: expected ${expected.slice(0,12)}\u2026, got ${actual.slice(0,12)}\u2026. Run \`arbiter doctor --repair-state\` to re-derive from arbiter.json.`),this.name="SnapshotChecksumError",this.expected=expected,this.actual=actual}}export class SnapshotShapeError extends Error{constructor(message){super(message),this.name="SnapshotShapeError"}}function isRecord(v){return typeof v=="object"&&v!==null&&!Array.isArray(v)}export function unwrapSnapshot(raw){if(!isRecord(raw))throw new SnapshotShapeError("snapshot is not a JSON object");const checksum=raw[".checksum"],version=raw.$schemaVersion,config=raw.config;if(typeof checksum!="string")throw new SnapshotShapeError('snapshot missing ".checksum" string');if(typeof version!="number")throw new SnapshotShapeError('snapshot missing "$schemaVersion" number');if(config===void 0)throw new SnapshotShapeError('snapshot missing "config" payload');const envelope={$schemaVersion:version,config},actual=computeChecksum(envelope);if(actual!==checksum)throw new SnapshotChecksumError(checksum,actual);return{envelope,checksum}}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
import{existsSync}from"node:fs";export{manifestKey}from"./manifest-key.js";import{ensureDir,renameTranslated,unlinkTranslated,writeFileTranslated,readFileTranslated}from"../utils/fs.js";import{join,dirname}from"node:path";import{randomBytes}from"node:crypto";import{FatalError}from"../utils/errors.js";export const GENERATED_MANIFEST_FILE=".arbiter-generated-manifest.json";const CURRENT_MANIFEST_VERSION=1;export function loadGeneratedManifest(dir){const path=join(dir,GENERATED_MANIFEST_FILE);if(!existsSync(path))return{};const raw=readFileTranslated(path,"utf-8");let parsed;try{parsed=JSON.parse(raw)}catch(err){throw new FatalError("E_MANIFEST_CORRUPT",`${GENERATED_MANIFEST_FILE} is present but unparseable (${err instanceof Error?err.message:String(err)}). Refusing to treat a corrupt manifest as empty (would silently withhold template fixes). Fix the JSON or delete the file to re-baseline on the next \`arbiter update\`.`)}if(!isManifestShape(parsed))throw new FatalError("E_MANIFEST_SHAPE",`${GENERATED_MANIFEST_FILE} has an invalid shape or unsupported $schemaVersion (expected { "$schemaVersion": ${CURRENT_MANIFEST_VERSION}, "files": { <path>: <sha256> } }). Fix or delete the file to re-baseline on the next \`arbiter update\`.`);return parsed.files}export function loadUnwiredGuards(dir){const path=join(dir,GENERATED_MANIFEST_FILE);if(!existsSync(path))return[];const raw=readFileTranslated(path,"utf-8");let parsed;try{parsed=JSON.parse(raw)}catch(err){throw new FatalError("E_MANIFEST_CORRUPT",`${GENERATED_MANIFEST_FILE} is present but unparseable (${err instanceof Error?err.message:String(err)}).`)}if(!isManifestShape(parsed))throw new FatalError("E_MANIFEST_SHAPE",`${GENERATED_MANIFEST_FILE} has an invalid shape or unsupported $schemaVersion.`);return parsed.unwiredGuards??[]}export function loadWithheldSafety(dir){const path=join(dir,GENERATED_MANIFEST_FILE);if(!existsSync(path))return[];const raw=readFileTranslated(path,"utf-8");let parsed;try{parsed=JSON.parse(raw)}catch(err){throw new FatalError("E_MANIFEST_CORRUPT",`${GENERATED_MANIFEST_FILE} is present but unparseable (${err instanceof Error?err.message:String(err)}).`)}if(!isManifestShape(parsed))throw new FatalError("E_MANIFEST_SHAPE",`${GENERATED_MANIFEST_FILE} has an invalid shape or unsupported $schemaVersion.`);return parsed.withheldSafety??[]}function isManifestShape(v){if(typeof v!="object"||v===null)return!1;const obj=v;if(obj.$schemaVersion!==CURRENT_MANIFEST_VERSION)return!1;const files=obj.files;if(typeof files!="object"||files===null||Array.isArray(files)||!Object.values(files).every(h=>typeof h=="string"))return!1;const unwired=obj.unwiredGuards;if(unwired!==void 0&&(!Array.isArray(unwired)||!unwired.every(s=>typeof s=="string")))return!1;const withheldSafety=obj.withheldSafety;return!(withheldSafety!==void 0&&(!Array.isArray(withheldSafety)||!withheldSafety.every(s=>typeof s=="string")))}export function saveGeneratedManifest(dir,files,unwiredGuards=[],withheldSafety=[]){const path=join(dir,GENERATED_MANIFEST_FILE),sorted=Object.fromEntries(Object.entries(files).sort(([a],[b])=>a<b?-1:a>b?1:0)),envelope={$schemaVersion:CURRENT_MANIFEST_VERSION,files:sorted};unwiredGuards.length>0&&(envelope.unwiredGuards=[...new Set(unwiredGuards)].sort((a,b)=>a<b?-1:a>b?1:0)),withheldSafety.length>0&&(envelope.withheldSafety=[...new Set(withheldSafety)].sort((a,b)=>a<b?-1:a>b?1:0));const body=JSON.stringify(envelope,null,2)+`
|
|
3
|
+
`;ensureDir(dirname(path));const tmp=`${path}.arbiter-tmp-${randomBytes(4).toString("hex")}`;try{writeFileTranslated(tmp,body),renameTranslated(tmp,path)}catch(err){try{unlinkTranslated(tmp)}catch{}throw err}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{migrateV0ToV1}from"./v0-to-v1.js";function isRecord(v){return typeof v=="object"&&v!==null&&!Array.isArray(v)}function looksLikeEnvelope(raw){return typeof raw.$schemaVersion=="number"&&"config"in raw}export function migrateState(raw){if(!isRecord(raw))throw new Error("snapshot must be a non-null JSON object");if(looksLikeEnvelope(raw)){const version=raw.$schemaVersion;if(version!==1)throw new Error(`unsupported snapshot $schemaVersion=${String(version)} (max supported: 1)`);return{envelope:{$schemaVersion:1,config:raw.config},migrated:!1}}return{envelope:migrateV0ToV1(raw),migrated:!0}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%- nodeVersion %>
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Handoff: {{TOPIC}}
|
|
2
|
+
|
|
3
|
+
**Date:** {{DATE}} · **Author:** _fill in — model + session that authored this_
|
|
4
|
+
**Source truth:** _fill in — path(s) to the evidence this handoff summarizes (audit report, plan doc, ADR, commit range)_
|
|
5
|
+
**Executor:** any competent model. Name a stronger tier per-task below only where a task genuinely requires judgment, not execution.
|
|
6
|
+
**Prime directive:** this file is memory for a COLD model with zero prior context. It must be executable without re-derivation — every task below carries its own AC and verification command.
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Context
|
|
11
|
+
|
|
12
|
+
_Fill in — 2-4 sentences: what was found, why it matters, and the evidence backing the claim (link a commit, issue, or report; do not just assert)._
|
|
13
|
+
|
|
14
|
+
## Evidence pointers
|
|
15
|
+
|
|
16
|
+
- _path/URL to primary evidence #1_
|
|
17
|
+
- _path/URL to primary evidence #2_
|
|
18
|
+
|
|
19
|
+
## Tasks (execute in strict order — each depends on the previous landing)
|
|
20
|
+
|
|
21
|
+
### 1. _Atomic task title_
|
|
22
|
+
|
|
23
|
+
- **What:** _one concrete paragraph — no "and also consider" scope creep._
|
|
24
|
+
- **Where:** _files/dirs touched._
|
|
25
|
+
- **AC:** _observable, falsifiable acceptance criterion._
|
|
26
|
+
- **Verify:** `<exact command that proves the AC — test run, build, or script>`
|
|
27
|
+
- **Suggested tier:** cheap (execution) — bump to expensive only if this task is root-cause/architecture judgment, not execution.
|
|
28
|
+
|
|
29
|
+
### 2. _Next atomic task title_
|
|
30
|
+
|
|
31
|
+
- **What:** …
|
|
32
|
+
- **Where:** …
|
|
33
|
+
- **AC:** …
|
|
34
|
+
- **Verify:** `…`
|
|
35
|
+
- **Suggested tier:** …
|
|
36
|
+
|
|
37
|
+
_(repeat one numbered section per atomic task; keep them small enough that a cold model can finish one per turn)_
|
|
38
|
+
|
|
39
|
+
## Non-goals
|
|
40
|
+
|
|
41
|
+
_Fill in — what this handoff explicitly excludes, so the executing model does not scope-creep into adjacent work._
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
_Model-pyramid note (see AGENTS.md, "Model-Pyramid: 90/10 Guidance"): most tasks above should need only a cheap model executing this plan as written. If an expensive model ends up doing more than a judgment call on one of them, the task description was under-specified — fix the task, not the model tier._
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import supertest from "supertest";
|
|
3
|
+
import express from "express";
|
|
4
|
+
import { correlationIdMiddleware } from "../../src/middleware/correlation-id.js";
|
|
5
|
+
import { errorHandler, AppError } from "../../src/middleware/error-handler.js";
|
|
6
|
+
|
|
7
|
+
const app = express();
|
|
8
|
+
app.use(correlationIdMiddleware);
|
|
9
|
+
app.get("/error", (_req, _res, next) => {
|
|
10
|
+
next(new AppError(422, "Validation Error", "field 'email' is required"));
|
|
11
|
+
});
|
|
12
|
+
app.get("/unknown-error", (_req, _res, next) => {
|
|
13
|
+
next(new Error("something unexpected"));
|
|
14
|
+
});
|
|
15
|
+
app.use(errorHandler);
|
|
16
|
+
|
|
17
|
+
describe("RFC 7807 error shape contract", () => {
|
|
18
|
+
it("AppError produces problem+json with correct shape", async () => {
|
|
19
|
+
const res = await supertest(app).get("/error");
|
|
20
|
+
expect(res.status).toBe(422);
|
|
21
|
+
expect(res.headers["content-type"]).toMatch(/application\/problem\+json/);
|
|
22
|
+
const body = res.body as Record<string, unknown>;
|
|
23
|
+
expect(body).toHaveProperty("type");
|
|
24
|
+
expect(body).toHaveProperty("title");
|
|
25
|
+
expect(body).toHaveProperty("status", 422);
|
|
26
|
+
expect(body).toHaveProperty("correlationId");
|
|
27
|
+
expect(body).not.toHaveProperty("stack");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("unknown error produces 500 with problem+json shape", async () => {
|
|
31
|
+
const res = await supertest(app).get("/unknown-error");
|
|
32
|
+
expect(res.status).toBe(500);
|
|
33
|
+
const body = res.body as Record<string, unknown>;
|
|
34
|
+
expect(body).toHaveProperty("status", 500);
|
|
35
|
+
expect(body).toHaveProperty("correlationId");
|
|
36
|
+
expect(body).not.toHaveProperty("stack");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("correlationId echoed in response header", async () => {
|
|
40
|
+
const res = await supertest(app)
|
|
41
|
+
.get("/error")
|
|
42
|
+
.set("X-Correlation-ID", "test-id-123");
|
|
43
|
+
expect(res.headers["x-correlation-id"]).toBe("test-id-123");
|
|
44
|
+
const body = res.body as Record<string, unknown>;
|
|
45
|
+
expect(body["correlationId"]).toBe("test-id-123");
|
|
46
|
+
});
|
|
47
|
+
});
|