@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,902 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Single orchestration entrypoint — drive an issue to a reviewed, merged PR (#1206, #1216)
|
|
3
|
+
argument-hint: '#NNN [--tier XS|S|Standard]'
|
|
4
|
+
title: '/ship #NNN'
|
|
5
|
+
doc_version: '2.0.0'
|
|
6
|
+
status: active
|
|
7
|
+
last_review: '2026-06-05'
|
|
8
|
+
owner: ''
|
|
9
|
+
canonical_id: ''
|
|
10
|
+
tags: ['audience/agent', 'audience/dev', 'kind/internal']
|
|
11
|
+
related: []
|
|
12
|
+
---
|
|
13
|
+
<% const _safetyNet = { XS: { reviewAgentCount: 1 }, S: { reviewAgentCount: 1 }, Standard: { reviewAgentCount: 2 } }; %>
|
|
14
|
+
<% const _tiers = (typeof taskTiers !== 'undefined' && taskTiers) ? taskTiers : _safetyNet; %>
|
|
15
|
+
<% const _reviewLeadAngles = ['bugs', 'domain', 'type-safety', 'test-quality', 'security', 'data-integrity', 'silent-failures']; %>
|
|
16
|
+
<% const _collaborationMode = (typeof collaborationMode !== 'undefined' && collaborationMode) ? collaborationMode : 'peer-review'; %>
|
|
17
|
+
<% const _mergeMode = (typeof mergeMode !== 'undefined' && mergeMode) ? mergeMode : 'pr-ff'; %>
|
|
18
|
+
<% const _testCommand = (typeof testCommand !== 'undefined' && testCommand) ? testCommand : 'npm test'; %>
|
|
19
|
+
<% const _backend = (typeof decompositionBackend !== 'undefined' ? decompositionBackend : null) ?? (useGitHub ? 'github' : 'markdown'); %>
|
|
20
|
+
<% const _soloMode = _collaborationMode === 'trunk-solo'; %>
|
|
21
|
+
<% const _refactorLabel = _soloMode ? 'dispatch 1 independent code-review agent (trunk-solo mode — a fresh subagent with no implementation context) + 1 adversarial verifier' : `dispatch ${_tiers.Standard.reviewAgentCount} code-review agents + 1 adversarial verifier`; %>
|
|
22
|
+
<% const _refactorCount = _soloMode ? '1' : `${_tiers.Standard.reviewAgentCount} (Standard)`; %>
|
|
23
|
+
|
|
24
|
+
# /ship #NNN
|
|
25
|
+
|
|
26
|
+
`/ship` is the **single orchestration entrypoint** — it drives an issue to a reviewed, merged PR by
|
|
27
|
+
auto-sequencing arbiter's engine (worktree → plan → red-team → TDD impl → review → verify → merge → cleanup).
|
|
28
|
+
Use `/task` subcommands (`init`, `advance`, `record-red`, etc.) only for low-level engine control or recovery.
|
|
29
|
+
|
|
30
|
+
> Semantics: `ship` = drive an issue to a merged PR. It is NOT deploy/release.
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## The loop
|
|
35
|
+
|
|
36
|
+
`arbiter ship` is the next-action computer; this command is the loop that executes the model-requiring
|
|
37
|
+
steps between its calls.
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# 1. Ask the orchestrator for the current step
|
|
41
|
+
arbiter ship #NNN --tier <tier>
|
|
42
|
+
|
|
43
|
+
# 2. Do the work the step describes (plan / write tests / implement / dispatch review agents)
|
|
44
|
+
|
|
45
|
+
# 3. Advance when this phase's gate is green (the gate throws if red)
|
|
46
|
+
arbiter ship #NNN --advance
|
|
47
|
+
|
|
48
|
+
# repeat 1–3 until the step reports "Phase: complete (done)"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
On every sub-step, pin the cursor so a mid-task `/clear` resumes exactly:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
arbiter mark --tdd GREEN --last "<done>" --next "<exact next action>" --digest "<one line>"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Train
|
|
60
|
+
|
|
61
|
+
A **train** is one worktree, one branch, one plan, one gate and one PR carrying N issues. It is
|
|
62
|
+
the **DEFAULT unit of ceremony** for every issue that does not widen the tier to Standard (the
|
|
63
|
+
XS/S band, size ≤ M). Ten three-line fixes pass ONE ceremony, not ten.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
arbiter ship #A #B #C # declare a train — sugar for `#A --chain #B --chain #C`
|
|
67
|
+
arbiter ship --chain-add #D # grow it, or be refused and told to land it first
|
|
68
|
+
arbiter ship --seal # close it now; the next issue starts a new train
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
| Runs ONCE per train | Runs per issue |
|
|
72
|
+
| ----------------------------------- | --------------------------------------- |
|
|
73
|
+
| plan (one cumulative plan) | its `AC-<issue>.<n>` anchor lines |
|
|
74
|
+
| plan-review | its TDD evidence file |
|
|
75
|
+
| red-team | its `Closes #N` line in the PR body |
|
|
76
|
+
| code review + adversarial verify | |
|
|
77
|
+
| review rounds (`ship.review.maxRounds`) | |
|
|
78
|
+
| cross-model review seat | |
|
|
79
|
+
| full gate | |
|
|
80
|
+
| PR (`Closes #A`, `Closes #B`, …) | |
|
|
81
|
+
|
|
82
|
+
**One plan, one anchor.** The train's plan carries a SINGLE `## Acceptance Criteria` section
|
|
83
|
+
listing every member's criteria, namespaced per issue as `AC-<issue>.<n>` (`AC-2401.1`,
|
|
84
|
+
`AC-2402.1`, …). The anchor parser accepts that dotted numeric form, and `check-acceptance`
|
|
85
|
+
rejects duplicate ids — which is exactly what an un-namespaced multi-issue plan produces. Every
|
|
86
|
+
other mandatory section (see §Plan contents) is written once, for the train.
|
|
87
|
+
|
|
88
|
+
**Tier = widest member.** Compute each member's tier as usual and take the widest; the
|
|
89
|
+
widen-only rule above applies unchanged (signals may widen, never narrow). An issue that widens
|
|
90
|
+
the train to Standard does not join it — a risk-bearing issue rides its own train.
|
|
91
|
+
|
|
92
|
+
**Stop rules** — the train seals, and the next issue starts a new one, on any of: an explicit
|
|
93
|
+
`--seal`, a member that widens the tier to Standard, `maxChain` ids already on the branch, or
|
|
94
|
+
`maxAgeMinutes` elapsed since the train opened. Both bounds come from `ship.train` in
|
|
95
|
+
`arbiter.json` (defaults: 10 issues, 480 minutes); `ship.review.maxRounds` bounds review rework
|
|
96
|
+
the same way (default 2). A refused `--chain-add` is the policy working — land the train.
|
|
97
|
+
|
|
98
|
+
**Gate cadence.** Targeted tests during `green` / `refactor`, `node scripts/check-all.mjs L1`
|
|
99
|
+
once at the landing commit, `L2` once at push — see §Gate economy, which governs a train exactly
|
|
100
|
+
as it governs a single issue. Gates are per LANDING, ceremony is per TRAIN; neither is per issue.
|
|
101
|
+
|
|
102
|
+
**Running the full per-issue ceremony over a batch of small issues is a playbook violation, not
|
|
103
|
+
extra safety.** It buys no additional signal — the same plan reviewer, the same red-team, the
|
|
104
|
+
same reviewer panel read the same kind of diff N times — and it spends the budget on the part of
|
|
105
|
+
the work that was already cheap instead of on the residual 10% (merge, red gate, conflict) that
|
|
106
|
+
is not.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Local-only state
|
|
111
|
+
|
|
112
|
+
Before writing task state, ensure runtime files never get committed:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
exclude_file="$(git rev-parse --git-path info/exclude)"
|
|
116
|
+
mkdir -p "$(dirname "$exclude_file")" .claude/plans
|
|
117
|
+
touch "$exclude_file"
|
|
118
|
+
node -e 'const fs=require("node:fs"),p=process.argv[1],s=fs.readFileSync(p,"utf8"),n=s.replace(/^\.arbiter\/\r?$(?:\n)?/gm,"");if(n!==s)fs.writeFileSync(p,n)' "$exclude_file"
|
|
119
|
+
for pattern in ".claude/.task-*" ".claude/.task/" ".claude/plans/" ".agents-dispatched"; do
|
|
120
|
+
grep -qxF "$pattern" "$exclude_file" || printf "%s\n" "$pattern" >> "$exclude_file"
|
|
121
|
+
done
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then seed task state:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
arbiter task init --id "#NNN" --plan ".claude/plans/task-NNN.md" --tier <tier>
|
|
128
|
+
arbiter task advance --to plan
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Phase map
|
|
134
|
+
|
|
135
|
+
<% if (governanceLevel !== 'L1') { %>
|
|
136
|
+
The tier (XS / S / Standard) sets the number of review agents dispatched per review phase.
|
|
137
|
+
|
|
138
|
+
**Code-review agents per tier: XS=1, S=1, Standard=2.** Recalibrated from the #2176 controlled
|
|
139
|
+
study: 1 reviewer catches 77% of known defects intent-to-treat but **88% per-protocol** (stage
|
|
140
|
+
actually completed), 2 reviewers 87.5%, 3 reviewers 90.1% — half a panel's value is
|
|
141
|
+
fault-tolerance, not extra eyes, and false positives grow with panel size.
|
|
142
|
+
|
|
143
|
+
### Optional cross-model review seat (#2357)
|
|
144
|
+
|
|
145
|
+
When `arbiter.json` opts in to `crossModelReview.enabled` and records explicit
|
|
146
|
+
`diffEgressConsent`, `/ship` replaces one code-review seat with the read-only
|
|
147
|
+
`codex-reviewer` CLI seat. The panel never grows: `reviewAgents` remains the total,
|
|
148
|
+
and `externalReviewers` is only the external portion. The external seat is assigned
|
|
149
|
+
to `security` when that vertical is active, otherwise `bugs`; unavailable, unauthenticated,
|
|
150
|
+
or unconsented access falls back to Anthropic.
|
|
151
|
+
For Standard with a fulfilled external seat, dispatch one Anthropic reviewer plus one
|
|
152
|
+
`codex-reviewer`; do not dispatch two Anthropic reviewers in addition to Codex.
|
|
153
|
+
|
|
154
|
+
When `arbiter ship` reaches the refactor step, it invokes the wired boundary below from the
|
|
155
|
+
repository root; the diff is sent on stdin and the actual `codex exec` invocation is delegated.
|
|
156
|
+
The same command is available for an explicit manual rerun when the evidence needs refreshing.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git diff --binary origin/main...HEAD | arbiter review cross-model --task '#NNN' --tier Standard --phase refactor --vertical security --prompt 'Review this change for bugs, type safety, security, data integrity, and silent failures.'
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The boundary invokes `codex exec --strict-config --ephemeral --ignore-user-config` with a
|
|
163
|
+
scratch-only profile extending `:read-only`, denying the host filesystem root, permitting scratch
|
|
164
|
+
reads, and disabling network. (Codex rejects combining the legacy `--sandbox read-only` override
|
|
165
|
+
with `default_permissions`.) The prompt and a maximum 512 KiB diff are passed on stdin. Output uses the reduced
|
|
166
|
+
`schemas/agent-return-external.schema.json` projection and is persisted only through
|
|
167
|
+
`scripts/record-agent-return.mjs` with `vendor=openai`, `cli=codex`, and
|
|
168
|
+
`dispatch=external-cli`. Retries are disabled. A truncated diff, failed coercion, or
|
|
169
|
+
recorder rejection is a degradation and must not be silently treated as a clean review.
|
|
170
|
+
|
|
171
|
+
Use the shared sidecar contract in the Refactor / code-review evidence below. The automatic CLI
|
|
172
|
+
bridge records a fulfilled external seat first; the manual block writes the complete reviewer
|
|
173
|
+
panel. When the external seat is active, preserve `codex-reviewer` in that same `agents[]` list
|
|
174
|
+
and set `count` to the total number actually dispatched; never inflate the panel.
|
|
175
|
+
|
|
176
|
+
**XS/S=1 depends on the completion gate.** A single reviewer is only safe because
|
|
177
|
+
`scripts/check-review-completion.mjs` (#2177) fails the stage when a dispatched reviewer returned
|
|
178
|
+
no envelope and re-dispatches exactly that agent once — that gate plus its single targeted retry
|
|
179
|
+
is what makes a single reviewer safe (it is what turns 77% ITT into 88% per-protocol). If the
|
|
180
|
+
completion gate is ever removed, XS/S must go back to a panel.
|
|
181
|
+
|
|
182
|
+
**Security escalation — 3 code-review agents.** When the change's **file-path-matched auditor set**
|
|
183
|
+
includes `security`, `data-integrity` or `silent-failures`, dispatch 3 code-review agents
|
|
184
|
+
regardless of tier (study: security-class defects — singles 82-83%, panels 97-99%). The trigger is
|
|
185
|
+
the file-path-matched auditor set computed by the existing router —
|
|
186
|
+
the router `route-auditors.mjs` over `git diff --name-only ...` with `--diff-stdin`, run **without**
|
|
187
|
+
`--size-floor`, whose `active` array comes from `.claude/auditor-routing.json` path matching. It is
|
|
188
|
+
**not** the tier's vertical floor: Standard's floor lists those same verticals as breadth for every
|
|
189
|
+
Standard change, so reading the escalation off the floor would make "Standard=2" unreachable. Same
|
|
190
|
+
mechanism, read without the size floor — no new classifier.
|
|
191
|
+
Where `route-auditors.mjs` and `.claude/auditor-routing.json` exist (arbiter's own tree), run
|
|
192
|
+
the router without `--size-floor` and read its `active` array; where they do not exist — every
|
|
193
|
+
generated project, since neither file is emitted — apply the same rule by inspecting changed paths
|
|
194
|
+
for auth/authz, crypto and secret material, database migrations and SQL, and CI workflow and
|
|
195
|
+
permission config. A missing router is never a "no security surface" verdict.
|
|
196
|
+
|
|
197
|
+
Red-team agent counts (XS=1, S=2, Standard=3) are **unchanged**: the study measured code review
|
|
198
|
+
only, so there is no evidence to move them.
|
|
199
|
+
|
|
200
|
+
Only a human may originate a non-widest ship tier: either an explicit `--tier XS|S` flag, or a tier persisted by `arbiter task init --id <id> --tier <tier>`. Without either, `arbiter ship` falls back to the widest tier (`Standard`) as a fail-safe. Deterministic signals do not originate a tier; they may only widen the selected tier and its review-agent count and vertical breadth.
|
|
201
|
+
|
|
202
|
+
**XS/S must be confirmed by blast radius, not diff size.** Diff size measures typing cost,
|
|
203
|
+
not risk: a one-line edit in a shared module carries a Standard-sized blast radius. Before
|
|
204
|
+
accepting a human-originated XS or S tier, run `/impact` on every file the plan touches and
|
|
205
|
+
record the dependent list in the plan. The tier stays XS/S only when every touched file is a
|
|
206
|
+
leaf — at most one upstream dependent — and none sits on a core path (`src/invariants/`,
|
|
207
|
+
`src/generators/`, `src/commands/`, `.claude/hooks/`, the shipped template tree (any file
|
|
208
|
+
with an `.ejs` twin), or config consumed by `scripts/check-all.mjs`). Two or more dependents, or any
|
|
209
|
+
core-path file, widens the tier to Standard. This is a count over the impact report, not a
|
|
210
|
+
judgment call, and it composes with the widen-only rule above: impact can widen a tier,
|
|
211
|
+
never narrow it. The impact report goes into the reviewer's context so the single XS
|
|
212
|
+
reviewer reads the change together with its callers.
|
|
213
|
+
|
|
214
|
+
The selected tier may be widened by deterministic signals only: a FRESH `graphify-out/graph.json` blast-radius over the plan's `files:` manifest, or a `wave`/`epic` label or milestone bundle (floor: Standard). Signals may only widen, never narrow. Tier/routing selection is never driven by text-only LLM classification (Study C, #2176: 75.6% adjacent accuracy, 20% fail-dangerous L→S). The review count follows the **final** tier — a widened tier gets the widened tier's count — and the security escalation only ever widens it further; nothing narrows it.
|
|
215
|
+
<% } %>
|
|
216
|
+
|
|
217
|
+
| Phase | What `/ship` does | Review agents |
|
|
218
|
+
|-------|-------------------|---------------|
|
|
219
|
+
| `preflight` | Open worktree (`/wt-open #NNN`), read issue, **readiness gate (INV-138)**: `gh issue view NNN --json body -q .body > /tmp/issue-NNN.md && [ -f scripts/issue-readiness.mjs ] && node scripts/issue-readiness.mjs --body-file /tmp/issue-NNN.md --emit-comment` — exit 1 ⇒ label `needs-clarification`, post the emitted comment (skip when already labeled), stop the ship. When the script is absent (brownfield trees predating its emission, ADR-110) a missing script is never a not-ready verdict — but the skip is declared, never silent: record `readiness: script absent — skipped` in the plan preamble so the omission stays visible. Seed task state (see Local-only state above) | — |
|
|
220
|
+
| `plan` | Write the plan; **freeze the issue's `AC-N:` criteria verbatim into `## Acceptance Criteria` + `## Non-Goals` (INV-138 anchor — the DoD derives from the issue, not from your interpretation)**; run the `senior-survey` skill for every new `src/` file the plan introduces (the pre-edit hook validates its Survey block); pass the plan-review gate (dispatch review agents, write `.arbiter/evidence/plan-review/<id>/latest.json` with verdict `PASS`); the plan carries every mandatory section (see §Plan contents) — a missing section is a FAIL | — |
|
|
221
|
+
| `red-team-review` | Dispatch tier-N red-team agents, recording their findings at `.arbiter/evidence/redteam/<task-id>.json` (the advance out of this phase asserts that file exists); route CRITICAL → `red-team-rework` | tier-N |
|
|
222
|
+
| `red-team-rework` | Lateral rework phase entered only on a CRITICAL red-team finding: revise the plan, then re-enter `red-team-review` (or `plan` for a full replan) | — |
|
|
223
|
+
| `red` | Write failing tests with the `tdd` skill (red → verify-red is its own step: watch each test fail for the right reason) — test titles cite the anchor ids (`it('… (AC-2)')`); the red commit body carries "tests map 1:1 to the acceptance criteria of #NNN"; `arbiter task record-red` | — |
|
|
224
|
+
| `green` | Implement the minimum to pass, continuing the `tdd` loop (composes with active companion plugins — see below) | — |
|
|
225
|
+
| `refactor` | Clean up; <%= _refactorLabel %> | <%= _refactorCount %> |
|
|
226
|
+
| `verification` | Run the `verification` skill, then the gate: `<%= _testCommand %>` then `node scripts/check-all.mjs check` | — |
|
|
227
|
+
| `close` | The closing phase (#A11): entry requires a valid L1 gate-pass marker and switches the active rule set to CLOSER mode (`.claude/rules/95-closer-mode.md`) — single named target, no discovery, findings to the PARKING list | — |
|
|
228
|
+
| `complete` | Commit, push, open/merge PR, close issue, clean up | — |
|
|
229
|
+
|
|
230
|
+
### Model tier per dispatch (static guidance, AGENTS.md §Model-Pyramid)
|
|
231
|
+
|
|
232
|
+
Mechanical sub-steps — readiness parsing, auditor routing, file discovery, grep sweeps — go
|
|
233
|
+
to the cheapest agent (`codebase-scanner`, Haiku). Review, context-check and gate-bridge
|
|
234
|
+
subagents run on Sonnet-class agents (their registry defaults). The session model
|
|
235
|
+
(Opus/Fable-class) is reserved for the judgment stages: plan synthesis, red-team attack
|
|
236
|
+
angles, and the adversarial verifier's verdict. This is dispatch guidance the orchestrator
|
|
237
|
+
applies when spawning agents, not runtime machinery — arbiter never selects a model tier
|
|
238
|
+
programmatically.
|
|
239
|
+
|
|
240
|
+
<% if (!_soloMode) { %>
|
|
241
|
+
Review-agent minimums by tier: XS=<%= _tiers.XS.reviewAgentCount %>, S=<%= _tiers.S.reviewAgentCount %>, Standard=<%= _tiers.Standard.reviewAgentCount %>.
|
|
242
|
+
<% } %>
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Merge Contract (derive before writing — INV-138)
|
|
247
|
+
|
|
248
|
+
Before the first edit of each slice, derive its **merge contract** and record it in the
|
|
249
|
+
plan; code and tests are born against the contract, never against a re-reading of the
|
|
250
|
+
issue. Six sources:
|
|
251
|
+
|
|
252
|
+
1. **Acceptance criteria** — the frozen `AC-N` anchor (the DoD core, hard-gated by
|
|
253
|
+
`check-acceptance`).
|
|
254
|
+
2. **Repo policy** — invariants/CANON in scope (cite `INV-NN` ids).
|
|
255
|
+
3. **Required tests** — the TDD units proving each `AC-N`, named up front.
|
|
256
|
+
4. **CI** — which gate checks/lanes the slice must keep green (L1/L2, workflows).
|
|
257
|
+
5. **Review/security** — the review verticals and security surfaces the diff will face.
|
|
258
|
+
6. **Dependencies** — modules/contracts the slice touches (blast radius via `/impact`).
|
|
259
|
+
|
|
260
|
+
Record `landing route supported: yes/no` and, when no, the blocking reason.
|
|
261
|
+
Adversarial review runs against this contract **before push**. Pricing the constraint set
|
|
262
|
+
in before the first line is what kills accordion PRs (write → review reveals a missed
|
|
263
|
+
constraint → rewrite → repeat).
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Plan contents (mandatory sections)
|
|
268
|
+
|
|
269
|
+
/ship plans with a SINGLE planner; these mandatory sections make that one plan carry what a multi-specialist panel would have produced (#2176 study: union-of-specialists prompt reproduced 3-specialist content at +19% cost vs +69% for real orchestration, equal quality — multi-specialist planning is NOT adopted).
|
|
270
|
+
|
|
271
|
+
- **Approach & decomposition** — module boundaries and data flow of the change.
|
|
272
|
+
- **Threat model & abuse cases** — who can abuse this and how. `n/a — no security surface` is accepted only with a one-line justification; a bare `n/a` is a plan-review FAIL.
|
|
273
|
+
- **Input validation** — what is validated, where the trust boundary is, what happens on invalid input.
|
|
274
|
+
- **Idiomatic patterns & pitfalls** — the recommended stdlib/framework APIs for this change and the known traps to avoid.
|
|
275
|
+
- **Acceptance criteria (merged)** — the frozen `AC-N` anchor VERBATIM, extended with security ACs and edge cases that continue the same numeric `AC-N` series (the anchor parser only accepts numeric ids like `AC-4` — or the dotted per-issue `AC-<issue>.<n>` form a train plan uses, see §Train; hand-invented ids such as `AC-S1` fail the gate); extend the existing `## Acceptance Criteria` anchor, never a rival heading.
|
|
276
|
+
- **Test strategy** — which TDD units prove which AC, and at which level (unit/integration/gate).
|
|
277
|
+
- **Risks** — what can go wrong, with the mitigation or the accepted residual.
|
|
278
|
+
|
|
279
|
+
Never one-shot it — draft, then revise once before finalizing: the revise pass was part of the measured treatment, not optional polish.
|
|
280
|
+
|
|
281
|
+
These sections EXPAND the Merge Contract's six sources (merged ACs ⊃ source 1, test strategy ⊃ source 3, threat model ⊃ source 5, decomposition ⊃ source 6) — derive the contract once, express it here.
|
|
282
|
+
|
|
283
|
+
Plan-review agents verify every mandatory section is present and non-empty; a missing or empty section is a FAIL verdict in `.arbiter/evidence/plan-review/<id>/latest.json`. No separate gate script exists for this — the reviewers are the check.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Companion plugins
|
|
288
|
+
|
|
289
|
+
`arbiter ship` is **companion-aware**. If a known companion plugin (first-class: **ponytail**, a
|
|
290
|
+
YAGNI drafting persona) is installed in your Claude home, the `green` step composes with it and every
|
|
291
|
+
step announces which companions are active:
|
|
292
|
+
|
|
293
|
+
```
|
|
294
|
+
Companion: ponytail (full) · arbiter gates remain the safety net
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
- **Detected HOME-only** — a companion is a per-user tool choice; your repo is never scanned, so a
|
|
298
|
+
cloned repo can never force a companion on you.
|
|
299
|
+
- **`lite` / `full`, never `ultra`** — ultra skips tests, incompatible with TDD.
|
|
300
|
+
- **Graceful** — no companion installed ⇒ ship is byte-identical to before (no `Companion:` line).
|
|
301
|
+
- **Gates stay authoritative** — if the persona cuts too much, your gate catches it.
|
|
302
|
+
|
|
303
|
+
Configure in `arbiter.json` (optional): `companions.ponytail.enabled=false` disables it;
|
|
304
|
+
`companions.ponytail.mode="lite"` or `"full"` wins explicitly. Without an override, arbiter
|
|
305
|
+
uses a conservative stack default: `java`, `kotlin`, and `csharp` resolve companions to `lite`;
|
|
306
|
+
other stacks (including TypeScript/JavaScript/Python) stay on the policy default `full`.
|
|
307
|
+
`ultra` is never representable. arbiter never vendors a companion's code.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## FEATURE_MATRIX (consume at plan, maintain at verification)
|
|
312
|
+
|
|
313
|
+
The project's `FEATURE_MATRIX.md` is the product RTM. /ship keeps it from being write-only ceremony by
|
|
314
|
+
**reading it at `plan`** and **updating it at `verification`** — so it drives the next action instead
|
|
315
|
+
of just being audited by the gate.
|
|
316
|
+
|
|
317
|
+
**At `plan`** — find the REQ row(s) this issue advances (match on the `issue_ref` column):
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
grep -rnE "REQ-[0-9]+" --include=FEATURE_MATRIX.md . | grep "#NNN"
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
If a row matches, surface its `feature_id`, current `status`, and the **gap to promote** (which of
|
|
324
|
+
`code_ref` / `test_ref` / `doc_ref` is empty), and state in the plan how this work advances that REQ.
|
|
325
|
+
If no row matches, the issue is out of product-RTM scope — note it and move on.
|
|
326
|
+
|
|
327
|
+
**At `verification`** — if the work supplied a missing `code_ref` / `test_ref` / `doc_ref`, update that
|
|
328
|
+
row (refs + status) and include the matrix change in the **same PR** (atomic code + SSOT). The
|
|
329
|
+
FEATURE_MATRIX gate (part of `check-all`) refreshes the counters and validates `status ⟺ refs` — e.g.
|
|
330
|
+
`Done` requires all three refs to exist on disk — so a status the refs don't back up fails closed.
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Gate economy (dev loop)
|
|
335
|
+
|
|
336
|
+
During `green` / `refactor` iteration, do **not** re-run `node scripts/check-all.mjs` — that
|
|
337
|
+
is the gate for the `verification` phase, and pre-commit / pre-push hooks already enforce it at
|
|
338
|
+
the boundary. Re-running it per edit wastes wall-clock.
|
|
339
|
+
|
|
340
|
+
Run only what covers the files you actually touched:
|
|
341
|
+
- the granular check script(s) whose scope includes the changed file(s),
|
|
342
|
+
- `<%= _testCommand %> run <path>` for added or changed tests,
|
|
343
|
+
- a formatter `--check` on just the edited files.
|
|
344
|
+
|
|
345
|
+
Resolve everything in one work session, then let the `verification` phase run the full gate
|
|
346
|
+
once. This is a **speed** optimization, not a gate skip. In a normal checkout the hooks run
|
|
347
|
+
the boundary checks before commit (L1) and before push (L2); the pre-commit hook intentionally
|
|
348
|
+
skips L1 in Git worktrees because their shared `node_modules` makes the license probe invalid
|
|
349
|
+
(#1695). That worktree skip is not an L1 PASS: run `node scripts/check-all.mjs L1` independently
|
|
350
|
+
in the worktree before committing and retain its receipt; the canonical integration checkout/CI
|
|
351
|
+
must repeat L1, and the push boundary must run L2.
|
|
352
|
+
|
|
353
|
+
Optional, at `verification` and before release-class changes: run `/tabletop <scenario>` to
|
|
354
|
+
walk one user journey end to end and record where the docs and the behaviour disagree
|
|
355
|
+
(`docs/internal/METHOD/TABLETOP-SCENARIOS.md`). It is evidence-only and never edits the tree;
|
|
356
|
+
blockers are hard stops — ship nothing until each one is fixed or filed with an owner.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Red-team review
|
|
361
|
+
|
|
362
|
+
<% if (governanceLevel !== 'L1') { %>
|
|
363
|
+
After advancing to `red-team-review`, dispatch **N parallel agents** (XS=1, S=2, Standard=3). Each agent
|
|
364
|
+
self-selects an attack angle from: `security`, `concurrency`, `performance`, `edge-cases`, `regression`,
|
|
365
|
+
`dependency`, `data-integrity`, `error-handling`.
|
|
366
|
+
|
|
367
|
+
**Evidence path:** `.arbiter/evidence/redteam/<task-id>.json` (schema: `RedTeamEvidenceV1`).
|
|
368
|
+
|
|
369
|
+
**Forward-link to code-review (#1212):** record each finding in the unified task document as
|
|
370
|
+
`redTeamFindings` — `{ id: "RT-01", severity, summary, auditorHint, resolved: false }` — where
|
|
371
|
+
`auditorHint` names the `auditor-routing.json` auditor whose remit covers the finding. At code-review,
|
|
372
|
+
every still-`resolved:false` finding caps its mapped auditor's verdict score and is tagged
|
|
373
|
+
`[RT-xx UNRESOLVED]`. Flip `resolved` to `true` once addressed.
|
|
374
|
+
|
|
375
|
+
| Impact | Action |
|
|
376
|
+
|--------|--------|
|
|
377
|
+
| CRITICAL | `arbiter task advance --to red-team-rework` → revise plan → re-run red-team-review |
|
|
378
|
+
| HIGH / MEDIUM | Adapt plan in-place before advancing |
|
|
379
|
+
| SUGGESTION | Note only — no blocking |
|
|
380
|
+
|
|
381
|
+
**Refutation of high-stakes findings (skill: `refutation`).** As soon as the red-team
|
|
382
|
+
returns findings, the orchestrator — not the reviewing agent — writes the marker
|
|
383
|
+
`.arbiter/evidence/agent-returns/<task>/refutation-required.json` listing every finding at
|
|
384
|
+
severity `high` or `critical`, then dispatches the skeptics (counts from
|
|
385
|
+
`.claude/agent-dispatch-matrix.json` `refutation_skeptics`: XS/S=1, where the red-team is
|
|
386
|
+
the skeptic; Standard=3). Writing the marker at this point is a numbered step of the review
|
|
387
|
+
phase, not a choice: `scripts/check-refutation-verdicts.mjs` adjudicates only when the
|
|
388
|
+
marker exists, so a marker left unwritten is a gate that never fires. No findings at or
|
|
389
|
+
above `high` ⇒ write the marker with an empty `findings` array, which records that the
|
|
390
|
+
threshold was evaluated.
|
|
391
|
+
|
|
392
|
+
<% } %>
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Refactor / code-review evidence
|
|
397
|
+
|
|
398
|
+
**Review rounds are bounded.** Entering `refactor` opens round 1; each review dispatched after a
|
|
399
|
+
FIX is `arbiter ship --review-round`, which counts. A completion-gate retry does not: re-dispatching
|
|
400
|
+
a reviewer that returned no envelope re-reads the same diff, so it is the same round. Round N ≥ 2
|
|
401
|
+
reviews the DELTA only — `git diff <lastReviewedSha>..HEAD`, printed as the step's `Review scope:`
|
|
402
|
+
line — never the whole change again: re-reading a growing diff always finds something new, which is
|
|
403
|
+
how a review loop burns a day without converging. Reviewer findings **below HIGH do not block
|
|
404
|
+
landing** — park them (`arbiter note` each, then ONE follow-up issue) and land; that threshold is
|
|
405
|
+
about REVIEWER findings, while the ac-fit verdicts below are a separate hard gate still requiring
|
|
406
|
+
all-PASS. The cap is `ship.review.maxRounds` in `arbiter.json` (default 2): the round past it is
|
|
407
|
+
refused naming both exits, and `arbiter ship --review-round --force-review` takes it deliberately
|
|
408
|
+
and records `forced`. Rounds are counted per train, like every other ceremony.
|
|
409
|
+
|
|
410
|
+
<% if (governanceLevel !== 'L1') { %>
|
|
411
|
+
<% if (_soloMode) { %>
|
|
412
|
+
**Solo review — independent reviewer (1 agent):**
|
|
413
|
+
|
|
414
|
+
Dispatch a single independent code-review agent covering: bugs & logic errors, type safety,
|
|
415
|
+
domain consistency (AGENTS.md / ADRs), silent failures (swallowed exceptions, wrong
|
|
416
|
+
fallbacks). The reviewer is a fresh subagent that receives the diff, the plan's frozen
|
|
417
|
+
anchor and the impact report — never the implementation transcript: a reviewer that shares
|
|
418
|
+
the implementer's context inherits the implementer's blind spots, which is the failure mode
|
|
419
|
+
review exists to catch.
|
|
420
|
+
|
|
421
|
+
Security escalation applies in trunk-solo too: when the escalation fires, the agent writes
|
|
422
|
+
`"count":3` and the three reviewer names into the `printf` instead of `1` and `["independent-review"]`
|
|
423
|
+
in `.arbiter/agents-dispatched.json` (#2177). Where `route-auditors.mjs` and
|
|
424
|
+
`.claude/auditor-routing.json` exist (arbiter's own tree), run the router without `--size-floor`
|
|
425
|
+
and read its `active` array; where they do not exist — every generated project, since neither file
|
|
426
|
+
is emitted — apply the same rule by inspecting changed paths for auth/authz, crypto and secret
|
|
427
|
+
material, database migrations and SQL, and CI workflow and permission config. A missing router is
|
|
428
|
+
never a "no security surface" verdict.
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
# Record dispatch evidence — fail-closed Stop hook (INV-114) reads branch+sha from this file
|
|
432
|
+
# The validated external-review path records the complete reviewer panel atomically; preserve the
|
|
433
|
+
# fulfilled Codex seat and do not add another Anthropic seat.
|
|
434
|
+
# Evidence source: `.arbiter/evidence/cross-model/<task>/dispatch.json`.
|
|
435
|
+
external_review_fulfilled=0
|
|
436
|
+
if ! task_id_json="$(node -e 'const f=require("node:fs"),t=JSON.parse(f.readFileSync(".claude/.task/status.json","utf8")).taskId;if(typeof t!=="string"||!/^#[0-9]+$/.test(t))process.exit(2);process.stdout.write(JSON.stringify(t))' 2>/dev/null)"; then
|
|
437
|
+
echo 'ERROR: active task id is missing or invalid' >&2
|
|
438
|
+
exit 2
|
|
439
|
+
fi
|
|
440
|
+
if ! task_tier="$(node -e 'const f=require("node:fs"),t=JSON.parse(f.readFileSync(".claude/.task/status.json","utf8")).tier;if(!["XS","S","Standard"].includes(t))process.exit(2);process.stdout.write(t)' 2>/dev/null)"; then
|
|
441
|
+
echo 'ERROR: active task tier is missing or invalid' >&2
|
|
442
|
+
exit 2
|
|
443
|
+
fi
|
|
444
|
+
review_agents_json='["independent-review"]'
|
|
445
|
+
if [ "$task_tier" = Standard ]; then
|
|
446
|
+
candidate_review_agents_json="$(node - "$review_agents_json" <<'NODE'
|
|
447
|
+
const agents = JSON.parse(process.argv[2])
|
|
448
|
+
if (!Array.isArray(agents) || agents.length === 0 || agents.some((agent) => typeof agent !== 'string'))
|
|
449
|
+
process.exit(2)
|
|
450
|
+
const candidate = [...agents]
|
|
451
|
+
const codex = candidate.indexOf('codex-reviewer')
|
|
452
|
+
if (codex === -1) candidate[candidate.length - 1] = 'codex-reviewer'
|
|
453
|
+
if (candidate.filter((agent) => agent === 'codex-reviewer').length !== 1)
|
|
454
|
+
process.exit(2)
|
|
455
|
+
process.stdout.write(JSON.stringify(candidate))
|
|
456
|
+
NODE
|
|
457
|
+
)"
|
|
458
|
+
candidate_review_count="$(node -e 'const agents=JSON.parse(process.argv[1]);process.stdout.write(String(agents.length))' "$candidate_review_agents_json")"
|
|
459
|
+
checker_status=0
|
|
460
|
+
node scripts/check-cross-model-review.mjs --require-fulfilled --record-panel "$candidate_review_agents_json" --record-count "$candidate_review_count" >/dev/null 2>&1 || checker_status=$?
|
|
461
|
+
if [ "$checker_status" = 0 ]; then
|
|
462
|
+
external_review_fulfilled=1
|
|
463
|
+
review_agents_json="$candidate_review_agents_json"
|
|
464
|
+
elif node scripts/check-cross-model-review.mjs --require-degraded >/dev/null 2>&1; then
|
|
465
|
+
:
|
|
466
|
+
elif node -e 'const f=require("node:fs");try{const c=JSON.parse(f.readFileSync("arbiter.json","utf8")),r=process.env.ARBITER_CROSS_MODEL_REVIEW?.trim().toLowerCase(),o=r===undefined?undefined:["true","1","yes","on"].includes(r)?true:["false","0","no","off"].includes(r)?false:undefined;process.exit((o??c.crossModelReview?.enabled)===true&&c.crossModelReview?.onUnavailable==="fail"?0:1)}catch{process.exit(1)}'; then
|
|
467
|
+
echo 'ERROR: cross-model review is required and did not fulfill its Codex seat' >&2
|
|
468
|
+
exit "$checker_status"
|
|
469
|
+
else
|
|
470
|
+
echo 'ERROR: cross-model review failed without valid degradation evidence' >&2
|
|
471
|
+
exit "$checker_status"
|
|
472
|
+
fi
|
|
473
|
+
fi
|
|
474
|
+
if [ "$external_review_fulfilled" != 1 ]; then
|
|
475
|
+
node - "$review_agents_json" "1" "$task_id_json" <<'NODE' || exit 2
|
|
476
|
+
const fs = require('node:fs')
|
|
477
|
+
const path = require('node:path')
|
|
478
|
+
const crypto = require('node:crypto')
|
|
479
|
+
const child = require('node:child_process')
|
|
480
|
+
|
|
481
|
+
if (process.platform === 'win32')
|
|
482
|
+
throw new Error('secure reviewer sidecar writing is unsupported on Windows')
|
|
483
|
+
|
|
484
|
+
const [agentsJson, countText, taskIdJson] = process.argv.slice(2)
|
|
485
|
+
const agents = JSON.parse(agentsJson)
|
|
486
|
+
const count = Number(countText)
|
|
487
|
+
const taskId = JSON.parse(taskIdJson)
|
|
488
|
+
if (!Number.isInteger(count) || !Array.isArray(agents) || agents.length !== count)
|
|
489
|
+
throw new Error('invalid reviewer sidecar panel')
|
|
490
|
+
|
|
491
|
+
const descriptorPath = (fd) => `${process.platform === 'linux' ? '/proc/self/fd' : '/dev/fd'}/${fd}`
|
|
492
|
+
const directoryFlags = fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW
|
|
493
|
+
let dirFd = -1
|
|
494
|
+
try {
|
|
495
|
+
dirFd = fs.openSync('/', directoryFlags)
|
|
496
|
+
for (const part of path.resolve(process.cwd()).split('/').filter(Boolean).concat('.arbiter')) {
|
|
497
|
+
const childPath = path.join(descriptorPath(dirFd), part)
|
|
498
|
+
try {
|
|
499
|
+
fs.mkdirSync(childPath)
|
|
500
|
+
} catch (error) {
|
|
501
|
+
if (error?.code !== 'EEXIST') throw error
|
|
502
|
+
}
|
|
503
|
+
const nextFd = fs.openSync(childPath, directoryFlags)
|
|
504
|
+
fs.closeSync(dirFd)
|
|
505
|
+
dirFd = nextFd
|
|
506
|
+
}
|
|
507
|
+
const dirPath = descriptorPath(dirFd)
|
|
508
|
+
const tempPath = path.join(dirPath, `.arbiter-tmp-${crypto.randomBytes(4).toString('hex')}`)
|
|
509
|
+
let tempFd = -1
|
|
510
|
+
let pendingTemp = tempPath
|
|
511
|
+
try {
|
|
512
|
+
tempFd = fs.openSync(
|
|
513
|
+
tempPath,
|
|
514
|
+
fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_NOFOLLOW,
|
|
515
|
+
0o600,
|
|
516
|
+
)
|
|
517
|
+
const branch = child.execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
518
|
+
encoding: 'utf8',
|
|
519
|
+
}).trim()
|
|
520
|
+
const sha = child.execFileSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).trim()
|
|
521
|
+
fs.writeFileSync(tempFd, `${JSON.stringify({ count, agents, branch, sha, taskId })}\n`)
|
|
522
|
+
fs.closeSync(tempFd)
|
|
523
|
+
tempFd = -1
|
|
524
|
+
fs.renameSync(tempPath, path.join(dirPath, 'agents-dispatched.json'))
|
|
525
|
+
pendingTemp = null
|
|
526
|
+
} finally {
|
|
527
|
+
if (tempFd !== -1) {
|
|
528
|
+
try {
|
|
529
|
+
fs.closeSync(tempFd)
|
|
530
|
+
} catch {
|
|
531
|
+
// Preserve the primary write error.
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
if (pendingTemp !== null) {
|
|
535
|
+
try {
|
|
536
|
+
fs.unlinkSync(pendingTemp)
|
|
537
|
+
} catch {
|
|
538
|
+
// Preserve the primary write error.
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
} finally {
|
|
543
|
+
if (dirFd !== -1) fs.closeSync(dirFd)
|
|
544
|
+
}
|
|
545
|
+
NODE
|
|
546
|
+
fi
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
Write this file only after the reviewer subagent has actually been dispatched — "I reviewed
|
|
550
|
+
it" without an agent tool call does not satisfy the gate, and the fail-closed Stop hook
|
|
551
|
+
(INV-114) reads branch+sha from this file, so a sidecar written for an undispatched reviewer
|
|
552
|
+
makes every later completion claim false.
|
|
553
|
+
|
|
554
|
+
**Persist.** The reviewer hands back an `arbiter-agent-return-v1` envelope with `role: "reviewer"`
|
|
555
|
+
and `agent: "independent-review"`, piped through `node scripts/record-agent-return.mjs --task '#NNN'`.
|
|
556
|
+
|
|
557
|
+
```bash
|
|
558
|
+
node scripts/check-review-completion.mjs --task '#NNN'
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
On non-zero: re-dispatch only the agent(s) named by the failure, exactly once, persist their returns
|
|
562
|
+
the same way, and re-run the check. If it still fails, stop and report the blocked agent —
|
|
563
|
+
advancing past an incomplete review is what the completion gate exists to prevent (it is
|
|
564
|
+
what turns 77% ITT into 88% per-protocol; see §Phase map). An agent that exhausted its turn budget but wrote its findings counts as COMPLETED —
|
|
565
|
+
it is never re-dispatched; only a missing or malformed artifact is.
|
|
566
|
+
|
|
567
|
+
<% } else { %>
|
|
568
|
+
**Dispatch parallel review agents (run ALL simultaneously):**
|
|
569
|
+
|
|
570
|
+
Each reviewer's mandate is the FULL active vertical floor for the tier — bugs & logic, type safety &
|
|
571
|
+
patterns, domain consistency, plus the tier's widened verticals — and its NAME is only its lead angle.
|
|
572
|
+
The #2176 study found a broad vs conformance-only mandate worth -0.5pp, so the count is what matters,
|
|
573
|
+
not the split. Lead angles for this dispatch: <%- Array.from({ length: _tiers.Standard.reviewAgentCount }, (_, i) => `\`${_reviewLeadAngles[i] ?? `reviewer-${i + 1}`}\``).join(', ') %>.
|
|
574
|
+
**Silent failure hunter:** silent failures remain in the FULL mandate; this is not a separate agent.
|
|
575
|
+
|
|
576
|
+
```bash
|
|
577
|
+
# Record dispatch evidence — fail-closed Stop hook (INV-114) reads branch+sha from this file
|
|
578
|
+
# review_agents: the exact reviewer names you dispatched — one per agent, same names the envelopes carry.
|
|
579
|
+
# The validated external-review path records the complete reviewer panel atomically; preserve the
|
|
580
|
+
# fulfilled Codex seat and do not add another Anthropic seat.
|
|
581
|
+
# Evidence source: `.arbiter/evidence/cross-model/<task>/dispatch.json`.
|
|
582
|
+
external_review_fulfilled=0
|
|
583
|
+
if ! task_id_json="$(node -e 'const f=require("node:fs"),t=JSON.parse(f.readFileSync(".claude/.task/status.json","utf8")).taskId;if(typeof t!=="string"||!/^#[0-9]+$/.test(t))process.exit(2);process.stdout.write(JSON.stringify(t))' 2>/dev/null)"; then
|
|
584
|
+
echo 'ERROR: active task id is missing or invalid' >&2
|
|
585
|
+
exit 2
|
|
586
|
+
fi
|
|
587
|
+
if ! task_tier="$(node -e 'const f=require("node:fs"),t=JSON.parse(f.readFileSync(".claude/.task/status.json","utf8")).tier;if(!["XS","S","Standard"].includes(t))process.exit(2);process.stdout.write(t)' 2>/dev/null)"; then
|
|
588
|
+
echo 'ERROR: active task tier is missing or invalid' >&2
|
|
589
|
+
exit 2
|
|
590
|
+
fi
|
|
591
|
+
review_agents_json='[<%- Array.from({ length: _tiers.Standard.reviewAgentCount }, (_, i) => `"${_reviewLeadAngles[i] ?? `reviewer-${i + 1}`}"`).join(',') %>]'
|
|
592
|
+
if [ "$task_tier" = Standard ]; then
|
|
593
|
+
candidate_review_agents_json="$(node - "$review_agents_json" <<'NODE'
|
|
594
|
+
const agents = JSON.parse(process.argv[2])
|
|
595
|
+
if (!Array.isArray(agents) || agents.length === 0 || agents.some((agent) => typeof agent !== 'string'))
|
|
596
|
+
process.exit(2)
|
|
597
|
+
const candidate = [...agents]
|
|
598
|
+
const codex = candidate.indexOf('codex-reviewer')
|
|
599
|
+
if (codex === -1) candidate[candidate.length - 1] = 'codex-reviewer'
|
|
600
|
+
if (candidate.filter((agent) => agent === 'codex-reviewer').length !== 1)
|
|
601
|
+
process.exit(2)
|
|
602
|
+
process.stdout.write(JSON.stringify(candidate))
|
|
603
|
+
NODE
|
|
604
|
+
)"
|
|
605
|
+
candidate_review_count="$(node -e 'const agents=JSON.parse(process.argv[1]);process.stdout.write(String(agents.length))' "$candidate_review_agents_json")"
|
|
606
|
+
checker_status=0
|
|
607
|
+
node scripts/check-cross-model-review.mjs --require-fulfilled --record-panel "$candidate_review_agents_json" --record-count "$candidate_review_count" >/dev/null 2>&1 || checker_status=$?
|
|
608
|
+
if [ "$checker_status" = 0 ]; then
|
|
609
|
+
external_review_fulfilled=1
|
|
610
|
+
review_agents_json="$candidate_review_agents_json"
|
|
611
|
+
elif node scripts/check-cross-model-review.mjs --require-degraded >/dev/null 2>&1; then
|
|
612
|
+
:
|
|
613
|
+
elif node -e 'const f=require("node:fs");try{const c=JSON.parse(f.readFileSync("arbiter.json","utf8")),r=process.env.ARBITER_CROSS_MODEL_REVIEW?.trim().toLowerCase(),o=r===undefined?undefined:["true","1","yes","on"].includes(r)?true:["false","0","no","off"].includes(r)?false:undefined;process.exit((o??c.crossModelReview?.enabled)===true&&c.crossModelReview?.onUnavailable==="fail"?0:1)}catch{process.exit(1)}'; then
|
|
614
|
+
echo 'ERROR: cross-model review is required and did not fulfill its Codex seat' >&2
|
|
615
|
+
exit "$checker_status"
|
|
616
|
+
else
|
|
617
|
+
echo 'ERROR: cross-model review failed without valid degradation evidence' >&2
|
|
618
|
+
exit "$checker_status"
|
|
619
|
+
fi
|
|
620
|
+
fi
|
|
621
|
+
if [ "$external_review_fulfilled" != 1 ]; then
|
|
622
|
+
node - "$review_agents_json" "<%= _tiers.Standard.reviewAgentCount %>" "$task_id_json" <<'NODE' || exit 2
|
|
623
|
+
const fs = require('node:fs')
|
|
624
|
+
const path = require('node:path')
|
|
625
|
+
const crypto = require('node:crypto')
|
|
626
|
+
const child = require('node:child_process')
|
|
627
|
+
|
|
628
|
+
if (process.platform === 'win32')
|
|
629
|
+
throw new Error('secure reviewer sidecar writing is unsupported on Windows')
|
|
630
|
+
|
|
631
|
+
const [agentsJson, countText, taskIdJson] = process.argv.slice(2)
|
|
632
|
+
const agents = JSON.parse(agentsJson)
|
|
633
|
+
const count = Number(countText)
|
|
634
|
+
const taskId = JSON.parse(taskIdJson)
|
|
635
|
+
if (!Number.isInteger(count) || !Array.isArray(agents) || agents.length !== count)
|
|
636
|
+
throw new Error('invalid reviewer sidecar panel')
|
|
637
|
+
|
|
638
|
+
const descriptorPath = (fd) => `${process.platform === 'linux' ? '/proc/self/fd' : '/dev/fd'}/${fd}`
|
|
639
|
+
const directoryFlags = fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW
|
|
640
|
+
let dirFd = -1
|
|
641
|
+
try {
|
|
642
|
+
dirFd = fs.openSync('/', directoryFlags)
|
|
643
|
+
for (const part of path.resolve(process.cwd()).split('/').filter(Boolean).concat('.arbiter')) {
|
|
644
|
+
const childPath = path.join(descriptorPath(dirFd), part)
|
|
645
|
+
try {
|
|
646
|
+
fs.mkdirSync(childPath)
|
|
647
|
+
} catch (error) {
|
|
648
|
+
if (error?.code !== 'EEXIST') throw error
|
|
649
|
+
}
|
|
650
|
+
const nextFd = fs.openSync(childPath, directoryFlags)
|
|
651
|
+
fs.closeSync(dirFd)
|
|
652
|
+
dirFd = nextFd
|
|
653
|
+
}
|
|
654
|
+
const dirPath = descriptorPath(dirFd)
|
|
655
|
+
const tempPath = path.join(dirPath, `.arbiter-tmp-${crypto.randomBytes(4).toString('hex')}`)
|
|
656
|
+
let tempFd = -1
|
|
657
|
+
let pendingTemp = tempPath
|
|
658
|
+
try {
|
|
659
|
+
tempFd = fs.openSync(
|
|
660
|
+
tempPath,
|
|
661
|
+
fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_NOFOLLOW,
|
|
662
|
+
0o600,
|
|
663
|
+
)
|
|
664
|
+
const branch = child.execFileSync('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {
|
|
665
|
+
encoding: 'utf8',
|
|
666
|
+
}).trim()
|
|
667
|
+
const sha = child.execFileSync('git', ['rev-parse', 'HEAD'], { encoding: 'utf8' }).trim()
|
|
668
|
+
fs.writeFileSync(tempFd, `${JSON.stringify({ count, agents, branch, sha, taskId })}\n`)
|
|
669
|
+
fs.closeSync(tempFd)
|
|
670
|
+
tempFd = -1
|
|
671
|
+
fs.renameSync(tempPath, path.join(dirPath, 'agents-dispatched.json'))
|
|
672
|
+
pendingTemp = null
|
|
673
|
+
} finally {
|
|
674
|
+
if (tempFd !== -1) {
|
|
675
|
+
try {
|
|
676
|
+
fs.closeSync(tempFd)
|
|
677
|
+
} catch {
|
|
678
|
+
// Preserve the primary write error.
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if (pendingTemp !== null) {
|
|
682
|
+
try {
|
|
683
|
+
fs.unlinkSync(pendingTemp)
|
|
684
|
+
} catch {
|
|
685
|
+
// Preserve the primary write error.
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
} finally {
|
|
690
|
+
if (dirFd !== -1) fs.closeSync(dirFd)
|
|
691
|
+
}
|
|
692
|
+
NODE
|
|
693
|
+
fi
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
When the security escalation fires, dispatch a third reviewer whose lead angle is the security-class
|
|
697
|
+
vertical that fired and include its name in `agents[]` and the `count` — the sidecar must never
|
|
698
|
+
under-declare the reviewers actually dispatched (#2177).
|
|
699
|
+
|
|
700
|
+
Write the sidecar only after the agents have actually been dispatched — "I reviewed it"
|
|
701
|
+
without agent tool calls does not satisfy this gate, and the fail-closed Stop hook (INV-114)
|
|
702
|
+
reads branch+sha from this file, so a sidecar written for undispatched reviewers makes every
|
|
703
|
+
later completion claim false.
|
|
704
|
+
|
|
705
|
+
**Persist.** Every reviewer hands back an `arbiter-agent-return-v1` envelope with `role: "reviewer"`
|
|
706
|
+
and `agent` equal to its name in `agents[]`, piped through `node scripts/record-agent-return.mjs --task '#NNN'`.
|
|
707
|
+
|
|
708
|
+
```bash
|
|
709
|
+
node scripts/check-review-completion.mjs --task '#NNN'
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
On non-zero: re-dispatch only the agent(s) named by the failure, exactly once, persist their returns
|
|
713
|
+
the same way, and re-run the check. If it still fails, stop and report the blocked agent —
|
|
714
|
+
advancing past an incomplete review is what the completion gate exists to prevent (it is
|
|
715
|
+
what turns 77% ITT into 88% per-protocol; see §Phase map). An agent that exhausted its turn budget but wrote its findings counts as COMPLETED —
|
|
716
|
+
it is never re-dispatched; only a missing or malformed artifact is.
|
|
717
|
+
|
|
718
|
+
<% } %>
|
|
719
|
+
|
|
720
|
+
**Adversarial Verifier (runs after review, every tier — review checks quality, the verifier
|
|
721
|
+
checks fit, and neither substitutes for the other):** Trace each new feature end-to-end; check dead code,
|
|
722
|
+
CLI option wiring end-to-end (flag declared → parsed → forwarded), fixture assumptions and test setup.
|
|
723
|
+
|
|
724
|
+
**FIT rubric (INV-138):** The verifier judges FIT against the plan's frozen `## Acceptance
|
|
725
|
+
Criteria` anchor — not a re-reading of the live issue (mutable) and not "is this good
|
|
726
|
+
code". For **each** `AC-N`: verdict PASS / FAIL / NOT-TESTED **with the diff or test
|
|
727
|
+
`file:line` that proves it** — an uncited PASS does not count. Write the verdicts to
|
|
728
|
+
`.arbiter/evidence/ac-fit/<taskId>.json` with the taskId SANITIZED for the filename —
|
|
729
|
+
`#` and `/` stripped, so task `#42` writes `42.json` (schema `arbiter-ac-fit-v1`,
|
|
730
|
+
committed; the `check-acceptance` gate validates it and hard-requires all-PASS at
|
|
731
|
+
verification/close).
|
|
732
|
+
Any FAIL or NOT-TESTED blocks advance — unproven criterion = REJECT. A REJECT that forces
|
|
733
|
+
a redo is rework data:
|
|
734
|
+
`[ -f scripts/rework-log.mjs ] && node scripts/rework-log.mjs add --issue NNN --reason <r> --caught review`
|
|
735
|
+
When the script is absent (brownfield trees predating its emission, ADR-110), note
|
|
736
|
+
`rework-log: script absent — skipped` next to the REJECT so the lost data point is visible.
|
|
737
|
+
|
|
738
|
+
<% } %>
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## Merge step
|
|
743
|
+
|
|
744
|
+
|
|
745
|
+
<% if (_collaborationMode === 'trunk-solo' && _mergeMode === 'direct') { %>
|
|
746
|
+
**trunk-solo + direct:** fast-forward the local branch onto `main` after a green gate:
|
|
747
|
+
|
|
748
|
+
```bash
|
|
749
|
+
git fetch origin main && git rebase origin/main
|
|
750
|
+
node scripts/check-all.mjs L2
|
|
751
|
+
git push origin HEAD:main # ff-only
|
|
752
|
+
```
|
|
753
|
+
<% } else { %>
|
|
754
|
+
<% if (_collaborationMode === 'trunk-solo') { %>
|
|
755
|
+
**trunk-solo + pr-ff:** open a PR as the check/audit carrier, then atomically
|
|
756
|
+
fast-forward `main` to the exact gated head SHA:
|
|
757
|
+
<% } else { %>
|
|
758
|
+
**peer-review / gated-review:** open a PR and merge without rewriting its commits.
|
|
759
|
+
|
|
760
|
+
> **This arc does NOT land the exact gated SHA.** The GitHub merge gives `main` a new
|
|
761
|
+
> tip, so here `main != gatedHeadSha` — the exact-SHA guarantee of `trunk-solo + pr-ff`
|
|
762
|
+
> does not carry over. Landing the gated head itself needs a trusted updater (a GitHub
|
|
763
|
+
> App authorised to advance the ref), tracked on #2289. Until it exists this is the only
|
|
764
|
+
> landing path available in these modes, and `scripts/pr-merge-watch.mjs` refuses them
|
|
765
|
+
> outright rather than pretending otherwise.
|
|
766
|
+
<% } %>
|
|
767
|
+
|
|
768
|
+
```bash
|
|
769
|
+
gh pr create --title "type(#NNN): summary" --body "$(cat <<'PRBODY'
|
|
770
|
+
## Summary
|
|
771
|
+
<1-3 bullet points of what changed and why>
|
|
772
|
+
|
|
773
|
+
## Changes
|
|
774
|
+
- `file/path.ts`: <what changed>
|
|
775
|
+
- `__tests__/...`: <tests added/updated>
|
|
776
|
+
|
|
777
|
+
## Test plan
|
|
778
|
+
- [ ] New tests pass (`<%= _testCommand %> run <path>`)
|
|
779
|
+
- [ ] Gate green (`node scripts/check-all.mjs L1`)
|
|
780
|
+
- [ ] Acceptance criteria verified (list each criterion: PASS/FAIL)
|
|
781
|
+
|
|
782
|
+
Closes #NNN
|
|
783
|
+
PRBODY
|
|
784
|
+
)"
|
|
785
|
+
<% if (_collaborationMode === 'trunk-solo') { %>
|
|
786
|
+
node scripts/pr-merge-watch.mjs \
|
|
787
|
+
"$(gh repo view --json nameWithOwner -q .nameWithOwner)" \
|
|
788
|
+
"$(gh pr view --json number -q .number)"
|
|
789
|
+
<% } else { %>
|
|
790
|
+
gh pr checks --watch
|
|
791
|
+
gh pr merge --merge
|
|
792
|
+
<% } %>
|
|
793
|
+
```
|
|
794
|
+
<% } %>
|
|
795
|
+
|
|
796
|
+
---
|
|
797
|
+
|
|
798
|
+
## Complete
|
|
799
|
+
|
|
800
|
+
<% if (typeof enableEvidenceHarness !== 'undefined' && enableEvidenceHarness !== false) { -%>
|
|
801
|
+
Capture done-evidence on the final committed candidate **before push**. It reuses
|
|
802
|
+
only a natively verified current L3 marker, otherwise runs one L3, then records
|
|
803
|
+
pinned files and required runtime proof. The native push verifier may reuse this
|
|
804
|
+
L3 at its L2 boundary. After merge, validate the unchanged receipt and exact refs;
|
|
805
|
+
do not repeat capture merely because the phase advanced.
|
|
806
|
+
|
|
807
|
+
Capture command (also releases the `guard-done-evidence` hook):
|
|
808
|
+
|
|
809
|
+
```bash
|
|
810
|
+
node scripts/done-evidence.mjs
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
<% } -%>
|
|
814
|
+
Close the issue:
|
|
815
|
+
|
|
816
|
+
<% if (_backend === 'github') { %>
|
|
817
|
+
```bash
|
|
818
|
+
gh issue close NNN
|
|
819
|
+
```
|
|
820
|
+
<% } else { %>
|
|
821
|
+
Mark the work item done manually (no CLI command for the `markdown` backend — the `work` command was
|
|
822
|
+
removed in #1817; track closure in your issue tracker of choice).
|
|
823
|
+
<% } %>
|
|
824
|
+
|
|
825
|
+
Advance to the terminal phase and close the worktree. `--to complete` now VERIFIES the landing:
|
|
826
|
+
it reads the branch's PR (`gh pr list --head <branch> --state all`) and refuses unless it is
|
|
827
|
+
MERGED, naming the PR, its state and every check whose conclusion is FAILURE / TIMED_OUT /
|
|
828
|
+
CANCELLED. A repo that lands by direct push passes `--no-pr` (logged as
|
|
829
|
+
`complete ← no-pr (direct landing)`); `--pr <n>` names the PR when the branch carries more than
|
|
830
|
+
one. With evidenceHarness active, the independent engine additionally requires the
|
|
831
|
+
passed v2 receipt and PR head/merge refs matching the qualified candidate, with
|
|
832
|
+
concluded successful CI. An unreadable `gh` refuses too — an unverifiable landing is not a landing.
|
|
833
|
+
|
|
834
|
+
```bash
|
|
835
|
+
arbiter task advance --to complete
|
|
836
|
+
arbiter wt close NNN
|
|
837
|
+
```
|
|
838
|
+
|
|
839
|
+
### Handover
|
|
840
|
+
|
|
841
|
+
A session may end in exactly two states: the PR is **merged**, or the PR is labeled
|
|
842
|
+
`needs-human` and the handover names the failing check. There is no third state — an open PR
|
|
843
|
+
with red CI that nobody owns is the failure this rule exists to prevent.
|
|
844
|
+
|
|
845
|
+
The handover file is `.arbiter/HANDOVER-<date>-<slug>.md` and its FIRST section is the open-PR
|
|
846
|
+
table, so whoever picks it up sees the debt before the narrative:
|
|
847
|
+
|
|
848
|
+
```markdown
|
|
849
|
+
## Open PRs
|
|
850
|
+
|
|
851
|
+
| PR | Branch | CI state | Blocker |
|
|
852
|
+
| ---- | ----------------------- | ---------------- | -------------------------------- |
|
|
853
|
+
| #123 | task/#120-thing | red (Docs Build) | needs-human: link check 404s |
|
|
854
|
+
| #124 | task/#121-other | green, unmerged | awaiting required review |
|
|
855
|
+
```
|
|
856
|
+
|
|
857
|
+
Every red row carries the check name and the `gh run view --job <id> --log` the watcher printed.
|
|
858
|
+
A row with no blocker text is an unfinished handover, not a finished one.
|
|
859
|
+
|
|
860
|
+
---
|
|
861
|
+
|
|
862
|
+
## Plan mode (auto)
|
|
863
|
+
|
|
864
|
+
At the **start of the `plan` phase** — and only when `.claude/.task/status.json` shows `phase` ∈
|
|
865
|
+
{`preflight`, `plan`} — call `EnterPlanMode` to enforce no-edit discipline while drafting the plan.
|
|
866
|
+
Do NOT call EnterPlanMode when resuming an exec phase (check the phase-doc first).
|
|
867
|
+
|
|
868
|
+
At **GO/handoff** (plan-review gate green):
|
|
869
|
+
1. Call `ExitPlanMode`.
|
|
870
|
+
2. Advance to red-team-review (no units yet — `checkHandoffGate` is not triggered here):
|
|
871
|
+
```bash
|
|
872
|
+
arbiter ship #NNN --advance
|
|
873
|
+
```
|
|
874
|
+
3. After red-team-review completes, advance to **red** with the unit count from the plan (§7):
|
|
875
|
+
```bash
|
|
876
|
+
arbiter ship #NNN --advance --units <N>
|
|
877
|
+
```
|
|
878
|
+
This is the transition where `checkHandoffGate` fires and the size-driven strategy applies.
|
|
879
|
+
4. Follow the printed banner: it shows the strategy (`inline` / `sub-agent` / `stop`) and the
|
|
880
|
+
exact resume steps (use `--post-clear` on re-entry after a `/clear`).
|
|
881
|
+
|
|
882
|
+
---
|
|
883
|
+
|
|
884
|
+
## Hard stops
|
|
885
|
+
|
|
886
|
+
- A phase gate throws (plan-review FAIL, TDD evidence missing, budget breach) → fix the root cause; do
|
|
887
|
+
not bypass. `arbiter ship --advance` surfaces the gate's exit code (78 handoff, 79 budget).
|
|
888
|
+
- CRITICAL red-team finding → `arbiter task advance --to red-team-rework`, revise, re-run review.
|
|
889
|
+
- If `tasks.worktree` is `always` in `arbiter.json`, open a worktree before any edit — a ship
|
|
890
|
+
that skipped it stops here, because every downstream artifact (branch, evidence, gate) is
|
|
891
|
+
anchored to the worktree.
|
|
892
|
+
- The fail-closed Stop hook (INV-114) requires three correlated artifacts before any completion claim:
|
|
893
|
+
plan-review `latest.json` (written by the plan-review dispatch — not a CLI command since #1817),
|
|
894
|
+
`.arbiter/agents-dispatched.json`
|
|
895
|
+
(written in the refactor section above), `.arbiter/gate-pass.json` (written by the gate). The
|
|
896
|
+
`phase: complete` state releases the guard. Review evidence binds to SOURCE CONTENT, not to an
|
|
897
|
+
exact HEAD: an evidence-only commit keeps it valid, a source change invalidates it, and a sidecar
|
|
898
|
+
whose `taskId` is another task counts as absent — record this task's own before claiming.
|
|
899
|
+
- An open PR with red CI is never abandoned — watch, fix, re-watch. Ending a session on one is
|
|
900
|
+
allowed only with the PR labeled `needs-human` and the failing check named in the handover.
|
|
901
|
+
- Never skip the gate, never commit to `main` outside the merge step, never leave the loop mid-phase
|
|
902
|
+
without an `arbiter mark` cursor.
|