@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,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// scripts/check-doc-set.mjs — generated by arbiter (#1428).
|
|
4
|
+
// Doc-set presence audit runner for this project.
|
|
5
|
+
// Delegates to the root-local `arbiter doc-set` CLI (no `yaml` dep —
|
|
6
|
+
// the engine runs inside arbiter's own environment against this repo).
|
|
7
|
+
//
|
|
8
|
+
// Usage: node scripts/check-doc-set.mjs [--check] [--strict] [--json] [--generate] [--help]
|
|
9
|
+
//
|
|
10
|
+
// Exit codes (INV-53): 0=PASS/advisory, 1=FAIL (missing mandatory under --strict), 2=ERROR.
|
|
11
|
+
// When invoked by check-all.mjs (advisory, L2) the exit code is informational; the
|
|
12
|
+
// gate never hard-fails on the doc-set result alone. Plain --check runs the engine in its
|
|
13
|
+
// default advisory mode and exits 0 (no day-1 redness); the strict hard guard is opt-in.
|
|
14
|
+
import { runLocalArbiter } from './lib/run-helpers.mjs'
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2)
|
|
17
|
+
|
|
18
|
+
process.exit(runLocalArbiter(['doc-set', ...args]))
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// <%= projectName %> — Docs gate: if src/ or __tests__/ changed since the merge-base with origin/main,
|
|
3
|
+
// docs/ or README.md must also change.
|
|
4
|
+
//
|
|
5
|
+
// Rebased-aware: uses `git merge-base HEAD origin/main` so a rebased branch only sees its own
|
|
6
|
+
// commits (not main commits replayed underneath). Falls back to `origin/main` then `main` if the
|
|
7
|
+
// remote ref is missing locally.
|
|
8
|
+
//
|
|
9
|
+
// Bypass: any commit message in the diff range containing `[skip-docs]` causes the gate to PASS.
|
|
10
|
+
// This mirrors the CI `docs-check` job so the gate fires identically pre-push.
|
|
11
|
+
import { spawnSync } from 'node:child_process';
|
|
12
|
+
|
|
13
|
+
const BYPASS_TOKEN = '[skip-docs]';
|
|
14
|
+
const TRIGGER_PREFIXES = ['src/', '__tests__/'];
|
|
15
|
+
const DOC_PREFIXES = ['docs/'];
|
|
16
|
+
const DOC_FILES = new Set(['README.md']);
|
|
17
|
+
|
|
18
|
+
function git(args) {
|
|
19
|
+
const r = spawnSync('git', args, { encoding: 'utf-8' });
|
|
20
|
+
return { status: r.status ?? 1, stdout: (r.stdout ?? '').trim(), stderr: (r.stderr ?? '').trim() };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function resolveBase() {
|
|
24
|
+
// Prefer the merge-base with origin/main (rebased-aware). Fall back to plain refs.
|
|
25
|
+
for (const ref of ['origin/main', 'main']) {
|
|
26
|
+
const verify = git(['rev-parse', '--verify', '--quiet', ref]);
|
|
27
|
+
if (verify.status === 0 && verify.stdout) {
|
|
28
|
+
const mb = git(['merge-base', 'HEAD', ref]);
|
|
29
|
+
if (mb.status === 0 && mb.stdout) return mb.stdout;
|
|
30
|
+
return ref;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
// No base available — treat all of HEAD as the diff (single-branch repo).
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const base = resolveBase();
|
|
38
|
+
const diffRange = base ? `${base}..HEAD` : null;
|
|
39
|
+
|
|
40
|
+
const diff = diffRange ? git(['diff', '--name-only', diffRange]) : { status: 0, stdout: '', stderr: '' };
|
|
41
|
+
if (diff.status !== 0) {
|
|
42
|
+
console.error('git diff failed:', diff.stderr);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const staged = git(['diff', '--name-only', '--cached']);
|
|
46
|
+
const changed = new Set(
|
|
47
|
+
[...diff.stdout.split('\n'), ...staged.stdout.split('\n')].map((s) => s.trim()).filter(Boolean),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
const hasCode = [...changed].some((f) => TRIGGER_PREFIXES.some((p) => f.startsWith(p)));
|
|
51
|
+
const hasDocs = [...changed].some(
|
|
52
|
+
(f) => DOC_PREFIXES.some((p) => f.startsWith(p)) || DOC_FILES.has(f),
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
// Bypass check: scan commit subjects+bodies in the diff range for BYPASS_TOKEN.
|
|
56
|
+
let bypassed = false;
|
|
57
|
+
if (diffRange) {
|
|
58
|
+
const log = git(['log', '--format=%B', diffRange]);
|
|
59
|
+
if (log.status === 0 && log.stdout.includes(BYPASS_TOKEN)) bypassed = true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (hasCode && !hasDocs && !bypassed) {
|
|
63
|
+
console.error('Code changed without documentation update.');
|
|
64
|
+
console.error('Files changed in src/ or __tests__/:');
|
|
65
|
+
for (const f of changed) {
|
|
66
|
+
if (TRIGGER_PREFIXES.some((p) => f.startsWith(p))) console.error(' ' + f);
|
|
67
|
+
}
|
|
68
|
+
console.error(`Update docs/ or README.md, or add "${BYPASS_TOKEN}" to a commit message to bypass.`);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
console.log('Docs check passed.');
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// <%= projectName %> — domain<->API surface-completeness gate (INV-125)
|
|
4
|
+
// Generated by arbiter (src/templates/scripts/check-domain-api-surface.mjs.ejs)
|
|
5
|
+
//
|
|
6
|
+
// CATALOG: INV-125 enforcement. Reads domain-api-surface.json at repo root; fails when a
|
|
7
|
+
// CATALOG: persisted domain field is absent from both request and response schemas.
|
|
8
|
+
// CATALOG: SKIP when manifest absent (non-governed projects never false-fail).
|
|
9
|
+
//
|
|
10
|
+
// Exit codes per INV-53: 0=PASS/SKIP, 1=surface gap, 2=schema/parse error
|
|
11
|
+
import { readFileSync, existsSync } from 'node:fs'
|
|
12
|
+
import { join, resolve } from 'node:path'
|
|
13
|
+
|
|
14
|
+
const MANIFEST_FILENAME = 'domain-api-surface.json'
|
|
15
|
+
const EXPECTED_SCHEMA = 'arbiter-domain-api-surface-v1'
|
|
16
|
+
|
|
17
|
+
const repoRoot = process.env.REPO_ROOT ?? resolve('.')
|
|
18
|
+
const manifestPath = join(repoRoot, MANIFEST_FILENAME)
|
|
19
|
+
|
|
20
|
+
if (!existsSync(manifestPath)) {
|
|
21
|
+
console.log(`[domain-api-surface] SKIP — manifest absent (${MANIFEST_FILENAME} not found)`)
|
|
22
|
+
// #2052: recognized marker so runCheck surfaces SKIP, not PASS, in the gate summary.
|
|
23
|
+
console.log(`[SKIP] manifest absent (${MANIFEST_FILENAME} not found)`)
|
|
24
|
+
process.exit(0)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let manifest
|
|
28
|
+
try {
|
|
29
|
+
manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
|
|
30
|
+
} catch (err) {
|
|
31
|
+
console.error(`[domain-api-surface] ERROR — cannot parse ${MANIFEST_FILENAME}: ${err.message}`)
|
|
32
|
+
process.exit(2)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (manifest.schema !== EXPECTED_SCHEMA) {
|
|
36
|
+
console.error(
|
|
37
|
+
`[domain-api-surface] ERROR — unexpected schema ${JSON.stringify(manifest.schema)}, ` +
|
|
38
|
+
`expected "${EXPECTED_SCHEMA}"`,
|
|
39
|
+
)
|
|
40
|
+
process.exit(2)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!Array.isArray(manifest.resources)) {
|
|
44
|
+
console.error(`[domain-api-surface] ERROR — manifest.resources must be an array`)
|
|
45
|
+
process.exit(2)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const gaps = []
|
|
49
|
+
|
|
50
|
+
for (const resource of manifest.resources) {
|
|
51
|
+
const resourceName = resource.resource ?? '(unnamed)'
|
|
52
|
+
if (!Array.isArray(resource.domainFields)) continue
|
|
53
|
+
|
|
54
|
+
for (const field of resource.domainFields) {
|
|
55
|
+
if (field.persisted === true && !field.inRequestSchema && !field.inResponseSchema) {
|
|
56
|
+
gaps.push({ resource: resourceName, field: field.name ?? '(unnamed)' })
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (gaps.length > 0) {
|
|
62
|
+
console.error(
|
|
63
|
+
`[domain-api-surface] FAIL — ${gaps.length} persisted field(s) unreachable through HTTP API:`,
|
|
64
|
+
)
|
|
65
|
+
for (const g of gaps) {
|
|
66
|
+
console.error(
|
|
67
|
+
` ${g.resource}.${g.field}: persisted=true but absent from request AND response schemas`,
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
console.error(
|
|
71
|
+
'Fix: set inRequestSchema:true or inResponseSchema:true, or set persisted:false if intentionally hidden.',
|
|
72
|
+
)
|
|
73
|
+
process.exit(1)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const checked = manifest.resources.reduce((sum, r) => sum + (r.domainFields?.length ?? 0), 0)
|
|
77
|
+
console.log(
|
|
78
|
+
`[domain-api-surface] PASS — ${checked} field(s) across ${manifest.resources.length} resource(s) all reachable`,
|
|
79
|
+
)
|
|
80
|
+
process.exit(0)
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// <%= projectName %> — generated content drift detector (INV-89)
|
|
3
|
+
// Validates that committed generated files match what the generator would produce.
|
|
4
|
+
// Uses a manifest of generated files with expected content hashes.
|
|
5
|
+
// Exits 0 when no drift found; exits 1 when generated content has drifted.
|
|
6
|
+
// Part of the anti-drift validator family (W6).
|
|
7
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
8
|
+
import { join, resolve } from 'node:path';
|
|
9
|
+
import { createHash } from 'node:crypto';
|
|
10
|
+
import { spawnSync } from 'node:child_process';
|
|
11
|
+
|
|
12
|
+
const args = process.argv.slice(2);
|
|
13
|
+
|
|
14
|
+
// #2044 (AC-2044.5/6): live-SSOT binding — a commit that touches CODE must also
|
|
15
|
+
// update every declared-live SSOT surface (matrix/ledger) in the SAME commit.
|
|
16
|
+
// The obligation is LIMITED to the surfaces declared in .arbiter/live-ssot.json
|
|
17
|
+
// (never every commit); the manifest absent => SKIP. The binding inspects the
|
|
18
|
+
// LAST commit (HEAD vs HEAD^): CI runs the gate against the branch head.
|
|
19
|
+
function runLiveSsotBinding() {
|
|
20
|
+
const LIVE_MANIFEST = join(CWD, '.arbiter', 'live-ssot.json');
|
|
21
|
+
if (!existsSync(LIVE_MANIFEST)) {
|
|
22
|
+
process.stdout.write('[SKIP] no .arbiter/live-ssot.json — no declared-live SSOT surfaces\n');
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
let declaration;
|
|
26
|
+
try {
|
|
27
|
+
declaration = JSON.parse(readFileSync(LIVE_MANIFEST, 'utf-8'));
|
|
28
|
+
} catch (err) {
|
|
29
|
+
process.stderr.write(`check-drift: FAIL — invalid JSON in ${LIVE_MANIFEST}: ${err.message}\n`);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
const surfaces = Array.isArray(declaration?.surfaces) ? declaration.surfaces : [];
|
|
33
|
+
if (surfaces.length === 0) {
|
|
34
|
+
process.stderr.write(`check-drift: FAIL — ${LIVE_MANIFEST} declares no surfaces\n`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const git = spawnSync('git', ['rev-parse', '--verify', 'HEAD^'], { cwd: CWD, encoding: 'utf-8' });
|
|
38
|
+
if (git.status !== 0) {
|
|
39
|
+
// Initial commit (no parent) — nothing to bind yet.
|
|
40
|
+
process.stdout.write('[SKIP] no parent commit — live-SSOT binding needs a commit range\n');
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
const changed = spawnSync('git', ['diff', '--name-only', 'HEAD^', 'HEAD'], {
|
|
44
|
+
cwd: CWD,
|
|
45
|
+
encoding: 'utf-8',
|
|
46
|
+
});
|
|
47
|
+
const changedFiles = (changed.stdout ?? '').split('\n').filter((l) => l.trim() !== '');
|
|
48
|
+
const surfacePaths = surfaces.map((s) => s?.path).filter((p) => typeof p === 'string');
|
|
49
|
+
const touchedSurfaces = changedFiles.filter((f) => surfacePaths.includes(f));
|
|
50
|
+
// Code = any changed path that is not a doc, not the drift/live manifests,
|
|
51
|
+
// not a declared surface, not a workflow/generated artifact.
|
|
52
|
+
const codeFiles = changedFiles.filter(
|
|
53
|
+
(f) =>
|
|
54
|
+
!f.startsWith('docs/') &&
|
|
55
|
+
!f.endsWith('.md') &&
|
|
56
|
+
!f.startsWith('.arbiter/') &&
|
|
57
|
+
!f.startsWith('.github/') &&
|
|
58
|
+
!surfacePaths.includes(f),
|
|
59
|
+
);
|
|
60
|
+
if (codeFiles.length === 0) {
|
|
61
|
+
process.stdout.write('check-drift: live-SSOT binding — no code files in the last commit\n');
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (touchedSurfaces.length === 0) {
|
|
65
|
+
process.stderr.write(
|
|
66
|
+
`check-drift: FAIL — live-SSOT binding: code changed without updating the declared-live surface(s):\n`,
|
|
67
|
+
);
|
|
68
|
+
for (const s of surfacePaths) process.stderr.write(` - ${s}\n`);
|
|
69
|
+
process.stderr.write(
|
|
70
|
+
` code files in commit: ${codeFiles.join(', ')}\n` +
|
|
71
|
+
' Fix: update the live surface in the SAME commit (INV-63 SSOT atomic).\n',
|
|
72
|
+
);
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
process.stdout.write(
|
|
76
|
+
`check-drift: live-SSOT binding OK — ${touchedSurfaces.length} surface(s) updated in the commit\n`,
|
|
77
|
+
);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
81
|
+
process.stdout.write([
|
|
82
|
+
'Usage: node scripts/check-drift.mjs [options]',
|
|
83
|
+
'',
|
|
84
|
+
'Validates that committed generated files match expected content hashes.',
|
|
85
|
+
'Exits 0 when no drift found; exits 1 when generated content has drifted.',
|
|
86
|
+
'',
|
|
87
|
+
'Manifest format: JSON array of { path, hash, generator } entries.',
|
|
88
|
+
'',
|
|
89
|
+
'Options:',
|
|
90
|
+
' --manifest <path> Path to drift manifest (default: .arbiter/drift-manifest.json)',
|
|
91
|
+
' --dir <path> Root directory (default: cwd)',
|
|
92
|
+
' --help, -h Show this help and exit',
|
|
93
|
+
'',
|
|
94
|
+
].join('\n'));
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const manifestArg = args.indexOf('--manifest');
|
|
99
|
+
const dirArg = args.indexOf('--dir');
|
|
100
|
+
const CWD = dirArg >= 0 && args[dirArg + 1] ? resolve(args[dirArg + 1]) : process.cwd();
|
|
101
|
+
const MANIFEST_PATH = manifestArg >= 0 && args[manifestArg + 1]
|
|
102
|
+
? resolve(args[manifestArg + 1])
|
|
103
|
+
: join(CWD, '.arbiter', 'drift-manifest.json');
|
|
104
|
+
|
|
105
|
+
// #2044: live-SSOT binding runs BEFORE the hash check (independent concern);
|
|
106
|
+
// a binding violation exits 1 without touching the hash audit.
|
|
107
|
+
if (!runLiveSsotBinding()) process.exit(1);
|
|
108
|
+
|
|
109
|
+
if (!existsSync(MANIFEST_PATH)) {
|
|
110
|
+
process.stdout.write('check-drift: SKIP — no drift manifest found (.arbiter/drift-manifest.json)\n');
|
|
111
|
+
// #2052/#2012: recognized marker so runCheck surfaces SKIP, not PASS. Without it a
|
|
112
|
+
// manifest-less repo reports PASS on every gate run while verifying nothing.
|
|
113
|
+
process.stdout.write('[SKIP] no drift manifest found (.arbiter/drift-manifest.json)\n');
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
let manifest;
|
|
118
|
+
try {
|
|
119
|
+
manifest = JSON.parse(readFileSync(MANIFEST_PATH, 'utf-8'));
|
|
120
|
+
} catch (err) {
|
|
121
|
+
if (err instanceof SyntaxError) {
|
|
122
|
+
process.stderr.write(`check-drift: FAIL — invalid JSON in manifest: ${err.message}\n`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!Array.isArray(manifest)) {
|
|
129
|
+
process.stderr.write('check-drift: FAIL — drift manifest must be a JSON array\n');
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let violations = 0;
|
|
134
|
+
let checked = 0;
|
|
135
|
+
|
|
136
|
+
for (const entry of manifest) {
|
|
137
|
+
if (!entry || typeof entry.path !== 'string' || typeof entry.hash !== 'string') {
|
|
138
|
+
process.stderr.write(`[FAIL] invalid manifest entry: ${JSON.stringify(entry)}\n`);
|
|
139
|
+
violations++;
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
const filePath = join(CWD, entry.path);
|
|
143
|
+
if (!existsSync(filePath)) {
|
|
144
|
+
process.stderr.write(`[FAIL] generated file missing: ${entry.path} (expected hash: ${entry.hash})\n`);
|
|
145
|
+
violations++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
checked++;
|
|
149
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
150
|
+
const actual = createHash('sha256').update(content).digest('hex');
|
|
151
|
+
if (actual !== entry.hash) {
|
|
152
|
+
const generator = entry.generator ? ` (generator: ${entry.generator})` : '';
|
|
153
|
+
process.stderr.write(
|
|
154
|
+
`[FAIL] drift detected in ${entry.path}${generator}\n expected: ${entry.hash}\n actual: ${actual}\n`,
|
|
155
|
+
);
|
|
156
|
+
violations++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (violations > 0) {
|
|
161
|
+
process.stderr.write(
|
|
162
|
+
`check-drift: FAIL — ${violations}/${manifest.length} generated file(s) have drifted (INV-89)\n`,
|
|
163
|
+
);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
process.stdout.write(`check-drift: OK — all ${checked} generated file(s) match manifest hashes (INV-89)\n`);
|
|
167
|
+
process.exit(0);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// check-duplication.mjs — generated by arbiter
|
|
3
|
+
// CATALOG: fail-closed duplication gate — runs jscpd v5 with the fileset from
|
|
4
|
+
// CATALOG: .jscpd.json#path and FAILS on config drift or a 0-source scan (which
|
|
5
|
+
// CATALOG: jscpd v5 exits 0 on, silently neutering a bare `npx jscpd` gate).
|
|
6
|
+
// CATALOG: rejected fold-in into debt-report.mjs because that is the ratchet leg
|
|
7
|
+
// CATALOG: (baseline comparison); this is the absolute threshold leg.
|
|
8
|
+
// Exits 1 on: unreadable config, missing/empty `path`, jscpd failure, missing
|
|
9
|
+
// report, 0 sources, or threshold breach (jscpd exit 1).
|
|
10
|
+
// Re-generate with: arbiter update
|
|
11
|
+
import { jscpdScan } from './debt-lib.mjs';
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const scan = jscpdScan(process.cwd());
|
|
15
|
+
if (scan.skipped) {
|
|
16
|
+
console.log('[duplication] FAIL: npx not available — cannot run jscpd');
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
if (scan.error) {
|
|
20
|
+
console.log(`[duplication] FAIL: ${scan.error}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (scan.legacyNoReport) {
|
|
24
|
+
// jscpd v4 binary with zero clones (v5 always writes the report). Pass
|
|
25
|
+
// with a loud upgrade warning: brownfield projects keep their pinned v4
|
|
26
|
+
// devDep until the dependency is bumped by hand.
|
|
27
|
+
console.log(
|
|
28
|
+
'[duplication] WARN: jscpd v4 semantics detected (no report on exit 0, zero clones). ' +
|
|
29
|
+
'Upgrade the jscpd devDep to v5 to keep this gate fail-closed.',
|
|
30
|
+
);
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
if ((scan.status ?? 0) !== 0) {
|
|
34
|
+
console.log(
|
|
35
|
+
`[duplication] FAIL: jscpd exit ${scan.status} — duplication over threshold (${scan.percentage}% across ${scan.sources} files)`,
|
|
36
|
+
);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
console.log(
|
|
40
|
+
`[duplication] OK: ${scan.percentage.toFixed(2)}% duplicated lines across ${scan.sources} files`,
|
|
41
|
+
);
|
|
42
|
+
} catch (err) {
|
|
43
|
+
console.log(`[duplication] FAIL: ${err.message}`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// CATALOG: #2043 (AC-2043.5/6) enforcement. Reads the append-only e2e reliability
|
|
4
|
+
// CATALOG: ledger (.arbiter/e2e-ledger.jsonl, written by lib/e2e-reliability.mjs's
|
|
5
|
+
// CATALOG: appendLedger) and escalates when the TRAILING run of consecutive
|
|
6
|
+
// CATALOG: REGRESSION entries reaches the configured threshold — the cross-run
|
|
7
|
+
// CATALOG: counterpart to the ship tick prompt's within-run strike count (#2043
|
|
8
|
+
// CATALOG: AC-2043.4). Configured via arbiter.json's e2ePolicy.escalation
|
|
9
|
+
// CATALOG: (schema-validated, src/config/schema.ts); absent config falls back to the
|
|
10
|
+
// CATALOG: pre-#2043 hardcoded 2-strike default so existing/ungoverned projects keep
|
|
11
|
+
// CATALOG: their current behavior. SKIP when the ledger doesn't exist yet (no runs
|
|
12
|
+
// CATALOG: recorded) or is empty.
|
|
13
|
+
// CATALOG: #2248 (AC-2248.2): escalation.strikes (e.g. [2, 3, 5]) drives a PER-RUNG
|
|
14
|
+
// CATALOG: ladder when present — the first rung crossed widens scope, the last rung
|
|
15
|
+
// CATALOG: crossed hard-stops to needs-human, any rung(s) in between force the full
|
|
16
|
+
// CATALOG: suite. escalation.maxStrikes alone (no strikes array) stays supported as
|
|
17
|
+
// CATALOG: the pre-#2248 single-rung scalar check (legacy).
|
|
18
|
+
// Exit codes (INV-53): 0=PASS/SKIP, 1=escalation triggered
|
|
19
|
+
// Usage: node scripts/check-e2e-escalation.mjs [--help]
|
|
20
|
+
import { readFileSync, existsSync } from 'node:fs'
|
|
21
|
+
import { join, resolve } from 'node:path'
|
|
22
|
+
|
|
23
|
+
const ROOT = resolve(process.cwd())
|
|
24
|
+
const LEDGER_PATH = join(ROOT, '.arbiter', 'e2e-ledger.jsonl')
|
|
25
|
+
const ARBITER_PATH = join(ROOT, 'arbiter.json')
|
|
26
|
+
// Pre-#2043 hardcoded behavior (was the ship tick prompt's undeclared "2-strike" rule) —
|
|
27
|
+
// the default when a project has not opted into e2ePolicy.escalation.
|
|
28
|
+
const DEFAULT_MAX_STRIKES = 2
|
|
29
|
+
|
|
30
|
+
const HELP = `Usage: node scripts/check-e2e-escalation.mjs [--help]
|
|
31
|
+
|
|
32
|
+
Reads .arbiter/e2e-ledger.jsonl (append-only e2e reliability ledger) and escalates
|
|
33
|
+
when the TRAILING run of consecutive REGRESSION entries reaches the configured
|
|
34
|
+
threshold. When e2ePolicy.escalation.strikes (e.g. [2, 3, 5]) is declared, each
|
|
35
|
+
rung crossed gets a distinct action: first rung widens scope, last rung hard-stops
|
|
36
|
+
to needs-human, any rung(s) between force the full suite. Without a strikes array,
|
|
37
|
+
falls back to the scalar e2ePolicy.escalation.maxStrikes (default ${DEFAULT_MAX_STRIKES}).
|
|
38
|
+
|
|
39
|
+
SKIP:
|
|
40
|
+
When .arbiter/e2e-ledger.jsonl is absent or empty (no runs recorded yet).
|
|
41
|
+
|
|
42
|
+
Exit codes:
|
|
43
|
+
0 — pass or SKIP (below threshold / no ledger)
|
|
44
|
+
1 — escalation triggered (consecutive REGRESSION count >= threshold)`
|
|
45
|
+
|
|
46
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
47
|
+
process.stdout.write(`${HELP}\n`)
|
|
48
|
+
process.exit(0)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Reads+parses arbiter.json. Returns { strikes, maxStrikes } — strikes is the
|
|
52
|
+
// per-rung ladder (sorted ascending) when e2ePolicy.escalation.strikes validates
|
|
53
|
+
// as a non-empty array of positive integers, else null (legacy scalar path).
|
|
54
|
+
// maxStrikes is the scalar threshold, defaulting when arbiter.json is absent,
|
|
55
|
+
// unreadable, malformed, or doesn't declare e2ePolicy.escalation.maxStrikes —
|
|
56
|
+
// this gate degrades gracefully rather than hard-failing on a config problem
|
|
57
|
+
// another gate (check-smoke-journeys, schema validation) already owns reporting.
|
|
58
|
+
function loadEscalationConfig() {
|
|
59
|
+
if (!existsSync(ARBITER_PATH)) return { strikes: null, maxStrikes: DEFAULT_MAX_STRIKES }
|
|
60
|
+
|
|
61
|
+
let raw
|
|
62
|
+
try {
|
|
63
|
+
raw = JSON.parse(readFileSync(ARBITER_PATH, 'utf-8'))
|
|
64
|
+
// FAIL-OPEN-INTENT: malformed arbiter.json defaults to DEFAULT_MAX_STRIKES; schema validation owns reporting.
|
|
65
|
+
} catch {
|
|
66
|
+
return { strikes: null, maxStrikes: DEFAULT_MAX_STRIKES }
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const maxStrikesRaw = raw?.e2ePolicy?.escalation?.maxStrikes
|
|
70
|
+
const maxStrikes =
|
|
71
|
+
typeof maxStrikesRaw === 'number' && Number.isInteger(maxStrikesRaw) && maxStrikesRaw >= 2
|
|
72
|
+
? maxStrikesRaw
|
|
73
|
+
: DEFAULT_MAX_STRIKES
|
|
74
|
+
|
|
75
|
+
const strikesRaw = raw?.e2ePolicy?.escalation?.strikes
|
|
76
|
+
const strikes =
|
|
77
|
+
Array.isArray(strikesRaw) &&
|
|
78
|
+
strikesRaw.length > 0 &&
|
|
79
|
+
strikesRaw.every((s) => typeof s === 'number' && Number.isInteger(s) && s >= 1)
|
|
80
|
+
? [...strikesRaw].sort((a, b) => a - b)
|
|
81
|
+
: null
|
|
82
|
+
|
|
83
|
+
return { strikes, maxStrikes }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// #2248 (AC-2248.2): the rung (0-based index into `strikes`) the current
|
|
87
|
+
// consecutive-REGRESSION count crosses, or -1 when it's below the first rung.
|
|
88
|
+
// `strikes` is pre-sorted ascending — the highest rung whose threshold is <=
|
|
89
|
+
// consecutive wins (a staircase: 4 consecutive against [2, 3, 5] is still
|
|
90
|
+
// "rung 2 crossed", not "between rungs").
|
|
91
|
+
function findCrossedRungIndex(strikes, consecutive) {
|
|
92
|
+
let idx = -1
|
|
93
|
+
for (let i = 0; i < strikes.length; i++) {
|
|
94
|
+
if (consecutive >= strikes[i]) idx = i
|
|
95
|
+
}
|
|
96
|
+
return idx
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// #2248 (AC-2248.2): rung-specific action text. First rung crossed → widen
|
|
100
|
+
// scope / root-cause; last rung crossed → hard stop + needs-human; any rung(s)
|
|
101
|
+
// strictly between → force the full suite. A single-entry ladder is both
|
|
102
|
+
// "first" and "last" — hard-stop wins (it's the only/final rung).
|
|
103
|
+
function rungMessage(strikes, idx, consecutive) {
|
|
104
|
+
const rungNum = idx + 1
|
|
105
|
+
const total = strikes.length
|
|
106
|
+
const threshold = strikes[idx]
|
|
107
|
+
const action =
|
|
108
|
+
idx === total - 1
|
|
109
|
+
? 'hard stop — escalate to needs-human'
|
|
110
|
+
: idx === 0
|
|
111
|
+
? 'widen scope / root-cause the failure'
|
|
112
|
+
: 'force the full suite'
|
|
113
|
+
return (
|
|
114
|
+
`[check-e2e-escalation] FAIL — escalation triggered: ${consecutive} consecutive ` +
|
|
115
|
+
`REGRESSION ledger entries >= rung ${rungNum}/${total} threshold ${threshold} — ` +
|
|
116
|
+
`${action} per e2ePolicy.escalation.strikes\n`
|
|
117
|
+
)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Loads the ledger as an array of parsed JSONL entries. Returns null when the ledger
|
|
121
|
+
// file doesn't exist (SKIP path); malformed lines are dropped rather than fail-closed —
|
|
122
|
+
// the ledger is an observability artifact, not a policy input, so a single corrupt
|
|
123
|
+
// line should not itself block the run.
|
|
124
|
+
function loadLedgerEntries() {
|
|
125
|
+
if (!existsSync(LEDGER_PATH)) return null
|
|
126
|
+
const raw = readFileSync(LEDGER_PATH, 'utf-8')
|
|
127
|
+
return raw
|
|
128
|
+
.split('\n')
|
|
129
|
+
.map((line) => line.trim())
|
|
130
|
+
.filter(Boolean)
|
|
131
|
+
.map((line) => {
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(line)
|
|
134
|
+
// FAIL-OPEN-INTENT: a corrupt ledger line is dropped, not fatal — observability data, not policy input.
|
|
135
|
+
} catch {
|
|
136
|
+
return null
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
.filter((entry) => entry !== null)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Counts REGRESSION entries from the TAIL of the ledger, stopping at the first
|
|
143
|
+
// non-REGRESSION (PASS/FLAKE/INFRA) entry — only a CONSECUTIVE run counts.
|
|
144
|
+
function countTrailingRegressions(entries) {
|
|
145
|
+
let count = 0
|
|
146
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
147
|
+
if (entries[i]?.verdict !== 'REGRESSION') break
|
|
148
|
+
count++
|
|
149
|
+
}
|
|
150
|
+
return count
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function main() {
|
|
154
|
+
const entries = loadLedgerEntries()
|
|
155
|
+
if (entries === null || entries.length === 0) {
|
|
156
|
+
process.stdout.write('[check-e2e-escalation] SKIP — no e2e ledger found\n')
|
|
157
|
+
process.exit(0)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const { strikes, maxStrikes } = loadEscalationConfig()
|
|
161
|
+
const consecutive = countTrailingRegressions(entries)
|
|
162
|
+
|
|
163
|
+
// #2248 (AC-2248.2): escalation.strikes present → per-rung ladder governs
|
|
164
|
+
// (maxStrikes is ignored here; it stays required by schema.ts alongside
|
|
165
|
+
// strikes but isn't consulted for the exit decision once a ladder exists).
|
|
166
|
+
if (strikes) {
|
|
167
|
+
const idx = findCrossedRungIndex(strikes, consecutive)
|
|
168
|
+
if (idx === -1) {
|
|
169
|
+
process.stdout.write(
|
|
170
|
+
`[check-e2e-escalation] OK — ${consecutive} consecutive REGRESSION entries below ` +
|
|
171
|
+
`rung 1 threshold ${strikes[0]}\n`,
|
|
172
|
+
)
|
|
173
|
+
process.exit(0)
|
|
174
|
+
}
|
|
175
|
+
process.stderr.write(rungMessage(strikes, idx, consecutive))
|
|
176
|
+
process.exit(1)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (consecutive >= maxStrikes) {
|
|
180
|
+
process.stderr.write(
|
|
181
|
+
`[check-e2e-escalation] FAIL — escalation triggered: ${consecutive} consecutive ` +
|
|
182
|
+
`REGRESSION ledger entries >= threshold ${maxStrikes} — force the full suite / ` +
|
|
183
|
+
`escalate to needs-human per e2ePolicy.escalation\n`,
|
|
184
|
+
)
|
|
185
|
+
process.exit(1)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
process.stdout.write(
|
|
189
|
+
`[check-e2e-escalation] OK — ${consecutive} consecutive REGRESSION entries below threshold ${maxStrikes}\n`,
|
|
190
|
+
)
|
|
191
|
+
process.exit(0)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
try {
|
|
195
|
+
main()
|
|
196
|
+
} catch (err) {
|
|
197
|
+
process.stderr.write(`[check-e2e-escalation] ERROR — unexpected: ${err.message}\n`)
|
|
198
|
+
process.exit(2)
|
|
199
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
// arbiter — E2E flaky-test quarantine hygiene gate (#1445, INV-130).
|
|
4
|
+
//
|
|
5
|
+
// The quarantine registry (.arbiter/e2e/quarantine.json) ANNOTATES known-unstable
|
|
6
|
+
// tests but NEVER suppresses them: quarantined tests still run and still report, and
|
|
7
|
+
// CI's exit code is unchanged by an entry's mere presence. What this gate enforces is
|
|
8
|
+
// that the registry itself does not ROT — a quarantine must be a temporary, owned,
|
|
9
|
+
// tracked exception, not a permanent silent mute. Every entry must carry the full
|
|
10
|
+
// required-field set AND a FUTURE `expires` date; an expired, malformed, or
|
|
11
|
+
// incomplete entry fails closed. Self-SKIPs (exit 0) when no registry is present.
|
|
12
|
+
//
|
|
13
|
+
// Exit codes (INV-53): 0 = clean / no registry · 1 = expired or malformed entry ·
|
|
14
|
+
// 2 = unexpected error.
|
|
15
|
+
import { readFileSync, existsSync } from 'node:fs'
|
|
16
|
+
import { join } from 'node:path'
|
|
17
|
+
import { validateQuarantine, QUARANTINE_REQUIRED_FIELDS } from './lib/e2e-reliability.mjs'
|
|
18
|
+
|
|
19
|
+
function parseDir(argv) {
|
|
20
|
+
const i = argv.indexOf('--dir')
|
|
21
|
+
return i >= 0 && argv[i + 1] ? argv[i + 1] : process.cwd()
|
|
22
|
+
}
|
|
23
|
+
const ROOT = parseDir(process.argv.slice(2))
|
|
24
|
+
const REGISTRY = join(ROOT, '.arbiter', 'e2e', 'quarantine.json')
|
|
25
|
+
|
|
26
|
+
if (!existsSync(REGISTRY)) {
|
|
27
|
+
process.stdout.write(
|
|
28
|
+
'check-e2e-quarantine: OK — no quarantine registry (.arbiter/e2e/quarantine.json absent)\n',
|
|
29
|
+
)
|
|
30
|
+
process.exit(0)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let registry
|
|
34
|
+
try {
|
|
35
|
+
registry = JSON.parse(readFileSync(REGISTRY, 'utf-8'))
|
|
36
|
+
} catch (err) {
|
|
37
|
+
// A present-but-broken registry must not silently pass — fail closed.
|
|
38
|
+
process.stderr.write(
|
|
39
|
+
`check-e2e-quarantine: FAIL — ${REGISTRY} is not valid JSON: ${err.message}\n`,
|
|
40
|
+
)
|
|
41
|
+
process.exit(1)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let result
|
|
45
|
+
try {
|
|
46
|
+
result = validateQuarantine(registry, new Date())
|
|
47
|
+
} catch (err) {
|
|
48
|
+
process.stderr.write(`check-e2e-quarantine: error validating registry: ${err.message}\n`)
|
|
49
|
+
process.exit(2)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!result.ok) {
|
|
53
|
+
process.stderr.write(
|
|
54
|
+
`check-e2e-quarantine: FAIL — ${result.errors.length} quarantine issue(s):\n`,
|
|
55
|
+
)
|
|
56
|
+
for (const e of result.errors) process.stderr.write(` [FAIL] ${e}\n`)
|
|
57
|
+
process.stderr.write(
|
|
58
|
+
`Each entry needs fields [${QUARANTINE_REQUIRED_FIELDS.join(', ')}] and a FUTURE 'expires' date. ` +
|
|
59
|
+
'A quarantine is a temporary owned exception, not a permanent mute.\n',
|
|
60
|
+
)
|
|
61
|
+
process.exit(1)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const count = Array.isArray(registry) ? registry.length : (registry.entries || []).length
|
|
65
|
+
process.stdout.write(
|
|
66
|
+
`check-e2e-quarantine: OK — ${count} quarantine entry(ies), all complete and unexpired\n`,
|
|
67
|
+
)
|
|
68
|
+
process.exit(0)
|