devrites 7.2.8 → 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 +32 -0
- package/README.md +1 -1
- package/docs/candidate-integrity.md +10 -0
- package/docs/cli.md +7 -1
- package/docs/command-map.md +5 -2
- package/docs/engine/commands.md +28 -4
- package/docs/orchestration.md +26 -13
- package/docs/skills.md +5 -0
- package/engine/internal/acceptance/cli.go +27 -26
- package/engine/internal/acceptance/preconditions.go +1 -1
- package/engine/internal/acceptance/run.go +42 -16
- package/engine/internal/acceptance/transcript.go +236 -45
- package/engine/internal/devritespaths/paths.go +16 -3
- package/engine/internal/gate/gate.go +6 -0
- package/engine/internal/lib/candidate.go +20 -7
- package/engine/internal/lib/candidate_coverage.go +2 -19
- package/engine/internal/lib/closeout.go +16 -4
- package/engine/internal/lib/context.go +64 -45
- package/engine/internal/lib/context_io.go +171 -0
- package/engine/internal/lib/detect.go +8 -8
- package/engine/internal/lib/dispatch.go +2 -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/slicecheck.go +7 -1
- package/engine/internal/lib/taskgraph.go +20 -36
- package/engine/internal/lib/triggers.go +28 -29
- 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/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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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 +1 -1
- 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 +57 -36
- 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
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
package lib
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"crypto/sha256"
|
|
5
|
+
"encoding/hex"
|
|
6
|
+
"errors"
|
|
7
|
+
"fmt"
|
|
8
|
+
"io"
|
|
9
|
+
"os"
|
|
10
|
+
"path/filepath"
|
|
11
|
+
"strings"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
// Binary patches can exceed the candidate's raw-byte bound; stream verification.
|
|
15
|
+
const maxFrozenDiffBytes = 4 * maxCandidateTotalBytes
|
|
16
|
+
|
|
17
|
+
type frozenDiffBinding struct {
|
|
18
|
+
name string
|
|
19
|
+
digest string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
func frozenDiffBindings(raw []byte) ([]frozenDiffBinding, error) {
|
|
23
|
+
var bindings []frozenDiffBinding
|
|
24
|
+
for _, line := range strings.Split(string(raw), "\n") {
|
|
25
|
+
fields := strings.Fields(line)
|
|
26
|
+
if len(fields) == 0 || fields[0] != "diff" {
|
|
27
|
+
continue
|
|
28
|
+
}
|
|
29
|
+
if len(fields) != 3 || len(fields[1]) != sha256.Size*2 || diffPathRE.FindString(fields[2]) != fields[2] {
|
|
30
|
+
return nil, errors.New("malformed diff checksum; use diff <SHA256> <path.diff|path.patch>")
|
|
31
|
+
}
|
|
32
|
+
if _, err := hex.DecodeString(fields[1]); err != nil {
|
|
33
|
+
return nil, errors.New("malformed diff SHA256 checksum")
|
|
34
|
+
}
|
|
35
|
+
bindings = append(bindings, frozenDiffBinding{name: fields[2], digest: strings.ToLower(fields[1])})
|
|
36
|
+
}
|
|
37
|
+
return bindings, nil
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func verifyFrozenDiff(name, expected string) error {
|
|
41
|
+
before, err := os.Lstat(name)
|
|
42
|
+
if err != nil {
|
|
43
|
+
return err
|
|
44
|
+
}
|
|
45
|
+
if !before.Mode().IsRegular() || before.Size() <= 0 {
|
|
46
|
+
return errors.New("frozen candidate diff must be a non-empty regular file")
|
|
47
|
+
}
|
|
48
|
+
if before.Size() > maxFrozenDiffBytes {
|
|
49
|
+
return errors.New("frozen candidate diff exceeds 1 GiB limit")
|
|
50
|
+
}
|
|
51
|
+
// #nosec G304 -- validated regular artifact, bounded streaming read below
|
|
52
|
+
file, err := os.Open(name)
|
|
53
|
+
if err != nil {
|
|
54
|
+
return err
|
|
55
|
+
}
|
|
56
|
+
defer func() { _ = file.Close() }()
|
|
57
|
+
opened, err := file.Stat()
|
|
58
|
+
if err != nil {
|
|
59
|
+
return err
|
|
60
|
+
}
|
|
61
|
+
if !opened.Mode().IsRegular() || !os.SameFile(before, opened) || before.Size() != opened.Size() || !before.ModTime().Equal(opened.ModTime()) {
|
|
62
|
+
return errors.New("frozen candidate diff changed while opening")
|
|
63
|
+
}
|
|
64
|
+
digest := sha256.New()
|
|
65
|
+
count, err := io.Copy(digest, io.LimitReader(file, maxFrozenDiffBytes+1))
|
|
66
|
+
if err != nil {
|
|
67
|
+
return err
|
|
68
|
+
}
|
|
69
|
+
after, err := file.Stat()
|
|
70
|
+
if err != nil {
|
|
71
|
+
return err
|
|
72
|
+
}
|
|
73
|
+
current, err := os.Lstat(name)
|
|
74
|
+
if err != nil {
|
|
75
|
+
return err
|
|
76
|
+
}
|
|
77
|
+
if count != before.Size() || !os.SameFile(opened, current) || after.Size() != count || current.Size() != count || !opened.ModTime().Equal(after.ModTime()) || !opened.ModTime().Equal(current.ModTime()) {
|
|
78
|
+
return errors.New("frozen candidate diff changed while reading")
|
|
79
|
+
}
|
|
80
|
+
if hex.EncodeToString(digest.Sum(nil)) != expected {
|
|
81
|
+
return errors.New("frozen candidate diff SHA256 mismatch; freeze the intended bytes under a new wave")
|
|
82
|
+
}
|
|
83
|
+
return nil
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
func resolvePacketDiff(root, slug, name string) (string, error) {
|
|
87
|
+
clean := filepath.Clean(filepath.FromSlash(name))
|
|
88
|
+
if clean == ".." || strings.HasPrefix(clean, ".."+string(filepath.Separator)) || clean != filepath.FromSlash(name) {
|
|
89
|
+
return "", fmt.Errorf("unsafe frozen candidate diff path %q", name)
|
|
90
|
+
}
|
|
91
|
+
dirs := []string{projectDir(root), featureDir(root, slug)}
|
|
92
|
+
// Freeze's checksum rows use this workspace-relative namespace, never a product packets/ directory.
|
|
93
|
+
if strings.HasPrefix(name, "packets/") {
|
|
94
|
+
dirs = []string{featureDir(root, slug)}
|
|
95
|
+
}
|
|
96
|
+
if filepath.IsAbs(name) {
|
|
97
|
+
parent, err := filepath.EvalSymlinks(filepath.Dir(name))
|
|
98
|
+
if err != nil {
|
|
99
|
+
return "", err
|
|
100
|
+
}
|
|
101
|
+
dirs = []string{parent}
|
|
102
|
+
name = filepath.Base(name)
|
|
103
|
+
}
|
|
104
|
+
for _, dir := range dirs {
|
|
105
|
+
info, exists, err := candidatePathInfo(dir, filepath.ToSlash(name))
|
|
106
|
+
if err != nil {
|
|
107
|
+
return "", err
|
|
108
|
+
}
|
|
109
|
+
if exists {
|
|
110
|
+
if !info.Mode().IsRegular() {
|
|
111
|
+
return "", errors.New("frozen candidate diff is not a regular file")
|
|
112
|
+
}
|
|
113
|
+
parent, err := filepath.EvalSymlinks(dir)
|
|
114
|
+
if err != nil {
|
|
115
|
+
return "", err
|
|
116
|
+
}
|
|
117
|
+
return filepath.Join(parent, filepath.FromSlash(name)), nil
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return "", fmt.Errorf("frozen candidate diff %q does not exist", name)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Caller may already hold the feature lock (dispatch); never acquire it here.
|
|
124
|
+
func lintPacketDiffs(root, slug, packet string, required bool) error {
|
|
125
|
+
raw, err := readBoundedRegularFile(packet, maxContractBytes)
|
|
126
|
+
if err != nil {
|
|
127
|
+
return fmt.Errorf("reviewer packet %s: %w", packet, err)
|
|
128
|
+
}
|
|
129
|
+
bindings, err := frozenDiffBindings(raw)
|
|
130
|
+
if err != nil {
|
|
131
|
+
return err
|
|
132
|
+
}
|
|
133
|
+
bound := make(map[string]string, len(bindings))
|
|
134
|
+
for _, binding := range bindings {
|
|
135
|
+
path, err := resolvePacketDiff(root, slug, binding.name)
|
|
136
|
+
if err != nil {
|
|
137
|
+
return err
|
|
138
|
+
}
|
|
139
|
+
if prior, ok := bound[path]; ok {
|
|
140
|
+
if prior != binding.digest {
|
|
141
|
+
return fmt.Errorf("conflicting diff checksums for %s", binding.name)
|
|
142
|
+
}
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
145
|
+
if err := verifyFrozenDiff(path, binding.digest); err != nil {
|
|
146
|
+
return fmt.Errorf("%s: %w", binding.name, err)
|
|
147
|
+
}
|
|
148
|
+
bound[path] = binding.digest
|
|
149
|
+
}
|
|
150
|
+
var names []string
|
|
151
|
+
for _, line := range strings.Split(string(raw), "\n") {
|
|
152
|
+
if entry, candidate := strings.CutPrefix(line, "file "); candidate {
|
|
153
|
+
identity, path, complete := strings.Cut(entry, " ")
|
|
154
|
+
// Candidate file identities describe product paths, not reviewer inputs.
|
|
155
|
+
if complete && path != "" {
|
|
156
|
+
if identity == "absent" {
|
|
157
|
+
continue
|
|
158
|
+
}
|
|
159
|
+
if digest, err := hex.DecodeString(identity); err == nil && len(digest) == sha256.Size {
|
|
160
|
+
continue
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
names = append(names, diffPathRE.FindAllString(line, -1)...)
|
|
165
|
+
}
|
|
166
|
+
if required && len(names) == 0 {
|
|
167
|
+
return errors.New("a Review or Seal reviewer packet must name the frozen candidate diff and bind its bytes with diff <SHA256> <path.diff|path.patch>")
|
|
168
|
+
}
|
|
169
|
+
for _, name := range names {
|
|
170
|
+
path, err := resolvePacketDiff(root, slug, name)
|
|
171
|
+
if err != nil {
|
|
172
|
+
return err
|
|
173
|
+
}
|
|
174
|
+
if _, ok := bound[path]; !ok {
|
|
175
|
+
return fmt.Errorf("unbound frozen candidate diff %s; add diff <SHA256> %s to the packet", name, name)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return nil
|
|
179
|
+
}
|
|
@@ -180,7 +180,7 @@ func pathSetIdentity(project string, paths []string) (candidateIdentity, error)
|
|
|
180
180
|
if err != nil {
|
|
181
181
|
return candidateIdentity{}, err
|
|
182
182
|
}
|
|
183
|
-
digest, err := hashCandidate(project, rows)
|
|
183
|
+
digest, err := hashCandidate(project, rows, false)
|
|
184
184
|
return candidateIdentity{digest: digest, rows: rows}, err
|
|
185
185
|
}
|
|
186
186
|
|
|
@@ -244,7 +244,7 @@ func runPerturbProbe(project string, identity candidateIdentity, gate *acceptanc
|
|
|
244
244
|
probe.reason = "candidate copy failed: " + oneLine(err.Error())
|
|
245
245
|
return probe
|
|
246
246
|
}
|
|
247
|
-
if probe.copyStart, err = hashCandidate(base, rows); err != nil || probe.copyStart != identity.digest {
|
|
247
|
+
if probe.copyStart, err = hashCandidate(base, rows, false); err != nil || probe.copyStart != identity.digest {
|
|
248
248
|
probe.reason = "the isolated copy does not hash to the candidate digest"
|
|
249
249
|
return probe
|
|
250
250
|
}
|
|
@@ -267,7 +267,7 @@ func runPerturbProbe(project string, identity candidateIdentity, gate *acceptanc
|
|
|
267
267
|
return probe
|
|
268
268
|
}
|
|
269
269
|
if err := validateCandidateRows(base, rows); err == nil {
|
|
270
|
-
probe.copyRestored, _ = hashCandidate(base, rows)
|
|
270
|
+
probe.copyRestored, _ = hashCandidate(base, rows, false)
|
|
271
271
|
}
|
|
272
272
|
if probe.copyRestored != identity.digest {
|
|
273
273
|
probe.reason = "the reverted copy does not hash to the candidate digest"
|
|
@@ -7,6 +7,7 @@ import (
|
|
|
7
7
|
"regexp"
|
|
8
8
|
"strings"
|
|
9
9
|
|
|
10
|
+
"github.com/devrites/devrites/internal/markdowntext"
|
|
10
11
|
"github.com/devrites/devrites/internal/state"
|
|
11
12
|
)
|
|
12
13
|
|
|
@@ -21,7 +22,7 @@ import (
|
|
|
21
22
|
// 0 contract holds 2 usage error 3 blocked: problems listed
|
|
22
23
|
|
|
23
24
|
var (
|
|
24
|
-
sliceFieldRe = regexp.MustCompile(`(?m)^([A-Za-z][A-Za-z /_-]*)
|
|
25
|
+
sliceFieldRe = regexp.MustCompile(`(?m)^([A-Za-z][A-Za-z /_-]*):[ \t]*(.*)$`)
|
|
25
26
|
sliceACRe = regexp.MustCompile(`\bAC-\d+\b`)
|
|
26
27
|
pathGlobCharRe = regexp.MustCompile(`[*?\[\]{}]`)
|
|
27
28
|
pathTraversalRe = regexp.MustCompile(`(^|/)\.\.(/|$)`)
|
|
@@ -48,6 +49,11 @@ func sliceSizeAdvisory(block string) (int, bool) {
|
|
|
48
49
|
// sliceFields extracts the single-line `Field: value` pairs of a slice block.
|
|
49
50
|
func sliceFields(block string) map[string]string {
|
|
50
51
|
fields := map[string]string{}
|
|
52
|
+
structural, err := markdowntext.Structural([]byte(block))
|
|
53
|
+
if err != nil {
|
|
54
|
+
return fields
|
|
55
|
+
}
|
|
56
|
+
block = string(structural)
|
|
51
57
|
for _, m := range sliceFieldRe.FindAllStringSubmatch(block, -1) {
|
|
52
58
|
key := strings.ToLower(strings.TrimSpace(m[1]))
|
|
53
59
|
if _, seen := fields[key]; !seen {
|
|
@@ -201,34 +201,10 @@ func PrecheckSkips(root, slug, slice string, gateIDs []string) (map[string]strin
|
|
|
201
201
|
// manifest and lockfile when it declares external dependencies. root is the
|
|
202
202
|
// .devrites directory.
|
|
203
203
|
func planReady(root, slug string) ([]parallel.SlicePaths, error) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
graph := ParseTaskGraph(raw)
|
|
209
|
-
if len(graph.Problems) > 0 {
|
|
210
|
-
return nil, fmt.Errorf("tasks.md: %s", strings.Join(graph.Problems, "; "))
|
|
211
|
-
}
|
|
212
|
-
built, err := builtSlices(root, slug)
|
|
213
|
-
if err != nil {
|
|
214
|
-
return nil, err
|
|
215
|
-
}
|
|
216
|
-
isBuilt := func(id string) bool { return built[sliceNumber(id)] }
|
|
217
|
-
paths, _ := sliceWritePaths(raw, graph)
|
|
218
|
-
project := filepath.Dir(root)
|
|
219
|
-
var ready []parallel.SlicePaths
|
|
220
|
-
for _, s := range graph.Slices {
|
|
221
|
-
if isBuilt(s.ID) || slices.ContainsFunc(s.Dependencies, func(dep string) bool { return !isBuilt(dep) }) {
|
|
222
|
-
continue
|
|
223
|
-
}
|
|
224
|
-
if len(paths[s.ID]) == 0 {
|
|
225
|
-
return nil, fmt.Errorf("%s has no Writer allowlist or Files likely touched", s.ID)
|
|
226
|
-
}
|
|
227
|
-
block, _ := state.ExtractTaskSlice(raw, s.ID)
|
|
228
|
-
external, _ := fieldValue(sliceFields(block), "external dependencies")
|
|
229
|
-
ready = append(ready, parallel.SlicePaths{ID: s.ID, Paths: withManifests(project, paths[s.ID], external)})
|
|
230
|
-
}
|
|
231
|
-
return ready, nil
|
|
204
|
+
ready, _, err := workspacePlanReady(root, slug, false, func(name string) ([]byte, error) {
|
|
205
|
+
return readWorkspaceArtifact(root, slug, name)
|
|
206
|
+
})
|
|
207
|
+
return ready, err
|
|
232
208
|
}
|
|
233
209
|
|
|
234
210
|
// builtWordRe marks a checked state.md item as a built checkpoint.
|
|
@@ -240,7 +216,13 @@ var builtWordRe = regexp.MustCompile(`(?i)\bbuilt\b`)
|
|
|
240
216
|
// was checkpointed and whose section has a `Checkpoint: <sha>` line — a missed
|
|
241
217
|
// checkbox must not keep dependents out of the ready set.
|
|
242
218
|
func builtSlices(root, slug string) (map[string]bool, error) {
|
|
243
|
-
|
|
219
|
+
return builtSlicesFrom(func(name string) ([]byte, error) {
|
|
220
|
+
return readWorkspaceArtifact(root, slug, name)
|
|
221
|
+
})
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
func builtSlicesFrom(read func(string) ([]byte, error)) (map[string]bool, error) {
|
|
225
|
+
raw, err := read("state.md")
|
|
244
226
|
if err != nil {
|
|
245
227
|
return nil, err
|
|
246
228
|
}
|
|
@@ -257,7 +239,7 @@ func builtSlices(root, slug string) (map[string]bool, error) {
|
|
|
257
239
|
built[strings.TrimLeft(m[1], "0")] = true
|
|
258
240
|
}
|
|
259
241
|
}
|
|
260
|
-
extra, err :=
|
|
242
|
+
extra, err := evidenceBuiltFrom(read)
|
|
261
243
|
if err != nil {
|
|
262
244
|
return nil, err
|
|
263
245
|
}
|
|
@@ -273,9 +255,9 @@ var (
|
|
|
273
255
|
checkpointSHARe = regexp.MustCompile(`(?m)^[ \t]*Checkpoint: [0-9a-fA-F]{7,40}\b`)
|
|
274
256
|
)
|
|
275
257
|
|
|
276
|
-
//
|
|
277
|
-
func
|
|
278
|
-
raw, err :=
|
|
258
|
+
// evidenceBuiltFrom reads evidence.md checkpoint sections. A missing file is none.
|
|
259
|
+
func evidenceBuiltFrom(read func(string) ([]byte, error)) (map[string]bool, error) {
|
|
260
|
+
raw, err := read("evidence.md")
|
|
279
261
|
if err != nil {
|
|
280
262
|
if errors.Is(err, os.ErrNotExist) {
|
|
281
263
|
return map[string]bool{}, nil
|
|
@@ -421,9 +403,11 @@ func planBatch(root, slug string, capN int) (eligible, batch []string, err error
|
|
|
421
403
|
return nil, nil, err
|
|
422
404
|
}
|
|
423
405
|
ids := func(in []parallel.SlicePaths) []string {
|
|
424
|
-
out
|
|
425
|
-
for
|
|
426
|
-
|
|
406
|
+
var out []string
|
|
407
|
+
for _, s := range in {
|
|
408
|
+
if s.Workspace == "" || s.Workspace == slug {
|
|
409
|
+
out = append(out, s.ID)
|
|
410
|
+
}
|
|
427
411
|
}
|
|
428
412
|
return out
|
|
429
413
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
package lib
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
|
-
"
|
|
4
|
+
"errors"
|
|
5
5
|
"os"
|
|
6
|
-
"path/filepath"
|
|
7
6
|
"regexp"
|
|
8
7
|
"slices"
|
|
9
8
|
"sort"
|
|
@@ -82,8 +81,7 @@ var triggerSignals = []struct {
|
|
|
82
81
|
|
|
83
82
|
// suggestTriggers returns declared, unselected trigger names whose firing facts
|
|
84
83
|
// hold in this workspace. Sorted for stable output.
|
|
85
|
-
func suggestTriggers(manifest loadsManifest,
|
|
86
|
-
facts := gatherTriggerFacts(root, featureDir, opts.role)
|
|
84
|
+
func suggestTriggers(manifest loadsManifest, opts contextOpts, facts triggerFacts) []string {
|
|
87
85
|
var suggested []string
|
|
88
86
|
for name := range manifest.Triggers {
|
|
89
87
|
if slices.Contains(opts.triggers, name) {
|
|
@@ -101,45 +99,46 @@ func suggestTriggers(manifest loadsManifest, root, featureDir string, opts conte
|
|
|
101
99
|
return suggested
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
func gatherTriggerFacts(root,
|
|
102
|
+
func gatherTriggerFacts(root, role string, sources *contextSources) (triggerFacts, error) {
|
|
105
103
|
facts := triggerFacts{role: roleBase(role)}
|
|
106
104
|
if root != "" {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
facts.afkParallel = afkAllowsParallel(string(data))
|
|
112
|
-
}
|
|
105
|
+
sentinels := contextSources{dir: root}
|
|
106
|
+
data, err := sentinels.read("AFK")
|
|
107
|
+
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
108
|
+
return facts, err
|
|
113
109
|
}
|
|
114
|
-
|
|
115
|
-
|
|
110
|
+
facts.afk = err == nil
|
|
111
|
+
facts.afkParallel = afkAllowsParallel(string(data))
|
|
112
|
+
_, err = sentinels.read("principles.md")
|
|
113
|
+
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
114
|
+
return facts, err
|
|
116
115
|
}
|
|
116
|
+
facts.principles = err == nil
|
|
117
117
|
}
|
|
118
|
-
if
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
if sources.dir != "" {
|
|
119
|
+
_, err := sources.read("ai-spec.md")
|
|
120
|
+
if err != nil && !errors.Is(err, os.ErrNotExist) {
|
|
121
|
+
return facts, err
|
|
121
122
|
}
|
|
123
|
+
facts.aiSpec = err == nil
|
|
122
124
|
var corpus strings.Builder
|
|
123
125
|
for _, name := range triggerEvidenceFiles {
|
|
124
|
-
|
|
125
|
-
info, err := os.Stat(path)
|
|
126
|
-
if err != nil || !info.Mode().IsRegular() {
|
|
127
|
-
continue
|
|
128
|
-
}
|
|
129
|
-
f, err := os.Open(path) // #nosec G304 -- workspace artifact; read is capped below
|
|
126
|
+
data, err := sources.read(name)
|
|
130
127
|
if err != nil {
|
|
131
|
-
|
|
128
|
+
if errors.Is(err, os.ErrNotExist) {
|
|
129
|
+
continue
|
|
130
|
+
}
|
|
131
|
+
return facts, err
|
|
132
132
|
}
|
|
133
|
-
data
|
|
134
|
-
|
|
135
|
-
if err == nil {
|
|
136
|
-
corpus.Write(data)
|
|
137
|
-
corpus.WriteByte('\n')
|
|
133
|
+
if len(data) > triggerEvidenceFileCap {
|
|
134
|
+
data = data[:triggerEvidenceFileCap]
|
|
138
135
|
}
|
|
136
|
+
corpus.Write(data)
|
|
137
|
+
corpus.WriteByte('\n')
|
|
139
138
|
}
|
|
140
139
|
facts.corpus = strings.ToLower(corpus.String())
|
|
141
140
|
}
|
|
142
|
-
return facts
|
|
141
|
+
return facts, nil
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
var afkParallelRe = regexp.MustCompile(`(?m)^\s*max_parallel\s*:\s*([0-9]+)\s*$`)
|