devrites 3.0.7 → 3.2.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 +18 -0
- package/README.md +82 -50
- package/SECURITY.md +31 -29
- package/docs/adr/0001-go-engine-as-control-plane.md +1 -1
- package/docs/adr/0002-dual-host-harness.md +1 -1
- package/docs/adr/0004-state-schema-phases-sections.md +1 -2
- package/docs/adr/0006-clock-seam-and-engine-ci-gates.md +3 -4
- package/docs/adr/0009-prebuild-decision-coverage-and-readiness.md +67 -0
- package/docs/adr/0010-agent-first-fresh-context-orchestration.md +71 -0
- package/docs/adr/0011-define-plan-transition-rights.md +28 -0
- package/docs/adr/0012-semantic-workspace-upgrades.md +77 -0
- package/docs/adr/README.md +4 -0
- package/docs/agents/triage-labels.md +7 -7
- package/docs/architecture.md +179 -141
- package/docs/cli.md +47 -12
- package/docs/command-map.md +61 -38
- package/docs/engine/agent-contract.md +92 -15
- package/docs/engine/commands.md +248 -72
- package/docs/engine/state-schema.md +52 -23
- package/docs/engine/workspace-schema.md +103 -15
- package/docs/extensions.md +1 -1
- package/docs/flow.md +86 -51
- package/docs/harness-compliance.md +29 -5
- package/docs/orchestration.md +107 -79
- package/docs/quick-reference.md +11 -3
- package/docs/release.md +4 -3
- package/docs/skills.md +67 -38
- package/docs/usage.md +84 -39
- package/engine/cmd/releasepack/main.go +219 -0
- package/engine/cmd/releasepack/main_test.go +170 -0
- package/engine/commands.go +170 -23
- package/engine/git_guard.go +187 -0
- package/engine/git_guard_test.go +283 -0
- package/engine/hookpolicy.go +53 -55
- package/engine/hookpolicy_test.go +91 -1
- package/engine/hooks.go +296 -75
- package/engine/hooks_events_test.go +276 -6
- package/engine/hooks_workspace.go +640 -159
- package/engine/internal/devritespaths/paths.go +65 -10
- package/engine/internal/devritespaths/paths_test.go +110 -0
- package/engine/internal/doctor/doctor.go +153 -23
- package/engine/internal/doctor/doctor_test.go +74 -0
- package/engine/internal/forge/forge.go +940 -0
- package/engine/internal/forge/forge_test.go +576 -0
- package/engine/internal/forge/git.go +245 -0
- package/engine/internal/forge/liveness_unix.go +48 -0
- package/engine/internal/forge/liveness_windows.go +67 -0
- package/engine/internal/forge/manifest.go +402 -0
- package/engine/internal/gate/gate.go +90 -71
- package/engine/internal/gate/gate_test.go +71 -2
- package/engine/internal/harness/compliance.go +18 -24
- package/engine/internal/harness/harness.go +37 -44
- package/engine/internal/harness/harness_test.go +21 -5
- package/engine/internal/install/install.go +486 -38
- package/engine/internal/install/install_test.go +383 -10
- package/engine/internal/iohooks/iohooks.go +350 -59
- package/engine/internal/iohooks/iohooks_test.go +421 -1
- package/engine/internal/lib/buildreadiness.go +43 -18
- package/engine/internal/lib/clarifyreturn.go +91 -0
- package/engine/internal/lib/clarifyreturn_test.go +123 -0
- package/engine/internal/lib/context.go +54 -15
- package/engine/internal/lib/cursor_compat_test.go +8 -0
- package/engine/internal/lib/extensions.go +2 -3
- package/engine/internal/lib/gitauthority.go +601 -0
- package/engine/internal/lib/gitauthority_test.go +346 -0
- package/engine/internal/lib/jsonout.go +25 -11
- package/engine/internal/lib/jsonout_test.go +16 -0
- package/engine/internal/lib/lanes.go +14 -8
- package/engine/internal/lib/observability_test.go +358 -0
- package/engine/internal/lib/packageexistence.go +151 -35
- package/engine/internal/lib/packageexistence_test.go +163 -0
- package/engine/internal/lib/progress.go +11 -9
- package/engine/internal/lib/provenance.go +462 -0
- package/engine/internal/lib/provenance_test.go +154 -0
- package/engine/internal/lib/readiness_contract.json +118 -0
- package/engine/internal/lib/readinessartifact.go +533 -0
- package/engine/internal/lib/readinessartifact_test.go +422 -0
- package/engine/internal/lib/reconcile.go +712 -88
- package/engine/internal/lib/reconcile_test.go +335 -16
- package/engine/internal/lib/recoveryattempts.go +298 -0
- package/engine/internal/lib/recoveryattempts_test.go +215 -0
- package/engine/internal/lib/resolve.go +23 -19
- package/engine/internal/lib/runbook_context_test.go +20 -0
- package/engine/internal/lib/session.go +701 -9
- package/engine/internal/lib/session_test.go +80 -13
- package/engine/internal/lib/testintegrity.go +33 -37
- package/engine/internal/lib/testintegrity_test.go +63 -1
- package/engine/internal/migrate/migrate.go +81 -1
- package/engine/internal/migrate/migrate_test.go +22 -1
- package/engine/internal/reason/reason.go +180 -0
- package/engine/internal/reason/reason_test.go +35 -0
- package/engine/internal/rootfacts/facts.go +466 -0
- package/engine/internal/rootfacts/facts_test.go +306 -0
- package/engine/internal/safepath/safepath.go +55 -0
- package/engine/internal/safepath/safepath_test.go +69 -0
- package/engine/internal/safepath/safepath_windows_test.go +26 -0
- package/engine/internal/state/clarify_transition.go +165 -0
- package/engine/internal/state/clarify_transition_test.go +130 -0
- package/engine/internal/state/cmd/workflowmanifest/main.go +12 -8
- package/engine/internal/state/cursor.go +58 -0
- package/engine/internal/state/cursor_test.go +42 -1
- package/engine/internal/state/feature.go +35 -48
- package/engine/internal/state/schema.go +90 -37
- package/engine/internal/state/snapshot.go +18 -2
- package/engine/internal/state/state_test.go +187 -7
- package/engine/internal/state/status.go +48 -11
- package/engine/internal/state/workflow_manifest.json +231 -50
- package/engine/internal/toolpolicy/classifier.go +533 -0
- package/engine/internal/toolpolicy/classifier_test.go +424 -0
- package/engine/internal/toolpolicy/git.go +616 -0
- package/engine/internal/toolpolicy/scanner.go +382 -0
- package/engine/main.go +160 -77
- package/engine/observability_cli_test.go +52 -0
- package/engine/root_routing_test.go +277 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=approved.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=emptystatus.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=legacycontract.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=noclarify.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=novet.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=stalevet.golden +1 -0
- package/engine/testdata/golden/TestParityBuildReadiness/arg=trailhash.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=trailpipe.golden +1 -1
- package/engine/testdata/golden/TestParityBuildReadiness/arg=vetnotready.golden +1 -0
- package/engine/testdata/golden/TestParityProgress/arg=allbuilt.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=done.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=mid.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=nophase.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=noslice.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=plan.golden +1 -1
- package/engine/testdata/golden/TestParityProgress/arg=seal.golden +1 -1
- package/engine/testdata/golden/TestParityReconcile/check-clean.golden +1 -1
- package/engine/testdata/golden/TestParityReconcile/inline-fallback.golden +1 -0
- package/engine/testdata/golden/TestParityReconcile/snapshot-no-allowlist.golden +1 -0
- package/engine/testdata/golden/TestParityWrightScope/devrites-edit-denied.golden +2 -0
- package/engine/testdata/golden/TestParityWrightScope/out-of-scope-enforce-denies.golden +1 -1
- package/engine/tests/adr_0011_define_plan_test.go +30 -0
- package/engine/tests/budget_test.go +19 -8
- package/engine/tests/concurrency_cli_test.go +7 -1
- package/engine/tests/doctor_cli_test.go +148 -2
- package/engine/tests/forge_cli_test.go +463 -0
- package/engine/tests/gate_test.go +63 -8
- package/engine/tests/hook_test.go +260 -8
- package/engine/tests/hooks_io_test.go +94 -3
- package/engine/tests/json_contract_test.go +127 -2
- package/engine/tests/migrate_cli_test.go +2 -2
- package/engine/tests/parity_buildreadiness_test.go +167 -10
- package/engine/tests/parity_learnings_test.go +16 -17
- package/engine/tests/parity_reconcile_test.go +20 -17
- package/engine/tests/parity_resolve_test.go +12 -11
- package/engine/tests/parity_test.go +21 -17
- package/pack/.claude/agents/devrites-code-reviewer.md +62 -48
- package/pack/.claude/agents/devrites-devex-reviewer.md +69 -53
- package/pack/.claude/agents/devrites-doubt-reviewer.md +29 -22
- package/pack/.claude/agents/devrites-evidence-scout.md +69 -0
- package/pack/.claude/agents/devrites-forge-judge.md +74 -61
- package/pack/.claude/agents/devrites-frontend-reviewer.md +48 -39
- package/pack/.claude/agents/devrites-performance-reviewer.md +49 -40
- package/pack/.claude/agents/devrites-plan-drafter.md +73 -0
- package/pack/.claude/agents/devrites-plan-reviewer.md +80 -47
- package/pack/.claude/agents/devrites-proof-runner.md +74 -0
- package/pack/.claude/agents/devrites-retrospector.md +48 -45
- package/pack/.claude/agents/devrites-security-auditor.md +46 -36
- package/pack/.claude/agents/devrites-simplifier-reviewer.md +50 -46
- package/pack/.claude/agents/devrites-slice-wright.md +153 -165
- package/pack/.claude/agents/devrites-spec-reviewer.md +34 -32
- package/pack/.claude/agents/devrites-strategy-reviewer.md +63 -34
- package/pack/.claude/agents/devrites-test-analyst.md +40 -30
- package/pack/.claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/.claude/settings.json +2 -1
- package/pack/.claude/skills/devrites-audit/SKILL.md +40 -61
- package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +24 -13
- package/pack/.claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/.claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/.claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/.claude/skills/devrites-doubt/SKILL.md +25 -17
- package/pack/.claude/skills/devrites-interview/SKILL.md +53 -52
- package/pack/.claude/skills/devrites-lib/SKILL.md +12 -9
- package/pack/.claude/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/.claude/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/.claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/.claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/.claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/.claude/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/.claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/.claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/.claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/.claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/.claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/.claude/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/.claude/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/.claude/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/.claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/.claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/.claude/skills/rite/SKILL.md +10 -6
- package/pack/.claude/skills/rite/reference/menu.md +13 -7
- package/pack/.claude/skills/rite-adopt/SKILL.md +33 -37
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +33 -28
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/.claude/skills/rite-build/SKILL.md +35 -30
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/.claude/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/.claude/skills/rite-build/reference/forge.md +186 -156
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/.claude/skills/rite-clarify/SKILL.md +90 -0
- package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/.claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/.claude/skills/rite-define/SKILL.md +58 -32
- package/pack/.claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/.claude/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/.claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/.claude/skills/rite-plan/SKILL.md +47 -16
- package/pack/.claude/skills/rite-plan/reference/task-breakdown.md +4 -0
- package/pack/.claude/skills/rite-polish/SKILL.md +27 -23
- package/pack/.claude/skills/rite-prototype/SKILL.md +25 -26
- package/pack/.claude/skills/rite-prove/SKILL.md +27 -17
- package/pack/.claude/skills/rite-resolve/SKILL.md +12 -11
- package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/.claude/skills/rite-review/SKILL.md +37 -28
- package/pack/.claude/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/.claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/.claude/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/.claude/skills/rite-spec/SKILL.md +84 -135
- package/pack/.claude/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/.claude/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/.claude/skills/rite-temper/SKILL.md +62 -47
- package/pack/.claude/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/.claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/.claude/skills/rite-vet/SKILL.md +114 -113
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/.claude/skills/rite-vet/reference/review-axes.md +39 -37
- package/pack/generated/claude/agents/devrites-code-reviewer.md +62 -48
- package/pack/generated/claude/agents/devrites-devex-reviewer.md +69 -53
- package/pack/generated/claude/agents/devrites-doubt-reviewer.md +29 -22
- package/pack/generated/claude/agents/devrites-evidence-scout.md +69 -0
- package/pack/generated/claude/agents/devrites-forge-judge.md +74 -61
- package/pack/generated/claude/agents/devrites-frontend-reviewer.md +48 -39
- package/pack/generated/claude/agents/devrites-performance-reviewer.md +49 -40
- package/pack/generated/claude/agents/devrites-plan-drafter.md +73 -0
- package/pack/generated/claude/agents/devrites-plan-reviewer.md +80 -47
- package/pack/generated/claude/agents/devrites-proof-runner.md +74 -0
- package/pack/generated/claude/agents/devrites-retrospector.md +48 -45
- package/pack/generated/claude/agents/devrites-security-auditor.md +46 -36
- package/pack/generated/claude/agents/devrites-simplifier-reviewer.md +50 -46
- package/pack/generated/claude/agents/devrites-slice-wright.md +153 -165
- package/pack/generated/claude/agents/devrites-spec-reviewer.md +34 -32
- package/pack/generated/claude/agents/devrites-strategy-reviewer.md +63 -34
- package/pack/generated/claude/agents/devrites-test-analyst.md +40 -30
- package/pack/generated/claude/agents/devrites-upgrade-planner.md +100 -0
- package/pack/generated/claude/settings.json +2 -1
- package/pack/generated/claude/skills/devrites-audit/SKILL.md +40 -61
- package/pack/generated/claude/skills/devrites-debug-recovery/SKILL.md +24 -13
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/generated/claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/generated/claude/skills/devrites-doubt/SKILL.md +25 -17
- package/pack/generated/claude/skills/devrites-interview/SKILL.md +53 -52
- package/pack/generated/claude/skills/devrites-lib/SKILL.md +12 -9
- package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/generated/claude/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/generated/claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/generated/claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/generated/claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/generated/claude/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/generated/claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/generated/claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/generated/claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/generated/claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/generated/claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/generated/claude/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/generated/claude/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/generated/claude/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/generated/claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/generated/claude/skills/rite/SKILL.md +10 -6
- package/pack/generated/claude/skills/rite/reference/menu.md +13 -7
- package/pack/generated/claude/skills/rite-adopt/SKILL.md +33 -37
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +33 -28
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/generated/claude/skills/rite-build/SKILL.md +35 -30
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/generated/claude/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/generated/claude/skills/rite-build/reference/forge.md +186 -156
- package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +90 -0
- package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/generated/claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/generated/claude/skills/rite-define/SKILL.md +58 -32
- package/pack/generated/claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/generated/claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/generated/claude/skills/rite-plan/SKILL.md +47 -16
- package/pack/generated/claude/skills/rite-plan/reference/task-breakdown.md +4 -0
- package/pack/generated/claude/skills/rite-polish/SKILL.md +27 -23
- package/pack/generated/claude/skills/rite-prototype/SKILL.md +25 -26
- package/pack/generated/claude/skills/rite-prove/SKILL.md +27 -17
- package/pack/generated/claude/skills/rite-resolve/SKILL.md +12 -11
- package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/generated/claude/skills/rite-review/SKILL.md +37 -28
- package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/generated/claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/generated/claude/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/generated/claude/skills/rite-spec/SKILL.md +84 -135
- package/pack/generated/claude/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/generated/claude/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/generated/claude/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/generated/claude/skills/rite-temper/SKILL.md +62 -47
- package/pack/generated/claude/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/generated/claude/skills/rite-upgrade/SKILL.md +125 -0
- package/pack/generated/claude/skills/rite-vet/SKILL.md +114 -113
- package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +39 -37
- package/pack/generated/codex/AGENTS.md +5 -2
- package/pack/generated/codex/agents/devrites-code-reviewer.toml +69 -47
- package/pack/generated/codex/agents/devrites-devex-reviewer.toml +75 -51
- package/pack/generated/codex/agents/devrites-doubt-reviewer.toml +35 -20
- package/pack/generated/codex/agents/devrites-evidence-scout.toml +75 -0
- package/pack/generated/codex/agents/devrites-forge-judge.toml +80 -59
- package/pack/generated/codex/agents/devrites-frontend-reviewer.toml +54 -37
- package/pack/generated/codex/agents/devrites-performance-reviewer.toml +55 -38
- package/pack/generated/codex/agents/devrites-plan-drafter.toml +79 -0
- package/pack/generated/codex/agents/devrites-plan-reviewer.toml +82 -47
- package/pack/generated/codex/agents/devrites-proof-runner.toml +80 -0
- package/pack/generated/codex/agents/devrites-retrospector.toml +54 -43
- package/pack/generated/codex/agents/devrites-security-auditor.toml +53 -35
- package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +56 -44
- package/pack/generated/codex/agents/devrites-slice-wright.toml +159 -163
- package/pack/generated/codex/agents/devrites-spec-reviewer.toml +40 -30
- package/pack/generated/codex/agents/devrites-strategy-reviewer.toml +65 -34
- package/pack/generated/codex/agents/devrites-test-analyst.toml +46 -28
- package/pack/generated/codex/agents/devrites-upgrade-planner.toml +106 -0
- package/pack/generated/codex/hooks.json +4 -14
- package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-audit/SKILL.md +47 -64
- package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-debug-recovery/SKILL.md +31 -16
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
- package/pack/generated/codex/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
- package/pack/generated/codex/skills/devrites-doubt/SKILL.md +32 -20
- package/pack/generated/codex/skills/devrites-frontend-craft/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-interview/SKILL.md +60 -55
- package/pack/generated/codex/skills/devrites-lib/SKILL.md +19 -12
- package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +4 -2
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
- package/pack/generated/codex/skills/devrites-lib/reference/reply-contract.md +8 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/README.md +38 -55
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +200 -190
- package/pack/generated/codex/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
- package/pack/generated/codex/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
- package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +16 -52
- package/pack/generated/codex/skills/devrites-lib/reference/standards/coding-style.md +2 -10
- package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
- package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +23 -18
- package/pack/generated/codex/skills/devrites-lib/reference/standards/deprecation.md +17 -57
- package/pack/generated/codex/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
- package/pack/generated/codex/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
- package/pack/generated/codex/skills/devrites-lib/reference/standards/hooks.md +3 -14
- package/pack/generated/codex/skills/devrites-lib/reference/standards/patterns.md +9 -25
- package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +0 -9
- package/pack/generated/codex/skills/devrites-lib/reference/standards/principles.md +1 -3
- package/pack/generated/codex/skills/devrites-lib/reference/standards/security.md +17 -7
- package/pack/generated/codex/skills/devrites-lib/reference/standards/testing.md +1 -27
- package/pack/generated/codex/skills/devrites-lib/reference/standards/tooling.md +46 -50
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +40 -10
- package/pack/generated/codex/skills/devrites-prose-craft/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-refresh-indexes/SKILL.md +7 -3
- package/pack/generated/codex/skills/devrites-source-driven/SKILL.md +29 -24
- package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite/SKILL.md +21 -13
- package/pack/generated/codex/skills/rite/reference/menu.md +13 -7
- package/pack/generated/codex/skills/rite-adopt/SKILL.md +40 -40
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +40 -31
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +21 -21
- package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
- package/pack/generated/codex/skills/rite-build/SKILL.md +42 -33
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +41 -39
- package/pack/generated/codex/skills/rite-build/reference/evidence-standard.md +10 -0
- package/pack/generated/codex/skills/rite-build/reference/forge.md +186 -156
- package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +4 -3
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +96 -175
- package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +10 -4
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +129 -134
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +106 -0
- package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +61 -0
- package/pack/generated/codex/skills/rite-converge/SKILL.md +42 -28
- package/pack/generated/codex/skills/rite-customize/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-define/SKILL.md +65 -35
- package/pack/generated/codex/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +18 -8
- package/pack/generated/codex/skills/rite-doctor/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-dogfood/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-explain/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-frame/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/generated/codex/skills/rite-handoff/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-learn/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-plan/SKILL.md +54 -19
- package/pack/generated/codex/skills/rite-plan/reference/task-breakdown.md +5 -1
- package/pack/generated/codex/skills/rite-polish/SKILL.md +34 -26
- package/pack/generated/codex/skills/rite-pov/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-pr-feedback/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-prototype/SKILL.md +32 -29
- package/pack/generated/codex/skills/rite-prove/SKILL.md +34 -20
- package/pack/generated/codex/skills/rite-quick/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-resolve/SKILL.md +19 -14
- package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +3 -0
- package/pack/generated/codex/skills/rite-review/SKILL.md +44 -31
- package/pack/generated/codex/skills/rite-seal/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +27 -92
- package/pack/generated/codex/skills/rite-seal/reference/risk-and-rollback.md +13 -0
- package/pack/generated/codex/skills/rite-ship/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-ship/reference/design-memory.md +31 -36
- package/pack/generated/codex/skills/rite-spec/SKILL.md +91 -138
- package/pack/generated/codex/skills/rite-spec/reference/investigation.md +37 -33
- package/pack/generated/codex/skills/rite-spec/reference/question-protocol.md +6 -2
- package/pack/generated/codex/skills/rite-spec/reference/spec-checklists.md +25 -24
- package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +9 -2
- package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +13 -3
- package/pack/generated/codex/skills/rite-status/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-temper/SKILL.md +69 -50
- package/pack/generated/codex/skills/rite-temper/reference/review-dimensions.md +24 -22
- package/pack/generated/codex/skills/rite-upgrade/SKILL.md +141 -0
- package/pack/generated/codex/skills/rite-upgrade/agents/openai.yaml +2 -0
- package/pack/generated/codex/skills/rite-vet/SKILL.md +121 -116
- package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +50 -9
- package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +40 -38
- package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +7 -3
- package/package.json +1 -1
- package/scripts/build-release-tarball.sh +32 -15
- package/scripts/check-authority-drift.py +125 -0
- package/scripts/check-instruction-size-baseline.mjs +19 -11
- package/scripts/check-invocation-integrity.py +2 -0
- package/scripts/codex-generate.sh +69 -33
- package/scripts/grade-feature.sh +121 -40
- package/scripts/live-hosts/agent-result.schema.json +230 -0
- package/scripts/live-hosts/claude.sh +87 -0
- package/scripts/live-hosts/codex.sh +81 -0
- package/scripts/live-hosts/common.sh +113 -0
- package/scripts/live-hosts/fake-host.py +264 -0
- package/scripts/live-hosts/host-transport.py +287 -0
- package/scripts/release-check.sh +5 -1
- package/scripts/run-agent-contract-evals.py +1380 -0
- package/scripts/run-behavioral-evals.sh +24 -30
- package/scripts/run-evals.sh +1 -5
- package/scripts/run-live-behavioral-evals.py +1274 -144
- package/scripts/run-outcome-evals.sh +445 -88
- package/scripts/run-tests.mjs +30 -2
- package/scripts/skills-inventory.mjs +1 -1
- package/scripts/validate-workflow-security.py +39 -20
- package/scripts/validate-workspace-schema.py +362 -10
- package/scripts/validate.sh +21 -15
- package/engine/testdata/golden/TestParityWrightScope/devrites-edit-allowed.golden +0 -1
- /package/engine/testdata/golden/{TestParityReconcile/check-no-claimed.golden → TestParityBuildReadiness/arg=clarifyopen.golden} +0 -0
|
@@ -2,30 +2,32 @@ package lib
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"bytes"
|
|
5
|
+
"encoding/json"
|
|
5
6
|
"os"
|
|
6
7
|
"path/filepath"
|
|
7
8
|
"strings"
|
|
8
9
|
"testing"
|
|
10
|
+
|
|
11
|
+
"github.com/devrites/devrites/internal/reason"
|
|
9
12
|
)
|
|
10
13
|
|
|
11
|
-
func
|
|
14
|
+
func TestTimelineLegacyWritesRejectedAndReadsPreserved(t *testing.T) {
|
|
12
15
|
t.Setenv("DEVRITES_NOW", "2026-07-09T10:11:12Z")
|
|
13
16
|
root := t.TempDir()
|
|
14
17
|
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if
|
|
18
|
-
t.Fatalf("timeline log failed: code=%d stdout=%q stderr=%q", code, stdout.String(), stderr.String())
|
|
19
|
-
}
|
|
20
|
-
data, err := os.ReadFile(filepath.Join(root, "timeline.jsonl"))
|
|
21
|
-
if err != nil {
|
|
18
|
+
legacy := []byte(`{"ts":"2026-07-09T10:11:12Z","event":"completed","decision":"ship"}` + "\n")
|
|
19
|
+
path := filepath.Join(root, "timeline.jsonl")
|
|
20
|
+
if err := os.WriteFile(path, legacy, 0o644); err != nil {
|
|
22
21
|
t.Fatal(err)
|
|
23
22
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
|
|
24
|
+
code := Timeline(root, []string{"log", "completed", "--skill", "rite-review", "--slug", "auth", "--outcome", "ok", "--decision", "PRIVATE_RESULT"}, stdout, stderr)
|
|
25
|
+
if code != 2 || !strings.Contains(stderr.String(), "legacy free-text writes are disabled") {
|
|
26
|
+
t.Fatalf("legacy timeline write code=%d stdout=%q stderr=%q", code, stdout.String(), stderr.String())
|
|
27
|
+
}
|
|
28
|
+
data, err := os.ReadFile(path)
|
|
29
|
+
if err != nil || !bytes.Equal(data, legacy) {
|
|
30
|
+
t.Fatalf("legacy write changed timeline: data=%q err=%v", data, err)
|
|
29
31
|
}
|
|
30
32
|
|
|
31
33
|
stdout.Reset()
|
|
@@ -44,6 +46,71 @@ func TestTimelineLogAndList(t *testing.T) {
|
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
func TestTimelineTypedFactsAreValidatedAndVersioned(t *testing.T) {
|
|
50
|
+
t.Setenv("DEVRITES_NOW", "2026-07-09T10:11:12Z")
|
|
51
|
+
t.Setenv("DEVRITES_RUN_ID", testRunID)
|
|
52
|
+
project := t.TempDir()
|
|
53
|
+
root := filepath.Join(project, ".devrites")
|
|
54
|
+
workspace := filepath.Join(root, "work", "auth")
|
|
55
|
+
if err := os.MkdirAll(workspace, 0o755); err != nil {
|
|
56
|
+
t.Fatal(err)
|
|
57
|
+
}
|
|
58
|
+
if err := os.WriteFile(filepath.Join(workspace, "state.md"), []byte("| phase | build |\n"), 0o644); err != nil {
|
|
59
|
+
t.Fatal(err)
|
|
60
|
+
}
|
|
61
|
+
t.Setenv("DEVRITES_ROOT", root)
|
|
62
|
+
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
63
|
+
code := Timeline(root, []string{
|
|
64
|
+
"log", "review-dispatch", "--slug", "auth",
|
|
65
|
+
"--execution-mode", "generic",
|
|
66
|
+
"--guard-strength", "observed",
|
|
67
|
+
"--reason-id", string(reason.AgentGenericFallback),
|
|
68
|
+
"--host", "codex",
|
|
69
|
+
"--evidence", ".devrites/work/auth/plan.md",
|
|
70
|
+
}, stdout, stderr)
|
|
71
|
+
if code != 0 {
|
|
72
|
+
t.Fatalf("timeline log code=%d stdout=%q stderr=%q", code, stdout.String(), stderr.String())
|
|
73
|
+
}
|
|
74
|
+
raw, err := os.ReadFile(filepath.Join(root, "timeline.jsonl"))
|
|
75
|
+
if err != nil {
|
|
76
|
+
t.Fatal(err)
|
|
77
|
+
}
|
|
78
|
+
var got EventV1
|
|
79
|
+
if err := json.Unmarshal(raw, &got); err != nil {
|
|
80
|
+
t.Fatal(err)
|
|
81
|
+
}
|
|
82
|
+
if got.Schema != EventSchemaV1 || got.ExecutionMode != ExecutionGeneric ||
|
|
83
|
+
got.GuardStrength != GuardObserved || got.ReasonID != reason.AgentGenericFallback ||
|
|
84
|
+
got.Host != HostCodex || got.Workspace != ".devrites/work/auth" {
|
|
85
|
+
t.Fatalf("typed event = %+v", got)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
stderr.Reset()
|
|
89
|
+
if code := Timeline(root, []string{
|
|
90
|
+
"log", "bad", "--execution-mode", "named", "--guard-strength", "enforced",
|
|
91
|
+
"--reason-id", "DRV-UNKNOWN",
|
|
92
|
+
}, &bytes.Buffer{}, stderr); code != 2 {
|
|
93
|
+
t.Fatalf("unknown reason code=%d stderr=%q", code, stderr.String())
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
func TestTimelineListPreservesAndDistinguishesLegacyAndCorruptRows(t *testing.T) {
|
|
98
|
+
root := t.TempDir()
|
|
99
|
+
legacy := `{"ts":"2026-01-01T00:00:00Z","event":"legacy"}`
|
|
100
|
+
corrupt := `{not-json}`
|
|
101
|
+
if err := os.WriteFile(filepath.Join(root, "timeline.jsonl"), []byte(legacy+"\n"+corrupt+"\n"), 0o644); err != nil {
|
|
102
|
+
t.Fatal(err)
|
|
103
|
+
}
|
|
104
|
+
stdout, stderr := &bytes.Buffer{}, &bytes.Buffer{}
|
|
105
|
+
if code := Timeline(root, []string{"list"}, stdout, stderr); code != 0 {
|
|
106
|
+
t.Fatalf("timeline list code=%d stderr=%q", code, stderr.String())
|
|
107
|
+
}
|
|
108
|
+
if got := stdout.String(); !strings.Contains(got, legacy) || !strings.Contains(got, corrupt) ||
|
|
109
|
+
strings.Contains(legacy, `"schema":"`+EventSchemaV1+`"`) {
|
|
110
|
+
t.Fatalf("legacy/corrupt history changed: %q", got)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
47
114
|
func TestHealthRecordValidatesScore(t *testing.T) {
|
|
48
115
|
t.Setenv("DEVRITES_NOW", "2026-07-09")
|
|
49
116
|
root := t.TempDir()
|
|
@@ -4,7 +4,6 @@ import (
|
|
|
4
4
|
"fmt"
|
|
5
5
|
"io"
|
|
6
6
|
"os"
|
|
7
|
-
"os/exec"
|
|
8
7
|
"path/filepath"
|
|
9
8
|
"regexp"
|
|
10
9
|
"strings"
|
|
@@ -18,14 +17,13 @@ var (
|
|
|
18
17
|
assertMarkers = regexp.MustCompile(`assert|expect\(|\.should\b|\brequire\.|EXPECT_|ASSERT_|XCTAssert|t\.Error|t\.Fatal`)
|
|
19
18
|
)
|
|
20
19
|
|
|
21
|
-
// TestIntegrity
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
// <root>/features/<slug>.
|
|
20
|
+
// TestIntegrity detects tests that were weakened instead of fixing the code. It
|
|
21
|
+
// compares test files in the retained reconcile tree with the current tree, or
|
|
22
|
+
// uses HEAD as the base outside a slice lifecycle. It does not modify the
|
|
23
|
+
// workspace at <root>/features/<slug>.
|
|
26
24
|
//
|
|
27
25
|
// 0 clean, or skipped because this is not a git repo
|
|
28
|
-
// 2 no active workspace /
|
|
26
|
+
// 2 no active workspace, bad args, or missing/corrupt baseline state
|
|
29
27
|
// 3 WEAKENED: a test was deleted, skipped, or de-asserted since the base
|
|
30
28
|
func TestIntegrity(root string, args []string, stdout, stderr io.Writer) int {
|
|
31
29
|
// Accept both `test-integrity [slug]` and the `check [slug]` alias; a leading
|
|
@@ -56,23 +54,26 @@ func TestIntegrity(root string, args []string, stdout, stderr io.Writer) int {
|
|
|
56
54
|
cwd, _ := os.Getwd()
|
|
57
55
|
gitRoot := gitToplevel(cwd)
|
|
58
56
|
if gitRoot == "" {
|
|
59
|
-
fmt.Fprintln(stderr, "test-integrity: not a git repo: gate skipped
|
|
57
|
+
fmt.Fprintln(stderr, "test-integrity: not a git repo: gate skipped; inspect the test diff manually.")
|
|
60
58
|
return 0
|
|
61
59
|
}
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
if
|
|
65
|
-
|
|
61
|
+
trees, err := captureSliceTreeRange(gitRoot, root, d)
|
|
62
|
+
if err != nil {
|
|
63
|
+
fmt.Fprintf(stderr, "test-integrity: cannot capture slice range: %v\n", err)
|
|
64
|
+
return 2
|
|
66
65
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
66
|
+
defer trees.cleanup()
|
|
67
|
+
changedPaths, err := changedTreePaths(gitRoot, trees.env, trees.base, trees.current)
|
|
68
|
+
if err != nil {
|
|
69
|
+
fmt.Fprintf(stderr, "test-integrity: cannot compare slice trees: %v\n", err)
|
|
70
|
+
return 2
|
|
70
71
|
}
|
|
71
72
|
|
|
72
73
|
weak := 0
|
|
73
74
|
srcChanged, testChanged := 0, 0
|
|
74
75
|
var report strings.Builder
|
|
75
|
-
for _, f := range
|
|
76
|
+
for _, f := range changedPaths {
|
|
76
77
|
if f == "" {
|
|
77
78
|
continue
|
|
78
79
|
}
|
|
@@ -83,19 +84,25 @@ func TestIntegrity(root string, args []string, stdout, stderr io.Writer) int {
|
|
|
83
84
|
continue
|
|
84
85
|
}
|
|
85
86
|
testChanged++
|
|
86
|
-
|
|
87
|
-
if
|
|
87
|
+
oldBytes, oldExists, err := treeFileContent(gitRoot, trees.env, trees.base, f)
|
|
88
|
+
if err != nil {
|
|
89
|
+
fmt.Fprintf(stderr, "test-integrity: cannot read baseline %s: %v\n", f, err)
|
|
90
|
+
return 2
|
|
91
|
+
}
|
|
92
|
+
if !oldExists || len(oldBytes) == 0 {
|
|
88
93
|
continue // new test file: adding tests is never a weakening
|
|
89
94
|
}
|
|
90
|
-
|
|
95
|
+
newBytes, newExists, err := treeFileContent(gitRoot, trees.env, trees.current, f)
|
|
96
|
+
if err != nil {
|
|
97
|
+
fmt.Fprintf(stderr, "test-integrity: cannot read current %s: %v\n", f, err)
|
|
98
|
+
return 2
|
|
99
|
+
}
|
|
100
|
+
if !newExists {
|
|
91
101
|
weak++
|
|
92
102
|
fmt.Fprintf(&report, " - %s: test file DELETED\n", f)
|
|
93
103
|
continue
|
|
94
104
|
}
|
|
95
|
-
|
|
96
|
-
if err != nil {
|
|
97
|
-
continue
|
|
98
|
-
}
|
|
105
|
+
old := string(oldBytes)
|
|
99
106
|
now := string(newBytes)
|
|
100
107
|
oldSkips, newSkips := countMatches(skipMarkers, old), countMatches(skipMarkers, now)
|
|
101
108
|
oldAsserts, newAsserts := countMatches(assertMarkers, old), countMatches(assertMarkers, now)
|
|
@@ -109,10 +116,9 @@ func TestIntegrity(root string, args []string, stdout, stderr io.Writer) int {
|
|
|
109
116
|
}
|
|
110
117
|
}
|
|
111
118
|
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
// with the change reverted. Printed on both the clean and weakened paths.
|
|
119
|
+
// When source changes without a test change, print the verification-gap
|
|
120
|
+
// advisory from testing.md. This is not a weakening verdict and appears on
|
|
121
|
+
// both clean and weakened paths.
|
|
116
122
|
gapAdvisory := ""
|
|
117
123
|
if srcChanged > 0 && testChanged == 0 {
|
|
118
124
|
gapAdvisory = fmt.Sprintf("test-integrity: advisory: %d source file(s) changed, 0 test file(s) touched; "+
|
|
@@ -122,7 +128,7 @@ func TestIntegrity(root string, args []string, stdout, stderr io.Writer) int {
|
|
|
122
128
|
if weak > 0 {
|
|
123
129
|
fmt.Fprintf(stderr, "test-integrity: WEAKENED: %d test file(s) lost coverage since the slice base:\n", weak)
|
|
124
130
|
fmt.Fprint(stderr, report.String())
|
|
125
|
-
fmt.Fprintln(stderr, "
|
|
131
|
+
fmt.Fprintln(stderr, "Weakening a test to pass the gate is a Critical finding. Restore the test, then fix the code or raise a blocking question.")
|
|
126
132
|
if gapAdvisory != "" {
|
|
127
133
|
fmt.Fprintln(stderr, gapAdvisory)
|
|
128
134
|
}
|
|
@@ -191,13 +197,3 @@ func isTestFile(f string) bool {
|
|
|
191
197
|
func countMatches(re *regexp.Regexp, text string) int {
|
|
192
198
|
return len(re.FindAllStringIndex(text, -1))
|
|
193
199
|
}
|
|
194
|
-
|
|
195
|
-
// gitShow returns the content of an object (e.g. "HEAD:path"), and false when it
|
|
196
|
-
// does not exist at that ref.
|
|
197
|
-
func gitShow(gitRoot, spec string) (string, bool) {
|
|
198
|
-
out, err := exec.Command("git", "-C", gitRoot, "show", spec).Output()
|
|
199
|
-
if err != nil {
|
|
200
|
-
return "", false
|
|
201
|
-
}
|
|
202
|
-
return string(out), true
|
|
203
|
-
}
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
package lib
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
"testing"
|
|
9
|
+
)
|
|
4
10
|
|
|
5
11
|
func TestIsTestFileClassifiesTests(t *testing.T) {
|
|
6
12
|
cases := []struct {
|
|
@@ -70,3 +76,59 @@ func TestIsSourceFileRecognisesCode(t *testing.T) {
|
|
|
70
76
|
}
|
|
71
77
|
}
|
|
72
78
|
}
|
|
79
|
+
|
|
80
|
+
func TestIntegrityDetectsDeletionFromDirtySliceBaseline(t *testing.T) {
|
|
81
|
+
gitRoot := newGitRepo(t)
|
|
82
|
+
root := workspace(t, "feat")
|
|
83
|
+
testPath := "tests/preexisting_test.go"
|
|
84
|
+
writeFile(t, filepath.Join(gitRoot, testPath), "package tests\n\nfunc TestBaseline(t *testing.T) { t.Fatal(\"assert\") }\n")
|
|
85
|
+
writeWrightAllowlist(t, root, "feat", testPath)
|
|
86
|
+
if code, out := runReconcile(t, root, "snapshot", "feat"); code != 0 {
|
|
87
|
+
t.Fatalf("snapshot = %d, want 0\n%s", code, out)
|
|
88
|
+
}
|
|
89
|
+
if err := os.Remove(filepath.Join(gitRoot, testPath)); err != nil {
|
|
90
|
+
t.Fatal(err)
|
|
91
|
+
}
|
|
92
|
+
if code, out := runReconcile(t, root, "check", "feat"); code != 0 {
|
|
93
|
+
t.Fatalf("reconcile check = %d, want 0\n%s", code, out)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
var stdout, stderr bytes.Buffer
|
|
97
|
+
code := TestIntegrity(root, []string{"feat"}, &stdout, &stderr)
|
|
98
|
+
if code != 3 {
|
|
99
|
+
t.Fatalf("test-integrity = %d, want 3\nstdout: %s\nstderr: %s", code, stdout.String(), stderr.String())
|
|
100
|
+
}
|
|
101
|
+
if !strings.Contains(stderr.String(), testPath+": test file DELETED") {
|
|
102
|
+
t.Fatalf("deleted dirty-baseline test missing from finding:\n%s", stderr.String())
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func TestIntegrityFailsClosedOnPartialReconcileBaseline(t *testing.T) {
|
|
107
|
+
newGitRepo(t)
|
|
108
|
+
root := workspace(t, "feat")
|
|
109
|
+
writeFile(t, filepath.Join(featureDir(root, "feat"), reconcileBaseName), "deadbeef\n")
|
|
110
|
+
|
|
111
|
+
var stdout, stderr bytes.Buffer
|
|
112
|
+
code := TestIntegrity(root, []string{"feat"}, &stdout, &stderr)
|
|
113
|
+
if code != 2 {
|
|
114
|
+
t.Fatalf("test-integrity = %d, want 2\nstdout: %s\nstderr: %s", code, stdout.String(), stderr.String())
|
|
115
|
+
}
|
|
116
|
+
if !strings.Contains(stderr.String(), "partial lifecycle") {
|
|
117
|
+
t.Fatalf("missing fail-closed lifecycle diagnostic:\n%s", stderr.String())
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
func TestIntegrityAdvisesWhenSourceChangesWithoutTests(t *testing.T) {
|
|
122
|
+
gitRoot := newGitRepo(t)
|
|
123
|
+
root := workspace(t, "feat")
|
|
124
|
+
writeFile(t, filepath.Join(gitRoot, "src", "feature.go"), "package src\n")
|
|
125
|
+
|
|
126
|
+
var stdout, stderr bytes.Buffer
|
|
127
|
+
code := TestIntegrity(root, []string{"feat"}, &stdout, &stderr)
|
|
128
|
+
if code != 0 {
|
|
129
|
+
t.Fatalf("test-integrity = %d, want 0\nstdout: %s\nstderr: %s", code, stdout.String(), stderr.String())
|
|
130
|
+
}
|
|
131
|
+
if !strings.Contains(stdout.String(), "source file(s) changed, 0 test file(s) touched") {
|
|
132
|
+
t.Fatalf("missing verification-gap advisory:\n%s", stdout.String())
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -11,6 +11,7 @@ import (
|
|
|
11
11
|
"path/filepath"
|
|
12
12
|
"slices"
|
|
13
13
|
"sort"
|
|
14
|
+
"strconv"
|
|
14
15
|
"strings"
|
|
15
16
|
"time"
|
|
16
17
|
|
|
@@ -93,6 +94,9 @@ func needsNormalizeFeature(dir string) bool {
|
|
|
93
94
|
if !regularFileExists(filepath.Join(dir, state.WorkspaceMapFile)) {
|
|
94
95
|
return true
|
|
95
96
|
}
|
|
97
|
+
if version := declaredSchemaVersion(dir); version < state.SchemaVersion {
|
|
98
|
+
return true
|
|
99
|
+
}
|
|
96
100
|
return regularFileExists(filepath.Join(dir, "proof.md")) && !regularFileExists(filepath.Join(dir, state.EvidenceFile)) ||
|
|
97
101
|
regularFileExists(filepath.Join(dir, "status.md")) && !regularFileExists(filepath.Join(dir, state.LedgerFile))
|
|
98
102
|
}
|
|
@@ -114,12 +118,88 @@ func normalizeFeatureDir(dir, slug string) error {
|
|
|
114
118
|
return fmt.Errorf("write workspace index: %w", err)
|
|
115
119
|
}
|
|
116
120
|
}
|
|
121
|
+
phase := derivePhase(filepath.Join(dir, state.LedgerFile))
|
|
122
|
+
if err := upgradeWorkspaceMapSchema(filepath.Join(dir, state.WorkspaceMapFile), slug, phase); err != nil {
|
|
123
|
+
return fmt.Errorf("upgrade workspace schema: %w", err)
|
|
124
|
+
}
|
|
117
125
|
if err := copyAliasFile(dir, "proof.md", state.EvidenceFile); err != nil {
|
|
118
126
|
return fmt.Errorf("copy proof.md to evidence.md: %w", err)
|
|
119
127
|
}
|
|
120
128
|
return copyAliasFile(dir, "status.md", state.LedgerFile)
|
|
121
129
|
}
|
|
122
130
|
|
|
131
|
+
func declaredSchemaVersion(dir string) int {
|
|
132
|
+
for _, name := range state.WorkspaceMapFiles() {
|
|
133
|
+
raw, err := os.ReadFile(filepath.Join(dir, name))
|
|
134
|
+
if err != nil {
|
|
135
|
+
continue
|
|
136
|
+
}
|
|
137
|
+
lines := strings.Split(string(raw), "\n")
|
|
138
|
+
if len(lines) == 0 || strings.TrimSpace(lines[0]) != "---" {
|
|
139
|
+
return 0
|
|
140
|
+
}
|
|
141
|
+
for _, line := range lines[1:] {
|
|
142
|
+
if strings.TrimSpace(line) == "---" {
|
|
143
|
+
break
|
|
144
|
+
}
|
|
145
|
+
key, value, ok := strings.Cut(line, ":")
|
|
146
|
+
if ok && strings.TrimSpace(key) == "schemaVersion" {
|
|
147
|
+
version, _ := strconv.Atoi(strings.TrimSpace(value))
|
|
148
|
+
return version
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return 0
|
|
152
|
+
}
|
|
153
|
+
return 0
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// upgradeWorkspaceMapSchema advances only the compatibility declaration. It
|
|
157
|
+
// never creates decision coverage, readiness, or proof artifacts: those must be
|
|
158
|
+
// earned by their owning phases.
|
|
159
|
+
func upgradeWorkspaceMapSchema(path, slug string, phase state.Phase) error {
|
|
160
|
+
raw, err := os.ReadFile(path)
|
|
161
|
+
if err != nil {
|
|
162
|
+
return err
|
|
163
|
+
}
|
|
164
|
+
version := declaredSchemaVersion(filepath.Dir(path))
|
|
165
|
+
if version > state.SchemaVersion {
|
|
166
|
+
return fmt.Errorf("schemaVersion %d is newer than this engine supports (%d)", version, state.SchemaVersion)
|
|
167
|
+
}
|
|
168
|
+
if version == state.SchemaVersion {
|
|
169
|
+
return nil
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
text := string(raw)
|
|
173
|
+
if !strings.HasPrefix(text, "---\n") {
|
|
174
|
+
prefix := fmt.Sprintf("---\nslug: %s\nphase: %s\nschemaVersion: %d\n---\n\n", slug, phase, state.SchemaVersion)
|
|
175
|
+
return state.AtomicWrite(path, []byte(prefix+text), 0o644)
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
lines := strings.Split(text, "\n")
|
|
179
|
+
end := -1
|
|
180
|
+
schemaLine := -1
|
|
181
|
+
for i := 1; i < len(lines); i++ {
|
|
182
|
+
if strings.TrimSpace(lines[i]) == "---" {
|
|
183
|
+
end = i
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
key, _, ok := strings.Cut(lines[i], ":")
|
|
187
|
+
if ok && strings.TrimSpace(key) == "schemaVersion" {
|
|
188
|
+
schemaLine = i
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if end < 0 {
|
|
192
|
+
return fmt.Errorf("workspace map has an unclosed frontmatter block")
|
|
193
|
+
}
|
|
194
|
+
value := fmt.Sprintf("schemaVersion: %d", state.SchemaVersion)
|
|
195
|
+
if schemaLine >= 0 {
|
|
196
|
+
lines[schemaLine] = value
|
|
197
|
+
} else {
|
|
198
|
+
lines = append(lines[:end], append([]string{value}, lines[end:]...)...)
|
|
199
|
+
}
|
|
200
|
+
return state.AtomicWrite(path, []byte(strings.Join(lines, "\n")), 0o644)
|
|
201
|
+
}
|
|
202
|
+
|
|
123
203
|
func copyAliasFile(dir, alias, canonical string) error {
|
|
124
204
|
src := filepath.Join(dir, alias)
|
|
125
205
|
dst := filepath.Join(dir, canonical)
|
|
@@ -133,7 +213,7 @@ func copyAliasFile(dir, alias, canonical string) error {
|
|
|
133
213
|
return state.AtomicWrite(dst, data, 0o644)
|
|
134
214
|
}
|
|
135
215
|
|
|
136
|
-
// workspaceIndex renders the compact map
|
|
216
|
+
// workspaceIndex renders the compact map used by a normalized workspace.
|
|
137
217
|
func workspaceIndex(slug string, phase state.Phase) string {
|
|
138
218
|
return fmt.Sprintf(`---
|
|
139
219
|
slug: %s
|
|
@@ -37,6 +37,7 @@ func TestRunNormalizesCanonicalWorkLayout(t *testing.T) {
|
|
|
37
37
|
assertFile(t, root, "work/alpha/evidence.md", "proof\n")
|
|
38
38
|
assertFile(t, root, "work/alpha/state.md", "status: done - shipped\n")
|
|
39
39
|
assertFileContains(t, root, "work/alpha/README.md", "phase: done")
|
|
40
|
+
assertFileContains(t, root, "work/alpha/README.md", "schemaVersion: 2")
|
|
40
41
|
assertMissing(t, root, "work/alpha/proof.md")
|
|
41
42
|
assertMissing(t, root, "work/alpha/status.md")
|
|
42
43
|
assertFile(t, root, "work/alpha/review.md", "review\n")
|
|
@@ -72,7 +73,8 @@ func TestRunNormalizesLiveFeatureAliases(t *testing.T) {
|
|
|
72
73
|
if got := strings.Join(res.Migrated, ","); got != "beta" {
|
|
73
74
|
t.Fatalf("Run normalized=%q, want beta", got)
|
|
74
75
|
}
|
|
75
|
-
|
|
76
|
+
assertFileContains(t, root, "features/beta/README.md", "schemaVersion: 2")
|
|
77
|
+
assertFileContains(t, root, "features/beta/README.md", "# Beta")
|
|
76
78
|
assertFile(t, root, "features/beta/state.md", "- Phase: prove\n")
|
|
77
79
|
assertFile(t, root, "features/beta/evidence.md", "evidence\n")
|
|
78
80
|
assertFile(t, root, "features/beta/status.md", "- Phase: prove\n")
|
|
@@ -87,6 +89,24 @@ func TestRunNormalizesLiveFeatureAliases(t *testing.T) {
|
|
|
87
89
|
}
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
func TestRunUpgradesV1DeclarationWithoutFabricatingReadiness(t *testing.T) {
|
|
93
|
+
root := t.TempDir()
|
|
94
|
+
testutil.WriteFile(t, filepath.Join(root, "work/old/README.md"), "---\nphase: vet\nschemaVersion: 1\n---\n\nOld workspace.\n")
|
|
95
|
+
testutil.WriteFile(t, filepath.Join(root, "work/old/state.md"), "| phase | vet |\n")
|
|
96
|
+
|
|
97
|
+
result, err := Run(root)
|
|
98
|
+
if err != nil {
|
|
99
|
+
t.Fatal(err)
|
|
100
|
+
}
|
|
101
|
+
if result.Skipped || strings.Join(result.Migrated, ",") != "old" {
|
|
102
|
+
t.Fatalf("result=%+v, want old migrated", result)
|
|
103
|
+
}
|
|
104
|
+
assertFileContains(t, root, "work/old/README.md", "schemaVersion: 2")
|
|
105
|
+
for _, name := range []string{"decision-coverage.md", "eng-review.md", "test-plan.md"} {
|
|
106
|
+
assertMissing(t, root, filepath.Join("work/old", name))
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
func TestMapLegacyPhase(t *testing.T) {
|
|
91
111
|
for _, phase := range state.LifecyclePhases() {
|
|
92
112
|
got, ok := mapLegacyPhase(string(phase))
|
|
@@ -101,6 +121,7 @@ func TestMapLegacyPhase(t *testing.T) {
|
|
|
101
121
|
ok bool
|
|
102
122
|
}{
|
|
103
123
|
{word: "specced", want: state.PhaseSpec, ok: true},
|
|
124
|
+
{word: "clarified", want: state.PhaseClarify, ok: true},
|
|
104
125
|
{word: "in-progress", want: state.PhaseBuild, ok: true},
|
|
105
126
|
{word: "reviewing", want: state.PhaseReview, ok: true},
|
|
106
127
|
{word: "done - shipped", want: state.PhaseDone, ok: true},
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// Package reason owns stable machine-readable decision identifiers.
|
|
2
|
+
package reason
|
|
3
|
+
|
|
4
|
+
import (
|
|
5
|
+
"fmt"
|
|
6
|
+
"sort"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// ID identifies one rule outcome independently of its human wording.
|
|
10
|
+
type ID string
|
|
11
|
+
|
|
12
|
+
const (
|
|
13
|
+
RootSelected ID = "DRV-ROOT-SELECTED"
|
|
14
|
+
|
|
15
|
+
GateReadinessPassed ID = "DRV-GATE-READINESS-PASSED" // #nosec G101 -- stable decision ID, not a credential
|
|
16
|
+
GateReadinessMissing ID = "DRV-GATE-READINESS-MISSING"
|
|
17
|
+
GateSealPassed ID = "DRV-GATE-SEAL-PASSED" // #nosec G101 -- stable decision ID, not a credential
|
|
18
|
+
GateSealMissing ID = "DRV-GATE-SEAL-MISSING"
|
|
19
|
+
|
|
20
|
+
HookDisabled ID = "DRV-HOOK-DISABLED"
|
|
21
|
+
HookAllowApproved ID = "DRV-HOOK-ALLOW-APPROVED"
|
|
22
|
+
HookStopClear ID = "DRV-HOOK-STOP-CLEAR"
|
|
23
|
+
HookStopInputInvalid ID = "DRV-HOOK-STOP-INPUT-INVALID"
|
|
24
|
+
HookStopReentry ID = "DRV-HOOK-STOP-REENTRY"
|
|
25
|
+
HookStopWorkspaceUnavailable ID = "DRV-HOOK-STOP-WORKSPACE-UNAVAILABLE" // #nosec G101 -- stable decision ID, not a credential
|
|
26
|
+
HookStopRed ID = "DRV-HOOK-STOP-RED"
|
|
27
|
+
HookStopUnsurfacedHumanGate ID = "DRV-HOOK-STOP-UNSURFACED-HUMAN-GATE"
|
|
28
|
+
HookStopMissingProof ID = "DRV-HOOK-STOP-MISSING-PROOF"
|
|
29
|
+
HookReviewerReadonlyDenied ID = "DRV-HOOK-REVIEWER-READONLY-DENIED"
|
|
30
|
+
HookReviewerReadonlyObserved ID = "DRV-HOOK-REVIEWER-READONLY-OBSERVED"
|
|
31
|
+
HookA1Denied ID = "DRV-HOOK-A1-DENIED"
|
|
32
|
+
HookA1Observed ID = "DRV-HOOK-A1-OBSERVED"
|
|
33
|
+
HookWrightScopeDenied ID = "DRV-HOOK-WRIGHT-SCOPE-DENIED"
|
|
34
|
+
HookWrightScopeObserved ID = "DRV-HOOK-WRIGHT-SCOPE-OBSERVED"
|
|
35
|
+
HookWrightForbiddenDenied ID = "DRV-HOOK-WRIGHT-FORBIDDEN-DENIED"
|
|
36
|
+
HookForgeBindingDenied ID = "DRV-HOOK-FORGE-BINDING-DENIED"
|
|
37
|
+
HookIngestWarning ID = "DRV-HOOK-INGEST-WARNING"
|
|
38
|
+
|
|
39
|
+
GitAuthorityPending ID = "DRV-GIT-AUTHORITY-PENDING"
|
|
40
|
+
GitAuthorityGranted ID = "DRV-GIT-AUTHORITY-GRANTED"
|
|
41
|
+
GitAuthorityExpired ID = "DRV-GIT-AUTHORITY-EXPIRED"
|
|
42
|
+
GitAuthorityRefused ID = "DRV-GIT-AUTHORITY-REFUSED"
|
|
43
|
+
GitAuthorityReplayed ID = "DRV-GIT-AUTHORITY-REPLAYED"
|
|
44
|
+
GitAuthorityCorrupt ID = "DRV-GIT-AUTHORITY-CORRUPT"
|
|
45
|
+
GitAuthorityUnavailable ID = "DRV-GIT-AUTHORITY-UNAVAILABLE"
|
|
46
|
+
GitWorkspaceUnavailable ID = "DRV-GIT-WORKSPACE-UNAVAILABLE"
|
|
47
|
+
|
|
48
|
+
GitInputTooLarge ID = "DRV-GIT-INPUT-TOO-LARGE"
|
|
49
|
+
GitAmbiguousSyntax ID = "DRV-GIT-AMBIGUOUS-SYNTAX"
|
|
50
|
+
GitAmbiguousDynamic ID = "DRV-GIT-AMBIGUOUS-DYNAMIC"
|
|
51
|
+
GitAmbiguousAlias ID = "DRV-GIT-AMBIGUOUS-ALIAS"
|
|
52
|
+
GitAmbiguousGlobalOption ID = "DRV-GIT-AMBIGUOUS-GLOBAL-OPTION"
|
|
53
|
+
GitAmbiguousStdin ID = "DRV-GIT-AMBIGUOUS-STDIN"
|
|
54
|
+
GitDestructiveReset ID = "DRV-GIT-DESTRUCTIVE-RESET"
|
|
55
|
+
GitDestructiveClean ID = "DRV-GIT-DESTRUCTIVE-CLEAN"
|
|
56
|
+
GitDestructiveCheckout ID = "DRV-GIT-DESTRUCTIVE-CHECKOUT"
|
|
57
|
+
GitDestructiveRestore ID = "DRV-GIT-DESTRUCTIVE-RESTORE"
|
|
58
|
+
GitDestructiveSwitch ID = "DRV-GIT-DESTRUCTIVE-SWITCH"
|
|
59
|
+
GitDestructiveRemove ID = "DRV-GIT-DESTRUCTIVE-RM"
|
|
60
|
+
GitDestructiveBranch ID = "DRV-GIT-DESTRUCTIVE-BRANCH"
|
|
61
|
+
GitDestructiveTag ID = "DRV-GIT-DESTRUCTIVE-TAG"
|
|
62
|
+
GitDestructiveUpdateRef ID = "DRV-GIT-DESTRUCTIVE-UPDATE-REF"
|
|
63
|
+
GitDestructiveStash ID = "DRV-GIT-DESTRUCTIVE-STASH"
|
|
64
|
+
GitDestructiveReflog ID = "DRV-GIT-DESTRUCTIVE-REFLOG"
|
|
65
|
+
GitDestructivePrune ID = "DRV-GIT-DESTRUCTIVE-PRUNE"
|
|
66
|
+
GitDestructiveHistory ID = "DRV-GIT-DESTRUCTIVE-HISTORY"
|
|
67
|
+
GitDestructivePushForce ID = "DRV-GIT-DESTRUCTIVE-PUSH-FORCE"
|
|
68
|
+
GitDestructivePushDelete ID = "DRV-GIT-DESTRUCTIVE-PUSH-DELETE"
|
|
69
|
+
GitDestructiveWorktree ID = "DRV-GIT-DESTRUCTIVE-WORKTREE"
|
|
70
|
+
GitDestructiveRefDeletion ID = "DRV-GIT-DESTRUCTIVE-REF-DELETE"
|
|
71
|
+
|
|
72
|
+
AgentNamed ID = "DRV-AGENT-NAMED"
|
|
73
|
+
AgentGenericFallback ID = "DRV-AGENT-GENERIC-FALLBACK"
|
|
74
|
+
AgentInlineFallback ID = "DRV-AGENT-INLINE-FALLBACK"
|
|
75
|
+
AgentUnavailable ID = "DRV-AGENT-UNAVAILABLE"
|
|
76
|
+
AgentResultAccepted ID = "DRV-AGENT-RESULT-ACCEPTED"
|
|
77
|
+
AgentResultMalformed ID = "DRV-AGENT-RESULT-MALFORMED"
|
|
78
|
+
AgentResultStale ID = "DRV-AGENT-RESULT-STALE"
|
|
79
|
+
AgentResultIdentityMismatch ID = "DRV-AGENT-RESULT-IDENTITY-MISMATCH"
|
|
80
|
+
AgentResultOutOfScope ID = "DRV-AGENT-RESULT-OUT-OF-SCOPE"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
var catalog = []ID{
|
|
84
|
+
RootSelected,
|
|
85
|
+
GateReadinessPassed,
|
|
86
|
+
GateReadinessMissing,
|
|
87
|
+
GateSealPassed,
|
|
88
|
+
GateSealMissing,
|
|
89
|
+
HookDisabled,
|
|
90
|
+
HookAllowApproved,
|
|
91
|
+
HookStopClear,
|
|
92
|
+
HookStopInputInvalid,
|
|
93
|
+
HookStopReentry,
|
|
94
|
+
HookStopWorkspaceUnavailable,
|
|
95
|
+
HookStopRed,
|
|
96
|
+
HookStopUnsurfacedHumanGate,
|
|
97
|
+
HookStopMissingProof,
|
|
98
|
+
HookReviewerReadonlyDenied,
|
|
99
|
+
HookReviewerReadonlyObserved,
|
|
100
|
+
HookA1Denied,
|
|
101
|
+
HookA1Observed,
|
|
102
|
+
HookWrightScopeDenied,
|
|
103
|
+
HookWrightScopeObserved,
|
|
104
|
+
HookWrightForbiddenDenied,
|
|
105
|
+
HookForgeBindingDenied,
|
|
106
|
+
HookIngestWarning,
|
|
107
|
+
GitAuthorityPending,
|
|
108
|
+
GitAuthorityGranted,
|
|
109
|
+
GitAuthorityExpired,
|
|
110
|
+
GitAuthorityRefused,
|
|
111
|
+
GitAuthorityReplayed,
|
|
112
|
+
GitAuthorityCorrupt,
|
|
113
|
+
GitAuthorityUnavailable,
|
|
114
|
+
GitWorkspaceUnavailable,
|
|
115
|
+
GitInputTooLarge,
|
|
116
|
+
GitAmbiguousSyntax,
|
|
117
|
+
GitAmbiguousDynamic,
|
|
118
|
+
GitAmbiguousAlias,
|
|
119
|
+
GitAmbiguousGlobalOption,
|
|
120
|
+
GitAmbiguousStdin,
|
|
121
|
+
GitDestructiveReset,
|
|
122
|
+
GitDestructiveClean,
|
|
123
|
+
GitDestructiveCheckout,
|
|
124
|
+
GitDestructiveRestore,
|
|
125
|
+
GitDestructiveSwitch,
|
|
126
|
+
GitDestructiveRemove,
|
|
127
|
+
GitDestructiveBranch,
|
|
128
|
+
GitDestructiveTag,
|
|
129
|
+
GitDestructiveUpdateRef,
|
|
130
|
+
GitDestructiveStash,
|
|
131
|
+
GitDestructiveReflog,
|
|
132
|
+
GitDestructivePrune,
|
|
133
|
+
GitDestructiveHistory,
|
|
134
|
+
GitDestructivePushForce,
|
|
135
|
+
GitDestructivePushDelete,
|
|
136
|
+
GitDestructiveWorktree,
|
|
137
|
+
GitDestructiveRefDeletion,
|
|
138
|
+
AgentNamed,
|
|
139
|
+
AgentGenericFallback,
|
|
140
|
+
AgentInlineFallback,
|
|
141
|
+
AgentUnavailable,
|
|
142
|
+
AgentResultAccepted,
|
|
143
|
+
AgentResultMalformed,
|
|
144
|
+
AgentResultStale,
|
|
145
|
+
AgentResultIdentityMismatch,
|
|
146
|
+
AgentResultOutOfScope,
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
var known = func() map[ID]struct{} {
|
|
150
|
+
out := make(map[ID]struct{}, len(catalog))
|
|
151
|
+
for _, id := range catalog {
|
|
152
|
+
if _, duplicate := out[id]; duplicate {
|
|
153
|
+
panic("duplicate reason id " + id)
|
|
154
|
+
}
|
|
155
|
+
out[id] = struct{}{}
|
|
156
|
+
}
|
|
157
|
+
return out
|
|
158
|
+
}()
|
|
159
|
+
|
|
160
|
+
// Parse accepts only identifiers in the frozen catalog.
|
|
161
|
+
func Parse(value string) (ID, error) {
|
|
162
|
+
id := ID(value)
|
|
163
|
+
if _, ok := known[id]; !ok {
|
|
164
|
+
return "", fmt.Errorf("unknown reason id %q", value)
|
|
165
|
+
}
|
|
166
|
+
return id, nil
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Known reports whether id belongs to the frozen catalog.
|
|
170
|
+
func Known(id ID) bool {
|
|
171
|
+
_, ok := known[id]
|
|
172
|
+
return ok
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// All returns the catalog in lexical order for generators and tests.
|
|
176
|
+
func All() []ID {
|
|
177
|
+
out := append([]ID(nil), catalog...)
|
|
178
|
+
sort.Slice(out, func(i, j int) bool { return out[i] < out[j] })
|
|
179
|
+
return out
|
|
180
|
+
}
|