devrites 7.2.7 → 7.3.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 +40 -0
- package/README.md +6 -1
- package/docs/candidate-integrity.md +10 -0
- package/docs/cli.md +7 -1
- package/docs/command-map.md +9 -2
- package/docs/engine/commands.md +50 -4
- package/docs/orchestration.md +35 -13
- package/docs/skills.md +5 -0
- package/engine/internal/acceptance/cli.go +35 -30
- package/engine/internal/acceptance/preconditions.go +1 -1
- package/engine/internal/acceptance/run.go +138 -53
- package/engine/internal/acceptance/transcript.go +236 -45
- package/engine/internal/devritespaths/paths.go +23 -5
- package/engine/internal/gate/gate.go +6 -0
- package/engine/internal/install/apply.go +5 -0
- package/engine/internal/install/merge.go +48 -6
- package/engine/internal/install/preflight.go +21 -3
- package/engine/internal/install/uninstall.go +9 -10
- package/engine/internal/lib/apply_bundle.go +7 -1
- package/engine/internal/lib/candidate.go +20 -7
- package/engine/internal/lib/candidate_coverage.go +2 -19
- package/engine/internal/lib/closeout.go +22 -10
- package/engine/internal/lib/context.go +67 -47
- package/engine/internal/lib/context_io.go +171 -0
- package/engine/internal/lib/detect.go +8 -8
- package/engine/internal/lib/dispatch.go +6 -0
- package/engine/internal/lib/packet.go +37 -7
- package/engine/internal/lib/packet_freeze.go +60 -12
- package/engine/internal/lib/packet_integrity.go +179 -0
- package/engine/internal/lib/perturb.go +3 -3
- package/engine/internal/lib/resolve.go +10 -5
- package/engine/internal/lib/slicecheck.go +7 -1
- package/engine/internal/lib/state_edit.go +9 -2
- package/engine/internal/lib/taskgraph.go +20 -36
- package/engine/internal/lib/triggers.go +30 -31
- package/engine/internal/lib/workspace_pool.go +330 -0
- package/engine/internal/parallel/cli.go +190 -49
- package/engine/internal/parallel/git.go +47 -14
- package/engine/internal/parallel/landing.go +232 -0
- package/engine/internal/parallel/lease.go +97 -18
- package/engine/internal/parallel/ops.go +312 -155
- package/engine/internal/parallel/pathdisjoint.go +48 -4
- package/engine/internal/parallel/prune.go +133 -0
- package/engine/internal/parallel/repository.go +239 -0
- package/engine/internal/parallel/select.go +64 -42
- package/engine/internal/state/cursor.go +5 -5
- package/engine/main.go +2 -1
- package/pack/.claude/agents/devrites-proof-runner.md +16 -9
- package/pack/.claude/skills/devrites-lib/SKILL.md +2 -0
- package/pack/.claude/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/.claude/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/.claude/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/.claude/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/.claude/skills/rite-build/SKILL.md +13 -10
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/.claude/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/.claude/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/.claude/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/.claude/skills/rite-clarify/SKILL.md +2 -2
- package/pack/.claude/skills/rite-converge/SKILL.md +4 -4
- package/pack/.claude/skills/rite-define/SKILL.md +7 -3
- package/pack/.claude/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/.claude/skills/rite-plan/SKILL.md +11 -8
- package/pack/.claude/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/.claude/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/.claude/skills/rite-polish/SKILL.md +3 -3
- package/pack/.claude/skills/rite-prove/SKILL.md +9 -5
- package/pack/.claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/.claude/skills/rite-review/SKILL.md +4 -3
- package/pack/.claude/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/.claude/skills/rite-seal/SKILL.md +1 -1
- package/pack/.claude/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/.claude/skills/rite-ship/SKILL.md +2 -2
- package/pack/.claude/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/.claude/skills/rite-spec/SKILL.md +8 -5
- package/pack/.claude/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/.claude/skills/rite-temper/SKILL.md +3 -3
- package/pack/.claude/skills/rite-vet/SKILL.md +9 -5
- package/pack/.claude/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/claude/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/claude/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/claude/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/claude/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/claude/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/claude/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/claude/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/claude/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/claude/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/claude/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/claude/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/claude/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/claude/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/claude/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/claude/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/claude/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/claude/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/claude/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/claude/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/claude/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/claude/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/claude/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/claude/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/codex/agents/devrites-proof-runner.toml +16 -9
- package/pack/generated/codex/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/codex/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/codex/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/codex/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/codex/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/codex/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/codex/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/codex/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/codex/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/codex/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/codex/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/codex/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/codex/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/codex/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/codex/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/codex/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/codex/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/codex/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/codex/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/codex/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/codex/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/codex/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/devin/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/devin/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/devin/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/devin/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/generated/devin/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/devin/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/devin/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/devin/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/devin/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/devin/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/devin/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/devin/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/devin/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/devin/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/devin/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/devin/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/devin/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/devin/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/devin/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/devin/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/devin/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/devin/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/devin/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/devin/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/devin/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/devin/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/devin/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/dsh/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/dsh/runtime/cordis.patch.yml +1 -1
- package/pack/generated/dsh/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/dsh/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/dsh/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/dsh/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/dsh/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/dsh/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/dsh/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/dsh/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/dsh/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/dsh/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/dsh/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/dsh/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/dsh/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/dsh/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/dsh/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/dsh/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/dsh/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/dsh/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/dsh/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/dsh/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/dsh/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/dsh/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/dsh/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/dsh/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/dsh/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/dsh/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/dsh/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/dsh/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/dsh/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/dsh/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/dsh/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/dsh/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/dsh/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/omp/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/omp/commands/rite-build.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/omp/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/omp/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +11 -3
- package/pack/generated/omp/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/omp/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/omp/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/omp/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/omp/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/omp/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/omp/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/omp/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/omp/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/omp/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/omp/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/omp/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/omp/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/omp/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/omp/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/omp/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/omp/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/omp/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/omp/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +12 -5
- package/pack/generated/pi/agents/devrites-proof-runner.md +16 -9
- package/pack/generated/pi/prompts/rite-build.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/SKILL.md +2 -0
- package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +7 -3
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +3 -0
- package/pack/generated/pi/skills/devrites-lib/reference/parallel-workspaces.md +202 -0
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +9 -12
- package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +7 -3
- package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/gates.md +18 -9
- package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -0
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +13 -10
- package/pack/generated/pi/skills/rite-autocomplete/reference/lookahead.md +4 -4
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +13 -9
- package/pack/generated/pi/skills/rite-build/SKILL.md +13 -10
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +60 -39
- package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +8 -5
- package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +7 -7
- package/pack/generated/pi/skills/rite-clarify/SKILL.md +2 -2
- package/pack/generated/pi/skills/rite-converge/SKILL.md +4 -4
- package/pack/generated/pi/skills/rite-define/SKILL.md +7 -3
- package/pack/generated/pi/skills/rite-define/reference/plan-template.md +4 -2
- package/pack/generated/pi/skills/rite-plan/SKILL.md +11 -8
- package/pack/generated/pi/skills/rite-plan/reference/dependency-graph.md +9 -2
- package/pack/generated/pi/skills/rite-plan/reference/slicing.md +2 -0
- package/pack/generated/pi/skills/rite-polish/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-prove/SKILL.md +9 -5
- package/pack/generated/pi/skills/rite-resolve/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +2 -0
- package/pack/generated/pi/skills/rite-review/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-review/reference/feature-scoped-review.md +2 -2
- package/pack/generated/pi/skills/rite-seal/SKILL.md +1 -1
- package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +1 -1
- package/pack/generated/pi/skills/rite-ship/SKILL.md +2 -2
- package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +2 -2
- package/pack/generated/pi/skills/rite-spec/SKILL.md +8 -5
- package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +5 -0
- package/pack/generated/pi/skills/rite-temper/SKILL.md +3 -3
- package/pack/generated/pi/skills/rite-vet/SKILL.md +9 -5
- package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +12 -5
- package/package.json +1 -1
- package/scripts/build-host-artifacts.sh +5 -6
- package/scripts/omp-generate.sh +24 -14
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
package parallel
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"reflect"
|
|
6
|
+
"strings"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
// landing is written before FF and retained afterward as the exact retry receipt.
|
|
10
|
+
// Worker transfers are rewritten on control; ancestry is not landing evidence.
|
|
11
|
+
type landing struct {
|
|
12
|
+
BatchID string `json:"batch_id"`
|
|
13
|
+
Controller string `json:"controller"`
|
|
14
|
+
Checkout string `json:"checkout"`
|
|
15
|
+
Ref string `json:"ref"`
|
|
16
|
+
PriorTip string `json:"prior_tip"`
|
|
17
|
+
NewTip string `json:"new_tip"`
|
|
18
|
+
Slice string `json:"slice,omitempty"`
|
|
19
|
+
Targets []LeaseSlice `json:"targets"`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func validateLanding(lease *Lease, record *landing, accepted bool) error {
|
|
23
|
+
if record == nil {
|
|
24
|
+
return nil
|
|
25
|
+
}
|
|
26
|
+
if record.BatchID != lease.BatchID || validateSlug(record.Controller) != nil || record.Checkout == "" || record.Ref == "" || len(record.PriorTip) != 40 || !shaRE.MatchString(record.PriorTip) || len(record.NewTip) != 40 || !shaRE.MatchString(record.NewTip) || record.PriorTip == record.NewTip || len(record.Targets) == 0 {
|
|
27
|
+
return fmt.Errorf("invalid landing identity")
|
|
28
|
+
}
|
|
29
|
+
if lease.ControlCheckout != record.Checkout || lease.ControlRef != record.Ref {
|
|
30
|
+
return fmt.Errorf("landing controller identity differs from lease")
|
|
31
|
+
}
|
|
32
|
+
seen := map[string]bool{}
|
|
33
|
+
for _, target := range record.Targets {
|
|
34
|
+
key := SliceKey(target.Workspace, target.ID)
|
|
35
|
+
if seen[key] || len(target.TransferCommit) != 40 || !shaRE.MatchString(target.TransferCommit) || target.WrightStatus != WrightGreen {
|
|
36
|
+
return fmt.Errorf("invalid landing target %s", key)
|
|
37
|
+
}
|
|
38
|
+
seen[key] = true
|
|
39
|
+
found := false
|
|
40
|
+
for _, sl := range lease.Slices {
|
|
41
|
+
if SliceKey(sl.Workspace, sl.ID) != key {
|
|
42
|
+
continue
|
|
43
|
+
}
|
|
44
|
+
if accepted {
|
|
45
|
+
if sl.WrightStatus != WrightIntegrated {
|
|
46
|
+
return fmt.Errorf("accepted landing target %s is not integrated", key)
|
|
47
|
+
}
|
|
48
|
+
sl.WrightStatus = WrightGreen
|
|
49
|
+
}
|
|
50
|
+
if !reflect.DeepEqual(sl, target) {
|
|
51
|
+
return fmt.Errorf("landing target %s changed", key)
|
|
52
|
+
}
|
|
53
|
+
found = true
|
|
54
|
+
break
|
|
55
|
+
}
|
|
56
|
+
if !found {
|
|
57
|
+
return fmt.Errorf("landing target %s missing", key)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if record.Slice != "" && (len(record.Targets) != 1 || SliceKey(record.Targets[0].Workspace, record.Targets[0].ID) != record.Slice) {
|
|
61
|
+
return fmt.Errorf("landing selector differs from targets")
|
|
62
|
+
}
|
|
63
|
+
if !accepted && !strings.HasPrefix(strings.ToLower(record.PriorTip), strings.ToLower(expectedControl(lease))) {
|
|
64
|
+
return fmt.Errorf("pending landing prior tip differs from lease")
|
|
65
|
+
}
|
|
66
|
+
if accepted && lease.ControlTip != record.NewTip {
|
|
67
|
+
return fmt.Errorf("accepted landing tip differs from lease")
|
|
68
|
+
}
|
|
69
|
+
return nil
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
func controlIdentity(root string) (string, string, error) {
|
|
73
|
+
ref, err := git(root, "symbolic-ref", "--quiet", "HEAD")
|
|
74
|
+
if err != nil {
|
|
75
|
+
if !strings.Contains(err.Error(), "exit 1") {
|
|
76
|
+
return "", "", err
|
|
77
|
+
}
|
|
78
|
+
ref = "HEAD"
|
|
79
|
+
}
|
|
80
|
+
return resolvedPath(root), ref, nil
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func ensureControllerIdentity(root string, lease *Lease) error {
|
|
84
|
+
if lease.ControlCheckout == "" && lease.ControlRef == "" {
|
|
85
|
+
return nil // Legacy leases have no historical checkout/ref evidence.
|
|
86
|
+
}
|
|
87
|
+
checkout, ref, err := controlIdentity(root)
|
|
88
|
+
if err != nil {
|
|
89
|
+
return err
|
|
90
|
+
}
|
|
91
|
+
if checkout != lease.ControlCheckout || ref != lease.ControlRef {
|
|
92
|
+
return fmt.Errorf("control checkout/ref changed; expected %s %s, have %s %s", lease.ControlCheckout, lease.ControlRef, checkout, ref)
|
|
93
|
+
}
|
|
94
|
+
return nil
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// recoverLanding runs under controller + feature locks. Only integrate may
|
|
98
|
+
// perform a prepared FF; abort may cancel exact-prior preparation instead.
|
|
99
|
+
func recoverLanding(root, slug, path string, lease *Lease, resume, cancel bool) (*landing, error) {
|
|
100
|
+
if err := ensureControllerIdentity(root, lease); err != nil {
|
|
101
|
+
return nil, err
|
|
102
|
+
}
|
|
103
|
+
record := lease.PendingLanding
|
|
104
|
+
if record == nil {
|
|
105
|
+
return nil, nil
|
|
106
|
+
}
|
|
107
|
+
if record.Controller != slug {
|
|
108
|
+
return nil, fmt.Errorf("pending landing controller changed")
|
|
109
|
+
}
|
|
110
|
+
if err := validateLanding(lease, record, false); err != nil {
|
|
111
|
+
return nil, err
|
|
112
|
+
}
|
|
113
|
+
prior, err := revParse(root, expectedControl(lease))
|
|
114
|
+
if err != nil {
|
|
115
|
+
return nil, err
|
|
116
|
+
}
|
|
117
|
+
if prior != record.PriorTip {
|
|
118
|
+
return nil, fmt.Errorf("pending landing resolved prior tip differs from lease")
|
|
119
|
+
}
|
|
120
|
+
head, err := headSHA(root)
|
|
121
|
+
if err != nil {
|
|
122
|
+
return nil, err
|
|
123
|
+
}
|
|
124
|
+
switch head {
|
|
125
|
+
case record.PriorTip:
|
|
126
|
+
if cancel {
|
|
127
|
+
lease.PendingLanding = nil
|
|
128
|
+
return nil, writeLease(path, lease)
|
|
129
|
+
}
|
|
130
|
+
if !resume {
|
|
131
|
+
return nil, fmt.Errorf("pending landing requires integrate --apply-to-control or abort before mutation")
|
|
132
|
+
}
|
|
133
|
+
var paths []string
|
|
134
|
+
for _, target := range record.Targets {
|
|
135
|
+
paths = append(paths, target.Paths...)
|
|
136
|
+
}
|
|
137
|
+
dirty, err := porcelainDirtyPaths(root, paths)
|
|
138
|
+
if err != nil {
|
|
139
|
+
return nil, err
|
|
140
|
+
}
|
|
141
|
+
if dirty {
|
|
142
|
+
return nil, fmt.Errorf("control has uncommitted changes on pending landing paths")
|
|
143
|
+
}
|
|
144
|
+
mergeErr := mergeFFOnly(root, record.NewTip)
|
|
145
|
+
// A post-merge hook may fail after the ref already advanced.
|
|
146
|
+
head, err = headSHA(root)
|
|
147
|
+
if err != nil {
|
|
148
|
+
return nil, err
|
|
149
|
+
}
|
|
150
|
+
if err := ensureControllerIdentity(root, lease); err != nil {
|
|
151
|
+
return nil, err
|
|
152
|
+
}
|
|
153
|
+
if head != record.NewTip {
|
|
154
|
+
return nil, fmt.Errorf("pending landing fast-forward did not reach exact recorded tip (HEAD=%s): %v", head, mergeErr)
|
|
155
|
+
}
|
|
156
|
+
case record.NewTip:
|
|
157
|
+
default:
|
|
158
|
+
return nil, fmt.Errorf("pending landing refuses external control tip %s; expected exactly %s or %s", head, record.PriorTip, record.NewTip)
|
|
159
|
+
}
|
|
160
|
+
for i := range lease.Slices {
|
|
161
|
+
for _, target := range record.Targets {
|
|
162
|
+
if SliceKey(lease.Slices[i].Workspace, lease.Slices[i].ID) == SliceKey(target.Workspace, target.ID) {
|
|
163
|
+
lease.Slices[i].WrightStatus = WrightIntegrated
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
lease.ControlTip = record.NewTip
|
|
168
|
+
lease.Status = StatusRunning
|
|
169
|
+
if len(activeSlices(lease)) == 0 {
|
|
170
|
+
lease.Status = StatusComplete
|
|
171
|
+
}
|
|
172
|
+
lease.PendingLanding = nil
|
|
173
|
+
lease.LastLanding = record
|
|
174
|
+
if err := writeLease(path, lease); err != nil {
|
|
175
|
+
return nil, fmt.Errorf("control landed at %s; persist landing recovery before further mutation: %w", record.NewTip, err)
|
|
176
|
+
}
|
|
177
|
+
return record, nil
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
func acceptedRetry(root string, lease *Lease, selector string) (string, error) {
|
|
181
|
+
record := lease.LastLanding
|
|
182
|
+
if record == nil || record.Slice != selector {
|
|
183
|
+
return "", nil
|
|
184
|
+
}
|
|
185
|
+
if err := ensureControllerIdentity(root, lease); err != nil {
|
|
186
|
+
return "", err
|
|
187
|
+
}
|
|
188
|
+
if err := ensureControlAtBase(root, record.NewTip); err != nil {
|
|
189
|
+
return "", err
|
|
190
|
+
}
|
|
191
|
+
if err := validateLanding(lease, record, true); err != nil {
|
|
192
|
+
return "", err
|
|
193
|
+
}
|
|
194
|
+
// An all-slice request after refill is new work, not the old all-slice retry.
|
|
195
|
+
if selector == "" && len(activeSlices(lease)) != 0 {
|
|
196
|
+
return "", nil
|
|
197
|
+
}
|
|
198
|
+
return record.NewTip, nil
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
func protectRawLease(current, next *Lease) error {
|
|
202
|
+
if current == nil {
|
|
203
|
+
if next.PendingLanding != nil || next.LastLanding != nil {
|
|
204
|
+
return fmt.Errorf("lease-write cannot fabricate landing evidence")
|
|
205
|
+
}
|
|
206
|
+
return nil
|
|
207
|
+
}
|
|
208
|
+
if current.PendingLanding != nil {
|
|
209
|
+
if !reflect.DeepEqual(current, next) {
|
|
210
|
+
return fmt.Errorf("lease-write refuses mutation during pending landing; recover integrate or abort first")
|
|
211
|
+
}
|
|
212
|
+
return nil
|
|
213
|
+
}
|
|
214
|
+
if next.PendingLanding != nil || !reflect.DeepEqual(current.LastLanding, next.LastLanding) || current.ControlCheckout != next.ControlCheckout || current.ControlRef != next.ControlRef {
|
|
215
|
+
return fmt.Errorf("lease-write cannot change landing evidence or controller identity")
|
|
216
|
+
}
|
|
217
|
+
for _, sl := range current.Slices {
|
|
218
|
+
if sl.WrightStatus != WrightIntegrated {
|
|
219
|
+
continue
|
|
220
|
+
}
|
|
221
|
+
found := false
|
|
222
|
+
for _, candidate := range next.Slices {
|
|
223
|
+
if SliceKey(sl.Workspace, sl.ID) == SliceKey(candidate.Workspace, candidate.ID) && reflect.DeepEqual(sl, candidate) {
|
|
224
|
+
found = true
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
if !found {
|
|
228
|
+
return fmt.Errorf("lease-write cannot change integrated slice %s", SliceKey(sl.Workspace, sl.ID))
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return nil
|
|
232
|
+
}
|
|
@@ -26,7 +26,7 @@ const (
|
|
|
26
26
|
// control; it no longer holds a parallel slot.
|
|
27
27
|
WrightIntegrated = "integrated"
|
|
28
28
|
|
|
29
|
-
MinParallelSlices =
|
|
29
|
+
MinParallelSlices = 1
|
|
30
30
|
MaxParallelSlices = 10
|
|
31
31
|
)
|
|
32
32
|
|
|
@@ -46,7 +46,12 @@ type Lease struct {
|
|
|
46
46
|
CreatedAt string `json:"created_at"`
|
|
47
47
|
BaseSHA string `json:"base_sha"`
|
|
48
48
|
ControlTip string `json:"control_tip,omitempty"`
|
|
49
|
+
ControlCheckout string `json:"control_checkout,omitempty"`
|
|
50
|
+
ControlRef string `json:"control_ref,omitempty"`
|
|
51
|
+
PendingLanding *landing `json:"pending_landing,omitempty"`
|
|
52
|
+
LastLanding *landing `json:"last_landing,omitempty"`
|
|
49
53
|
N int `json:"n"`
|
|
54
|
+
Capacity int `json:"capacity,omitempty"`
|
|
50
55
|
Status string `json:"status"`
|
|
51
56
|
ControlPIDOrSession string `json:"control_pid_or_session"`
|
|
52
57
|
Slices []LeaseSlice `json:"slices"`
|
|
@@ -57,6 +62,7 @@ type Lease struct {
|
|
|
57
62
|
// from the original create).
|
|
58
63
|
type LeaseSlice struct {
|
|
59
64
|
ID string `json:"id"`
|
|
65
|
+
Workspace string `json:"workspace,omitempty"`
|
|
60
66
|
Paths []string `json:"paths"`
|
|
61
67
|
WorktreePath string `json:"worktree_path"`
|
|
62
68
|
Branch string `json:"branch"`
|
|
@@ -87,7 +93,7 @@ func activeSlices(lease *Lease) []SlicePaths {
|
|
|
87
93
|
var active []SlicePaths
|
|
88
94
|
for _, sl := range lease.Slices {
|
|
89
95
|
if sl.WrightStatus != WrightIntegrated {
|
|
90
|
-
active = append(active, SlicePaths{ID: sl.ID, Paths: sl.Paths})
|
|
96
|
+
active = append(active, SlicePaths{ID: sl.ID, Workspace: sl.Workspace, Paths: sl.Paths})
|
|
91
97
|
}
|
|
92
98
|
}
|
|
93
99
|
return active
|
|
@@ -112,17 +118,64 @@ func IntegrateBranchName(slug, batchID string) string {
|
|
|
112
118
|
return fmt.Sprintf("devrites/parallel/%s/%s/integrate", slug, batchID)
|
|
113
119
|
}
|
|
114
120
|
|
|
115
|
-
// ownedBranchName reports whether branch is inside this batch's namespace —
|
|
116
|
-
// devrites/parallel/<slug>/<batch>/…. Cleanup deletes only owned branches;
|
|
117
|
-
// a lease naming anything else (e.g. a forged "main") is left alone.
|
|
118
|
-
func ownedBranchName(slug, batchID, branch string) bool {
|
|
119
|
-
return strings.HasPrefix(branch, fmt.Sprintf("devrites/parallel/%s/%s/", slug, batchID))
|
|
120
|
-
}
|
|
121
|
-
|
|
122
121
|
func WorkerWorktreePath(repoRoot, batchID, sliceID string) string {
|
|
123
122
|
return filepath.Join(ScratchRoot(repoRoot), batchID, sliceID)
|
|
124
123
|
}
|
|
125
124
|
|
|
125
|
+
func workerBranch(slug, batchID, workspace, id string) string {
|
|
126
|
+
if workspace != "" {
|
|
127
|
+
return WorkerBranch(slug, batchID, "_workspaces/"+workspace+"/"+id)
|
|
128
|
+
}
|
|
129
|
+
return WorkerBranch(slug, batchID, id)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
func workerWorktreePath(root, batchID, workspace, id string) string {
|
|
133
|
+
if workspace != "" {
|
|
134
|
+
return filepath.Join(ScratchRoot(root), batchID, "_workspaces", workspace, id)
|
|
135
|
+
}
|
|
136
|
+
return WorkerWorktreePath(root, batchID, id)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
func leaseCapacity(lease *Lease) int {
|
|
140
|
+
if lease.Capacity == 0 {
|
|
141
|
+
return MaxParallelSlices
|
|
142
|
+
}
|
|
143
|
+
return lease.Capacity
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
func validateCapacity(capacity int) error {
|
|
147
|
+
if capacity < 0 || capacity > MaxParallelSlices {
|
|
148
|
+
return fmt.Errorf("cap must be 1-%d (got %d)", MaxParallelSlices, capacity)
|
|
149
|
+
}
|
|
150
|
+
return nil
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
func normalizeLease(lease *Lease, controller string) error {
|
|
154
|
+
for i := range lease.Slices {
|
|
155
|
+
if lease.Slices[i].Workspace == controller {
|
|
156
|
+
lease.Slices[i].Workspace = ""
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return ValidateLease(lease)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
func normalizeSliceRef(controller, ref string) (string, error) {
|
|
163
|
+
workspace, id, qualified := strings.Cut(ref, "/")
|
|
164
|
+
if !qualified {
|
|
165
|
+
return ref, validateSliceID(ref)
|
|
166
|
+
}
|
|
167
|
+
if err := validateSlug(workspace); err != nil {
|
|
168
|
+
return "", err
|
|
169
|
+
}
|
|
170
|
+
if err := validateSliceID(id); err != nil {
|
|
171
|
+
return "", err
|
|
172
|
+
}
|
|
173
|
+
if workspace == controller {
|
|
174
|
+
workspace = ""
|
|
175
|
+
}
|
|
176
|
+
return SliceKey(workspace, id), nil
|
|
177
|
+
}
|
|
178
|
+
|
|
126
179
|
func validateSlug(slug string) error {
|
|
127
180
|
if !slugRE.MatchString(slug) {
|
|
128
181
|
return fmt.Errorf("invalid slug %q", slug)
|
|
@@ -177,8 +230,11 @@ func ValidateLease(lease *Lease) error {
|
|
|
177
230
|
if len(lease.Slices) < MinParallelSlices {
|
|
178
231
|
return checkParallelSliceCount(len(lease.Slices))
|
|
179
232
|
}
|
|
180
|
-
if
|
|
181
|
-
return
|
|
233
|
+
if err := validateCapacity(lease.Capacity); err != nil {
|
|
234
|
+
return err
|
|
235
|
+
}
|
|
236
|
+
if active := len(activeSlices(lease)); active > leaseCapacity(lease) {
|
|
237
|
+
return fmt.Errorf("parallel requires %d-%d slices active at once (got %d)", MinParallelSlices, leaseCapacity(lease), active)
|
|
182
238
|
}
|
|
183
239
|
if lease.N != len(lease.Slices) {
|
|
184
240
|
return fmt.Errorf("lease n=%d does not match slices=%d", lease.N, len(lease.Slices))
|
|
@@ -188,25 +244,37 @@ func ValidateLease(lease *Lease) error {
|
|
|
188
244
|
if err := validateSliceID(sl.ID); err != nil {
|
|
189
245
|
return fmt.Errorf("slice %d: %w", i, err)
|
|
190
246
|
}
|
|
191
|
-
if
|
|
192
|
-
|
|
247
|
+
if sl.Workspace != "" {
|
|
248
|
+
if err := validateSlug(sl.Workspace); err != nil {
|
|
249
|
+
return fmt.Errorf("slice %d: %w", i, err)
|
|
250
|
+
}
|
|
193
251
|
}
|
|
194
|
-
|
|
195
|
-
if _,
|
|
252
|
+
key := SliceKey(sl.Workspace, sl.ID)
|
|
253
|
+
if _, ok := seen[key]; ok {
|
|
254
|
+
return fmt.Errorf("duplicate slice id %q", key)
|
|
255
|
+
}
|
|
256
|
+
seen[key] = struct{}{}
|
|
257
|
+
if _, err := validateSlicePaths(sl.Paths, fmt.Sprintf("slice %q", key), ""); err != nil {
|
|
196
258
|
return err
|
|
197
259
|
}
|
|
198
260
|
switch sl.WrightStatus {
|
|
199
261
|
case "", WrightPending, WrightGreen, WrightRed, WrightGap, WrightIntegrated:
|
|
200
262
|
default:
|
|
201
|
-
return fmt.Errorf("slice %q: invalid wright_status %q",
|
|
263
|
+
return fmt.Errorf("slice %q: invalid wright_status %q", key, sl.WrightStatus)
|
|
202
264
|
}
|
|
203
265
|
if sl.TransferCommit != "" && !shaRE.MatchString(sl.TransferCommit) {
|
|
204
|
-
return fmt.Errorf("slice %q: invalid transfer_commit %q",
|
|
266
|
+
return fmt.Errorf("slice %q: invalid transfer_commit %q", key, sl.TransferCommit)
|
|
205
267
|
}
|
|
206
268
|
if sl.BaseSHA != "" && !shaRE.MatchString(sl.BaseSHA) {
|
|
207
|
-
return fmt.Errorf("slice %q: invalid base_sha %q",
|
|
269
|
+
return fmt.Errorf("slice %q: invalid base_sha %q", key, sl.BaseSHA)
|
|
208
270
|
}
|
|
209
271
|
}
|
|
272
|
+
if err := validateLanding(lease, lease.PendingLanding, false); err != nil {
|
|
273
|
+
return err
|
|
274
|
+
}
|
|
275
|
+
if err := validateLanding(lease, lease.LastLanding, true); err != nil {
|
|
276
|
+
return err
|
|
277
|
+
}
|
|
210
278
|
return nil
|
|
211
279
|
}
|
|
212
280
|
|
|
@@ -228,11 +296,17 @@ func EmitLeaseMarkdown(lease *Lease) (string, error) {
|
|
|
228
296
|
fmt.Fprintf(&b, "control_tip: %s\n", yamlQuote(lease.ControlTip))
|
|
229
297
|
}
|
|
230
298
|
fmt.Fprintf(&b, "n: %d\n", lease.N)
|
|
299
|
+
if lease.Capacity != 0 {
|
|
300
|
+
fmt.Fprintf(&b, "capacity: %d\n", lease.Capacity)
|
|
301
|
+
}
|
|
231
302
|
fmt.Fprintf(&b, "status: %s\n", yamlQuote(lease.Status))
|
|
232
303
|
fmt.Fprintf(&b, "control_pid_or_session: %s\n", yamlQuote(lease.ControlPIDOrSession))
|
|
233
304
|
b.WriteString("slices:\n")
|
|
234
305
|
for _, sl := range lease.Slices {
|
|
235
306
|
fmt.Fprintf(&b, " - id: %s\n", yamlQuote(sl.ID))
|
|
307
|
+
if sl.Workspace != "" {
|
|
308
|
+
fmt.Fprintf(&b, " workspace: %s\n", yamlQuote(sl.Workspace))
|
|
309
|
+
}
|
|
236
310
|
if len(sl.Paths) == 0 {
|
|
237
311
|
b.WriteString(" paths: []\n")
|
|
238
312
|
} else {
|
|
@@ -299,6 +373,11 @@ func ReadLease(path string) (*Lease, error) {
|
|
|
299
373
|
}
|
|
300
374
|
|
|
301
375
|
func ClearLease(path string) error {
|
|
376
|
+
if lease, err := ReadLease(path); err == nil && lease.PendingLanding != nil {
|
|
377
|
+
return fmt.Errorf("lease-clear refuses pending landing; recover with integrate --apply-to-control or abort")
|
|
378
|
+
} else if err != nil && !os.IsNotExist(err) {
|
|
379
|
+
return err
|
|
380
|
+
}
|
|
302
381
|
err := os.Remove(path)
|
|
303
382
|
if err != nil && !os.IsNotExist(err) {
|
|
304
383
|
return err
|