devrites 3.0.6 → 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 +18 -0
- package/README.md +67 -45
- 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 +575 -58
- package/engine/internal/install/install_test.go +490 -9
- 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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
package state
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"errors"
|
|
5
|
+
"strings"
|
|
6
|
+
"testing"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func TestNextClarifyCursorCases(t *testing.T) {
|
|
10
|
+
build := ClarifyCursor{Phase: PhaseBuild, Status: "running", NextAction: "/rite-build"}
|
|
11
|
+
clarify := ClarifyCursor{
|
|
12
|
+
Phase: PhaseClarify,
|
|
13
|
+
Status: "running",
|
|
14
|
+
NextAction: "/rite-clarify",
|
|
15
|
+
ReturnPhase: PhaseBuild,
|
|
16
|
+
ReturnNextAction: "/rite-build",
|
|
17
|
+
HasReturn: true,
|
|
18
|
+
}
|
|
19
|
+
cases := []struct {
|
|
20
|
+
name string
|
|
21
|
+
intent ClarifyIntent
|
|
22
|
+
current ClarifyCursor
|
|
23
|
+
want ClarifyCursor
|
|
24
|
+
wantErr bool
|
|
25
|
+
}{
|
|
26
|
+
{"enter", ClarifyEnter, build, clarify, false},
|
|
27
|
+
{"duplicate enter", ClarifyEnter, clarify, clarify, false},
|
|
28
|
+
{"too early enter", ClarifyEnter, ClarifyCursor{Phase: PhaseSpec}, ClarifyCursor{}, true},
|
|
29
|
+
{"missing restore target", ClarifyRestore, ClarifyCursor{Phase: PhaseClarify}, ClarifyCursor{Phase: PhaseClarify}, false},
|
|
30
|
+
{"invalid restore target", ClarifyRestore, ClarifyCursor{Phase: PhaseClarify, ReturnPhase: PhaseSpec, HasReturn: true}, ClarifyCursor{}, true},
|
|
31
|
+
{"restore", ClarifyRestore, clarify, build, false},
|
|
32
|
+
}
|
|
33
|
+
for _, tc := range cases {
|
|
34
|
+
t.Run(tc.name, func(t *testing.T) {
|
|
35
|
+
got, err := NextClarifyCursor(tc.intent, ClarifyTransitionInput{
|
|
36
|
+
Cursor: tc.current,
|
|
37
|
+
ClarifyNextAction: "/rite-clarify",
|
|
38
|
+
DefaultReturnNextAction: "/rite-build",
|
|
39
|
+
})
|
|
40
|
+
if tc.wantErr {
|
|
41
|
+
var transitionErr *ClarifyTransitionError
|
|
42
|
+
if !errors.As(err, &transitionErr) {
|
|
43
|
+
t.Fatalf("error=%v, want ClarifyTransitionError", err)
|
|
44
|
+
}
|
|
45
|
+
return
|
|
46
|
+
}
|
|
47
|
+
if err != nil || got != tc.want {
|
|
48
|
+
t.Fatalf("NextClarifyCursor()=(%+v, %v), want %+v", got, err, tc.want)
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func TestClarifyCursorSerializationIsByteIdempotent(t *testing.T) {
|
|
55
|
+
original := []string{
|
|
56
|
+
"# State",
|
|
57
|
+
"",
|
|
58
|
+
"## Cursor",
|
|
59
|
+
"| Key | Value |",
|
|
60
|
+
"| --- | --- |",
|
|
61
|
+
"| phase | build |",
|
|
62
|
+
"| status | running |",
|
|
63
|
+
"| next_action | /rite-build |",
|
|
64
|
+
"",
|
|
65
|
+
"Curated note stays exactly here.",
|
|
66
|
+
}
|
|
67
|
+
current, err := ParseClarifyCursor(original)
|
|
68
|
+
if err != nil {
|
|
69
|
+
t.Fatal(err)
|
|
70
|
+
}
|
|
71
|
+
entered, err := NextClarifyCursor(ClarifyEnter, ClarifyTransitionInput{
|
|
72
|
+
Cursor: current,
|
|
73
|
+
ClarifyNextAction: "/rite-clarify",
|
|
74
|
+
DefaultReturnNextAction: "/rite-build",
|
|
75
|
+
})
|
|
76
|
+
if err != nil {
|
|
77
|
+
t.Fatal(err)
|
|
78
|
+
}
|
|
79
|
+
once := ApplyClarifyCursor(original, entered)
|
|
80
|
+
parsed, err := ParseClarifyCursor(once)
|
|
81
|
+
if err != nil {
|
|
82
|
+
t.Fatal(err)
|
|
83
|
+
}
|
|
84
|
+
twiceState, err := NextClarifyCursor(ClarifyEnter, ClarifyTransitionInput{
|
|
85
|
+
Cursor: parsed,
|
|
86
|
+
ClarifyNextAction: "/rite-clarify",
|
|
87
|
+
DefaultReturnNextAction: "/rite-build",
|
|
88
|
+
})
|
|
89
|
+
if err != nil {
|
|
90
|
+
t.Fatal(err)
|
|
91
|
+
}
|
|
92
|
+
twice := ApplyClarifyCursor(once, twiceState)
|
|
93
|
+
if got, want := strings.Join(twice, "\n"), strings.Join(once, "\n"); got != want {
|
|
94
|
+
t.Fatalf("second serialization changed bytes:\n--- once\n%s\n--- twice\n%s", want, got)
|
|
95
|
+
}
|
|
96
|
+
if !strings.Contains(strings.Join(once, "\n"), "Curated note stays exactly here.") {
|
|
97
|
+
t.Fatal("serializer removed curated Markdown")
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
restored, err := NextClarifyCursor(ClarifyRestore, ClarifyTransitionInput{
|
|
101
|
+
Cursor: parsed,
|
|
102
|
+
ClarifyNextAction: "/rite-clarify",
|
|
103
|
+
DefaultReturnNextAction: "/rite-build",
|
|
104
|
+
})
|
|
105
|
+
if err != nil {
|
|
106
|
+
t.Fatal(err)
|
|
107
|
+
}
|
|
108
|
+
restoreOnce := ApplyClarifyCursor(once, restored)
|
|
109
|
+
restoreParsed, err := ParseClarifyCursor(restoreOnce)
|
|
110
|
+
if err != nil {
|
|
111
|
+
t.Fatal(err)
|
|
112
|
+
}
|
|
113
|
+
restoreTwice, err := NextClarifyCursor(ClarifyRestore, ClarifyTransitionInput{Cursor: restoreParsed})
|
|
114
|
+
if err != nil {
|
|
115
|
+
t.Fatal(err)
|
|
116
|
+
}
|
|
117
|
+
if got, want := strings.Join(ApplyClarifyCursor(restoreOnce, restoreTwice), "\n"), strings.Join(restoreOnce, "\n"); got != want {
|
|
118
|
+
t.Fatalf("second restore serialization changed bytes:\n--- once\n%s\n--- twice\n%s", want, got)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
func TestParseClarifyCursorRejectsInvalidReturnPhase(t *testing.T) {
|
|
123
|
+
_, err := ParseClarifyCursor([]string{
|
|
124
|
+
"| phase | clarify |",
|
|
125
|
+
"| return_phase | not-a-phase |",
|
|
126
|
+
})
|
|
127
|
+
if err == nil || !strings.Contains(err.Error(), "invalid return phase") {
|
|
128
|
+
t.Fatalf("error=%v, want invalid return phase", err)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
@@ -18,15 +18,19 @@ func main() {
|
|
|
18
18
|
flag.Parse()
|
|
19
19
|
|
|
20
20
|
document := struct {
|
|
21
|
-
GeneratedBy
|
|
22
|
-
SchemaVersion
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
GeneratedBy string `json:"generatedBy"`
|
|
22
|
+
SchemaVersion int `json:"schemaVersion"`
|
|
23
|
+
AuthorityPolicy state.AuthorityPolicy `json:"authorityPolicy"`
|
|
24
|
+
Phases []state.WorkflowPhase `json:"phases"`
|
|
25
|
+
ClarifyReturnFields []state.ClarifyFieldPolicy `json:"clarifyReturnFields"`
|
|
26
|
+
CursorKeyAliases []state.CursorKeyAlias `json:"cursorKeyAliases"`
|
|
25
27
|
}{
|
|
26
|
-
GeneratedBy:
|
|
27
|
-
SchemaVersion:
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
GeneratedBy: "go generate ./internal/state; DO NOT EDIT",
|
|
29
|
+
SchemaVersion: state.SchemaVersion,
|
|
30
|
+
AuthorityPolicy: state.WorkflowAuthorityPolicy(),
|
|
31
|
+
Phases: state.WorkflowPhases(),
|
|
32
|
+
ClarifyReturnFields: state.ClarifyFieldPolicies(),
|
|
33
|
+
CursorKeyAliases: state.CursorKeyAliases(),
|
|
30
34
|
}
|
|
31
35
|
data, err := json.MarshalIndent(document, "", " ")
|
|
32
36
|
if err != nil {
|
|
@@ -16,6 +16,8 @@ const (
|
|
|
16
16
|
CursorQuestionID = "question_id"
|
|
17
17
|
CursorActiveSlice = "active_slice"
|
|
18
18
|
CursorAFKSlicesRemaining = "afk_slices_remaining"
|
|
19
|
+
CursorReturnPhase = "return_phase"
|
|
20
|
+
CursorReturnNextAction = "return_next_action"
|
|
19
21
|
)
|
|
20
22
|
|
|
21
23
|
var cursorKeyAliases = map[string]string{
|
|
@@ -87,6 +89,62 @@ func SetCursorField(lines []string, key, value string) ([]string, bool) {
|
|
|
87
89
|
return out, false
|
|
88
90
|
}
|
|
89
91
|
|
|
92
|
+
// UpsertCursorField replaces key when present or inserts it into the canonical
|
|
93
|
+
// cursor table (falling back to a legacy bullet when no table exists).
|
|
94
|
+
func UpsertCursorField(lines []string, key, value string) []string {
|
|
95
|
+
if out, ok := SetCursorField(lines, key, value); ok {
|
|
96
|
+
return out
|
|
97
|
+
}
|
|
98
|
+
out := append([]string(nil), lines...)
|
|
99
|
+
lastTable := -1
|
|
100
|
+
inCursor := false
|
|
101
|
+
for i, line := range out {
|
|
102
|
+
trimmed := strings.TrimSpace(line)
|
|
103
|
+
if strings.HasPrefix(trimmed, "## ") {
|
|
104
|
+
if inCursor {
|
|
105
|
+
break
|
|
106
|
+
}
|
|
107
|
+
inCursor = strings.EqualFold(strings.TrimSpace(strings.TrimPrefix(trimmed, "## ")), "Cursor")
|
|
108
|
+
continue
|
|
109
|
+
}
|
|
110
|
+
if len(trimmed) >= 2 && trimmed[0] == '|' && trimmed[len(trimmed)-1] == '|' {
|
|
111
|
+
gotKey, _, kind, ok := parseCursorLine(line)
|
|
112
|
+
normalized := normalizeCursorKey(gotKey)
|
|
113
|
+
if !inCursor && ok && (normalized == normalizeCursorKey(CursorPhase) ||
|
|
114
|
+
normalized == normalizeCursorKey(CursorStatus) ||
|
|
115
|
+
normalized == normalizeCursorKey(CursorNextAction)) {
|
|
116
|
+
inCursor = true
|
|
117
|
+
}
|
|
118
|
+
if inCursor && ok && kind == cursorLineTable {
|
|
119
|
+
lastTable = i
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if lastTable >= 0 {
|
|
124
|
+
insert := "| " + key + " | " + value + " |"
|
|
125
|
+
out = append(out, "")
|
|
126
|
+
copy(out[lastTable+2:], out[lastTable+1:])
|
|
127
|
+
out[lastTable+1] = insert
|
|
128
|
+
return out
|
|
129
|
+
}
|
|
130
|
+
return append(out, "- "+key+": "+value)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// DeleteCursorField removes every presentation of key from canonical or legacy
|
|
134
|
+
// state without disturbing unrelated prose.
|
|
135
|
+
func DeleteCursorField(lines []string, key string) []string {
|
|
136
|
+
want := normalizeCursorKey(key)
|
|
137
|
+
out := make([]string, 0, len(lines))
|
|
138
|
+
for _, line := range lines {
|
|
139
|
+
gotKey, _, _, ok := parseCursorLine(line)
|
|
140
|
+
if ok && normalizeCursorKey(gotKey) == want {
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
out = append(out, line)
|
|
144
|
+
}
|
|
145
|
+
return out
|
|
146
|
+
}
|
|
147
|
+
|
|
90
148
|
func parseCursorLine(line string) (key, value string, kind cursorLineKind, ok bool) {
|
|
91
149
|
trimmed := strings.TrimSpace(line)
|
|
92
150
|
if len(trimmed) >= 2 && trimmed[0] == '|' && trimmed[len(trimmed)-1] == '|' {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
package state
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import (
|
|
4
|
+
"strings"
|
|
5
|
+
"testing"
|
|
6
|
+
)
|
|
4
7
|
|
|
5
8
|
func TestCursorFieldReadsCanonicalTableAndLegacyLines(t *testing.T) {
|
|
6
9
|
table := []string{
|
|
@@ -56,3 +59,41 @@ func TestSetCursorFieldPreservesCanonicalAndLegacyFormats(t *testing.T) {
|
|
|
56
59
|
})
|
|
57
60
|
}
|
|
58
61
|
}
|
|
62
|
+
|
|
63
|
+
func TestUpsertAndDeleteCursorFieldStayInsideCursorTable(t *testing.T) {
|
|
64
|
+
lines := []string{
|
|
65
|
+
"# State",
|
|
66
|
+
"",
|
|
67
|
+
"## Cursor",
|
|
68
|
+
"| Key | Value |",
|
|
69
|
+
"| --- | --- |",
|
|
70
|
+
"| phase | build |",
|
|
71
|
+
"| status | running |",
|
|
72
|
+
"",
|
|
73
|
+
"## Awaiting human",
|
|
74
|
+
"| Key | Value |",
|
|
75
|
+
"| --- | --- |",
|
|
76
|
+
"| question_id | q-1 |",
|
|
77
|
+
}
|
|
78
|
+
lines = UpsertCursorField(lines, CursorReturnPhase, "build")
|
|
79
|
+
value, ok := CursorField(lines, CursorReturnPhase)
|
|
80
|
+
if !ok || value != "build" {
|
|
81
|
+
t.Fatalf("return phase=(%q,%v), want build", value, ok)
|
|
82
|
+
}
|
|
83
|
+
returnIndex, questionIndex := -1, -1
|
|
84
|
+
for i, line := range lines {
|
|
85
|
+
if strings.Contains(line, CursorReturnPhase) {
|
|
86
|
+
returnIndex = i
|
|
87
|
+
}
|
|
88
|
+
if strings.Contains(line, CursorQuestionID) {
|
|
89
|
+
questionIndex = i
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if returnIndex < 0 || questionIndex < 0 || returnIndex > questionIndex {
|
|
93
|
+
t.Fatalf("upsert inserted outside cursor table:\n%s", strings.Join(lines, "\n"))
|
|
94
|
+
}
|
|
95
|
+
lines = DeleteCursorField(lines, CursorReturnPhase)
|
|
96
|
+
if _, ok := CursorField(lines, CursorReturnPhase); ok {
|
|
97
|
+
t.Fatalf("DeleteCursorField left return phase:\n%s", strings.Join(lines, "\n"))
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -10,52 +10,28 @@ import (
|
|
|
10
10
|
"strings"
|
|
11
11
|
|
|
12
12
|
"github.com/devrites/devrites/internal/devritespaths"
|
|
13
|
+
"github.com/devrites/devrites/internal/rootfacts"
|
|
13
14
|
)
|
|
14
15
|
|
|
15
16
|
// ResolveRoot returns the .devrites directory to operate on. A non-empty
|
|
16
17
|
// override (e.g. from DEVRITES_ROOT) may name either the project root or its
|
|
17
18
|
// .devrites directory; otherwise the nearest ancestor .devrites is used.
|
|
18
19
|
func ResolveRoot(override string) (string, error) {
|
|
19
|
-
|
|
20
|
-
info, err := os.Stat(override)
|
|
21
|
-
if err != nil {
|
|
22
|
-
return "", fmt.Errorf("DEVRITES_ROOT %q: %w", override, err)
|
|
23
|
-
}
|
|
24
|
-
if !info.IsDir() {
|
|
25
|
-
return "", fmt.Errorf("DEVRITES_ROOT %q is not a directory", override)
|
|
26
|
-
}
|
|
27
|
-
if filepath.Base(filepath.Clean(override)) == ".devrites" {
|
|
28
|
-
return override, nil
|
|
29
|
-
}
|
|
30
|
-
child := filepath.Join(override, ".devrites")
|
|
31
|
-
if info, err := os.Stat(child); err == nil && info.IsDir() {
|
|
32
|
-
return child, nil
|
|
33
|
-
}
|
|
34
|
-
return "", fmt.Errorf("DEVRITES_ROOT %q is not a project root or .devrites directory", override)
|
|
35
|
-
}
|
|
36
|
-
cwd, err := os.Getwd()
|
|
20
|
+
facts, err := rootfacts.Resolve(override)
|
|
37
21
|
if err != nil {
|
|
38
|
-
return "",
|
|
39
|
-
}
|
|
40
|
-
for dir := cwd; ; {
|
|
41
|
-
cand := filepath.Join(dir, ".devrites")
|
|
42
|
-
if info, err := os.Stat(cand); err == nil && info.IsDir() {
|
|
43
|
-
return cand, nil
|
|
44
|
-
}
|
|
45
|
-
parent := filepath.Dir(dir)
|
|
46
|
-
if parent == dir {
|
|
47
|
-
return "", errors.New("no .devrites directory found (set DEVRITES_ROOT or run inside a DevRites workspace)")
|
|
48
|
-
}
|
|
49
|
-
dir = parent
|
|
22
|
+
return "", err
|
|
50
23
|
}
|
|
24
|
+
return facts.PhysicalRoot, nil
|
|
51
25
|
}
|
|
52
26
|
|
|
53
27
|
// Feature is a loaded per-feature workspace: its declared phase plus which
|
|
54
28
|
// completeness sections currently have real content.
|
|
55
29
|
type Feature struct {
|
|
56
|
-
Slug
|
|
57
|
-
Phase
|
|
58
|
-
Present
|
|
30
|
+
Slug string
|
|
31
|
+
Phase Phase
|
|
32
|
+
Present map[Section]bool
|
|
33
|
+
PresentFiles map[string]bool
|
|
34
|
+
LegacyLayout bool
|
|
59
35
|
}
|
|
60
36
|
|
|
61
37
|
// featureDir is where per-feature state lives under the root. work/ is the
|
|
@@ -174,7 +150,17 @@ func LoadFeature(root, slug string) (*Feature, error) {
|
|
|
174
150
|
for _, s := range Sections {
|
|
175
151
|
present[s] = sectionPresentAny(dir, s)
|
|
176
152
|
}
|
|
177
|
-
|
|
153
|
+
presentFiles := make(map[string]bool)
|
|
154
|
+
for _, name := range WorkspaceFiles() {
|
|
155
|
+
presentFiles[name] = sectionPresent(filepath.Join(dir, name))
|
|
156
|
+
}
|
|
157
|
+
return &Feature{
|
|
158
|
+
Slug: slug,
|
|
159
|
+
Phase: phase,
|
|
160
|
+
Present: present,
|
|
161
|
+
PresentFiles: presentFiles,
|
|
162
|
+
LegacyLayout: filepath.Clean(dir) == filepath.Clean(filepath.Join(root, "features", slug)),
|
|
163
|
+
}, nil
|
|
178
164
|
}
|
|
179
165
|
|
|
180
166
|
// sectionPresentAny reports whether any file that can satisfy section s has real
|
|
@@ -204,22 +190,23 @@ func declaredPhaseFromLedger(path string) (Phase, bool) {
|
|
|
204
190
|
return Phase(word), true
|
|
205
191
|
}
|
|
206
192
|
|
|
207
|
-
// ReadDeclaredSchemaVersion returns the schemaVersion
|
|
208
|
-
//
|
|
209
|
-
//
|
|
210
|
-
// the engine supports: doctor needs to observe a newer version to report skew,
|
|
211
|
-
// not fail on it.
|
|
193
|
+
// ReadDeclaredSchemaVersion returns the schemaVersion from feature.md
|
|
194
|
+
// frontmatter, or 0 if the file, frontmatter, or field is missing or invalid.
|
|
195
|
+
// Unlike LoadFeature, it returns newer versions so doctor can report the skew.
|
|
212
196
|
func ReadDeclaredSchemaVersion(root, slug string) int {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
197
|
+
dir := featureDir(root, slug)
|
|
198
|
+
for _, name := range workspaceMapFiles {
|
|
199
|
+
raw, err := os.ReadFile(filepath.Join(dir, name))
|
|
200
|
+
if err != nil {
|
|
201
|
+
continue
|
|
202
|
+
}
|
|
203
|
+
fm, _ := splitFrontmatter(raw)
|
|
204
|
+
n, err := strconv.Atoi(strings.TrimSpace(fm["schemaVersion"]))
|
|
205
|
+
if err == nil {
|
|
206
|
+
return n
|
|
207
|
+
}
|
|
221
208
|
}
|
|
222
|
-
return
|
|
209
|
+
return 0
|
|
223
210
|
}
|
|
224
211
|
|
|
225
212
|
// MaxDeclaredSchemaVersion returns the highest schemaVersion declared by any
|
|
@@ -6,7 +6,7 @@ package state
|
|
|
6
6
|
// A workspace map may declare its own schemaVersion in frontmatter; the engine
|
|
7
7
|
// refuses a version newer than this (see LoadFeature) and otherwise reads the
|
|
8
8
|
// files, which evolve additively.
|
|
9
|
-
const SchemaVersion =
|
|
9
|
+
const SchemaVersion = 2
|
|
10
10
|
|
|
11
11
|
const (
|
|
12
12
|
WorkspaceMapFile = "README.md"
|
|
@@ -20,9 +20,8 @@ func WorkspaceMapFiles() []string {
|
|
|
20
20
|
return append([]string(nil), workspaceMapFiles...)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
// Section is one single-
|
|
24
|
-
//
|
|
25
|
-
// each file context-cheap and makes completeness self-evident.
|
|
23
|
+
// Section is one single-purpose completeness file in a feature directory. Small
|
|
24
|
+
// files use less context and make missing content easier to spot.
|
|
26
25
|
type Section string
|
|
27
26
|
|
|
28
27
|
const (
|
|
@@ -47,7 +46,7 @@ var Sections = []Section{
|
|
|
47
46
|
// sectionFiles lists the filenames that can satisfy each section, canonical name
|
|
48
47
|
// first, then supported aliases: the same mapping `devrites-engine migrate`
|
|
49
48
|
// normalizes (proof→evidence, status→state). A section
|
|
50
|
-
// counts as present if
|
|
49
|
+
// counts as present if any of its files has real content, so the engine reads a
|
|
51
50
|
// live workspace before the pack sweep converges the filenames. The workspace
|
|
52
51
|
// map is not a section; it is handled separately in LoadFeature.
|
|
53
52
|
var sectionFiles = map[Section][]string{
|
|
@@ -70,6 +69,7 @@ type Phase string
|
|
|
70
69
|
const (
|
|
71
70
|
PhaseFrame Phase = "frame" // problem framing
|
|
72
71
|
PhaseSpec Phase = "spec" // specification
|
|
72
|
+
PhaseClarify Phase = "clarify" // decision-coverage closure
|
|
73
73
|
PhaseTemper Phase = "temper" // strategic specification review
|
|
74
74
|
PhaseDefine Phase = "define" // plan definition
|
|
75
75
|
PhasePlan Phase = "plan" // approved plan
|
|
@@ -84,13 +84,13 @@ const (
|
|
|
84
84
|
PhaseDone Phase = "done" // archived completion
|
|
85
85
|
)
|
|
86
86
|
|
|
87
|
-
// phaseDefinition
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
// additions compile-visible and lets every consumer derive the same arc.
|
|
87
|
+
// phaseDefinition owns lifecycle order and phase behavior. Workflow topology is
|
|
88
|
+
// versioned application logic rather than deployment configuration, so the
|
|
89
|
+
// compiler sees changes and every consumer derives the same ordering.
|
|
91
90
|
type phaseDefinition struct {
|
|
92
91
|
phase Phase
|
|
93
92
|
resumeVerb string
|
|
93
|
+
transitionRight string
|
|
94
94
|
required []Section
|
|
95
95
|
aliases []string
|
|
96
96
|
workspaceRequired []string
|
|
@@ -106,43 +106,64 @@ var (
|
|
|
106
106
|
sectionsProof = []Section{SectionSpec, SectionPlan, SectionDecisions, SectionTasks, SectionProof}
|
|
107
107
|
sectionsComplete = []Section{SectionSpec, SectionPlan, SectionDecisions, SectionTasks, SectionProof, SectionStatus}
|
|
108
108
|
|
|
109
|
-
workspaceFrame
|
|
110
|
-
workspaceSpec
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
workspaceFrame = []string{"state.md"}
|
|
110
|
+
workspaceSpec = []string{"brief.md", "spec.md", "state.md", "decisions.md", "assumptions.md", "questions.md"}
|
|
111
|
+
workspaceClarify = append(append([]string(nil), workspaceSpec...), "decision-coverage.md")
|
|
112
|
+
workspacePlan = append(append([]string(nil), workspaceClarify...), "architecture.md", "plan.md", "tasks.md", "traceability.md")
|
|
113
|
+
workspaceVetted = append(append([]string(nil), workspacePlan...), "eng-review.md", "test-plan.md")
|
|
114
|
+
workspaceProof = append(append([]string(nil), workspaceVetted...), "evidence.md", "touched-files.md")
|
|
113
115
|
)
|
|
114
116
|
|
|
115
117
|
// Completeness is phase-relative: a section not yet required (e.g. proof during
|
|
116
|
-
// spec) never blocks. Requirements are additive down the arc.
|
|
117
|
-
//
|
|
118
|
-
// resume command.
|
|
118
|
+
// spec) never blocks. Requirements are additive down the arc. Define is active
|
|
119
|
+
// authoring; Plan is the approved/repaired checkpoint that resumes at Vet.
|
|
119
120
|
var phaseDefinitions = []phaseDefinition{
|
|
120
|
-
{phase: PhaseFrame, resumeVerb: "frame", workspaceRequired: workspaceFrame},
|
|
121
|
-
{phase: PhaseSpec, resumeVerb: "spec", required: sectionsSpec, aliases: []string{"specced", "specifying"}, workspaceRequired: workspaceSpec},
|
|
122
|
-
{phase:
|
|
123
|
-
{phase:
|
|
124
|
-
{phase:
|
|
125
|
-
{phase:
|
|
126
|
-
{phase:
|
|
127
|
-
{phase:
|
|
128
|
-
{phase:
|
|
129
|
-
{phase:
|
|
130
|
-
{phase:
|
|
131
|
-
{phase:
|
|
132
|
-
{phase:
|
|
133
|
-
{phase:
|
|
121
|
+
{phase: PhaseFrame, resumeVerb: "frame", transitionRight: "Frame an unstructured request before lifecycle work.", workspaceRequired: workspaceFrame},
|
|
122
|
+
{phase: PhaseSpec, resumeVerb: "spec", transitionRight: "Author the product specification.", required: sectionsSpec, aliases: []string{"specced", "specifying"}, workspaceRequired: workspaceSpec},
|
|
123
|
+
{phase: PhaseClarify, resumeVerb: "clarify", transitionRight: "Close decision coverage in the written specification.", required: sectionsSpec, aliases: []string{"clarified", "clarifying"}, workspaceRequired: workspaceClarify, blocksOpenQuestions: true},
|
|
124
|
+
{phase: PhaseTemper, resumeVerb: "temper", transitionRight: "Optionally challenge the clarified specification strategy.", required: sectionsSpec, aliases: []string{"tempered", "tempering"}, workspaceRequired: workspaceClarify, blocksOpenQuestions: true},
|
|
125
|
+
{phase: PhaseDefine, resumeVerb: "define", transitionRight: "Author and approve the initial implementation plan.", required: sectionsPlan, aliases: []string{"defined", "defining"}, workspaceRequired: workspacePlan, blocksOpenQuestions: true},
|
|
126
|
+
{phase: PhasePlan, resumeVerb: "vet", transitionRight: "Hold the approved or repaired plan checkpoint for engineering review.", required: sectionsPlan, aliases: []string{"planned", "planning"}, workspaceRequired: workspacePlan, blocksOpenQuestions: true},
|
|
127
|
+
{phase: PhaseVet, resumeVerb: "vet", transitionRight: "Review implementation readiness before build.", required: sectionsBuild, aliases: []string{"vetted", "vetting"}, workspaceRequired: workspaceVetted, blocksOpenQuestions: true},
|
|
128
|
+
{phase: PhaseBuild, resumeVerb: "build", transitionRight: "Implement the next approved vertical slice.", required: sectionsBuild, aliases: []string{"building", "wip", "in", "in-progress"}, workspaceRequired: workspaceVetted, blocksOpenQuestions: true},
|
|
129
|
+
{phase: PhaseConverge, resumeVerb: "converge", transitionRight: "Recover unmet clarified intent into new slices.", required: sectionsBuild, aliases: []string{"converged", "converging"}, workspaceRequired: workspaceVetted, blocksOpenQuestions: true},
|
|
130
|
+
{phase: PhaseProve, resumeVerb: "prove", transitionRight: "Produce acceptance evidence for the implementation.", required: sectionsProof, aliases: []string{"proving", "proven", "testing"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true},
|
|
131
|
+
{phase: PhasePolish, resumeVerb: "polish", transitionRight: "Apply the bounded quality pass.", required: sectionsProof, aliases: []string{"polished", "polishing"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true},
|
|
132
|
+
{phase: PhaseReview, resumeVerb: "review", transitionRight: "Review the proven implementation.", required: sectionsProof, aliases: []string{"reviewed", "reviewing"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true},
|
|
133
|
+
{phase: PhaseSeal, resumeVerb: "seal", transitionRight: "Decide the final GO or NO-GO.", required: sectionsComplete, aliases: []string{"sealed", "sealing"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true, shippable: true},
|
|
134
|
+
{phase: PhaseShip, resumeVerb: "ship", transitionRight: "Perform authorized release and close-out mutations.", required: sectionsComplete, aliases: []string{"shipped", "shipping"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true, shippable: true},
|
|
135
|
+
{phase: PhaseDone, transitionRight: "Represent archived completion with no resume command.", required: sectionsComplete, aliases: []string{"closed", "complete", "completed"}, workspaceRequired: workspaceProof, proofRequired: true, blocksOpenQuestions: true, shippable: true},
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
// WorkflowPhase is the read-only cross-format view used to generate the compact
|
|
137
139
|
// manifest consumed by non-Go release tooling.
|
|
138
140
|
type WorkflowPhase struct {
|
|
139
|
-
ID Phase
|
|
140
|
-
ResumeVerb string
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
ID Phase `json:"id"`
|
|
142
|
+
ResumeVerb string `json:"resumeVerb,omitempty"`
|
|
143
|
+
TransitionRight string `json:"transitionRight"`
|
|
144
|
+
Aliases []string `json:"aliases,omitempty"`
|
|
145
|
+
RequiredSections []Section `json:"requiredSections,omitempty"`
|
|
146
|
+
WorkspaceRequired []string `json:"workspaceRequired"`
|
|
147
|
+
ProofRequired bool `json:"proofRequired,omitempty"`
|
|
148
|
+
BlocksOpenQuestions bool `json:"blocksOpenQuestions,omitempty"`
|
|
149
|
+
Shippable bool `json:"shippable,omitempty"`
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// AuthorityPolicy owns the small cross-format trust and tracking assertions
|
|
153
|
+
// that otherwise drift between current docs.
|
|
154
|
+
type AuthorityPolicy struct {
|
|
155
|
+
PrinciplesTrust string `json:"principlesTrust"`
|
|
156
|
+
TrackedState []string `json:"trackedState"`
|
|
157
|
+
LocalState []string `json:"localState"`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// WorkflowAuthorityPolicy returns copied policy metadata for the manifest.
|
|
161
|
+
func WorkflowAuthorityPolicy() AuthorityPolicy {
|
|
162
|
+
return AuthorityPolicy{
|
|
163
|
+
PrinciplesTrust: "Project principles may become project policy only after explicit provenance and validation; arbitrary project-local Markdown is never inherently trusted executable instruction.",
|
|
164
|
+
TrackedState: []string{".devrites/specs/"},
|
|
165
|
+
LocalState: []string{".devrites/work/", ".devrites/archive/", ".devrites/ACTIVE"},
|
|
166
|
+
}
|
|
146
167
|
}
|
|
147
168
|
|
|
148
169
|
// WorkflowPhases returns copied metadata suitable for deterministic generation.
|
|
@@ -152,7 +173,9 @@ func WorkflowPhases() []WorkflowPhase {
|
|
|
152
173
|
out = append(out, WorkflowPhase{
|
|
153
174
|
ID: definition.phase,
|
|
154
175
|
ResumeVerb: definition.resumeVerb,
|
|
176
|
+
TransitionRight: definition.transitionRight,
|
|
155
177
|
Aliases: append([]string(nil), definition.aliases...),
|
|
178
|
+
RequiredSections: append([]Section(nil), definition.required...),
|
|
156
179
|
WorkspaceRequired: append([]string(nil), definition.workspaceRequired...),
|
|
157
180
|
ProofRequired: definition.proofRequired,
|
|
158
181
|
BlocksOpenQuestions: definition.blocksOpenQuestions,
|
|
@@ -239,3 +262,33 @@ func RequiredSections(p Phase) []Section {
|
|
|
239
262
|
}
|
|
240
263
|
return out
|
|
241
264
|
}
|
|
265
|
+
|
|
266
|
+
// RequiredWorkspaceFiles returns the canonical per-file completeness contract
|
|
267
|
+
// for phase p. Unlike the legacy Section view, this includes every durable
|
|
268
|
+
// workflow artifact (for example decision-coverage.md and test-plan.md), so
|
|
269
|
+
// runtime gates cannot silently ignore files added to the lifecycle registry.
|
|
270
|
+
func RequiredWorkspaceFiles(p Phase) []string {
|
|
271
|
+
definition, ok := definitionFor(p)
|
|
272
|
+
if !ok {
|
|
273
|
+
return nil
|
|
274
|
+
}
|
|
275
|
+
return append([]string(nil), definition.workspaceRequired...)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// WorkspaceFiles returns every lifecycle-owned workspace filename once, in
|
|
279
|
+
// first-required order. It is derived from phaseDefinitions so the runtime
|
|
280
|
+
// presence model and the generated workflow manifest share one authority.
|
|
281
|
+
func WorkspaceFiles() []string {
|
|
282
|
+
seen := make(map[string]bool)
|
|
283
|
+
var out []string
|
|
284
|
+
for _, definition := range phaseDefinitions {
|
|
285
|
+
for _, name := range definition.workspaceRequired {
|
|
286
|
+
if seen[name] {
|
|
287
|
+
continue
|
|
288
|
+
}
|
|
289
|
+
seen[name] = true
|
|
290
|
+
out = append(out, name)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return out
|
|
294
|
+
}
|
|
@@ -38,6 +38,8 @@ type WorkspaceSnapshot struct {
|
|
|
38
38
|
Complete bool `json:"complete"`
|
|
39
39
|
Sections []SectionSnapshot `json:"sections"`
|
|
40
40
|
MissingSections []string `json:"missingSections,omitempty"`
|
|
41
|
+
Files []FileSnapshot `json:"files"`
|
|
42
|
+
MissingFiles []string `json:"missingFiles,omitempty"`
|
|
41
43
|
CurrentSlice *SliceSnapshot `json:"currentSlice,omitempty"`
|
|
42
44
|
Evidence EvidenceSnapshot `json:"evidence"`
|
|
43
45
|
Drift DriftSnapshot `json:"drift"`
|
|
@@ -63,6 +65,12 @@ type SectionSnapshot struct {
|
|
|
63
65
|
Required bool `json:"required"`
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
type FileSnapshot struct {
|
|
69
|
+
Name string `json:"name"`
|
|
70
|
+
Present bool `json:"present"`
|
|
71
|
+
Required bool `json:"required"`
|
|
72
|
+
}
|
|
73
|
+
|
|
66
74
|
type SliceSnapshot struct {
|
|
67
75
|
Index int `json:"index"`
|
|
68
76
|
Total int `json:"total"`
|
|
@@ -150,8 +158,16 @@ func Snapshot(root, slug string) (*WorkspaceSnapshot, error) {
|
|
|
150
158
|
for _, section := range report.Missing {
|
|
151
159
|
snap.MissingSections = append(snap.MissingSections, string(section))
|
|
152
160
|
}
|
|
153
|
-
|
|
154
|
-
snap.
|
|
161
|
+
for _, name := range WorkspaceFiles() {
|
|
162
|
+
snap.Files = append(snap.Files, FileSnapshot{
|
|
163
|
+
Name: name,
|
|
164
|
+
Present: report.PresentFiles[name],
|
|
165
|
+
Required: report.RequiredFiles[name],
|
|
166
|
+
})
|
|
167
|
+
}
|
|
168
|
+
snap.MissingFiles = append(snap.MissingFiles, report.MissingFiles...)
|
|
169
|
+
if snap.RunMode == "AFK" && len(snap.MissingFiles) > 0 {
|
|
170
|
+
snap.Warnings = append(snap.Warnings, "AFK workspace has missing required files")
|
|
155
171
|
}
|
|
156
172
|
if report.Required[SectionProof] && snap.Evidence.Status != "fresh" {
|
|
157
173
|
snap.Warnings = append(snap.Warnings, "proof phase requires fresh evidence")
|