devrites 5.14.4 → 6.0.1
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 +23 -0
- package/NOTICE.md +6 -4
- package/README.md +77 -16
- package/SECURITY.md +25 -11
- package/bin/devrites.mjs +49 -15
- package/docs/adr/0001-go-engine-as-control-plane.md +6 -3
- package/docs/adr/0029-v5-workspace-schema-and-native-migration.md +9 -0
- package/docs/adr/README.md +3 -2
- package/docs/agents/issue-tracker.md +1 -1
- package/docs/architecture.md +6 -3
- package/docs/cli.md +32 -9
- package/docs/command-map.md +5 -3
- package/docs/engine/state-schema.md +1 -1
- package/docs/flow.md +1 -1
- package/docs/harness-compliance.md +2 -2
- package/docs/release.md +15 -11
- package/docs/usage.md +1 -1
- package/engine/commands.go +1 -1
- package/engine/go.mod +1 -1
- package/engine/help.go +41 -15
- package/engine/help_test.go +134 -0
- package/engine/internal/acceptance/acceptance_test.go +298 -7
- package/engine/internal/acceptance/approve.go +7 -2
- package/engine/internal/acceptance/cli.go +3 -0
- package/engine/internal/acceptance/evidence.go +69 -5
- package/engine/internal/acceptance/lint.go +1 -1
- package/engine/internal/acceptance/run.go +5 -3
- package/engine/internal/acceptance/scaffold.go +5 -16
- package/engine/internal/devritespaths/paths.go +7 -6
- package/engine/internal/devritespaths/paths_test.go +18 -0
- package/engine/internal/fsutil/copy.go +83 -49
- package/engine/internal/fsutil/copy_test.go +70 -109
- package/engine/internal/gate/gate.go +89 -16
- package/engine/internal/gate/gate_test.go +101 -0
- package/engine/internal/hostpack/hostpack.go +52 -2
- package/engine/internal/hostpack/hostpack_test.go +83 -2
- package/engine/internal/install/apply.go +59 -16
- package/engine/internal/install/binary.go +10 -1
- package/engine/internal/install/install_test.go +428 -0
- package/engine/internal/install/merge.go +69 -38
- package/engine/internal/install/preflight.go +7 -0
- package/engine/internal/install/uninstall.go +43 -4
- package/engine/internal/lib/claims.go +25 -4
- package/engine/internal/lib/claims_test.go +57 -0
- package/engine/internal/lib/closeout.go +41 -3
- package/engine/internal/lib/closeout_test.go +144 -0
- package/engine/internal/lib/context.go +8 -4
- package/engine/internal/lib/context_next_test.go +100 -0
- package/engine/internal/lib/detect.go +1 -1
- package/engine/internal/lib/detect_test.go +13 -0
- package/engine/internal/lib/diffscope.go +19 -9
- package/engine/internal/lib/dispatch.go +7 -0
- package/engine/internal/lib/dup.go +40 -37
- package/engine/internal/lib/dup_test.go +178 -0
- package/engine/internal/lib/manifest_union.go +4 -1
- package/engine/internal/lib/manifest_union_test.go +37 -0
- package/engine/internal/lib/metrics.go +4 -0
- package/engine/internal/lib/metrics_test.go +28 -0
- package/engine/internal/lib/migrate_test.go +59 -0
- package/engine/internal/lib/observe_budgets.go +25 -9
- package/engine/internal/lib/observe_budgets_test.go +254 -0
- package/engine/internal/lib/observe_summary.go +23 -2
- package/engine/internal/lib/open_visual.go +4 -2
- package/engine/internal/lib/open_visual_test.go +11 -0
- package/engine/internal/lib/regression.go +62 -23
- package/engine/internal/lib/regression_test.go +103 -0
- package/engine/internal/lib/resolve.go +36 -17
- package/engine/internal/lib/resolve_remediation_test.go +132 -0
- package/engine/internal/lib/skilltrust.go +0 -11
- package/engine/internal/lib/slicecheck.go +7 -5
- package/engine/internal/lib/slicecheck_test.go +18 -0
- package/engine/internal/lib/triggers.go +9 -3
- package/engine/internal/lib/triggers_test.go +23 -0
- package/engine/internal/lib/util.go +17 -3
- package/engine/internal/lib/util_test.go +104 -0
- package/engine/internal/lib/visual_outline.go +7 -3
- package/engine/internal/lib/visual_outline_test.go +28 -0
- package/engine/internal/lib/windows.go +13 -9
- package/engine/internal/lib/windows_test.go +98 -0
- package/engine/internal/lib/workspace_read.go +2 -11
- package/engine/internal/lib/workspace_read_test.go +102 -0
- package/engine/internal/markdowntext/markdowntext.go +194 -11
- package/engine/internal/markdowntext/testdata/structural.json +250 -0
- package/engine/internal/notes/cli.go +30 -12
- package/engine/internal/notes/notes.go +242 -39
- package/engine/internal/notes/notes_test.go +372 -0
- package/engine/internal/overhaul/admit/packet.go +89 -0
- package/engine/internal/overhaul/admit/packet_test.go +223 -0
- package/engine/internal/overhaul/admit/run.go +4 -0
- package/engine/internal/overhaul/bench/run.go +6 -0
- package/engine/internal/overhaul/bench/run_test.go +46 -0
- package/engine/internal/overhaul/overhaul.go +6 -1
- package/engine/internal/overhaul/ovio/ovio.go +10 -3
- package/engine/internal/overhaul/ovio/ovio_test.go +75 -0
- package/engine/internal/overhaul/packet/packet.go +208 -0
- package/engine/internal/overhaul/packet/packet_test.go +263 -0
- package/engine/internal/overhaul/records/check.go +6 -0
- package/engine/internal/overhaul/records/init.go +16 -5
- package/engine/internal/overhaul/records/records_test.go +4 -0
- package/engine/internal/overhaul/records/run.go +66 -0
- package/engine/internal/overhaul/records/run_test.go +77 -0
- package/engine/internal/overhaul/render/run.go +15 -11
- package/engine/internal/overhaul/render/run_test.go +463 -1
- package/engine/internal/overhaul/render/visual.go +95 -33
- package/engine/internal/overhaul/score/run.go +20 -0
- package/engine/internal/overhaul/score/run_test.go +156 -1
- package/engine/internal/overhaul/snapshot/run.go +78 -21
- package/engine/internal/overhaul/snapshot/run_test.go +344 -8
- package/engine/internal/parallel/cli.go +33 -20
- package/engine/internal/parallel/cli_test.go +59 -0
- package/engine/internal/parallel/git.go +39 -1
- package/engine/internal/parallel/ops.go +101 -11
- package/engine/internal/parallel/ops_test.go +552 -69
- package/engine/internal/parallel/parallel_test.go +31 -1
- package/engine/internal/parallel/pathdisjoint.go +19 -1
- package/engine/internal/parallel/pathdisjoint_test.go +72 -0
- package/engine/internal/parallel/select.go +6 -2
- package/engine/internal/release/release.go +13 -3
- package/engine/internal/release/release_test.go +208 -3
- package/engine/internal/rootfacts/facts.go +9 -0
- package/engine/internal/rootfacts/facts_test.go +38 -0
- package/engine/internal/state/acceptance.go +7 -1
- package/engine/internal/state/budgets.go +11 -10
- package/engine/internal/state/budgets_test.go +93 -0
- package/engine/internal/state/cursor.go +19 -8
- package/engine/internal/state/cursor_test.go +120 -0
- package/engine/internal/state/lock_unix.go +7 -1
- package/engine/internal/state/lock_windows.go +7 -1
- package/engine/internal/state/state_test.go +49 -18
- package/engine/internal/state/taskgraph.go +18 -4
- package/engine/internal/state/taskgraph_test.go +43 -0
- package/engine/internal/state/workspaceschema.go +16 -2
- package/engine/internal/state/workspaceschema_test.go +34 -0
- package/engine/internal/state/write.go +67 -6
- package/engine/internal/state/write_test.go +136 -0
- package/engine/internal/version/version_test.go +2 -0
- package/engine/main.go +8 -1
- package/engine/observation_contract_test.go +1 -1
- package/engine/root_routing_test.go +23 -1
- package/install.sh +132 -12
- package/pack/.claude/agents/devrites-spec-reviewer.md +2 -2
- package/pack/.claude/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/.claude/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/.claude/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/.claude/skills/devrites-interview/SKILL.md +4 -4
- package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/.claude/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/.claude/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/.claude/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/.claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/.claude/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/.claude/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/.claude/skills/overhaul/SKILL.md +1 -1
- package/pack/.claude/skills/overhaul/references/orchestration.md +5 -3
- package/pack/.claude/skills/overhaul/references/records.md +39 -0
- package/pack/.claude/skills/overhaul/references/scoring.md +14 -4
- package/pack/.claude/skills/rite/reference/menu.md +1 -1
- package/pack/.claude/skills/rite-adopt/SKILL.md +8 -2
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/.claude/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/.claude/skills/rite-build/SKILL.md +2 -1
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/.claude/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/.claude/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/.claude/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/.claude/skills/rite-clarify/SKILL.md +5 -4
- package/pack/.claude/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/.claude/skills/rite-converge/SKILL.md +2 -0
- package/pack/.claude/skills/rite-customize/SKILL.md +6 -4
- package/pack/.claude/skills/rite-define/SKILL.md +2 -0
- package/pack/.claude/skills/rite-define/reference/gates.md +8 -7
- package/pack/.claude/skills/rite-explain/SKILL.md +1 -1
- package/pack/.claude/skills/rite-explain/reference/intake.md +1 -1
- package/pack/.claude/skills/rite-fast/SKILL.md +1 -1
- package/pack/.claude/skills/rite-plan/SKILL.md +4 -3
- package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/.claude/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/.claude/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/.claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/.claude/skills/rite-seal/SKILL.md +4 -3
- package/pack/.claude/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/.claude/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/.claude/skills/rite-ship/SKILL.md +4 -2
- package/pack/.claude/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/.claude/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/.claude/skills/rite-spec/SKILL.md +2 -2
- package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/.claude/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/.claude/skills/rite-temper/SKILL.md +12 -9
- package/pack/.claude/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/.claude/skills/rite-temper/reference/significance.md +10 -3
- package/pack/.claude/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/.claude/skills/rite-vet/SKILL.md +4 -3
- package/pack/.claude/skills/rite-vet/reference/artifacts.md +1 -1
- package/pack/.claude/workflows/devrites-readonly-review.js +5 -4
- package/pack/generated/claude/agents/devrites-spec-reviewer.md +2 -2
- package/pack/generated/claude/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/generated/claude/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/generated/claude/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/generated/claude/skills/devrites-interview/SKILL.md +4 -4
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/generated/claude/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/generated/claude/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/generated/claude/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/generated/claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/generated/claude/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/generated/claude/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/generated/claude/skills/overhaul/SKILL.md +1 -1
- package/pack/generated/claude/skills/overhaul/references/orchestration.md +5 -3
- package/pack/generated/claude/skills/overhaul/references/records.md +39 -0
- package/pack/generated/claude/skills/overhaul/references/scoring.md +14 -4
- package/pack/generated/claude/skills/rite/reference/menu.md +1 -1
- package/pack/generated/claude/skills/rite-adopt/SKILL.md +8 -2
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/generated/claude/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/generated/claude/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +5 -4
- package/pack/generated/claude/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/generated/claude/skills/rite-converge/SKILL.md +2 -0
- package/pack/generated/claude/skills/rite-customize/SKILL.md +6 -4
- package/pack/generated/claude/skills/rite-define/SKILL.md +2 -0
- package/pack/generated/claude/skills/rite-define/reference/gates.md +8 -7
- package/pack/generated/claude/skills/rite-explain/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-explain/reference/intake.md +1 -1
- package/pack/generated/claude/skills/rite-fast/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-plan/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/generated/claude/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/generated/claude/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/generated/claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-seal/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/generated/claude/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/generated/claude/skills/rite-ship/SKILL.md +4 -2
- package/pack/generated/claude/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/generated/claude/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/generated/claude/skills/rite-spec/SKILL.md +2 -2
- package/pack/generated/claude/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/generated/claude/skills/rite-temper/SKILL.md +12 -9
- package/pack/generated/claude/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/generated/claude/skills/rite-temper/reference/significance.md +10 -3
- package/pack/generated/claude/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/generated/claude/skills/rite-vet/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +1 -1
- package/pack/generated/claude/workflows/devrites-readonly-review.js +5 -4
- package/pack/generated/codex/AGENTS.md +1 -1
- package/pack/generated/codex/agents/devrites-spec-reviewer.toml +2 -2
- package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/generated/codex/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/generated/codex/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/generated/codex/skills/devrites-interview/SKILL.md +4 -4
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/generated/codex/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/generated/codex/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/generated/codex/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/generated/codex/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/generated/codex/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/generated/codex/skills/overhaul/SKILL.md +1 -1
- package/pack/generated/codex/skills/overhaul/references/orchestration.md +5 -3
- package/pack/generated/codex/skills/overhaul/references/records.md +39 -0
- package/pack/generated/codex/skills/overhaul/references/scoring.md +14 -4
- package/pack/generated/codex/skills/rite/reference/menu.md +1 -1
- package/pack/generated/codex/skills/rite-adopt/SKILL.md +8 -2
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/generated/codex/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/generated/codex/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +5 -4
- package/pack/generated/codex/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/generated/codex/skills/rite-converge/SKILL.md +2 -0
- package/pack/generated/codex/skills/rite-customize/SKILL.md +6 -4
- package/pack/generated/codex/skills/rite-define/SKILL.md +2 -0
- package/pack/generated/codex/skills/rite-define/reference/gates.md +8 -7
- package/pack/generated/codex/skills/rite-explain/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-explain/reference/intake.md +1 -1
- package/pack/generated/codex/skills/rite-fast/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-plan/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/generated/codex/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/generated/codex/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/generated/codex/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-seal/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/generated/codex/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/generated/codex/skills/rite-ship/SKILL.md +4 -2
- package/pack/generated/codex/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/generated/codex/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/generated/codex/skills/rite-spec/SKILL.md +2 -2
- package/pack/generated/codex/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/generated/codex/skills/rite-temper/SKILL.md +12 -9
- package/pack/generated/codex/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/generated/codex/skills/rite-temper/reference/significance.md +10 -3
- package/pack/generated/codex/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/generated/codex/skills/rite-vet/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +1 -1
- package/pack/generated/devin/AGENTS.md +1 -1
- package/pack/generated/devin/agents/devrites-spec-reviewer.md +2 -2
- package/pack/generated/devin/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/generated/devin/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/generated/devin/skills/devrites-interview/SKILL.md +4 -4
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/generated/devin/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/generated/devin/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/generated/devin/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/generated/devin/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/generated/devin/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/generated/devin/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/generated/devin/skills/overhaul/SKILL.md +1 -1
- package/pack/generated/devin/skills/overhaul/references/orchestration.md +5 -3
- package/pack/generated/devin/skills/overhaul/references/records.md +39 -0
- package/pack/generated/devin/skills/overhaul/references/scoring.md +14 -4
- package/pack/generated/devin/skills/rite/reference/menu.md +1 -1
- package/pack/generated/devin/skills/rite-adopt/SKILL.md +8 -2
- package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/generated/devin/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/devin/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/generated/devin/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/devin/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/generated/devin/skills/rite-clarify/SKILL.md +5 -4
- package/pack/generated/devin/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/generated/devin/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/generated/devin/skills/rite-converge/SKILL.md +2 -0
- package/pack/generated/devin/skills/rite-customize/SKILL.md +6 -4
- package/pack/generated/devin/skills/rite-define/SKILL.md +2 -0
- package/pack/generated/devin/skills/rite-define/reference/gates.md +8 -7
- package/pack/generated/devin/skills/rite-explain/SKILL.md +1 -1
- package/pack/generated/devin/skills/rite-explain/reference/intake.md +1 -1
- package/pack/generated/devin/skills/rite-fast/SKILL.md +1 -1
- package/pack/generated/devin/skills/rite-plan/SKILL.md +4 -3
- package/pack/generated/devin/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/generated/devin/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/generated/devin/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/generated/devin/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-seal/SKILL.md +4 -3
- package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/generated/devin/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/generated/devin/skills/rite-ship/SKILL.md +4 -2
- package/pack/generated/devin/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/generated/devin/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/generated/devin/skills/rite-spec/SKILL.md +2 -2
- package/pack/generated/devin/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/generated/devin/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/generated/devin/skills/rite-temper/SKILL.md +12 -9
- package/pack/generated/devin/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/generated/devin/skills/rite-temper/reference/significance.md +10 -3
- package/pack/generated/devin/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/generated/devin/skills/rite-vet/SKILL.md +4 -3
- package/pack/generated/devin/skills/rite-vet/reference/artifacts.md +1 -1
- package/pack/generated/omp/agents/devrites-spec-reviewer.md +2 -2
- package/pack/generated/omp/commands/rite-define.md +1 -1
- package/pack/generated/omp/commands/rite-handoff.md +1 -1
- package/pack/generated/omp/commands/rite-plan.md +1 -1
- package/pack/generated/omp/commands/rite-pressure-test.md +1 -1
- package/pack/generated/omp/commands/rite-quick.md +1 -1
- package/pack/generated/omp/commands/rite-status.md +1 -1
- package/pack/generated/omp/commands/rite-temper.md +1 -1
- package/pack/generated/omp/commands/rite-zoom-out.md +1 -1
- package/pack/generated/omp/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/generated/omp/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/generated/omp/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/generated/omp/skills/devrites-interview/SKILL.md +4 -4
- package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/generated/omp/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/generated/omp/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/generated/omp/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/generated/omp/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/generated/omp/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/generated/omp/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/generated/omp/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/generated/omp/skills/overhaul/SKILL.md +1 -1
- package/pack/generated/omp/skills/overhaul/references/orchestration.md +5 -3
- package/pack/generated/omp/skills/overhaul/references/records.md +39 -0
- package/pack/generated/omp/skills/overhaul/references/scoring.md +14 -4
- package/pack/generated/omp/skills/rite/reference/menu.md +1 -1
- package/pack/generated/omp/skills/rite-adopt/SKILL.md +8 -2
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/generated/omp/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/omp/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/generated/omp/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/generated/omp/skills/rite-clarify/SKILL.md +5 -4
- package/pack/generated/omp/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/generated/omp/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/generated/omp/skills/rite-converge/SKILL.md +2 -0
- package/pack/generated/omp/skills/rite-customize/SKILL.md +6 -4
- package/pack/generated/omp/skills/rite-define/SKILL.md +2 -0
- package/pack/generated/omp/skills/rite-define/reference/gates.md +8 -7
- package/pack/generated/omp/skills/rite-explain/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-explain/reference/intake.md +1 -1
- package/pack/generated/omp/skills/rite-fast/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-plan/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/generated/omp/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/generated/omp/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/generated/omp/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-seal/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/generated/omp/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/generated/omp/skills/rite-ship/SKILL.md +4 -2
- package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/generated/omp/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/generated/omp/skills/rite-spec/SKILL.md +2 -2
- package/pack/generated/omp/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/generated/omp/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/generated/omp/skills/rite-temper/SKILL.md +12 -9
- package/pack/generated/omp/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/generated/omp/skills/rite-temper/reference/significance.md +10 -3
- package/pack/generated/omp/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/generated/omp/skills/rite-vet/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-vet/reference/artifacts.md +1 -1
- package/pack/generated/pi/AGENTS.md +1 -1
- package/pack/generated/pi/agents/devrites-spec-reviewer.md +2 -2
- package/pack/generated/pi/prompts/rite-define.md +1 -1
- package/pack/generated/pi/prompts/rite-handoff.md +1 -1
- package/pack/generated/pi/prompts/rite-plan.md +1 -1
- package/pack/generated/pi/prompts/rite-pressure-test.md +1 -1
- package/pack/generated/pi/prompts/rite-quick.md +1 -1
- package/pack/generated/pi/prompts/rite-status.md +1 -1
- package/pack/generated/pi/prompts/rite-temper.md +1 -1
- package/pack/generated/pi/prompts/rite-zoom-out.md +1 -1
- package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +2 -2
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +18 -18
- package/pack/generated/pi/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
- package/pack/generated/pi/skills/devrites-interview/SKILL.md +4 -4
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +9 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +5 -2
- package/pack/generated/pi/skills/devrites-lib/reference/standards/gates.md +6 -5
- package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
- package/pack/generated/pi/skills/devrites-lib/reference/standards/windows.md +3 -3
- package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
- package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
- package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +11 -12
- package/pack/generated/pi/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
- package/pack/generated/pi/skills/overhaul/SKILL.md +1 -1
- package/pack/generated/pi/skills/overhaul/references/orchestration.md +5 -3
- package/pack/generated/pi/skills/overhaul/references/records.md +39 -0
- package/pack/generated/pi/skills/overhaul/references/scoring.md +14 -4
- package/pack/generated/pi/skills/rite/reference/menu.md +1 -1
- package/pack/generated/pi/skills/rite-adopt/SKILL.md +8 -2
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +11 -6
- package/pack/generated/pi/skills/rite-autocomplete/reference/decision-policy.md +3 -2
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
- package/pack/generated/pi/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/checkpoint-protocol.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +5 -0
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +2 -2
- package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +6 -3
- package/pack/generated/pi/skills/rite-clarify/SKILL.md +5 -4
- package/pack/generated/pi/skills/rite-clarify/reference/anti-patterns.md +2 -2
- package/pack/generated/pi/skills/rite-clarify/reference/decision-coverage.md +3 -2
- package/pack/generated/pi/skills/rite-converge/SKILL.md +2 -0
- package/pack/generated/pi/skills/rite-customize/SKILL.md +6 -4
- package/pack/generated/pi/skills/rite-define/SKILL.md +2 -0
- package/pack/generated/pi/skills/rite-define/reference/gates.md +8 -7
- package/pack/generated/pi/skills/rite-explain/SKILL.md +1 -1
- package/pack/generated/pi/skills/rite-explain/reference/intake.md +1 -1
- package/pack/generated/pi/skills/rite-fast/SKILL.md +1 -1
- package/pack/generated/pi/skills/rite-plan/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +4 -4
- package/pack/generated/pi/skills/rite-polish/reference/anti-ai-slop.md +1 -1
- package/pack/generated/pi/skills/rite-prove/reference/browser-proof.md +5 -5
- package/pack/generated/pi/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-seal/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +3 -2
- package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +2 -0
- package/pack/generated/pi/skills/rite-ship/SKILL.md +4 -2
- package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +8 -2
- package/pack/generated/pi/skills/rite-ship/reference/ship-template.md +2 -1
- package/pack/generated/pi/skills/rite-spec/SKILL.md +2 -2
- package/pack/generated/pi/skills/rite-spec/reference/spec-checklists.md +1 -1
- package/pack/generated/pi/skills/rite-spec/reference/spec-template.md +7 -3
- package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +2 -0
- package/pack/generated/pi/skills/rite-temper/SKILL.md +12 -9
- package/pack/generated/pi/skills/rite-temper/reference/scope-modes.md +1 -1
- package/pack/generated/pi/skills/rite-temper/reference/significance.md +10 -3
- package/pack/generated/pi/skills/rite-temper/reference/strategy-template.md +13 -2
- package/pack/generated/pi/skills/rite-vet/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +1 -1
- package/package.json +5 -4
- package/scripts/build-host-artifacts.sh +15 -0
- package/scripts/codex-generate.sh +1 -1
- package/scripts/devin-generate.sh +1 -1
- package/scripts/expand-includes.py +46 -0
- package/scripts/install-lib.sh +42 -7
- package/scripts/omp-generate.sh +11 -0
- package/scripts/pi-generate.sh +12 -1
- package/update.sh +1 -2
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/README.md +0 -7
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/architecture.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/assumptions.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/brief.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/decision-coverage.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/decisions.md +0 -4
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/eng-review.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/gates.md +0 -4
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/plan.md +0 -5
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/questions.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/spec.md +0 -6
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/state.md +0 -8
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/tasks.md +0 -1
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/test-plan.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/traceability.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/README.md +0 -7
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/assumptions.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/brief.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/decisions.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/questions.md +0 -3
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/spec.md +0 -6
- package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/state.md +0 -3
- package/engine/testdata/golden/TestParityCloseOut/active_pointed_elsewhere.golden +0 -2
- package/engine/testdata/golden/TestParityCloseOut/active_slug_cleared.golden +0 -2
- package/engine/testdata/golden/TestParityCloseOut/archive_clobber.golden +0 -1
- package/engine/testdata/golden/TestParityCloseOut/missing_slug.golden +0 -1
- package/engine/testdata/golden/TestParityCloseOut/missing_workspace.golden +0 -1
- package/engine/testdata/golden/TestParityLearnings/add.golden +0 -2
- package/engine/testdata/golden/TestParityLearnings/list.golden +0 -5
- package/engine/testdata/golden/TestParityLearnings/mine-no-archive.golden +0 -2
- package/engine/testdata/golden/TestParityLearnings/mine.golden +0 -5
- package/engine/testdata/golden/TestParityLearnings/nudge.golden +0 -2
- package/engine/testdata/golden/TestParityLearnings/unknown.golden +0 -1
- package/engine/testdata/golden/TestParityPackageExistence/ghost-workspace.golden +0 -1
- package/engine/testdata/golden/TestParityPackageExistence/no-manifest.golden +0 -1
- package/engine/testdata/golden/TestParityPackageExistence/not-git.golden +0 -1
- package/engine/testdata/golden/TestParityPackageExistence/undeclared.golden +0 -1
- package/engine/testdata/golden/TestParityPreamble/afk/a.golden +0 -14
- package/engine/testdata/golden/TestParityPreamble/hitl/active.golden +0 -18
- package/engine/testdata/golden/TestParityPreamble/hitl/bare.golden +0 -10
- package/engine/testdata/golden/TestParityPreamble/hitl/full.golden +0 -18
- package/engine/testdata/golden/TestParityPreamble/hitl/ghost.golden +0 -2
- package/engine/testdata/golden/TestParityPreamble/hitl/nonl.golden +0 -11
- package/engine/testdata/golden/TestParityPreamble/hitl/openend.golden +0 -13
- package/engine/testdata/golden/TestParityProgress/arg=allbuilt.golden +0 -4
- package/engine/testdata/golden/TestParityProgress/arg=done.golden +0 -3
- package/engine/testdata/golden/TestParityProgress/arg=ghost.golden +0 -1
- package/engine/testdata/golden/TestParityProgress/arg=mid.golden +0 -4
- package/engine/testdata/golden/TestParityProgress/arg=nophase.golden +0 -3
- package/engine/testdata/golden/TestParityProgress/arg=noslice.golden +0 -3
- package/engine/testdata/golden/TestParityProgress/arg=plan.golden +0 -4
- package/engine/testdata/golden/TestParityProgress/arg=seal.golden +0 -3
- package/engine/testdata/golden/TestParityResolve/answer/questions.md.golden +0 -9
- package/engine/testdata/golden/TestParityResolve/answer/state.md.golden +0 -7
- package/engine/testdata/golden/TestParityResolve/answer.golden +0 -4
- package/engine/testdata/golden/TestParityResolve/batch/questions.md.golden +0 -9
- package/engine/testdata/golden/TestParityResolve/batch-unterminated/questions.md.golden +0 -9
- package/engine/testdata/golden/TestParityResolve/batch-unterminated.golden +0 -2
- package/engine/testdata/golden/TestParityResolve/batch.golden +0 -3
- package/engine/testdata/golden/TestParityResolve/drop/questions.md.golden +0 -9
- package/engine/testdata/golden/TestParityResolve/drop/state.md.golden +0 -9
- package/engine/testdata/golden/TestParityResolve/drop.golden +0 -4
- package/engine/testdata/golden/TestParityResolve/missing-answer.golden +0 -1
- package/engine/testdata/golden/TestParityResolve/no-workspace.golden +0 -1
- package/engine/testdata/golden/TestParityResolve/not-found.golden +0 -1
- package/engine/testdata/golden/TestParityResolve/not-open.golden +0 -1
- package/engine/testdata/golden/TestStatusLiveWorkspace.golden +0 -10
- package/engine/testdata/golden/status/auth-tokens.txt +0 -9
- package/engine/testdata/golden/status/search-ranking.txt +0 -9
- package/engine/testdata/visual/open-visual-smoke.html +0 -675
- package/engine/testdata/visual/open-visual-smoke.outline.md +0 -54
- package/engine/tests/adr_0003_gate_exit_code_test.go +0 -32
- package/engine/tests/adr_0004_required_by_phase_test.go +0 -54
- package/engine/tests/adr_0011_define_plan_test.go +0 -32
- package/engine/tests/adr_0027_readiness_binding_test.go +0 -107
- package/engine/tests/cli_test.go +0 -126
- package/engine/tests/gate_test.go +0 -669
- package/engine/tests/meta_test.go +0 -37
- package/engine/tests/parity_closeout_test.go +0 -105
- package/engine/tests/parity_githelpers_test.go +0 -41
- package/engine/tests/parity_resolve_test.go +0 -136
- package/engine/tests/parity_test.go +0 -86
- package/engine/tests/workspace_observation_migration_test.go +0 -1069
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
package admit
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"os"
|
|
5
|
+
"path/filepath"
|
|
6
|
+
"strings"
|
|
7
|
+
"testing"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
const packetName = "full-1__T-1__A1__implementer.json"
|
|
11
|
+
|
|
12
|
+
// packetRun builds a run area named full-1 with one dispatched attempt and
|
|
13
|
+
// returns the run path and the path of its valid packet.
|
|
14
|
+
func packetRun(t *testing.T) (string, string) {
|
|
15
|
+
t.Helper()
|
|
16
|
+
dir := filepath.Join(t.TempDir(), "work", "full-1")
|
|
17
|
+
write(t, filepath.Join(dir, "CURRENT"), "g0001\n")
|
|
18
|
+
write(t, filepath.Join(dir, "g0001/run.json"), J{"run_id": "full-1"})
|
|
19
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
20
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "snapshot": "s1", "status": "dispatched",
|
|
21
|
+
"receipt": "receipts/full-1__T-1__A1__implementer.json", "packet": "packets/" + packetName},
|
|
22
|
+
J{"task_id": "T-1", "attempt_id": "A0", "role": "implementer", "snapshot": "s1", "status": "admitted"},
|
|
23
|
+
}})
|
|
24
|
+
pk := write(t, filepath.Join(dir, "packets", packetName), validPacket(dir))
|
|
25
|
+
return dir, pk
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
func validPacket(dir string) J {
|
|
29
|
+
return J{"run_id": "full-1", "phase": "REMEDIATING", "task_id": "T-1", "attempt_id": "A1",
|
|
30
|
+
"role": "implementer", "lane": "backend", "snapshot": "s1", "authorized_by": "APPROVAL-1",
|
|
31
|
+
"brief": "packets/BRIEF.md", "write_paths": L{"a.go"},
|
|
32
|
+
"receipt_path": filepath.Join(dir, "receipts", "full-1__T-1__A1__implementer.json")}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
func TestPacketAdmit(t *testing.T) {
|
|
36
|
+
cases := []struct {
|
|
37
|
+
name string
|
|
38
|
+
mutate func(J)
|
|
39
|
+
code int
|
|
40
|
+
want string
|
|
41
|
+
}{
|
|
42
|
+
{"valid", func(J) {}, 0, `{"verdict": "ADMISSIBLE", "reasons": []}`},
|
|
43
|
+
{"missing snapshot", func(p J) { delete(p, "snapshot") }, 1, "missing or empty snapshot"},
|
|
44
|
+
{"missing attempt_id", func(p J) { delete(p, "attempt_id") }, 1, "missing or empty attempt_id"},
|
|
45
|
+
{"empty role", func(p J) { p["role"] = "" }, 1, "missing or empty role"},
|
|
46
|
+
{"wrong run", func(p J) { p["run_id"] = "full-2" }, 1, "run_id differs from the run"},
|
|
47
|
+
{"receipt elsewhere", func(p J) { p["receipt_path"] = "/elsewhere/r.json" }, 1, "receipt_path must be <run>/receipts/"},
|
|
48
|
+
{"snapshot mismatch", func(p J) { p["snapshot"] = "s2" }, 1, "snapshot differs from the dispatched attempt"},
|
|
49
|
+
{"role mismatch", func(p J) { p["role"] = "reviewer" }, 1, "role differs from the dispatched attempt"},
|
|
50
|
+
{"unknown attempt", func(p J) { p["attempt_id"] = "A9" }, 1, "no such dispatched attempt"},
|
|
51
|
+
{"already admitted", func(p J) { p["attempt_id"] = "A0" }, 3, `{"verdict": "DUPLICATE_OR_LATE", "attempt_status": "admitted"}`},
|
|
52
|
+
}
|
|
53
|
+
for _, c := range cases {
|
|
54
|
+
t.Run(c.name, func(t *testing.T) {
|
|
55
|
+
dir, _ := packetRun(t)
|
|
56
|
+
p := validPacket(dir)
|
|
57
|
+
c.mutate(p)
|
|
58
|
+
// the file keeps its name so only the field under test is wrong
|
|
59
|
+
pk := write(t, filepath.Join(dir, "packets", packetName), p)
|
|
60
|
+
code, out, errs := run("packet", dir, pk)
|
|
61
|
+
if code != c.code || !strings.Contains(out, c.want) {
|
|
62
|
+
t.Fatalf("want %d with %q, got %d:\n%s%s", c.code, c.want, code, out, errs)
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The dispatch.json attempt records the receipt location; a packet naming
|
|
69
|
+
// another run-relative receipt is not the packet that was dispatched.
|
|
70
|
+
func TestPacketReceiptDiffersFromAttempt(t *testing.T) {
|
|
71
|
+
dir, pk := packetRun(t)
|
|
72
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
73
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "snapshot": "s1", "status": "dispatched",
|
|
74
|
+
"receipt": "receipts/other.json"}}})
|
|
75
|
+
code, out, _ := run("packet", dir, pk)
|
|
76
|
+
if code != 1 || !strings.Contains(out, "receipt_path differs from the dispatched attempt's receipt") {
|
|
77
|
+
t.Fatalf("got %d: %s", code, out)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The attempt also records the packet location; an attempt that recorded one
|
|
82
|
+
// packet cannot admit a different file whose identifiers happen to match.
|
|
83
|
+
func TestPacketPathDiffersFromAttempt(t *testing.T) {
|
|
84
|
+
dir, pk := packetRun(t)
|
|
85
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
86
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "snapshot": "s1", "status": "dispatched",
|
|
87
|
+
"packet": "packets/other.json"}}})
|
|
88
|
+
code, out, _ := run("packet", dir, pk)
|
|
89
|
+
if code != 1 || !strings.Contains(out, "packet path differs from the dispatched attempt's packet") {
|
|
90
|
+
t.Fatalf("got %d: %s", code, out)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// An attempt that records no packet key predates the field and is judged on
|
|
95
|
+
// the other agreements alone.
|
|
96
|
+
func TestPacketAttemptWithoutPacketKey(t *testing.T) {
|
|
97
|
+
dir, pk := packetRun(t)
|
|
98
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
99
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "snapshot": "s1", "status": "dispatched"}}})
|
|
100
|
+
code, out, errs := run("packet", dir, pk)
|
|
101
|
+
if code != 0 || !strings.Contains(out, `"verdict": "ADMISSIBLE"`) {
|
|
102
|
+
t.Fatalf("got %d: %s%s", code, out, errs)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// A recorded packet path that names the same file by an unclean spelling is
|
|
107
|
+
// the packet that was dispatched.
|
|
108
|
+
func TestPacketPathUncleanSpelling(t *testing.T) {
|
|
109
|
+
for _, rec := range []string{"packets/./" + packetName, "./packets/../packets/" + packetName} {
|
|
110
|
+
t.Run(rec, func(t *testing.T) {
|
|
111
|
+
dir, pk := packetRun(t)
|
|
112
|
+
write(t, filepath.Join(dir, "g0001/dispatch.json"), J{"attempts": L{
|
|
113
|
+
J{"task_id": "T-1", "attempt_id": "A1", "role": "implementer", "snapshot": "s1", "status": "dispatched",
|
|
114
|
+
"packet": rec}}})
|
|
115
|
+
code, out, errs := run("packet", dir, pk)
|
|
116
|
+
if code != 0 || !strings.Contains(out, `"verdict": "ADMISSIBLE"`) {
|
|
117
|
+
t.Fatalf("got %d: %s%s", code, out, errs)
|
|
118
|
+
}
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// admit packet accepts exactly the receipt_path spellings packet.Validate
|
|
124
|
+
// accepts: the run's receipts file, absolute or spelled from the working
|
|
125
|
+
// directory, and nothing else.
|
|
126
|
+
func TestPacketReceiptPathSpellings(t *testing.T) {
|
|
127
|
+
dir, pk := packetRun(t)
|
|
128
|
+
name := "full-1__T-1__A1__implementer.json"
|
|
129
|
+
for _, c := range []struct {
|
|
130
|
+
label, path string
|
|
131
|
+
code int
|
|
132
|
+
}{
|
|
133
|
+
{"bare file name", name, 1},
|
|
134
|
+
{"receipts/<name>", filepath.Join("receipts", name), 1},
|
|
135
|
+
{"another run", filepath.Join("work", "full-2", "receipts", name), 1},
|
|
136
|
+
{"relative to the working directory", filepath.Join("full-1", "receipts", name), 0},
|
|
137
|
+
} {
|
|
138
|
+
t.Run(c.label, func(t *testing.T) {
|
|
139
|
+
t.Chdir(filepath.Dir(dir))
|
|
140
|
+
p := validPacket(dir)
|
|
141
|
+
p["receipt_path"] = c.path
|
|
142
|
+
write(t, pk, p)
|
|
143
|
+
code, out, errs := run("packet", dir, pk)
|
|
144
|
+
if code != c.code || (c.code == 1 && !strings.Contains(out, "receipt_path must be")) {
|
|
145
|
+
t.Fatalf("want %d, got %d: %s%s", c.code, code, out, errs)
|
|
146
|
+
}
|
|
147
|
+
})
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// A valid packet with an absolute receipt_path is admitted from an unrelated
|
|
152
|
+
// working directory with an absolute run path, and from the run's parent
|
|
153
|
+
// directory with a relative run path.
|
|
154
|
+
func TestPacketAdmitFromAnyCwd(t *testing.T) {
|
|
155
|
+
dir, pk := packetRun(t)
|
|
156
|
+
t.Chdir(t.TempDir())
|
|
157
|
+
if code, out, errs := run("packet", dir, pk); code != 0 {
|
|
158
|
+
t.Fatalf("absolute run: %d %s%s", code, out, errs)
|
|
159
|
+
}
|
|
160
|
+
t.Chdir(filepath.Dir(dir))
|
|
161
|
+
if code, out, errs := run("packet", "full-1", filepath.Join("full-1", "packets", packetName)); code != 0 {
|
|
162
|
+
t.Fatalf("relative run: %d %s%s", code, out, errs)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
func TestPacketUsesWorkingGeneration(t *testing.T) {
|
|
167
|
+
dir, pk := packetRun(t)
|
|
168
|
+
stage := filepath.Join(dir, "g0002.tmp")
|
|
169
|
+
write(t, filepath.Join(stage, ".base"), "g0001")
|
|
170
|
+
write(t, filepath.Join(stage, "run.json"), J{"run_id": "full-1"})
|
|
171
|
+
write(t, filepath.Join(stage, "dispatch.json"), J{"attempts": L{}})
|
|
172
|
+
if code, out, _ := run("packet", dir, pk); code != 1 || !strings.Contains(out, "no such dispatched attempt") {
|
|
173
|
+
t.Fatalf("open stage ignored: %d %s", code, out)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
func TestPacketSymlinkedPath(t *testing.T) {
|
|
178
|
+
dir, pk := packetRun(t)
|
|
179
|
+
link := filepath.Join(dir, "packets", "link.json")
|
|
180
|
+
if err := os.Symlink(pk, link); err != nil {
|
|
181
|
+
t.Skip(err)
|
|
182
|
+
}
|
|
183
|
+
if code, out, _ := run("packet", dir, link); code != 1 || !strings.Contains(out, "must not be a symlink") {
|
|
184
|
+
t.Fatalf("symlinked file: %d %s", code, out)
|
|
185
|
+
}
|
|
186
|
+
// a symlinked packets directory is not the run's packets directory
|
|
187
|
+
real := filepath.Join(t.TempDir(), "packets")
|
|
188
|
+
if err := os.Rename(filepath.Join(dir, "packets"), real); err != nil {
|
|
189
|
+
t.Fatal(err)
|
|
190
|
+
}
|
|
191
|
+
if err := os.Symlink(real, filepath.Join(dir, "packets")); err != nil {
|
|
192
|
+
t.Skip(err)
|
|
193
|
+
}
|
|
194
|
+
if code, out, _ := run("packet", dir, filepath.Join(dir, "packets", packetName)); code != 1 || !strings.Contains(out, "not under the run's packets directory") {
|
|
195
|
+
t.Fatalf("symlinked packets dir: %d %s", code, out)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
func TestPacketMisplaced(t *testing.T) {
|
|
200
|
+
dir, pk := packetRun(t)
|
|
201
|
+
moved := filepath.Join(dir, "stray.json")
|
|
202
|
+
if err := os.Rename(pk, moved); err != nil {
|
|
203
|
+
t.Fatal(err)
|
|
204
|
+
}
|
|
205
|
+
code, out, _ := run("packet", dir, moved)
|
|
206
|
+
if code != 1 || !strings.Contains(out, "file name does not match") || !strings.Contains(out, "not under the run's packets directory") {
|
|
207
|
+
t.Fatalf("got %d: %s", code, out)
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
func TestPacketIOAndUsage(t *testing.T) {
|
|
212
|
+
dir, _ := packetRun(t)
|
|
213
|
+
if code, _, errs := run("packet", dir, filepath.Join(dir, "packets", "missing.json")); code != 2 || !strings.HasPrefix(errs, "ERROR: ") {
|
|
214
|
+
t.Fatalf("missing packet: %d %q", code, errs)
|
|
215
|
+
}
|
|
216
|
+
write(t, filepath.Join(dir, "packets", "bad.json"), "{not json")
|
|
217
|
+
if code, _, errs := run("packet", dir, filepath.Join(dir, "packets", "bad.json")); code != 2 || !strings.HasPrefix(errs, "ERROR: ") {
|
|
218
|
+
t.Fatalf("unparsable packet: %d %q", code, errs)
|
|
219
|
+
}
|
|
220
|
+
if code, _, errs := run("packet", dir); code != 2 || !strings.Contains(errs, "packet RUN PACKET") {
|
|
221
|
+
t.Fatalf("usage: %d %q", code, errs)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// checks for worker output.
|
|
3
3
|
//
|
|
4
4
|
// receipt RUN RECEIPT [--observed FILE] receipt vs its dispatch packet; writers vs observed paths
|
|
5
|
+
// packet RUN PACKET packet shape and identity vs its dispatch attempt
|
|
5
6
|
// anchor ROOT PROPOSALS every quoted location matches its file lines (ROOT = snapshot tree or repo)
|
|
6
7
|
//
|
|
7
8
|
// Exit: 0 admissible, 1 reject (reasons listed), 2 usage/IO error, 3 duplicate
|
|
@@ -30,6 +31,7 @@ import (
|
|
|
30
31
|
const usage = `usage: overhaul admit <command> ...
|
|
31
32
|
|
|
32
33
|
receipt RUN RECEIPT [--observed FILE] receipt vs its dispatch packet; writers vs observed paths
|
|
34
|
+
packet RUN PACKET packet shape and identity vs its dispatch attempt
|
|
33
35
|
anchor ROOT PROPOSALS every quoted location matches its file lines (ROOT = snapshot tree or repo)
|
|
34
36
|
Exit: 0 admissible, 1 reject (reasons listed), 2 usage/IO error, 3 duplicate or late receipt.
|
|
35
37
|
`
|
|
@@ -57,6 +59,8 @@ func Run(args []string, stdout, stderr io.Writer) int {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
code, err = receipt(args[1], args[2], observed, hasObserved, stdout)
|
|
62
|
+
case len(args) == 3 && args[0] == "packet":
|
|
63
|
+
code, err = packetAdmit(args[1], args[2], stdout)
|
|
60
64
|
case len(args) >= 3 && args[0] == "anchor":
|
|
61
65
|
code, err = anchor(args[1], args[2], stdout, stderr)
|
|
62
66
|
default:
|
|
@@ -172,6 +172,9 @@ func compare(d map[string]any) (any, error) {
|
|
|
172
172
|
if err != nil {
|
|
173
173
|
return nil, err
|
|
174
174
|
}
|
|
175
|
+
if !(floor >= 0) {
|
|
176
|
+
return nil, fmt.Errorf("resolution must be a number >= 0, got %v", floor)
|
|
177
|
+
}
|
|
175
178
|
rng, err := seeded(d)
|
|
176
179
|
if err != nil {
|
|
177
180
|
return nil, err
|
|
@@ -207,6 +210,9 @@ func compare(d map[string]any) (any, error) {
|
|
|
207
210
|
hiIdx += len(boots)
|
|
208
211
|
}
|
|
209
212
|
bootLo, bootHi := boots[int(0.025*float64(len(boots)))], boots[hiIdx]
|
|
213
|
+
if math.IsInf(bootLo, 0) || math.IsInf(bootHi, 0) || math.IsNaN(bootLo) || math.IsNaN(bootHi) {
|
|
214
|
+
return noRatio{"NO_RATIO", "resampled medians reach zero: ratio interval is unbounded", ma, mb, bud, er, notes}, nil
|
|
215
|
+
}
|
|
210
216
|
lo, hi := bootLo, bootHi
|
|
211
217
|
target, err := number(d, "target", 1)
|
|
212
218
|
if err != nil {
|
|
@@ -142,6 +142,52 @@ func TestBench(t *testing.T) {
|
|
|
142
142
|
})
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
func assertFinite(t *testing.T, v any, path string) {
|
|
146
|
+
t.Helper()
|
|
147
|
+
switch x := v.(type) {
|
|
148
|
+
case float64:
|
|
149
|
+
if math.IsInf(x, 0) || math.IsNaN(x) {
|
|
150
|
+
t.Fatalf("%s is not finite: %v", path, x)
|
|
151
|
+
}
|
|
152
|
+
case []any:
|
|
153
|
+
for i, e := range x {
|
|
154
|
+
assertFinite(t, e, fmt.Sprintf("%s[%d]", path, i))
|
|
155
|
+
}
|
|
156
|
+
case map[string]any:
|
|
157
|
+
for k, e := range x {
|
|
158
|
+
assertFinite(t, e, path+"."+k)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
func TestBenchNonFiniteInputs(t *testing.T) {
|
|
164
|
+
fast, _ := fixture()
|
|
165
|
+
someZeros := append(make([]float64, 8), gauss(rand.New(rand.NewPCG(3, 0)), 10, 0.4, 12)...)
|
|
166
|
+
|
|
167
|
+
t.Run("zero-valued resamples give a finite verdict", func(t *testing.T) {
|
|
168
|
+
for name, d := range map[string]map[string]any{
|
|
169
|
+
"lower is better": with(fast, "candidate", someZeros),
|
|
170
|
+
"higher is better": with(fast, "direction", "higher_is_better", "baseline", someZeros, "candidate", fast["baseline"]),
|
|
171
|
+
} {
|
|
172
|
+
v, res := verdict(t, d)
|
|
173
|
+
if v != "NO_RATIO" && v != "INCONCLUSIVE" {
|
|
174
|
+
t.Fatalf("%s: got %v", name, res)
|
|
175
|
+
}
|
|
176
|
+
assertFinite(t, res, name)
|
|
177
|
+
}
|
|
178
|
+
})
|
|
179
|
+
t.Run("negative resolution is an error", func(t *testing.T) {
|
|
180
|
+
code, _, stderr := run(t, with(fast, "resolution", -1))
|
|
181
|
+
if code != 2 || !strings.Contains(stderr, "resolution") {
|
|
182
|
+
t.Fatalf("exit %d %q", code, stderr)
|
|
183
|
+
}
|
|
184
|
+
})
|
|
185
|
+
t.Run("every float of a normal result is finite", func(t *testing.T) {
|
|
186
|
+
_, res := verdict(t, fast)
|
|
187
|
+
assertFinite(t, res, "result")
|
|
188
|
+
})
|
|
189
|
+
}
|
|
190
|
+
|
|
145
191
|
func TestStats(t *testing.T) {
|
|
146
192
|
if k := tailCount(10, 10, 0.05); k != 24 {
|
|
147
193
|
t.Fatalf("n=m=10 alpha .05: k=%d, want 24 (Hollander-Wolfe D_(24), D_(77))", k)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Package overhaul dispatches the deterministic tools behind the standalone
|
|
2
2
|
// /overhaul skill: run-record generations and validation, worker-output
|
|
3
|
-
// admission, baseline snapshots, readiness scoring, benchmark statistics and
|
|
3
|
+
// admission, dispatch packets, baseline snapshots, readiness scoring, benchmark statistics and
|
|
4
4
|
// escaped offline views. It never calls a model or the network.
|
|
5
5
|
package overhaul
|
|
6
6
|
|
|
@@ -10,6 +10,7 @@ import (
|
|
|
10
10
|
|
|
11
11
|
"github.com/devrites/devrites/internal/overhaul/admit"
|
|
12
12
|
"github.com/devrites/devrites/internal/overhaul/bench"
|
|
13
|
+
"github.com/devrites/devrites/internal/overhaul/packet"
|
|
13
14
|
"github.com/devrites/devrites/internal/overhaul/records"
|
|
14
15
|
"github.com/devrites/devrites/internal/overhaul/render"
|
|
15
16
|
"github.com/devrites/devrites/internal/overhaul/score"
|
|
@@ -25,7 +26,9 @@ const Usage = `usage: devrites-engine overhaul <tool> ...
|
|
|
25
26
|
overhaul records publish <run>
|
|
26
27
|
overhaul records validate <run>
|
|
27
28
|
overhaul admit receipt <run> <receipt.json> [--observed <paths.txt>]
|
|
29
|
+
overhaul admit packet <run> <packet.json>
|
|
28
30
|
overhaul admit anchor <tree> <proposals.json>
|
|
31
|
+
overhaul packet write <run> <task> <attempt> <role> [--from <fields.json>] [--phase P] [--wave W] [--lane L] [--snapshot S] [--authorized-by A] [--brief PATH] [--write-path PATH]...
|
|
29
32
|
overhaul snapshot capture <repo> <out>
|
|
30
33
|
overhaul snapshot fingerprint <repo>
|
|
31
34
|
overhaul snapshot verify <repo> <out> [--agent-paths <file>]
|
|
@@ -50,6 +53,8 @@ func Run(args []string, stdout, stderr io.Writer) int {
|
|
|
50
53
|
return records.Run(rest, stdout, stderr)
|
|
51
54
|
case "admit":
|
|
52
55
|
return admit.Run(rest, stdout, stderr)
|
|
56
|
+
case "packet":
|
|
57
|
+
return packet.Run(rest, stdout, stderr)
|
|
53
58
|
case "snapshot":
|
|
54
59
|
return snapshot.Run(rest, stdout, stderr)
|
|
55
60
|
case "score":
|
|
@@ -9,6 +9,7 @@ import (
|
|
|
9
9
|
"encoding/hex"
|
|
10
10
|
"encoding/json"
|
|
11
11
|
"fmt"
|
|
12
|
+
"io"
|
|
12
13
|
"os"
|
|
13
14
|
"path/filepath"
|
|
14
15
|
"strings"
|
|
@@ -22,11 +23,16 @@ func SHA256Bytes(b []byte) string {
|
|
|
22
23
|
|
|
23
24
|
// SHA256File returns the lowercase hex SHA-256 of the file's exact bytes.
|
|
24
25
|
func SHA256File(path string) (string, error) {
|
|
25
|
-
|
|
26
|
+
f, err := os.Open(path) // #nosec G304 -- callers pass operator-selected run-area paths
|
|
26
27
|
if err != nil {
|
|
27
28
|
return "", err
|
|
28
29
|
}
|
|
29
|
-
|
|
30
|
+
defer func() { _ = f.Close() }()
|
|
31
|
+
h := sha256.New()
|
|
32
|
+
if _, err := io.Copy(h, f); err != nil {
|
|
33
|
+
return "", err
|
|
34
|
+
}
|
|
35
|
+
return hex.EncodeToString(h.Sum(nil)), nil
|
|
30
36
|
}
|
|
31
37
|
|
|
32
38
|
// LoadJSON decodes a UTF-8 JSON document. Numbers stay json.Number so digests,
|
|
@@ -146,7 +152,8 @@ func Truthy(v any) bool {
|
|
|
146
152
|
case string:
|
|
147
153
|
return x != ""
|
|
148
154
|
case json.Number:
|
|
149
|
-
|
|
155
|
+
f, err := x.Float64()
|
|
156
|
+
return err != nil || f != 0
|
|
150
157
|
case float64:
|
|
151
158
|
return x != 0
|
|
152
159
|
case []any:
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
package ovio
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"bytes"
|
|
5
|
+
"encoding/json"
|
|
6
|
+
"os"
|
|
7
|
+
"path/filepath"
|
|
8
|
+
"runtime"
|
|
9
|
+
"testing"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
func TestTruthyNumberZeroSpellingsAreFalse(t *testing.T) {
|
|
13
|
+
t.Parallel()
|
|
14
|
+
for _, n := range []json.Number{"0", "0.0", "0.00", "0.000", "-0", "-0.0", "0e0", "0e-1"} {
|
|
15
|
+
if Truthy(n) {
|
|
16
|
+
t.Errorf("Truthy(json.Number(%q)) = true, want false", n)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func TestTruthyNumberNonZeroValuesAreTrue(t *testing.T) {
|
|
22
|
+
t.Parallel()
|
|
23
|
+
for _, n := range []json.Number{"1", "0.5", "-1", "-0.5", "1e-3", "1e400"} {
|
|
24
|
+
if !Truthy(n) {
|
|
25
|
+
t.Errorf("Truthy(json.Number(%q)) = false, want true", n)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
func TestTruthyNumberZeroAndNonZeroAreDistinguishable(t *testing.T) {
|
|
31
|
+
t.Parallel()
|
|
32
|
+
zero, one := Truthy(json.Number("0.00")), Truthy(json.Number("1"))
|
|
33
|
+
if zero == one {
|
|
34
|
+
t.Errorf("Truthy(json.Number(\"0.00\")) = Truthy(json.Number(\"1\")) = %v, want false and true", zero)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func TestTruthyMissingAndNullKeysAreFalse(t *testing.T) {
|
|
39
|
+
t.Parallel()
|
|
40
|
+
var record map[string]any
|
|
41
|
+
if err := json.Unmarshal([]byte(`{"present": 1, "explicit_null": null}`), &record); err != nil {
|
|
42
|
+
t.Fatal(err)
|
|
43
|
+
}
|
|
44
|
+
for _, key := range []string{"absent", "explicit_null"} {
|
|
45
|
+
if Truthy(Get(record, key)) {
|
|
46
|
+
t.Errorf("Truthy(Get(record, %q)) = true, want false", key)
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
func TestSHA256FileStreamsWithoutBufferingTheFile(t *testing.T) {
|
|
52
|
+
const size = 32 << 20
|
|
53
|
+
path := filepath.Join(t.TempDir(), "big.bin")
|
|
54
|
+
want := func() string {
|
|
55
|
+
data := bytes.Repeat([]byte("0123456789abcdef"), size/16)
|
|
56
|
+
if err := os.WriteFile(path, data, 0o600); err != nil {
|
|
57
|
+
t.Fatal(err)
|
|
58
|
+
}
|
|
59
|
+
return SHA256Bytes(data)
|
|
60
|
+
}()
|
|
61
|
+
var before, after runtime.MemStats
|
|
62
|
+
runtime.GC()
|
|
63
|
+
runtime.ReadMemStats(&before)
|
|
64
|
+
got, err := SHA256File(path)
|
|
65
|
+
runtime.ReadMemStats(&after)
|
|
66
|
+
if err != nil {
|
|
67
|
+
t.Fatal(err)
|
|
68
|
+
}
|
|
69
|
+
if got != want {
|
|
70
|
+
t.Errorf("SHA256File digest = %s, want %s", got, want)
|
|
71
|
+
}
|
|
72
|
+
if delta := after.TotalAlloc - before.TotalAlloc; delta > 1<<20 {
|
|
73
|
+
t.Errorf("SHA256File allocated %d bytes for a %d byte file, want under 1MiB", delta, size)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// Package packet implements the /overhaul packet tool: it writes the dispatch
|
|
2
|
+
// packet for one worker attempt and validates packets on load.
|
|
3
|
+
//
|
|
4
|
+
// write RUN TASK ATTEMPT ROLE [flags] create RUN/packets/<run>__<task>__<attempt>__<role>.json
|
|
5
|
+
//
|
|
6
|
+
// A packet is a JSON object. Flags fill the common fields; --from FILE supplies
|
|
7
|
+
// any further fields (plan, task, read paths, budgets) and flags override it.
|
|
8
|
+
// Exit: 0 written, 1 invalid packet or packet already exists, 2 usage/IO error.
|
|
9
|
+
package packet
|
|
10
|
+
|
|
11
|
+
import (
|
|
12
|
+
"flag"
|
|
13
|
+
"fmt"
|
|
14
|
+
"io"
|
|
15
|
+
"os"
|
|
16
|
+
"path/filepath"
|
|
17
|
+
"strings"
|
|
18
|
+
|
|
19
|
+
"github.com/devrites/devrites/internal/overhaul/ovio"
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
const usage = `usage: overhaul packet <command> ...
|
|
23
|
+
|
|
24
|
+
write RUN TASK ATTEMPT ROLE [--from FILE] [--phase P] [--wave W] [--lane L]
|
|
25
|
+
[--snapshot S] [--authorized-by A] [--brief PATH] [--write-path PATH]...
|
|
26
|
+
Exit: 0 written, 1 invalid packet or packet already exists, 2 usage/IO error.
|
|
27
|
+
`
|
|
28
|
+
|
|
29
|
+
// required are the string fields every packet carries.
|
|
30
|
+
var required = []string{"run_id", "phase", "task_id", "attempt_id", "role", "lane", "snapshot", "authorized_by", "brief", "receipt_path"}
|
|
31
|
+
|
|
32
|
+
// idFields name the path components of a packet file and must be plain names.
|
|
33
|
+
var idFields = []string{"run_id", "task_id", "attempt_id", "role"}
|
|
34
|
+
|
|
35
|
+
type multi []string
|
|
36
|
+
|
|
37
|
+
func (m *multi) String() string { return strings.Join(*m, ",") }
|
|
38
|
+
func (m *multi) Set(s string) error { *m = append(*m, s); return nil }
|
|
39
|
+
|
|
40
|
+
// Run executes the tool with its arguments (tool name excluded).
|
|
41
|
+
func Run(args []string, stdout, stderr io.Writer) int {
|
|
42
|
+
if len(args) < 5 || args[0] != "write" {
|
|
43
|
+
fmt.Fprint(stderr, usage)
|
|
44
|
+
return 2
|
|
45
|
+
}
|
|
46
|
+
fs := flag.NewFlagSet("packet write", flag.ContinueOnError)
|
|
47
|
+
fs.SetOutput(stderr)
|
|
48
|
+
from := fs.String("from", "", "JSON object with further packet fields")
|
|
49
|
+
set := map[string]*string{}
|
|
50
|
+
for flagName, field := range map[string]string{
|
|
51
|
+
"phase": "phase", "wave": "wave", "lane": "lane", "snapshot": "snapshot",
|
|
52
|
+
"authorized-by": "authorized_by", "brief": "brief",
|
|
53
|
+
} {
|
|
54
|
+
set[field] = fs.String(flagName, "", field)
|
|
55
|
+
}
|
|
56
|
+
var paths multi
|
|
57
|
+
fs.Var(&paths, "write-path", "exact path the worker may write (repeatable)")
|
|
58
|
+
if err := fs.Parse(args[5:]); err != nil {
|
|
59
|
+
return 2
|
|
60
|
+
}
|
|
61
|
+
if fs.NArg() > 0 {
|
|
62
|
+
fmt.Fprintf(stderr, "ERROR: unexpected argument %q\n", fs.Arg(0))
|
|
63
|
+
return 2
|
|
64
|
+
}
|
|
65
|
+
run := args[1]
|
|
66
|
+
p := map[string]any{}
|
|
67
|
+
if *from != "" {
|
|
68
|
+
m, err := ovio.LoadObject(*from)
|
|
69
|
+
if err != nil {
|
|
70
|
+
fmt.Fprintf(stderr, "ERROR: %v\n", err)
|
|
71
|
+
return 2
|
|
72
|
+
}
|
|
73
|
+
p = m
|
|
74
|
+
}
|
|
75
|
+
p["run_id"], p["task_id"], p["attempt_id"], p["role"] = filepath.Base(filepath.Clean(run)), args[2], args[3], args[4]
|
|
76
|
+
for field, v := range set {
|
|
77
|
+
if *v != "" {
|
|
78
|
+
p[field] = *v
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if _, ok := p["write_paths"]; !ok || len(paths) > 0 {
|
|
82
|
+
wp := []any{}
|
|
83
|
+
for _, w := range paths {
|
|
84
|
+
wp = append(wp, w)
|
|
85
|
+
}
|
|
86
|
+
p["write_paths"] = wp
|
|
87
|
+
}
|
|
88
|
+
if ovio.Str(p["receipt_path"]) == "" {
|
|
89
|
+
p["receipt_path"] = filepath.Join(run, "receipts", Name(p)+".json")
|
|
90
|
+
}
|
|
91
|
+
if why := Validate(run, p); len(why) > 0 {
|
|
92
|
+
for _, w := range why {
|
|
93
|
+
fmt.Fprintf(stderr, "REJECT: %s\n", w)
|
|
94
|
+
}
|
|
95
|
+
return 1
|
|
96
|
+
}
|
|
97
|
+
out, code, err := write(run, p)
|
|
98
|
+
if err != nil {
|
|
99
|
+
fmt.Fprintf(stderr, "ERROR: %v\n", err)
|
|
100
|
+
return code
|
|
101
|
+
}
|
|
102
|
+
fmt.Fprintln(stdout, out)
|
|
103
|
+
return 0
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Name is the packet file stem: <run>__<task>__<attempt>__<role>.
|
|
107
|
+
func Name(p map[string]any) string {
|
|
108
|
+
return strings.Join([]string{ovio.Str(p["run_id"]), ovio.Str(p["task_id"]), ovio.Str(p["attempt_id"]), ovio.Str(p["role"])}, "__")
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Validate returns every reason the packet is malformed for the run area run;
|
|
112
|
+
// none means valid. receipt_path must be a clean path that resolves to <run>/receipts/<name>.json.
|
|
113
|
+
func Validate(run string, p map[string]any) []string {
|
|
114
|
+
var why []string
|
|
115
|
+
for _, k := range required {
|
|
116
|
+
if ovio.Str(p[k]) == "" {
|
|
117
|
+
why = append(why, "missing or empty "+k)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
for _, k := range idFields {
|
|
121
|
+
if s := ovio.Str(p[k]); s == "." || s == ".." || strings.ContainsAny(s, `/\`+"\x00") || strings.Contains(s, "__") {
|
|
122
|
+
why = append(why, k+" must be a plain name without path separators or \"__\"")
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if rp := ovio.Str(p["receipt_path"]); rp != "" && !samePath(rp, filepath.Join(run, "receipts", Name(p)+".json")) {
|
|
126
|
+
why = append(why, "receipt_path must be <run>/receipts/<run_id>__<task_id>__<attempt_id>__<role>.json")
|
|
127
|
+
}
|
|
128
|
+
if w, ok := p["write_paths"].([]any); !ok {
|
|
129
|
+
why = append(why, "write_paths must be an array (empty for read-only roles)")
|
|
130
|
+
} else if len(ovio.Strings(w)) != len(w) {
|
|
131
|
+
why = append(why, "write_paths must hold only strings")
|
|
132
|
+
}
|
|
133
|
+
if pl, ok := p["plan"]; ok && ovio.Str(ovio.Obj(pl)["file"]) == "" {
|
|
134
|
+
why = append(why, "plan must be an object with a file")
|
|
135
|
+
}
|
|
136
|
+
return why
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// samePath reports whether a is the clean spelling of the location b names.
|
|
140
|
+
func samePath(a, b string) bool {
|
|
141
|
+
x, err1 := filepath.Abs(a)
|
|
142
|
+
y, err2 := filepath.Abs(b)
|
|
143
|
+
return err1 == nil && err2 == nil && a == filepath.Clean(a) && x == y
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Load reads a packet file and validates it against the run area that holds
|
|
147
|
+
// its packets/ directory, including that the file name matches the packet's
|
|
148
|
+
// own identifiers.
|
|
149
|
+
func Load(path string) (map[string]any, error) {
|
|
150
|
+
p, err := ovio.LoadObject(path)
|
|
151
|
+
if err != nil {
|
|
152
|
+
return nil, err
|
|
153
|
+
}
|
|
154
|
+
why := Validate(filepath.Dir(filepath.Dir(path)), p)
|
|
155
|
+
if len(why) == 0 && filepath.Base(path) != Name(p)+".json" {
|
|
156
|
+
why = append(why, "file name does not match run_id, task_id, attempt_id and role")
|
|
157
|
+
}
|
|
158
|
+
if len(why) > 0 {
|
|
159
|
+
return nil, fmt.Errorf("%s: %s", path, strings.Join(why, "; "))
|
|
160
|
+
}
|
|
161
|
+
return p, nil
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// write publishes the packet atomically and never replaces an existing one:
|
|
165
|
+
// the content is written to a temporary file that is then hard-linked into place.
|
|
166
|
+
func write(run string, p map[string]any) (string, int, error) {
|
|
167
|
+
if !realDir(run) {
|
|
168
|
+
return "", 2, fmt.Errorf("run area %s is not a directory", run)
|
|
169
|
+
}
|
|
170
|
+
dir := filepath.Join(run, "packets")
|
|
171
|
+
if err := os.MkdirAll(dir, 0o700); err != nil {
|
|
172
|
+
return "", 2, err
|
|
173
|
+
}
|
|
174
|
+
if !realDir(dir) {
|
|
175
|
+
return "", 2, fmt.Errorf("%s is not a plain directory", dir)
|
|
176
|
+
}
|
|
177
|
+
b, err := ovio.MarshalIndent(p)
|
|
178
|
+
if err != nil {
|
|
179
|
+
return "", 2, err
|
|
180
|
+
}
|
|
181
|
+
tmp, err := os.CreateTemp(dir, ".packet-*.tmp")
|
|
182
|
+
if err != nil {
|
|
183
|
+
return "", 2, err
|
|
184
|
+
}
|
|
185
|
+
defer func() { _ = os.Remove(tmp.Name()) }()
|
|
186
|
+
if _, err := tmp.Write(b); err != nil {
|
|
187
|
+
_ = tmp.Close()
|
|
188
|
+
return "", 2, err
|
|
189
|
+
}
|
|
190
|
+
if err := tmp.Close(); err != nil {
|
|
191
|
+
return "", 2, err
|
|
192
|
+
}
|
|
193
|
+
dest := filepath.Join(dir, Name(p)+".json")
|
|
194
|
+
if err := os.Link(tmp.Name(), dest); err != nil {
|
|
195
|
+
if os.IsExist(err) {
|
|
196
|
+
return "", 1, fmt.Errorf("packet %s already exists", dest)
|
|
197
|
+
}
|
|
198
|
+
return "", 2, err
|
|
199
|
+
}
|
|
200
|
+
return dest, 0, nil
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// realDir reports whether path is a directory and not a symlink to one, so a
|
|
204
|
+
// packet is never written through a link out of the run area.
|
|
205
|
+
func realDir(path string) bool {
|
|
206
|
+
st, err := os.Lstat(filepath.Clean(path))
|
|
207
|
+
return err == nil && st.IsDir()
|
|
208
|
+
}
|