devrites 5.14.4 → 6.0.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 +17 -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 +3 -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 +3 -2
- 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 +3 -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 +3 -2
- 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 +3 -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 +3 -2
- 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 +3 -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 +3 -2
- 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 +3 -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 +3 -2
- 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 +3 -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 +3 -2
- 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
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
package notes
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
+
"bytes"
|
|
4
5
|
"os"
|
|
5
6
|
"path/filepath"
|
|
6
7
|
"strings"
|
|
7
8
|
"testing"
|
|
9
|
+
|
|
10
|
+
"github.com/devrites/devrites/internal/gate"
|
|
8
11
|
)
|
|
9
12
|
|
|
10
13
|
func writeFile(t *testing.T, root, rel, body string) {
|
|
@@ -71,6 +74,40 @@ func TestParseNotesMasksFencedBlocks(t *testing.T) {
|
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
76
|
|
|
77
|
+
func TestParseNotesMasksListIndentedFences(t *testing.T) {
|
|
78
|
+
text := "# Notes\n\n- how to write a note\n\n ```\n - NOTE-999: fenced fake\n SUBJECT: x.go\n QUOTE: y\n ```\n\n" + sampleNotes
|
|
79
|
+
doc := ParseNotes(text)
|
|
80
|
+
if len(doc.Errors) != 0 || len(doc.Notes) != 2 {
|
|
81
|
+
t.Fatalf("notes=%d errors=%v", len(doc.Notes), doc.Errors)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
func TestOpenBlockingQuestionAfterIndentedCodeStaysVisible(t *testing.T) {
|
|
86
|
+
for name, text := range map[string]string{
|
|
87
|
+
"top-level indented code": "# Q\n\n - example\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
88
|
+
"list indented code": "- a\n\n - not a list\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
89
|
+
"unclosed list fence": "- a\n\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
90
|
+
"unclosed ordered fence": "1. step\n\n ```\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
91
|
+
"unclosed nested fence": "- a\n - b\n\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
92
|
+
"thematic break": "* * *\n\n ```\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
93
|
+
"ordered cannot interrupt": "text\n2. foo\n\n ```\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
94
|
+
"list-indented fence ends": "- a\n\n ```\n ## Q-002\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
95
|
+
"empty dash then list fence": "-\n\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
96
|
+
"setext dash then list fence": "Intro\n-\n\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
97
|
+
"empty star then list fence": "Some text\n*\n\n ```\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
98
|
+
"empty dash then table": "-\n\n ```\n | ID | Status | Gate |\n |---|---|---|\n | Q-001 | open | blocking |\n",
|
|
99
|
+
"unclosed list fence to EOF": "- a\n\n ```\n text\n\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
100
|
+
"list fence dedents before close": "- a\n\n ```\n text\nback\n ```\n## Q-001\nstatus: open\ngate: blocking\n",
|
|
101
|
+
"tab-indented closer then table": "- a\n\n ```\n\t```\n | ID | Status | Gate |\n |---|---|---|\n | Q-001 | open | blocking |\n ```\n",
|
|
102
|
+
} {
|
|
103
|
+
t.Run(name, func(t *testing.T) {
|
|
104
|
+
if got := gate.OpenBlockingQuestionGates([]byte(text)); len(got) != 1 || got[0] != "blocking" {
|
|
105
|
+
t.Fatalf("OpenBlockingQuestionGates = %v, want [blocking]", got)
|
|
106
|
+
}
|
|
107
|
+
})
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
74
111
|
func TestGradeExactMovedStaleAmbiguousLost(t *testing.T) {
|
|
75
112
|
project := t.TempDir()
|
|
76
113
|
writeFile(t, project, "src/pool.go", "package src\n\nconst maxConns = 4\n")
|
|
@@ -171,3 +208,338 @@ func TestRepairSubjectRewritesOnlyThatLine(t *testing.T) {
|
|
|
171
208
|
t.Fatal("repair touched the other note")
|
|
172
209
|
}
|
|
173
210
|
}
|
|
211
|
+
|
|
212
|
+
// anchorQuote is the verbatim quote every subject in the cases below still
|
|
213
|
+
// carries, so a decline to read the file is the only reason a note is not exact.
|
|
214
|
+
const anchorQuote = "maxConns = 4"
|
|
215
|
+
|
|
216
|
+
// writeOversizedQuoteSubject grows path past the read cap while keeping the
|
|
217
|
+
// anchor quote.
|
|
218
|
+
func writeOversizedQuoteSubject(t *testing.T, path string) {
|
|
219
|
+
t.Helper()
|
|
220
|
+
filler := strings.Repeat("padding line past the read cap\n", maxSearchFileBytes/28+1)
|
|
221
|
+
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
|
|
222
|
+
t.Fatal(err)
|
|
223
|
+
}
|
|
224
|
+
if err := os.WriteFile(path, []byte("package src\n\nconst "+anchorQuote+"\n"+filler), 0o644); err != nil {
|
|
225
|
+
t.Fatal(err)
|
|
226
|
+
}
|
|
227
|
+
info, err := os.Stat(path)
|
|
228
|
+
if err != nil {
|
|
229
|
+
t.Fatal(err)
|
|
230
|
+
}
|
|
231
|
+
if info.Size() <= int64(maxSearchFileBytes) {
|
|
232
|
+
t.Fatalf("oversized subject is %d bytes, not past the %d-byte read cap", info.Size(), maxSearchFileBytes)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// unreadableSubjects are the ways a subject this pass will not read as text can
|
|
237
|
+
// still contain the quote. Each degrades an existing, quote-bearing subject.
|
|
238
|
+
var unreadableSubjects = map[string]func(t *testing.T, path string){
|
|
239
|
+
"permission denied": func(t *testing.T, path string) {
|
|
240
|
+
if err := os.Chmod(path, 0o000); err != nil {
|
|
241
|
+
t.Fatal(err)
|
|
242
|
+
}
|
|
243
|
+
t.Cleanup(func() { _ = os.Chmod(path, 0o644) })
|
|
244
|
+
if _, err := os.ReadFile(path); err == nil {
|
|
245
|
+
t.Skip("chmod 000 does not deny reads for this process; the permission decline is not exercised here")
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
"nul prefixed": func(t *testing.T, path string) {
|
|
249
|
+
if err := os.WriteFile(path, []byte("\x00package src\n\nconst "+anchorQuote+"\n"), 0o644); err != nil {
|
|
250
|
+
t.Fatal(err)
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// subjectProject builds a project whose quote-bearing subject this pass will
|
|
256
|
+
// decline, next to one unrelated file carrying the same quote. That second
|
|
257
|
+
// file is the trap: only a wrongly-run relocation scan would name it.
|
|
258
|
+
func subjectProject(t *testing.T, degrade func(t *testing.T, path string)) string {
|
|
259
|
+
t.Helper()
|
|
260
|
+
project := t.TempDir()
|
|
261
|
+
writeFile(t, project, "src/pool.go", "package src\n\nconst "+anchorQuote+"\n")
|
|
262
|
+
writeFile(t, project, "other/unrelated.txt", "unrelated prose repeating "+anchorQuote+" verbatim\n")
|
|
263
|
+
degrade(t, filepath.Join(project, "src", "pool.go"))
|
|
264
|
+
return project
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
func anchorNotes() string {
|
|
268
|
+
return Render("", "\n", "NOTE-001", "pool cap rationale", "src/pool.go", anchorQuote, "")
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// A subject this pass declines to read is not evidence that the quote moved.
|
|
272
|
+
// The assertion is the negative, not the silence: no moved grade, no
|
|
273
|
+
// relocation target, and repairMoved returns the artifact byte-identical.
|
|
274
|
+
func TestUnreadableSubjectIsNotRelocatedOrRewritten(t *testing.T) {
|
|
275
|
+
for name, degrade := range unreadableSubjects {
|
|
276
|
+
t.Run(name, func(t *testing.T) {
|
|
277
|
+
project := subjectProject(t, degrade)
|
|
278
|
+
|
|
279
|
+
notesText := anchorNotes()
|
|
280
|
+
doc := ParseNotes(notesText)
|
|
281
|
+
if len(doc.Errors) != 0 {
|
|
282
|
+
t.Fatalf("parse: %v", doc.Errors)
|
|
283
|
+
}
|
|
284
|
+
graded := GradeAll(project, doc)
|
|
285
|
+
if graded[0].Grade == GradeExact {
|
|
286
|
+
t.Fatalf("declined subject graded exact without being read: %+v", graded[0])
|
|
287
|
+
}
|
|
288
|
+
if graded[0].Grade == GradeMoved {
|
|
289
|
+
t.Fatalf("declined subject graded moved -> %q", graded[0].MovedTo)
|
|
290
|
+
}
|
|
291
|
+
if graded[0].MovedTo != "" {
|
|
292
|
+
t.Fatalf("declined subject carries a relocation target: %q", graded[0].MovedTo)
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
repaired, repairedText := repairMoved(notesText, doc, graded)
|
|
296
|
+
if repaired != 0 {
|
|
297
|
+
t.Fatalf("repairMoved rewrote %d note(s) it did not positively determine moved", repaired)
|
|
298
|
+
}
|
|
299
|
+
if repairedText != notesText {
|
|
300
|
+
t.Fatalf("repairMoved changed the artifact:\n got %q\nwant %q", repairedText, notesText)
|
|
301
|
+
}
|
|
302
|
+
})
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// cmdAdd re-verifies the quote against the subject before writing. It must
|
|
307
|
+
// refuse a subject the pass will not read as text, so a note can never be
|
|
308
|
+
// created against one.
|
|
309
|
+
func TestAddRefusesSubjectItCannotReadAsText(t *testing.T) {
|
|
310
|
+
project := t.TempDir()
|
|
311
|
+
root := filepath.Join(project, ".devrites")
|
|
312
|
+
work := filepath.Join(root, "work", "feat")
|
|
313
|
+
if err := os.MkdirAll(work, 0o755); err != nil {
|
|
314
|
+
t.Fatal(err)
|
|
315
|
+
}
|
|
316
|
+
writeFile(t, project, "src/pool.go", "\x00package src\n\nconst "+anchorQuote+"\n")
|
|
317
|
+
|
|
318
|
+
t.Setenv("DEVRITES_WORKSPACE", "")
|
|
319
|
+
var stdout, stderr bytes.Buffer
|
|
320
|
+
if code := cmdAdd(root, []string{"feat", "src/pool.go", anchorQuote, "pool cap rationale"},
|
|
321
|
+
&stdout, &stderr); code != ExitBlocked {
|
|
322
|
+
t.Fatalf("note add exit = %d, want %d for an unreadable subject:\n%s%s",
|
|
323
|
+
code, ExitBlocked, stdout.String(), stderr.String())
|
|
324
|
+
}
|
|
325
|
+
if _, err := os.Stat(filepath.Join(work, NotesFile)); err == nil {
|
|
326
|
+
t.Fatal("note add wrote notes.md for a subject it could not read")
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// A subject past the read cap that still carries the quote anchors exactly. The
|
|
331
|
+
// cap bounds relocation scanning, not whether a note can be anchored at all.
|
|
332
|
+
func TestOversizedSubjectWithQuoteGradesExactAndAnchors(t *testing.T) {
|
|
333
|
+
project := t.TempDir()
|
|
334
|
+
writeFile(t, project, "other/unrelated.txt", "unrelated prose repeating "+anchorQuote+" verbatim\n")
|
|
335
|
+
writeOversizedQuoteSubject(t, filepath.Join(project, "src", "pool.go"))
|
|
336
|
+
|
|
337
|
+
doc := ParseNotes(anchorNotes())
|
|
338
|
+
graded := GradeAll(project, doc)
|
|
339
|
+
if graded[0].Grade != GradeExact || graded[0].MovedTo != "" || graded[0].Detail != "" {
|
|
340
|
+
t.Fatalf("oversized quote-bearing subject = %+v, want exact", graded[0])
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
root := filepath.Join(project, ".devrites")
|
|
344
|
+
work := filepath.Join(root, "work", "feat")
|
|
345
|
+
if err := os.MkdirAll(work, 0o755); err != nil {
|
|
346
|
+
t.Fatal(err)
|
|
347
|
+
}
|
|
348
|
+
t.Setenv("DEVRITES_WORKSPACE", "")
|
|
349
|
+
var stdout, stderr bytes.Buffer
|
|
350
|
+
if code := cmdAdd(root, []string{"feat", "src/pool.go", anchorQuote, "pool cap rationale"},
|
|
351
|
+
&stdout, &stderr); code != ExitOK {
|
|
352
|
+
t.Fatalf("note add exit = %d, want %d for an oversized subject carrying the quote:\n%s%s",
|
|
353
|
+
code, ExitOK, stdout.String(), stderr.String())
|
|
354
|
+
}
|
|
355
|
+
stdout.Reset()
|
|
356
|
+
if code := cmdCheck(root, []string{"feat"}, &stdout, &stderr); code != ExitOK {
|
|
357
|
+
t.Fatalf("note check exit = %d, want %d:\n%s%s", code, ExitOK, stdout.String(), stderr.String())
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// An oversized subject that has lost the quote is read to the end and graded on
|
|
362
|
+
// what it holds, so the relocation scan may then name the single other home.
|
|
363
|
+
func TestOversizedSubjectWithoutQuoteIsRegradedFromItsContent(t *testing.T) {
|
|
364
|
+
project := t.TempDir()
|
|
365
|
+
writeFile(t, project, "other/unrelated.txt", "unrelated prose repeating "+anchorQuote+" verbatim\n")
|
|
366
|
+
subject := filepath.Join(project, "src", "pool.go")
|
|
367
|
+
writeOversizedQuoteSubject(t, subject)
|
|
368
|
+
if err := os.WriteFile(subject, bytes.ReplaceAll(mustRead(t, subject), []byte(anchorQuote), []byte("maxConns = 8")), 0o644); err != nil {
|
|
369
|
+
t.Fatal(err)
|
|
370
|
+
}
|
|
371
|
+
graded := GradeAll(project, ParseNotes(anchorNotes()))
|
|
372
|
+
if graded[0].Grade != GradeMoved || graded[0].MovedTo != "other/unrelated.txt" {
|
|
373
|
+
t.Fatalf("oversized subject without the quote = %+v, want moved -> other/unrelated.txt", graded[0])
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
func mustRead(t *testing.T, path string) []byte {
|
|
378
|
+
t.Helper()
|
|
379
|
+
b, err := os.ReadFile(path)
|
|
380
|
+
if err != nil {
|
|
381
|
+
t.Fatal(err)
|
|
382
|
+
}
|
|
383
|
+
return b
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// The quote is matched after whitespace normalization, so it must be found when
|
|
387
|
+
// the raw whitespace around and inside it straddles any internal read boundary.
|
|
388
|
+
func TestSubjectQuoteFoundAcrossReadBoundaries(t *testing.T) {
|
|
389
|
+
for _, pad := range []int{0, 1, 4095, 4096, 4097, 32764, 32766, 32767, 32768, 32769, 32770, 65520, 65530, 65533, 65534, 65535, 65536, 65537, 131070, 131072} {
|
|
390
|
+
for _, sp := range []string{" ", "\n\t ", "\u00a0\u2003"} {
|
|
391
|
+
project := t.TempDir()
|
|
392
|
+
body := strings.Repeat("\n", pad) + "const maxConns" + sp + "=" + sp + "4" + sp + "tail\n"
|
|
393
|
+
writeFile(t, project, "src/pool.go", body)
|
|
394
|
+
if g := GradeNote(project, &Note{Subject: "src/pool.go", Quote: anchorQuote}); g.Grade != GradeExact {
|
|
395
|
+
t.Fatalf("pad %d spacing %q graded %+v, want exact", pad, sp, g)
|
|
396
|
+
}
|
|
397
|
+
writeFile(t, project, "src/pool.go", strings.Repeat("\n", pad)+"const maxConns"+sp+"=")
|
|
398
|
+
if g := GradeNote(project, &Note{Subject: "src/pool.go", Quote: anchorQuote}); g.Grade == GradeExact {
|
|
399
|
+
t.Fatalf("pad %d spacing %q graded exact for a truncated quote", pad, sp)
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// The rewrite is the harm, so the CLI oracle is a byte comparison of notes.md
|
|
406
|
+
// across `note check --repair`, not a line-count or a "no false positive".
|
|
407
|
+
func TestCheckRepairLeavesNotesByteIdenticalWhenSubjectUnreadable(t *testing.T) {
|
|
408
|
+
for name, degrade := range unreadableSubjects {
|
|
409
|
+
t.Run(name, func(t *testing.T) {
|
|
410
|
+
project := t.TempDir()
|
|
411
|
+
subjectPath := filepath.Join(project, "src", "pool.go")
|
|
412
|
+
writeFile(t, project, "src/pool.go", "package src\n\nconst "+anchorQuote+"\n")
|
|
413
|
+
writeFile(t, project, "other/unrelated.txt", "unrelated prose repeating "+anchorQuote+" verbatim\n")
|
|
414
|
+
root := filepath.Join(project, ".devrites")
|
|
415
|
+
work := filepath.Join(root, "work", "feat")
|
|
416
|
+
if err := os.MkdirAll(work, 0o755); err != nil {
|
|
417
|
+
t.Fatal(err)
|
|
418
|
+
}
|
|
419
|
+
notesPath := filepath.Join(work, NotesFile)
|
|
420
|
+
if err := os.WriteFile(notesPath, []byte(anchorNotes()), 0o644); err != nil {
|
|
421
|
+
t.Fatal(err)
|
|
422
|
+
}
|
|
423
|
+
degrade(t, subjectPath)
|
|
424
|
+
|
|
425
|
+
before, err := os.ReadFile(notesPath)
|
|
426
|
+
if err != nil {
|
|
427
|
+
t.Fatal(err)
|
|
428
|
+
}
|
|
429
|
+
t.Setenv("DEVRITES_WORKSPACE", "")
|
|
430
|
+
var stdout, stderr bytes.Buffer
|
|
431
|
+
code := cmdCheck(root, []string{"feat", "--repair"}, &stdout, &stderr)
|
|
432
|
+
|
|
433
|
+
// Check the rewrite first: re-pointing the anchor, even to a
|
|
434
|
+
// correct location, is itself the harm for a subject that was not read.
|
|
435
|
+
after, err := os.ReadFile(notesPath)
|
|
436
|
+
if err != nil {
|
|
437
|
+
t.Fatal(err)
|
|
438
|
+
}
|
|
439
|
+
if !bytes.Equal(before, after) {
|
|
440
|
+
t.Fatalf("notes.md was rewritten in place:\nbefore %q\nafter %q", before, after)
|
|
441
|
+
}
|
|
442
|
+
if code == ExitOK {
|
|
443
|
+
t.Fatalf("note check --repair exited 0 for a subject it never read:\n%s%s", stdout.String(), stderr.String())
|
|
444
|
+
}
|
|
445
|
+
if !strings.Contains(stdout.String(), "result: drifted") {
|
|
446
|
+
t.Fatalf("want a drifted result, got:\n%s", stdout.String())
|
|
447
|
+
}
|
|
448
|
+
for _, line := range strings.Split(stdout.String(), "\n") {
|
|
449
|
+
if strings.HasPrefix(line, "note: NOTE-001 moved") {
|
|
450
|
+
t.Fatalf("reported a relocation the scan was never entitled to run: %q\n%s", line, stdout.String())
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
})
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// A relocation scan that could not enter part of the tree has not seen every
|
|
458
|
+
// candidate, so a single hit among the readable files is not a unique location.
|
|
459
|
+
func TestPartialScanDoesNotGradeSingleHitMoved(t *testing.T) {
|
|
460
|
+
project := t.TempDir()
|
|
461
|
+
writeFile(t, project, "visible/a.txt", "prose repeating "+anchorQuote+" verbatim\n")
|
|
462
|
+
writeFile(t, project, "hidden/b.txt", "prose repeating "+anchorQuote+" verbatim\n")
|
|
463
|
+
hidden := filepath.Join(project, "hidden")
|
|
464
|
+
if err := os.Chmod(hidden, 0o000); err != nil {
|
|
465
|
+
t.Fatal(err)
|
|
466
|
+
}
|
|
467
|
+
t.Cleanup(func() { _ = os.Chmod(hidden, 0o755) })
|
|
468
|
+
if _, err := os.ReadDir(hidden); err == nil {
|
|
469
|
+
t.Skip("chmod 000 does not deny directory reads for this process")
|
|
470
|
+
}
|
|
471
|
+
root := filepath.Join(project, ".devrites")
|
|
472
|
+
work := filepath.Join(root, "work", "feat")
|
|
473
|
+
if err := os.MkdirAll(work, 0o755); err != nil {
|
|
474
|
+
t.Fatal(err)
|
|
475
|
+
}
|
|
476
|
+
notesPath := filepath.Join(work, NotesFile)
|
|
477
|
+
if err := os.WriteFile(notesPath, []byte(anchorNotes()), 0o644); err != nil {
|
|
478
|
+
t.Fatal(err)
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
doc := ParseNotes(anchorNotes())
|
|
482
|
+
graded := GradeAll(project, doc)
|
|
483
|
+
if graded[0].Grade != GradeAmbiguous {
|
|
484
|
+
t.Fatalf("grade = %s (moved to %q), want %s for a partial scan", graded[0].Grade, graded[0].MovedTo, GradeAmbiguous)
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
before, err := os.ReadFile(notesPath)
|
|
488
|
+
if err != nil {
|
|
489
|
+
t.Fatal(err)
|
|
490
|
+
}
|
|
491
|
+
t.Setenv("DEVRITES_WORKSPACE", "")
|
|
492
|
+
var stdout, stderr bytes.Buffer
|
|
493
|
+
cmdCheck(root, []string{"feat", "--repair"}, &stdout, &stderr)
|
|
494
|
+
after, err := os.ReadFile(notesPath)
|
|
495
|
+
if err != nil {
|
|
496
|
+
t.Fatal(err)
|
|
497
|
+
}
|
|
498
|
+
if !bytes.Equal(before, after) {
|
|
499
|
+
t.Fatalf("notes.md was rewritten from a partial scan:\nbefore %q\nafter %q", before, after)
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Several notes whose subjects are gone share one repository walk: each
|
|
504
|
+
// candidate file is read once however many notes are looking for a quote, and
|
|
505
|
+
// every note keeps the grade and location it would get on its own.
|
|
506
|
+
func TestGradeAllReadsEachCandidateOnce(t *testing.T) {
|
|
507
|
+
project := t.TempDir()
|
|
508
|
+
writeFile(t, project, "a.txt", "alpha quote one lives here\n")
|
|
509
|
+
writeFile(t, project, "b.txt", "beta quote two lives here\n")
|
|
510
|
+
writeFile(t, project, "c.txt", "beta quote two lives here too\n")
|
|
511
|
+
writeFile(t, project, "d.txt", "nothing relevant\n")
|
|
512
|
+
doc := ParseNotes(`- NOTE-001: one
|
|
513
|
+
SUBJECT: gone/one.txt
|
|
514
|
+
QUOTE: alpha quote one
|
|
515
|
+
- NOTE-002: two
|
|
516
|
+
SUBJECT: gone/two.txt
|
|
517
|
+
QUOTE: beta quote two
|
|
518
|
+
- NOTE-003: three
|
|
519
|
+
SUBJECT: gone/three.txt
|
|
520
|
+
QUOTE: absent from everywhere
|
|
521
|
+
`)
|
|
522
|
+
reads := map[string]int{}
|
|
523
|
+
orig := readCandidate
|
|
524
|
+
readCandidate = func(path string) fileRead {
|
|
525
|
+
reads[filepath.Base(path)]++
|
|
526
|
+
return orig(path)
|
|
527
|
+
}
|
|
528
|
+
t.Cleanup(func() { readCandidate = orig })
|
|
529
|
+
|
|
530
|
+
graded := GradeAll(project, doc)
|
|
531
|
+
for name, n := range reads {
|
|
532
|
+
if n > 1 {
|
|
533
|
+
t.Errorf("%s read %d times, want at most once", name, n)
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if graded[0].Grade != GradeMoved || graded[0].MovedTo != "a.txt" {
|
|
537
|
+
t.Errorf("note 1: %+v", graded[0])
|
|
538
|
+
}
|
|
539
|
+
if graded[1].Grade != GradeAmbiguous {
|
|
540
|
+
t.Errorf("note 2: %+v", graded[1])
|
|
541
|
+
}
|
|
542
|
+
if graded[2].Grade != GradeLost {
|
|
543
|
+
t.Errorf("note 3: %+v", graded[2])
|
|
544
|
+
}
|
|
545
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
package admit
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"io"
|
|
5
|
+
"os"
|
|
6
|
+
"path/filepath"
|
|
7
|
+
"strings"
|
|
8
|
+
|
|
9
|
+
"github.com/devrites/devrites/internal/overhaul/ovio"
|
|
10
|
+
"github.com/devrites/devrites/internal/overhaul/packet"
|
|
11
|
+
"github.com/devrites/devrites/internal/overhaul/records"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// packetAdmit checks a dispatch packet file against the run area and the
|
|
15
|
+
// dispatch.json attempt it names. The packet must sit, unlinked, at
|
|
16
|
+
// RUN/packets/<name>.json and pass packet.Validate for that run, which reads
|
|
17
|
+
// a relative receipt_path from the working directory, as packet write does.
|
|
18
|
+
func packetAdmit(run, path string, stdout io.Writer) (int, error) {
|
|
19
|
+
cur, err := os.ReadFile(join(run, "CURRENT"))
|
|
20
|
+
if err != nil {
|
|
21
|
+
return 0, err
|
|
22
|
+
}
|
|
23
|
+
gen := workingGeneration(run, strings.TrimSpace(string(cur)))
|
|
24
|
+
rj, err := ovio.LoadObject(join(gen, "run.json"))
|
|
25
|
+
if err != nil {
|
|
26
|
+
return 0, err
|
|
27
|
+
}
|
|
28
|
+
disp, err := ovio.LoadObject(join(gen, "dispatch.json"))
|
|
29
|
+
if err != nil {
|
|
30
|
+
return 0, err
|
|
31
|
+
}
|
|
32
|
+
p, err := ovio.LoadObject(path)
|
|
33
|
+
if err != nil {
|
|
34
|
+
return 0, err
|
|
35
|
+
}
|
|
36
|
+
eq := func(a, b any) bool { return records.Repr(a) == records.Repr(b) }
|
|
37
|
+
|
|
38
|
+
// Resolved once, so every check below sees the same run location whatever
|
|
39
|
+
// the working directory. receipt_path is judged exactly as packet write
|
|
40
|
+
// judges it: unchanged, by packet.Validate.
|
|
41
|
+
absRun, err := filepath.Abs(run)
|
|
42
|
+
if err != nil {
|
|
43
|
+
return 0, err
|
|
44
|
+
}
|
|
45
|
+
canon := filepath.Join(absRun, "receipts", packet.Name(p)+".json")
|
|
46
|
+
why := packet.Validate(absRun, p)
|
|
47
|
+
|
|
48
|
+
if st, err := os.Lstat(path); err != nil || st.Mode()&os.ModeSymlink != 0 {
|
|
49
|
+
why = append(why, "packet file must not be a symlink")
|
|
50
|
+
}
|
|
51
|
+
if filepath.Base(path) != packet.Name(p)+".json" {
|
|
52
|
+
why = append(why, "file name does not match run_id, task_id, attempt_id and role")
|
|
53
|
+
}
|
|
54
|
+
if realpath(filepath.Dir(path)) != filepath.Join(realpath(run), "packets") {
|
|
55
|
+
why = append(why, "packet is not under the run's packets directory")
|
|
56
|
+
}
|
|
57
|
+
if !eq(p["run_id"], rj["run_id"]) {
|
|
58
|
+
why = append(why, "run_id differs from the run")
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var x map[string]any
|
|
62
|
+
for _, it := range ovio.List(disp["attempts"]) {
|
|
63
|
+
if a := ovio.Obj(it); eq(a["task_id"], p["task_id"]) && eq(a["attempt_id"], p["attempt_id"]) {
|
|
64
|
+
x = a
|
|
65
|
+
break
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if x == nil {
|
|
69
|
+
why = append(why, "no such dispatched attempt")
|
|
70
|
+
return result(stdout, why, "ADMISSIBLE"), nil
|
|
71
|
+
}
|
|
72
|
+
if s := ovio.Str(x["status"]); s == "admitted" || s == "rejected" || s == "cancelled" {
|
|
73
|
+
verdict(stdout, "DUPLICATE_OR_LATE", "attempt_status", x["status"])
|
|
74
|
+
return 3, nil
|
|
75
|
+
}
|
|
76
|
+
if !eq(p["role"], x["role"]) {
|
|
77
|
+
why = append(why, "role differs from the dispatched attempt")
|
|
78
|
+
}
|
|
79
|
+
if ovio.Truthy(x["snapshot"]) && !eq(p["snapshot"], x["snapshot"]) {
|
|
80
|
+
why = append(why, "snapshot differs from the dispatched attempt")
|
|
81
|
+
}
|
|
82
|
+
if r := ovio.Str(x["receipt"]); r != "" && filepath.Clean(join(absRun, r)) != canon {
|
|
83
|
+
why = append(why, "receipt_path differs from the dispatched attempt's receipt")
|
|
84
|
+
}
|
|
85
|
+
if pp := ovio.Str(x["packet"]); pp != "" && filepath.Clean(join(absRun, pp)) != filepath.Join(absRun, "packets", packet.Name(p)+".json") {
|
|
86
|
+
why = append(why, "packet path differs from the dispatched attempt's packet")
|
|
87
|
+
}
|
|
88
|
+
return result(stdout, why, "ADMISSIBLE"), nil
|
|
89
|
+
}
|