devrites 3.0.7 → 3.1.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 +12 -0
- package/README.md +67 -47
- 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/README.md +3 -0
- package/docs/agents/triage-labels.md +7 -7
- package/docs/architecture.md +157 -140
- package/docs/cli.md +41 -12
- package/docs/command-map.md +49 -35
- package/docs/engine/agent-contract.md +92 -15
- package/docs/engine/commands.md +242 -72
- package/docs/engine/state-schema.md +52 -23
- package/docs/engine/workspace-schema.md +94 -15
- package/docs/extensions.md +1 -1
- package/docs/flow.md +80 -50
- package/docs/harness-compliance.md +29 -5
- package/docs/orchestration.md +107 -79
- package/docs/quick-reference.md +7 -3
- package/docs/release.md +4 -3
- package/docs/skills.md +64 -38
- package/docs/usage.md +57 -38
- 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 +35 -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 +111 -0
- package/engine/internal/lib/readinessartifact.go +510 -0
- package/engine/internal/lib/readinessartifact_test.go +321 -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=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 +141 -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 +71 -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/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 +11 -9
- package/pack/.claude/skills/devrites-lib/reference/intent-map.md +3 -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 +198 -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 +23 -10
- package/pack/.claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/.claude/skills/rite/SKILL.md +8 -6
- package/pack/.claude/skills/rite/reference/menu.md +8 -6
- 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 +38 -38
- 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/wright-dispatch.md +129 -134
- package/pack/.claude/skills/rite-clarify/SKILL.md +89 -0
- package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +59 -0
- package/pack/.claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/.claude/skills/rite-define/SKILL.md +57 -32
- package/pack/.claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/.claude/skills/rite-define/reference/plan-template.md +16 -8
- package/pack/.claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/.claude/skills/rite-plan/SKILL.md +44 -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-vet/SKILL.md +110 -113
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +42 -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 +71 -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/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 +11 -9
- package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +3 -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 +198 -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 +23 -10
- package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +23 -22
- package/pack/generated/claude/skills/rite/SKILL.md +8 -6
- package/pack/generated/claude/skills/rite/reference/menu.md +8 -6
- 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 +38 -38
- 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/wright-dispatch.md +129 -134
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +89 -0
- package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +59 -0
- package/pack/generated/claude/skills/rite-converge/SKILL.md +35 -25
- package/pack/generated/claude/skills/rite-define/SKILL.md +57 -32
- package/pack/generated/claude/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +16 -8
- package/pack/generated/claude/skills/rite-frame/reference/failure-modes.md +22 -24
- package/pack/generated/claude/skills/rite-plan/SKILL.md +44 -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-vet/SKILL.md +110 -113
- package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +42 -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 +77 -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/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 +18 -12
- package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +3 -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 +198 -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 +23 -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 +19 -13
- package/pack/generated/codex/skills/rite/reference/menu.md +8 -6
- 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 +38 -38
- 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/wright-dispatch.md +129 -134
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +105 -0
- package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +59 -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 +64 -35
- package/pack/generated/codex/skills/rite-define/reference/gates.md +16 -15
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +16 -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 +51 -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-vet/SKILL.md +117 -116
- package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +42 -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 +414 -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
|
@@ -1,36 +1,125 @@
|
|
|
1
1
|
package main_test
|
|
2
2
|
|
|
3
|
-
// TestParityBuildReadiness checks the build-readiness gate's stdout
|
|
3
|
+
// TestParityBuildReadiness checks the build-readiness gate's stdout and exit code
|
|
4
4
|
// against the golden snapshot for each state.md fixture.
|
|
5
5
|
|
|
6
|
-
import
|
|
6
|
+
import (
|
|
7
|
+
"fmt"
|
|
8
|
+
"path/filepath"
|
|
9
|
+
"testing"
|
|
10
|
+
|
|
11
|
+
"github.com/devrites/devrites/internal/lib"
|
|
12
|
+
)
|
|
7
13
|
|
|
8
14
|
func TestParityBuildReadiness(t *testing.T) {
|
|
9
15
|
work := t.TempDir()
|
|
10
16
|
|
|
11
|
-
// Status halts
|
|
17
|
+
// Status halts write only to stderr; parity covers stdout and the exit code.
|
|
12
18
|
writeFeatureFile(t, work, "await", "state.md", "- Status: awaiting_human\n") // exit 3
|
|
13
19
|
writeFeatureFile(t, work, "blocked", "state.md", "- Status: blocked\n") // exit 4
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
writeReadyArtifacts := func(slug string) {
|
|
22
|
+
t.Helper()
|
|
23
|
+
writeCoverageArtifacts(t, work, slug)
|
|
24
|
+
for name, body := range map[string]string{
|
|
25
|
+
"architecture.md": "# Architecture\n\nExisting layer.\n",
|
|
26
|
+
"plan.md": "# Plan\n\nOne slice.\n",
|
|
27
|
+
"tasks.md": "# Tasks\n\n## SLICE-001\nBuild.\n",
|
|
28
|
+
"traceability.md": "# Traceability\n\nAC-001 -> SLICE-001.\n",
|
|
29
|
+
"test-plan.md": `# Test plan
|
|
30
|
+
|
|
31
|
+
## Build-entry preflight
|
|
32
|
+
| Gate | Command | Cwd | Expected | Prerequisites | Provenance to recapture |
|
|
33
|
+
| --- | --- | --- | --- | --- | --- |
|
|
34
|
+
| unit | go test ./... | engine | exit 0 | none | go version |
|
|
35
|
+
|
|
36
|
+
## Per-gap test requirements
|
|
37
|
+
| ID | Path / flow | Test file | Asserts | Kind | Slice | Priority |
|
|
38
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
39
|
+
| T1 | flow | flow_test.go | request → success | unit | SLICE-001 | P1 |
|
|
40
|
+
|
|
41
|
+
## Acceptance → test map
|
|
42
|
+
- AC-001 → T1
|
|
43
|
+
`,
|
|
44
|
+
} {
|
|
45
|
+
writeFeatureFile(t, work, slug, name, body)
|
|
46
|
+
}
|
|
47
|
+
root := filepath.Join(work, ".devrites")
|
|
48
|
+
digest, err := lib.ReadinessInputDigest(root, slug, "engineering")
|
|
49
|
+
if err != nil {
|
|
50
|
+
t.Fatal(err)
|
|
51
|
+
}
|
|
52
|
+
writeFeatureFile(t, work, slug, "eng-review.md", fmt.Sprintf(`# Eng review
|
|
53
|
+
|
|
54
|
+
Implementation readiness: READY
|
|
55
|
+
Readiness inputs SHA-256: %s
|
|
56
|
+
|
|
57
|
+
## 2a. Build-entry preflight
|
|
58
|
+
| Gate | Command + cwd | Tool/version | Prerequisite owner | Full provenance inputs | Fixture/smoke | Verdict |
|
|
59
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
60
|
+
| unit | go test ./... | go | none | go.mod | focused | pass |
|
|
61
|
+
|
|
62
|
+
## 2b. Implementation readiness
|
|
63
|
+
| Surface | Requirement/decision | Boundary/wiring | Slice | Proof | Verdict |
|
|
64
|
+
| --- | --- | --- | --- | --- | --- |
|
|
65
|
+
| flow | AC-001 | existing | SLICE-001 | T1 | ready |
|
|
66
|
+
|
|
67
|
+
## 4. Failure modes
|
|
68
|
+
| New codepath | Realistic failure | Test? | Handling? | Silent? | Verdict |
|
|
69
|
+
| --- | --- | --- | --- | --- | --- |
|
|
70
|
+
| flow | invalid | yes | yes | no | ok |
|
|
71
|
+
|
|
72
|
+
## 7. Completion summary
|
|
73
|
+
- Ready.
|
|
74
|
+
`, digest))
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// A ready feature has an approved plan, running status, and current
|
|
78
|
+
// clarification and vet artifacts.
|
|
79
|
+
for _, slug := range []string{"approved", "trailpipe", "trailhash", "emptystatus"} {
|
|
80
|
+
writeReadyArtifacts(slug)
|
|
81
|
+
}
|
|
82
|
+
writeFeatureFile(t, work, "approved", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 0
|
|
17
83
|
|
|
18
84
|
// Plan not approved: missing line, or the literal "none".
|
|
85
|
+
writeCoverageArtifacts(t, work, "noapprove")
|
|
86
|
+
writeCoverageArtifacts(t, work, "approvenone")
|
|
19
87
|
writeFeatureFile(t, work, "noapprove", "state.md", "- Status: running\n") // exit 2
|
|
20
88
|
writeFeatureFile(t, work, "approvenone", "state.md", "- Plan approved: none\n- Status: running\n") // exit 2
|
|
21
89
|
|
|
22
90
|
// field() strip: a trailing " | none" / " # note" annotation is trimmed off
|
|
23
91
|
// Status before the case match, so both stay "running" and reach OK.
|
|
24
|
-
writeFeatureFile(t, work, "trailpipe", "state.md", "- Plan approved: 2024-01-01\n- Status: running | none\n") // exit 0
|
|
25
|
-
writeFeatureFile(t, work, "trailhash", "state.md", "- Plan approved: 2024-01-01\n- Status: running # note\n") // exit 0
|
|
92
|
+
writeFeatureFile(t, work, "trailpipe", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running | none\n") // exit 0
|
|
93
|
+
writeFeatureFile(t, work, "trailhash", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running # note\n") // exit 0
|
|
26
94
|
|
|
27
|
-
//
|
|
28
|
-
writeFeatureFile(t, work, "emptystatus", "state.md", "- Plan approved: 2024-01-01\n- Status: \n") // exit 0
|
|
95
|
+
// An empty Status with an approved plan renders as "running".
|
|
96
|
+
writeFeatureFile(t, work, "emptystatus", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: \n") // exit 0
|
|
97
|
+
|
|
98
|
+
// A plan cannot build without an explicit closed clarification scan and a
|
|
99
|
+
// successful engineering-readiness verdict. These are objective routes, not
|
|
100
|
+
// human questions.
|
|
101
|
+
writeFeatureFile(t, work, "noclarify", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 6
|
|
102
|
+
|
|
103
|
+
writeFeatureFile(t, work, "clarifyopen", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 6
|
|
104
|
+
writeFeatureFile(t, work, "clarifyopen", "brief.md", "# Brief\n\nOutcome.\n")
|
|
105
|
+
writeFeatureFile(t, work, "clarifyopen", "spec.md", "# Spec\n\nAC-001.\n")
|
|
106
|
+
writeFeatureFile(t, work, "clarifyopen", "decision-coverage.md", "# Decision coverage\n\n- Decision coverage: NEEDS CLARIFICATION\n")
|
|
107
|
+
|
|
108
|
+
writeFeatureFile(t, work, "novet", "state.md", "- Phase: plan\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
|
|
109
|
+
writeCoverageArtifacts(t, work, "novet")
|
|
110
|
+
|
|
111
|
+
writeFeatureFile(t, work, "vetnotready", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
|
|
112
|
+
writeCoverageArtifacts(t, work, "vetnotready")
|
|
113
|
+
writeFeatureFile(t, work, "vetnotready", "eng-review.md", "# Engineering review\n\n- Implementation readiness: NEEDS REPLAN\n")
|
|
114
|
+
|
|
115
|
+
writeReadyArtifacts("stalevet")
|
|
116
|
+
writeFeatureFile(t, work, "stalevet", "state.md", "- Phase: plan\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
|
|
29
117
|
|
|
30
118
|
// "ghost" is intentionally never created → no workspace/state.md (exit 5).
|
|
31
119
|
for _, arg := range []string{
|
|
32
120
|
"await", "blocked", "approved", "noapprove", "approvenone",
|
|
33
|
-
"trailpipe", "trailhash", "emptystatus", "
|
|
121
|
+
"trailpipe", "trailhash", "emptystatus", "noclarify", "clarifyopen",
|
|
122
|
+
"novet", "vetnotready", "stalevet", "ghost",
|
|
34
123
|
} {
|
|
35
124
|
c := parityCase{
|
|
36
125
|
workdir: work,
|
|
@@ -40,3 +129,45 @@ func TestParityBuildReadiness(t *testing.T) {
|
|
|
40
129
|
t.Run("arg="+arg, func(t *testing.T) { c.assertEqual(t) })
|
|
41
130
|
}
|
|
42
131
|
}
|
|
132
|
+
|
|
133
|
+
func writeCoverageArtifacts(t *testing.T, work, slug string) {
|
|
134
|
+
t.Helper()
|
|
135
|
+
writeFeatureFile(t, work, slug, "brief.md", "# Brief\n\nOutcome.\n")
|
|
136
|
+
writeFeatureFile(t, work, slug, "spec.md", "# Spec\n\n## Acceptance criteria\n- AC-001 succeeds.\n")
|
|
137
|
+
writeFeatureFile(t, work, slug, "decisions.md", "# Decisions\n\nNo open product decisions.\n")
|
|
138
|
+
writeFeatureFile(t, work, slug, "assumptions.md", "# Assumptions\n\nNo material assumptions.\n")
|
|
139
|
+
writeFeatureFile(t, work, slug, "questions.md", "# Questions\n\nNone.\n")
|
|
140
|
+
root := filepath.Join(work, ".devrites")
|
|
141
|
+
digest, err := lib.ReadinessInputDigest(root, slug, "coverage")
|
|
142
|
+
if err != nil {
|
|
143
|
+
t.Fatal(err)
|
|
144
|
+
}
|
|
145
|
+
writeFeatureFile(t, work, slug, "decision-coverage.md", fmt.Sprintf(`# Decision coverage
|
|
146
|
+
|
|
147
|
+
Decision coverage: CLEAR
|
|
148
|
+
Coverage inputs SHA-256: %s
|
|
149
|
+
|
|
150
|
+
## Topology
|
|
151
|
+
| Surface | Kind | Related IDs | Evidence |
|
|
152
|
+
| --- | --- | --- | --- |
|
|
153
|
+
| flow | behavior | AC-001 | spec.md |
|
|
154
|
+
|
|
155
|
+
## Coverage matrix
|
|
156
|
+
| Surface | Dimension | Status | Canonical reference | Owner / validation gate | Consequence if wrong |
|
|
157
|
+
| --- | --- | --- | --- | --- | --- |
|
|
158
|
+
| flow | behavior | closed | AC-001 | rite-prove | failure |
|
|
159
|
+
|
|
160
|
+
## Assumption audit
|
|
161
|
+
| Assumption | Evidence | Confidence | Owner | Validation | Consequence if wrong |
|
|
162
|
+
| --- | --- | --- | --- | --- | --- |
|
|
163
|
+
| none | n/a | high | n/a | n/a | n/a |
|
|
164
|
+
|
|
165
|
+
## Residual uncertainty
|
|
166
|
+
| Item | Why nonblocking | Owner | Validation gate |
|
|
167
|
+
| --- | --- | --- | --- |
|
|
168
|
+
| none | n/a | n/a | n/a |
|
|
169
|
+
|
|
170
|
+
## Readiness verdict
|
|
171
|
+
No unresolved decision remains.
|
|
172
|
+
`, digest))
|
|
173
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
package main_test
|
|
2
2
|
|
|
3
3
|
// TestParityLearnings checks the learnings command against the golden snapshots.
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// never depends on a platform-specific tie-break.
|
|
4
|
+
// Learning state lives at the root selected by DEVRITES_ROOT. The mine and nudge
|
|
5
|
+
// fixtures use counts of 3 and 2 so sorting never depends on a platform-specific
|
|
6
|
+
// tie.
|
|
8
7
|
|
|
9
8
|
import (
|
|
10
9
|
"path/filepath"
|
|
@@ -14,10 +13,11 @@ import (
|
|
|
14
13
|
func TestParityLearnings(t *testing.T) {
|
|
15
14
|
learn := func(a ...string) []string { return append([]string{"learnings"}, a...) }
|
|
16
15
|
|
|
17
|
-
//
|
|
18
|
-
// appends
|
|
19
|
-
// contract
|
|
16
|
+
// Add to a fresh workspace. Bash creates the ledger and a dated entry, then Go
|
|
17
|
+
// appends another. Only stdout ("learnings: recorded.") and exit 0 belong to
|
|
18
|
+
// the contract because the dated file entry is nondeterministic.
|
|
20
19
|
addw := t.TempDir()
|
|
20
|
+
mkdirAllT(t, addw, ".devrites")
|
|
21
21
|
t.Run("add", func(t *testing.T) {
|
|
22
22
|
(parityCase{
|
|
23
23
|
workdir: addw, env: libRootEnv(addw),
|
|
@@ -25,7 +25,7 @@ func TestParityLearnings(t *testing.T) {
|
|
|
25
25
|
}).assertEqual(t)
|
|
26
26
|
})
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// List a prepared ledger. Both implementations print the file unchanged.
|
|
29
29
|
listw := t.TempDir()
|
|
30
30
|
writeFile(t, listw, filepath.Join(".devrites", "learnings.md"),
|
|
31
31
|
"# DevRites learnings ledger\n\n"+
|
|
@@ -38,10 +38,9 @@ func TestParityLearnings(t *testing.T) {
|
|
|
38
38
|
}).assertEqual(t)
|
|
39
39
|
})
|
|
40
40
|
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
// count 2. Distinct counts ⇒ deterministic order on any `sort`.
|
|
41
|
+
// Mine and nudge use two archived features. Normalization strips IDs, paths,
|
|
42
|
+
// and numbers, so "recurring finding" has count 3 and "second dead end" has
|
|
43
|
+
// count 2. The distinct counts keep sort order stable.
|
|
45
44
|
arch := t.TempDir()
|
|
46
45
|
writeFile(t, arch, filepath.Join(".devrites", "archive", "feat-a", "decisions.md"),
|
|
47
46
|
"# decisions for feat-a\n"+
|
|
@@ -55,7 +54,7 @@ func TestParityLearnings(t *testing.T) {
|
|
|
55
54
|
"- second dead end: retry backoff exceeded 9 attempts\n"+
|
|
56
55
|
"- a one-off dismiss note about the flaky linter run\n")
|
|
57
56
|
|
|
58
|
-
//
|
|
57
|
+
// Both implementations resolve the default archive to the same directory.
|
|
59
58
|
t.Run("mine", func(t *testing.T) {
|
|
60
59
|
(parityCase{
|
|
61
60
|
workdir: arch, env: libRootEnv(arch),
|
|
@@ -63,8 +62,8 @@ func TestParityLearnings(t *testing.T) {
|
|
|
63
62
|
}).assertEqual(t)
|
|
64
63
|
})
|
|
65
64
|
|
|
66
|
-
//
|
|
67
|
-
//
|
|
65
|
+
// Both implementations resolve an explicit relative path against workdir, so
|
|
66
|
+
// the missing path in the message is identical.
|
|
68
67
|
t.Run("mine-no-archive", func(t *testing.T) {
|
|
69
68
|
(parityCase{
|
|
70
69
|
workdir: arch, env: libRootEnv(arch),
|
|
@@ -72,7 +71,7 @@ func TestParityLearnings(t *testing.T) {
|
|
|
72
71
|
}).assertEqual(t)
|
|
73
72
|
})
|
|
74
73
|
|
|
75
|
-
//
|
|
74
|
+
// Two features, three occurrences, and no review marker produce a nudge.
|
|
76
75
|
t.Run("nudge", func(t *testing.T) {
|
|
77
76
|
(parityCase{
|
|
78
77
|
workdir: arch, env: libRootEnv(arch),
|
|
@@ -80,7 +79,7 @@ func TestParityLearnings(t *testing.T) {
|
|
|
80
79
|
}).assertEqual(t)
|
|
81
80
|
})
|
|
82
81
|
|
|
83
|
-
//
|
|
82
|
+
// An unknown command writes usage to stderr and exits 2 without stdout.
|
|
84
83
|
t.Run("unknown", func(t *testing.T) {
|
|
85
84
|
(parityCase{
|
|
86
85
|
workdir: arch, env: libRootEnv(arch),
|
|
@@ -2,14 +2,15 @@ package main_test
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
5
|
+
"strings"
|
|
5
6
|
"testing"
|
|
6
7
|
)
|
|
7
8
|
|
|
8
9
|
// TestParityReconcile checks reconcile against the golden snapshots: snapshot
|
|
9
|
-
// captures the worktree as a tree object, check diffs it and flags
|
|
10
|
-
// outside the
|
|
11
|
-
//
|
|
12
|
-
//
|
|
10
|
+
// captures the worktree as a tree object, check diffs it and flags changes
|
|
11
|
+
// outside the orchestrator-authored allowlist, and close ends the retained
|
|
12
|
+
// post-slice baseline. It runs Git in a real repository, so stdout and exit are
|
|
13
|
+
// captured from the live command.
|
|
13
14
|
func TestParityReconcile(t *testing.T) {
|
|
14
15
|
requireGit(t)
|
|
15
16
|
|
|
@@ -25,7 +26,12 @@ func TestParityReconcile(t *testing.T) {
|
|
|
25
26
|
}
|
|
26
27
|
// snapshot is also a setup step for the check-* cases, so it snapshots under a
|
|
27
28
|
// distinct key to avoid colliding with check's golden in the same subtest.
|
|
28
|
-
snapshot := func(t *testing.T, work string) {
|
|
29
|
+
snapshot := func(t *testing.T, work string, allowed ...string) {
|
|
30
|
+
body := ""
|
|
31
|
+
if len(allowed) > 0 {
|
|
32
|
+
body = strings.Join(allowed, "\n") + "\n"
|
|
33
|
+
}
|
|
34
|
+
writeFeatureFile(t, work, "feat", ".wright-allowlist", body)
|
|
29
35
|
out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "snapshot", "feat")
|
|
30
36
|
assertGoldenKey(t, t.Name()+"/snapshot", fmt.Sprintf("exit %d\n%s", code, out))
|
|
31
37
|
}
|
|
@@ -38,38 +44,35 @@ func TestParityReconcile(t *testing.T) {
|
|
|
38
44
|
|
|
39
45
|
t.Run("check-clean", func(t *testing.T) {
|
|
40
46
|
work := newRepo(t)
|
|
41
|
-
snapshot(t, work)
|
|
47
|
+
snapshot(t, work, "src/a.js")
|
|
42
48
|
writeFile(t, work, "src/a.js", "console.log(999)\n") // the wright's change
|
|
43
|
-
writeFeatureFile(t, work, "feat", ".reconcile-claimed", "src/a.js\n")
|
|
44
49
|
check(t, work)
|
|
45
50
|
})
|
|
46
51
|
|
|
47
52
|
t.Run("check-violation", func(t *testing.T) {
|
|
48
53
|
work := newRepo(t)
|
|
49
|
-
snapshot(t, work)
|
|
54
|
+
snapshot(t, work, "src/a.js")
|
|
50
55
|
writeFile(t, work, "src/a.js", "console.log(999)\n")
|
|
51
|
-
writeFile(t, work, "src/b.js", "console.log(888)\n") //
|
|
52
|
-
writeFeatureFile(t, work, "feat", ".reconcile-claimed", "src/a.js\n")
|
|
56
|
+
writeFile(t, work, "src/b.js", "console.log(888)\n") // Outside the allowlist; an A1 breach.
|
|
53
57
|
check(t, work)
|
|
54
58
|
})
|
|
55
59
|
|
|
56
60
|
t.Run("check-no-base", func(t *testing.T) {
|
|
57
61
|
work := newRepo(t)
|
|
58
|
-
|
|
59
|
-
check(t, work) // no snapshot -> exit 6
|
|
62
|
+
check(t, work) // No snapshot, so exit 6.
|
|
60
63
|
})
|
|
61
64
|
|
|
62
|
-
t.Run("
|
|
65
|
+
t.Run("snapshot-no-allowlist", func(t *testing.T) {
|
|
63
66
|
work := newRepo(t)
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "snapshot", "feat")
|
|
68
|
+
assertGolden(t, out, code)
|
|
66
69
|
})
|
|
67
70
|
|
|
68
71
|
t.Run("inline-fallback", func(t *testing.T) {
|
|
69
72
|
work := newRepo(t)
|
|
70
73
|
snapshot(t, work)
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "close", "feat")
|
|
75
|
+
assertGolden(t, out, code)
|
|
73
76
|
})
|
|
74
77
|
|
|
75
78
|
t.Run("not-git", func(t *testing.T) {
|
|
@@ -7,8 +7,8 @@ import (
|
|
|
7
7
|
"testing"
|
|
8
8
|
)
|
|
9
9
|
|
|
10
|
-
// Golden
|
|
11
|
-
//
|
|
10
|
+
// Golden snapshots for resolve include its changes to questions.md and state.md.
|
|
11
|
+
// Each case records stdout and the exit code. Mutating cases also record the
|
|
12
12
|
// resulting file bytes. The two nondeterministic timestamp fields (answered_at
|
|
13
13
|
// and the Log entry) are masked out before the file content is snapshotted so the
|
|
14
14
|
// golden is deterministic across runs.
|
|
@@ -45,8 +45,8 @@ const resolveState = `- Status: awaiting_human
|
|
|
45
45
|
`
|
|
46
46
|
|
|
47
47
|
func TestParityResolve(t *testing.T) {
|
|
48
|
-
// setup writes
|
|
49
|
-
//
|
|
48
|
+
// setup writes fixtures under .devrites/features/feat and returns the
|
|
49
|
+
// workspace root.
|
|
50
50
|
setup := func(t *testing.T, questions, state string) (gwork string) {
|
|
51
51
|
t.Helper()
|
|
52
52
|
gwork = t.TempDir()
|
|
@@ -55,7 +55,7 @@ func TestParityResolve(t *testing.T) {
|
|
|
55
55
|
writeFile(t, gwork, filepath.Join(".devrites", "ACTIVE"), "feat\n")
|
|
56
56
|
return gwork
|
|
57
57
|
}
|
|
58
|
-
// run executes resolve in gwork and snapshots
|
|
58
|
+
// run executes resolve in gwork and snapshots stdout and the exit code under the
|
|
59
59
|
// current subtest's golden.
|
|
60
60
|
run := func(t *testing.T, gwork string, args ...string) {
|
|
61
61
|
t.Helper()
|
|
@@ -124,16 +124,17 @@ answer: prior
|
|
|
124
124
|
})
|
|
125
125
|
|
|
126
126
|
t.Run("no-workspace", func(t *testing.T) {
|
|
127
|
-
//
|
|
127
|
+
// A bare tree with no explicit root, ACTIVE, or questions.md exits 2.
|
|
128
|
+
// Pointing DEVRITES_ROOT at the nonexistent .devrites child would instead
|
|
129
|
+
// be an explicit unsafe-root refusal, which is a different contract.
|
|
128
130
|
gwork := t.TempDir()
|
|
129
|
-
|
|
131
|
+
out, code := runArgv(t, gwork, libEnv, "", binPath, "resolve", "q-1", "x")
|
|
132
|
+
assertGolden(t, out, code)
|
|
130
133
|
})
|
|
131
134
|
|
|
132
135
|
t.Run("next-qid", func(t *testing.T) {
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
// boundaries: without it the qid tracks the real date and the snapshot
|
|
136
|
-
// fails every day but the one it was recorded on (ADR-0006, clock seam).
|
|
136
|
+
// DEVRITES_NOW fixes the date used by next-qid so the snapshot stays stable.
|
|
137
|
+
// See ADR-0006.
|
|
137
138
|
dir := t.TempDir()
|
|
138
139
|
writeFile(t, dir, "questions.md", "## q-2024-01-01-001\nstatus: open\n")
|
|
139
140
|
qpath := filepath.Join(dir, "questions.md")
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
package main_test
|
|
2
2
|
|
|
3
3
|
// Golden CLI harness: run `devrites-engine <args>` against a fixture and compare its
|
|
4
|
-
// stdout
|
|
4
|
+
// stdout and exit code to a recorded snapshot under testdata/golden. The snapshots
|
|
5
5
|
// were captured from the commands once they were proven correct, so a later change
|
|
6
6
|
// that alters observable behaviour fails here. Regenerate them deliberately with
|
|
7
7
|
// UPDATE_GOLDEN=1 (e.g. `UPDATE_GOLDEN=1 go test ./...`).
|
|
8
8
|
//
|
|
9
|
-
// stderr is
|
|
9
|
+
// stderr is not captured because it is diagnostic rather than contractual. Only
|
|
10
10
|
// stdout (the output the hook/command consumer reads) and the exit code are.
|
|
11
11
|
|
|
12
12
|
import (
|
|
@@ -28,7 +28,7 @@ type parityCase struct {
|
|
|
28
28
|
goArgs []string // args to the built devrites-engine binary (binPath is prepended)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
// assertEqual runs the command and compares its stdout
|
|
31
|
+
// assertEqual runs the command and compares its stdout and exit code to the golden
|
|
32
32
|
// snapshot for the current subtest.
|
|
33
33
|
func (c parityCase) assertEqual(t *testing.T) {
|
|
34
34
|
t.Helper()
|
|
@@ -104,8 +104,8 @@ func TestParityReviewerReadonly(t *testing.T) {
|
|
|
104
104
|
{"enforce-deny-mutating", []string{"DEVRITES_REVIEWER_RO=enforce"}, `{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"}}`},
|
|
105
105
|
{"enforce-deny-git-commit", []string{"DEVRITES_REVIEWER_RO=enforce"}, `{"tool_name":"Bash","tool_input":{"command":"git commit -m x"}}`},
|
|
106
106
|
{"observe-mutating-silent", nil, `{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"}}`},
|
|
107
|
-
// The agent-required gate reads agent_type
|
|
108
|
-
// so a subagent_type-only payload has no identity and is allowed.
|
|
107
|
+
// The agent-required gate reads only agent_type, matching the Bash hook's
|
|
108
|
+
// Node parser, so a subagent_type-only payload has no identity and is allowed.
|
|
109
109
|
{"agent-required-subagent-type-only-allows",
|
|
110
110
|
[]string{"DEVRITES_REVIEWER_RO=enforce", "DEVRITES_REVIEWER_AGENT_REQUIRED=1"},
|
|
111
111
|
`{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"},"subagent_type":"devrites-code-reviewer"}`},
|
|
@@ -268,7 +268,7 @@ func TestParityRedwatch(t *testing.T) {
|
|
|
268
268
|
}
|
|
269
269
|
|
|
270
270
|
// TestParityA1Guard checks `hook a1-guard` against golden snapshots for each
|
|
271
|
-
// payload
|
|
271
|
+
// payload. It blocks a main-thread source edit only when the build window is open
|
|
272
272
|
// and enforce is on, and allows subagent edits, .devrites bookkeeping edits, an
|
|
273
273
|
// inline-fallback window, and a closed window.
|
|
274
274
|
func TestParityA1Guard(t *testing.T) {
|
|
@@ -308,23 +308,27 @@ func TestParityA1Guard(t *testing.T) {
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
// TestParityWrightScope checks `hook wright-scope` against golden snapshots for
|
|
311
|
-
// each payload:
|
|
312
|
-
//
|
|
313
|
-
// agent-required gate skips a non-
|
|
311
|
+
// each payload: an exact orchestrator-allowlisted path is allowed, one outside
|
|
312
|
+
// it and every .devrites path are denied for an active wright, read-only tools
|
|
313
|
+
// pass, and the agent-required gate skips a non-DevRites caller.
|
|
314
314
|
func TestParityWrightScope(t *testing.T) {
|
|
315
315
|
work := t.TempDir()
|
|
316
|
-
writeFeatureFile(t, work, "ws", "
|
|
316
|
+
writeFeatureFile(t, work, "ws", ".wright-allowlist", "src/app.js\n")
|
|
317
317
|
|
|
318
318
|
enforce := []string{"DEVRITES_WRIGHT_SCOPE=enforce"}
|
|
319
|
+
activeWright := []string{
|
|
320
|
+
"DEVRITES_AGENT_RUN=1",
|
|
321
|
+
"DEVRITES_ACTIVE_AGENT=devrites-slice-wright",
|
|
322
|
+
}
|
|
319
323
|
for _, tc := range []struct {
|
|
320
324
|
name string
|
|
321
325
|
env []string
|
|
322
326
|
stdin string
|
|
323
327
|
}{
|
|
324
|
-
{"in-scope-allowed",
|
|
325
|
-
{"out-of-scope-enforce-denies",
|
|
326
|
-
{"devrites-edit-
|
|
327
|
-
{"non-edit-tool",
|
|
328
|
+
{"in-scope-allowed", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":"src/app.js"}}`},
|
|
329
|
+
{"out-of-scope-enforce-denies", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"}}`},
|
|
330
|
+
{"devrites-edit-denied", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":".devrites/x/y.md"}}`},
|
|
331
|
+
{"non-edit-tool", activeWright, `{"tool_name":"Bash","tool_input":{"command":"ls"}}`},
|
|
328
332
|
{"out-of-scope-observe-silent", nil, `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"}}`},
|
|
329
333
|
{"agent-required-non-wright", append([]string{"DEVRITES_WRIGHT_AGENT_REQUIRED=1"}, enforce...),
|
|
330
334
|
`{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"},"agent_type":"Explore"}`},
|
|
@@ -343,7 +347,7 @@ func TestParityWrightScope(t *testing.T) {
|
|
|
343
347
|
}
|
|
344
348
|
|
|
345
349
|
// setActiveAFK points .devrites/ACTIVE at slug (or removes it) and toggles the
|
|
346
|
-
// .devrites/AFK sentinel: the two files bash (via CWD) and
|
|
350
|
+
// .devrites/AFK sentinel: the two files bash (via CWD) and Go (via
|
|
347
351
|
// <root>) both read from the same shared location.
|
|
348
352
|
func setActiveAFK(t *testing.T, work, slug string, afk bool) {
|
|
349
353
|
t.Helper()
|
|
@@ -371,8 +375,8 @@ func TestParityOrientSilentPath(t *testing.T) {
|
|
|
371
375
|
|
|
372
376
|
c := parityCase{
|
|
373
377
|
workdir: dir,
|
|
374
|
-
//
|
|
375
|
-
//
|
|
378
|
+
// Clear DEVRITES_ROOT so the Go side cannot resolve a real workspace. It
|
|
379
|
+
// must see "not a DevRites project".
|
|
376
380
|
env: []string{"DEVRITES_ROOT="},
|
|
377
381
|
goArgs: []string{"hook", "orient", "--harness=claude"},
|
|
378
382
|
}
|