@joshuafolkken/kit 1.1784.0 → 1.2114.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/.claude/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/workflow-commands/SKILL.md +6 -6
- package/.claude/skills/workflow-commands/background-commands.md +8 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +41 -32
- package/.claude/skills/workflow-commands/delegation.md +6 -6
- package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +7 -5
- package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
- package/.claude/skills/workflow-commands/fullrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +9 -4
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -2
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
- package/.claude/skills/workflow-commands/prerequisite.md +3 -2
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +7 -5
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-pnpm/action.yml +9 -16
- package/.github/dependabot.yml +16 -0
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +155 -15
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +59 -45
- package/.vscode/settings.json +19 -0
- package/CLAUDE.md +5 -12
- package/SECURITY.md +2 -2
- package/dist/CLAUDE.md +5 -12
- package/dist/commands/document-read-cli.js +2 -1
- package/dist/commands/document-section-main.js +2 -1
- package/dist/commands/read-set-cli.js +194 -134
- package/dist/commands/run-prep-main.js +9694 -10173
- package/dist/commands/run-step-cli.js +22138 -18285
- package/dist/hooks/audit-provision.js +23 -5
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
- package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
- package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
- package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +8 -8
- package/dist/hooks/format-edited.js +4 -5
- package/dist/hooks/inputs.json +415 -389
- package/dist/hooks/pretool-guard.js +7 -6
- package/dist/hooks/session-lang.js +101 -258
- package/dist/hooks/stop-guard.js +1744 -2576
- package/dist/josh.js +7133 -6368
- package/dist/version/index.js +161 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/package.json +15 -8
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +14 -11
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +40 -21
- package/prompts/collaboration-workflow/lane-instructions.md +3 -1
- package/prompts/collaboration-workflow/measurement.md +8 -1
- package/prompts/collaboration-workflow/operating-rules.md +11 -2
- package/prompts/collaboration-workflow/output-bounds.md +6 -2
- package/prompts/collaboration-workflow/plan-comment.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
- package/prompts/collaboration-workflow/wip-cap.md +3 -1
- package/prompts/review-rubric.md +8 -0
- package/prompts/review.md +31 -22
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +20 -9
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-cli.ts +6 -1
- package/scripts/backlog/backlog-drive-hold.ts +3 -3
- package/scripts/backlog/backlog-drive-idle.ts +10 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
- package/scripts/backlog/backlog-drive-named.ts +28 -7
- package/scripts/backlog/backlog-drive-paused.ts +5 -4
- package/scripts/backlog/backlog-drive-restore.ts +11 -3
- package/scripts/backlog/backlog-drive.ts +21 -60
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next.ts +39 -49
- package/scripts/backlog/backlog-occupied.ts +2 -2
- package/scripts/backlog/backlog-overlap.ts +42 -8
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +19 -6
- package/scripts/backlog/backlog-pool.ts +50 -12
- package/scripts/backlog/backlog-rank.ts +60 -13
- package/scripts/backlog/backlog-stalled-detect.ts +2 -1
- package/scripts/backlog/backlog-waves.ts +17 -2
- package/scripts/backlog/backlogrun-launch.ts +7 -4
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-cli.ts +37 -16
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +2 -2
- package/scripts/delegation/duplicate-read-guard.ts +1 -0
- package/scripts/delegation/investigation-guard.ts +14 -2
- package/scripts/delegation/investigation-reads.ts +45 -23
- package/scripts/dependabot/dependabot-cooldown.ts +3 -2
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +17 -7
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-cli-argv.ts +2 -2
- package/scripts/epic/epic-fetch.ts +4 -2
- package/scripts/epic/epic-graph.ts +7 -2
- package/scripts/epic/epic-issue.ts +3 -1
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +13 -10
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +41 -11
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
- package/scripts/followup/git-pr-followup.ts +62 -27
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
- package/scripts/gate/busy-average.ts +34 -2
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/command-memory.ts +1 -1
- package/scripts/gate/core-admission.ts +24 -6
- package/scripts/gate/core-budget-timing.ts +20 -6
- package/scripts/gate/core-budget.ts +40 -11
- package/scripts/gate/core-wait-record.ts +3 -2
- package/scripts/gate/core-wait.ts +25 -2
- package/scripts/gate/core-weights.ts +15 -7
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +14 -6
- package/scripts/gate/gate-plan.ts +103 -58
- package/scripts/gate/gate-report.ts +9 -7
- package/scripts/gate/gate-run-steps.ts +26 -3
- package/scripts/gate/gate-skip.ts +45 -6
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +2 -1
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/scoped-green.ts +68 -15
- package/scripts/gate/since-green.ts +14 -6
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/verification-gate.ts +51 -16
- package/scripts/gate/verification-inputs.ts +21 -6
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +23 -2
- package/scripts/gh/git-ai-review-scan.ts +1 -1
- package/scripts/gh/git-gh-api-path.ts +12 -3
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +4 -2
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +8 -2
- package/scripts/gh/git-gh-issue.ts +12 -5
- package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +3 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +21 -7
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +3 -0
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/git/base-tree.ts +30 -0
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +16 -1
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +66 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-schemas.ts +13 -0
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +53 -5
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +11 -2
- package/scripts/git/stash/stash-push-cli.ts +10 -0
- package/scripts/hooks/batch-guard.ts +40 -21
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +22 -2
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +14 -1
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +76 -10
- package/scripts/hooks/pretool-guard.ts +2 -0
- package/scripts/hooks/reserved-run.ts +14 -1
- package/scripts/hooks/run-hook.sh +23 -8
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +3 -15
- package/scripts/hooks/stop-guard.ts +7 -6
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +5 -1
- package/scripts/init/hook-launch.ts +4 -2
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-line.ts +19 -1
- package/scripts/issue/defect-rate-cli.ts +5 -102
- package/scripts/issue/defect-report.ts +4 -4
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +64 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-body-or-comment.ts +38 -4
- package/scripts/issue/issue-cite-cli.ts +1 -3
- package/scripts/issue/issue-classification.ts +1 -0
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-evidence-exit.ts +4 -2
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +111 -38
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +43 -6
- package/scripts/issue/issue-labels.ts +19 -2
- package/scripts/issue/issue-lint-cli.ts +27 -2
- package/scripts/issue/issue-measured-cli.ts +13 -35
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-not-before-label.ts +2 -2
- package/scripts/issue/issue-not-before.ts +4 -1
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +174 -43
- package/scripts/issue/issue-rank.ts +21 -4
- package/scripts/issue/issue-read-cli.ts +32 -6
- package/scripts/issue/issue-read.ts +37 -12
- package/scripts/issue/issue-sample-gate.ts +95 -74
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +12 -11
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +31 -1
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -12
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -70
- package/scripts/issue/plan-consumers-section.ts +22 -1
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/command-usage.ts +3 -2
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -82
- package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
- package/scripts/josh/josh-commands-ai.ts +5 -5
- package/scripts/josh/josh-commands-development.ts +59 -58
- package/scripts/josh/josh-commands-issue-write.ts +23 -4
- package/scripts/josh/josh-commands-issue.ts +32 -0
- package/scripts/josh/josh-commands-lane.ts +87 -4
- package/scripts/josh/josh-commands-lint.ts +16 -3
- package/scripts/josh/josh-commands-maintenance.ts +15 -0
- package/scripts/josh/josh-commands-review.ts +41 -6
- package/scripts/josh/josh-commands-ship.ts +56 -8
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +5 -3
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/stamp-file.ts +11 -2
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +5 -8
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-check-stats.ts +29 -8
- package/scripts/lane/lane-child-invocation.ts +9 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-close.ts +8 -3
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +2 -2
- package/scripts/lane/lane-gap-stats.ts +7 -6
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +119 -36
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +31 -177
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +176 -59
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +16 -7
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +4 -1
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-registry.ts +14 -1
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-sampler.ts +23 -4
- package/scripts/lane/lane-session-action.ts +93 -18
- package/scripts/lane/lane-session-broker.ts +49 -21
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-spent.ts +1 -1
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +13 -1
- package/scripts/lane/lane-state.ts +41 -9
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +21 -5
- package/scripts/lane/lane-stop-stats.ts +51 -19
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-transcript-calls.ts +67 -10
- package/scripts/lane/lane-transcript-stats.ts +44 -12
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +108 -31
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +45 -6
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/import-graph.ts +141 -11
- package/scripts/lint/lint-gate-scope.ts +2 -2
- package/scripts/lint/lint-parallel.ts +54 -6
- package/scripts/lint/lint-related.ts +154 -33
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/telegram-notify.ts +12 -3
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush.ts +32 -9
- package/scripts/overrides/overrides-check.ts +9 -1
- package/scripts/release/release-approval-prune.ts +7 -1
- package/scripts/repo/required-checks-logic.ts +4 -1
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +15 -1
- package/scripts/report/report-labels.ts +12 -1
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +26 -7
- package/scripts/report/report-lint.ts +2 -20
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +68 -19
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +14 -7
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +85 -22
- package/scripts/review/review-finding-ledger.ts +109 -7
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +11 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +4 -2
- package/scripts/review/review-record-cli.ts +177 -54
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +91 -29
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +24 -8
- package/scripts/review/review-stamps.ts +7 -3
- package/scripts/review/review-stop-log.ts +20 -6
- package/scripts/review/review-stops-cli.ts +2 -1
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/rules/agent-model.ts +1 -1
- package/scripts/rules/bash-triggers.ts +3 -3
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle.ts +1 -1
- package/scripts/rules/delivered-rules.ts +36 -17
- package/scripts/rules/destructive-command.ts +3 -11
- package/scripts/rules/direct-issue-comment.ts +34 -12
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +4 -24
- package/scripts/rules/early-heartbeat.ts +2 -0
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/guard-remedy.ts +14 -5
- package/scripts/rules/implementation-cut.ts +61 -28
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +9 -4
- package/scripts/rules/josh-git-bare.ts +1 -1
- package/scripts/rules/lane-background.ts +41 -13
- package/scripts/rules/lane-direct-tool.ts +107 -9
- package/scripts/rules/lane-interactive-ask.ts +4 -1
- package/scripts/rules/lane-park.ts +4 -2
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +1 -1
- package/scripts/rules/lane-switch-main.ts +4 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/permission-guards.ts +5 -1
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +67 -17
- package/scripts/rules/poll-loop.ts +72 -9
- package/scripts/rules/pr-merge.ts +5 -5
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +88 -24
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +5 -15
- package/scripts/rules/rule-value-cache.ts +53 -5
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +59 -11
- package/scripts/rules/rule-value.ts +17 -4
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +10 -2
- package/scripts/rules/stop-rule-rows.ts +1 -13
- package/scripts/rules/stop-rules.ts +33 -58
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +110 -23
- package/scripts/rules/timed-rerun.ts +1 -1
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +22 -7
- package/scripts/run/board/run-board-ending-reason.ts +6 -2
- package/scripts/run/board/run-board-fit.ts +24 -1
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-header.ts +8 -0
- package/scripts/run/board/run-board-labels.ts +11 -1
- package/scripts/run/board/run-board-lane-time.ts +1 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-notes.ts +7 -1
- package/scripts/run/board/run-board-operation.ts +4 -2
- package/scripts/run/board/run-board-phase.ts +2 -5
- package/scripts/run/board/run-board-plan.ts +1 -1
- package/scripts/run/board/run-board-read.ts +46 -1
- package/scripts/run/board/run-board-reason.ts +20 -8
- package/scripts/run/board/run-board-render-checks.ts +3 -2
- package/scripts/run/board/run-board-render-drawn.ts +11 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-render-legend.ts +19 -0
- package/scripts/run/board/run-board-render-tail.ts +1 -1
- package/scripts/run/board/run-board-render.ts +82 -18
- package/scripts/run/board/run-board-spin.ts +1 -3
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +39 -10
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +3 -2
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +52 -8
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-filed.ts +9 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +4 -0
- package/scripts/run/event/run-event-stream.ts +25 -3
- package/scripts/run/hold/run-stop-notify.ts +3 -8
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +66 -23
- package/scripts/run/merge/run-merge-outcome.ts +2 -0
- package/scripts/run/merge/run-merge-ship.ts +13 -3
- package/scripts/run/merge/run-merge-signals.ts +40 -23
- package/scripts/run/merge/run-merge-steps.ts +56 -36
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +41 -14
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +26 -6
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-prep.ts +1 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/ship/run-ship-args.ts +19 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +131 -39
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +10 -4
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +27 -26
- package/scripts/run/ship/run-ship-overlap.ts +8 -3
- package/scripts/run/ship/run-ship-place.ts +9 -2
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
- package/scripts/run/ship/run-ship-preflight.ts +16 -4
- package/scripts/run/ship/run-ship-probe.ts +23 -9
- package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-return.ts +103 -29
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +230 -59
- package/scripts/run/ship/run-ship-review.ts +171 -51
- package/scripts/run/ship/run-ship-reviewer.ts +138 -42
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +49 -13
- package/scripts/run/ship/run-ship-steps.ts +24 -4
- package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-sync.ts +171 -30
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +16 -2
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +6 -113
- package/scripts/run/wake/run-wake-code.ts +53 -11
- package/scripts/run/wake/run-wake-driver.ts +5 -3
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +5 -3
- package/scripts/run/wake/run-wake-ports.ts +11 -3
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake.ts +3 -2
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/project-config.ts +3 -2
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-provision-main.ts +9 -1
- package/scripts/security/security-audit-provision.ts +1 -1
- package/scripts/security/security-audit.ts +21 -1
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/split/split-assess.ts +12 -3
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +20 -2
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +208 -20
- package/scripts/test/test-pinned-main.ts +84 -18
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +258 -47
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +35 -11
- package/scripts/test/test-read-recording.ts +17 -5
- package/scripts/test/test-read-trace.ts +26 -8
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red.ts +34 -14
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +4 -1
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +43 -23
- package/scripts/test/test-related-scope.ts +99 -34
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +167 -83
- package/scripts/test/test-unit-guard.ts +28 -5
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-worker-share.ts +5 -4
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +12 -1
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +36 -5
- package/scripts/time-runtime/time-markers.ts +2 -2
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +17 -5
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/latest-corepack.ts +2 -0
- package/templates/gitignore +2 -0
- package/templates/workflows/ci.yml +41 -0
- package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
- package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
- package/dist/hooks/chunk-TUIFS5E7.js +0 -72
- package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/rules/filing-cap.ts +0 -139
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
2
|
+
import { review_attest, type ReviewSlot } from '#scripts/review/review-attest'
|
|
2
3
|
import { review_finding_ledger } from '#scripts/review/review-finding-ledger'
|
|
4
|
+
import { review_finding_text } from '#scripts/review/review-finding-text'
|
|
5
|
+
import { review_prior_findings } from '#scripts/review/review-prior-findings'
|
|
3
6
|
import { review_record_cli } from '#scripts/review/review-record-cli'
|
|
4
7
|
|
|
5
8
|
// The pure half of `josh ship --review`: the one-line prompts the supervised reviewers are launched
|
|
@@ -24,17 +27,14 @@ const HIGH = 'high'
|
|
|
24
27
|
const MEDIUM = 'medium'
|
|
25
28
|
const FIXED_PREFIX = 'fixed '
|
|
26
29
|
const KIND_FIELDS = 2
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const SENTENCE_END = /(?<=[.!?])\s|(?<=。)/u
|
|
36
|
-
const SENTENCE_LIMIT = 200
|
|
37
|
-
const ELLIPSIS = '…'
|
|
30
|
+
// `findings_path` is set only for a lane whose josh predates `review:submit`
|
|
31
|
+
// (`lane-session-action.ts`).
|
|
32
|
+
type PromptOf = (
|
|
33
|
+
brief_path: string,
|
|
34
|
+
slot: ReviewSlot,
|
|
35
|
+
issue: string,
|
|
36
|
+
findings_path?: string,
|
|
37
|
+
) => string
|
|
38
38
|
|
|
39
39
|
const VERDICT = {
|
|
40
40
|
CLEAN: 'clean',
|
|
@@ -78,24 +78,68 @@ const MISSING_NOTE = 'the reviewer wrote no findings file — the review did not
|
|
|
78
78
|
const CLEAN_NOTE = 'review clean or Low-only — recorded; shipping on.'
|
|
79
79
|
const FIXED_NOTE =
|
|
80
80
|
'review fixes applied in place — recorded; the gate re-runs on the fixed tree and round 2 follows the commit.'
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
// Every stop that hands findings back for a fix: a fix of only the cited line left the same pattern
|
|
82
|
+
// beside it for the next round to stop on again (joshuafolkken/kit#4673).
|
|
83
|
+
const SWEEP_INSTRUCTION = [
|
|
84
|
+
'Before fixing, sweep each finding for its other sites — the same file, the callers of the same',
|
|
85
|
+
'function and a grep of the pattern — fix every site in one pass, and list each range searched on its',
|
|
86
|
+
'own line in the Issue fix comment.',
|
|
87
|
+
].join(' ')
|
|
88
|
+
const BLOCKING_NOTE = `review found High/Medium it did not fix — recorded. ${SWEEP_INSTRUCTION} Then take the round-2 route (\`chain-rule.md\`).`
|
|
83
89
|
const UNVERIFIED_OUTCOME: RoundOutcome = {
|
|
84
90
|
is_passing: false,
|
|
85
|
-
note:
|
|
91
|
+
note: `review fixes did not pass the scoped checks — recorded as unfixed. ${SWEEP_INSTRUCTION} Then take the round-2 route (\`chain-rule.md\`).`,
|
|
86
92
|
}
|
|
93
|
+
// The findings line is all a stopped ship hands the lane, so the other sites the rubric asks the
|
|
94
|
+
// reviewer to cite ride on it rather than in its prose report (joshuafolkken/kit#4673).
|
|
95
|
+
const OTHER_SITES_CLAUSE = '"other sites: <file>:<line>, …" for each other site of the same pattern'
|
|
87
96
|
const ROUND_TWO_CLEAN_NOTE = 'round 2 clean or Low-only — recorded; shipping on.'
|
|
88
|
-
const
|
|
89
|
-
|
|
97
|
+
const SUBMIT_COMMAND = 'pnpm josh review:submit'
|
|
98
|
+
const ROUND_TWO_BLOCKING_NOTE = `round 2 found High/Medium or edited the tree — recorded; round 2 is final. ${SWEEP_INSTRUCTION} Then push and gate it, and run followup (\`chain-rule.md\` step 4).`
|
|
99
|
+
|
|
100
|
+
// **The reviewer hands its findings to a command, never to a path it copies** (joshuafolkken/kit#4799):
|
|
101
|
+
// a reviewer that copied the findings path matched the `josh-review-*` files beside it and dropped
|
|
102
|
+
// `ship-`, so the supervisor never read a review it had finished. `review:submit` knows the slot's path.
|
|
103
|
+
function submit_command(slot: ReviewSlot): string {
|
|
104
|
+
return slot === review_attest.REVIEW_SLOT.CODE
|
|
105
|
+
? SUBMIT_COMMAND
|
|
106
|
+
: `${SUBMIT_COMMAND} --interaction`
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// **A lane whose josh predates `review:submit` is handed the path**: the supervisor reloads onto main
|
|
110
|
+
// at its pass boundary (`run-wake-code.ts`), so it meets lanes branched before the command existed.
|
|
111
|
+
function sink_clauses(
|
|
112
|
+
slot: ReviewSlot,
|
|
113
|
+
findings_path: string | undefined,
|
|
114
|
+
): readonly [string, string] {
|
|
115
|
+
if (findings_path !== undefined) {
|
|
116
|
+
return [
|
|
117
|
+
`Then write every finding to ${findings_path},`,
|
|
118
|
+
'and an empty file when there is none.',
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return [
|
|
123
|
+
`Then pipe every finding on stdin to \`${submit_command(slot)}\` — never write a findings file yourself —`,
|
|
124
|
+
'or run it with `--none` and no stdin when there is none; if it refuses a line, fix that line and run it again.',
|
|
125
|
+
]
|
|
126
|
+
}
|
|
90
127
|
|
|
91
|
-
function findings_instruction(
|
|
128
|
+
function findings_instruction(
|
|
129
|
+
slot: ReviewSlot,
|
|
130
|
+
fixed_clause: string,
|
|
131
|
+
findings_path: string | undefined,
|
|
132
|
+
): string {
|
|
92
133
|
const categories = review_finding_ledger.CATEGORIES.join(', ')
|
|
134
|
+
const [opening, closing] = sink_clauses(slot, findings_path)
|
|
93
135
|
|
|
94
136
|
return [
|
|
95
|
-
|
|
96
|
-
|
|
137
|
+
opening,
|
|
138
|
+
'one per line as',
|
|
139
|
+
`<category>:<severity>:<file>[:<line>]${review_finding_text.DESCRIPTION_SEPARATOR}<one sentence: what is wrong and why>`,
|
|
97
140
|
`(category one of ${categories}; severity high, medium or low)${fixed_clause},`,
|
|
98
|
-
|
|
141
|
+
`a high or medium line ending with ${OTHER_SITES_CLAUSE},`,
|
|
142
|
+
closing,
|
|
99
143
|
].join(' ')
|
|
100
144
|
}
|
|
101
145
|
|
|
@@ -109,56 +153,99 @@ function issue_read_instruction(issue: string): string {
|
|
|
109
153
|
].join(' ')
|
|
110
154
|
}
|
|
111
155
|
|
|
156
|
+
// **The review runs in this session itself** (joshuafolkken/kit#4715): a reviewer that invoked the
|
|
157
|
+
// `/code-review` skill forked a second agent that read the same diff and brief again. The session is
|
|
158
|
+
// launched without the `Skill` and `Agent` tools (`claude-agent-argv.ts`), and the prompt says so.
|
|
159
|
+
const IN_SESSION_CLAUSE =
|
|
160
|
+
'Review it yourself in this session — you carry no Skill or Agent tool, so never launch a second reviewer.'
|
|
161
|
+
|
|
162
|
+
function round_one_opening(brief_path: string): string {
|
|
163
|
+
return [
|
|
164
|
+
`Review this checkout as a /code-review: read the review brief at ${brief_path} and follow it exactly —`,
|
|
165
|
+
'the level on its first line, the rubric it names, the checkout it pins and its review:attest step.',
|
|
166
|
+
IN_SESSION_CLAUSE,
|
|
167
|
+
].join(' ')
|
|
168
|
+
}
|
|
169
|
+
|
|
112
170
|
// One line, because `detached_launch` refuses an argument carrying a control character: the multi-line
|
|
113
171
|
// brief travels by path, never inline.
|
|
114
|
-
function reviewer_prompt(
|
|
172
|
+
function reviewer_prompt(
|
|
173
|
+
brief_path: string,
|
|
174
|
+
slot: ReviewSlot,
|
|
175
|
+
issue: string,
|
|
176
|
+
findings_path?: string,
|
|
177
|
+
): string {
|
|
115
178
|
return [
|
|
116
|
-
|
|
117
|
-
'the level on its first line, the rubric it names, the checkout it pins and its review:attest step.',
|
|
179
|
+
round_one_opening(brief_path),
|
|
118
180
|
issue_read_instruction(issue),
|
|
181
|
+
...review_prior_findings.prompt_clauses(issue),
|
|
119
182
|
'Apply a fix only for a Medium finding whose fix is small and local — a one-function refactor, an',
|
|
120
183
|
'added test, an added guard; never fix a High or a change that reaches beyond one place, and never',
|
|
121
184
|
'commit, stage or push. After any fix, run `pnpm josh lint:related && pnpm josh test:related` and',
|
|
122
185
|
'return only once both are green; revert a fix you cannot get green and report that finding unfixed.',
|
|
123
|
-
findings_instruction(
|
|
186
|
+
findings_instruction(
|
|
187
|
+
slot,
|
|
188
|
+
`, prefixing a finding you fixed with "${FIXED_PREFIX}"`,
|
|
189
|
+
findings_path,
|
|
190
|
+
),
|
|
124
191
|
].join(' ')
|
|
125
192
|
}
|
|
126
193
|
|
|
194
|
+
// The round-1 review run beside the code review: it reads only, so the two sessions never fix, verify
|
|
195
|
+
// and revert in the one shared checkout at once; its findings go to the lane's one fix pass.
|
|
196
|
+
function report_prompt(
|
|
197
|
+
brief_path: string,
|
|
198
|
+
slot: ReviewSlot,
|
|
199
|
+
issue: string,
|
|
200
|
+
findings_path?: string,
|
|
201
|
+
): string {
|
|
202
|
+
return [
|
|
203
|
+
round_one_opening(brief_path),
|
|
204
|
+
'Do not edit any file: the code review running beside this one fixes in this checkout.',
|
|
205
|
+
issue_read_instruction(issue),
|
|
206
|
+
...review_prior_findings.prompt_clauses(issue),
|
|
207
|
+
findings_instruction(slot, '', findings_path),
|
|
208
|
+
].join(' ')
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// **One reviewer edits the checkout** (joshuafolkken/kit#4672): a slot reviewed beside the code slot
|
|
212
|
+
// reads only, and a slot reviewed alone takes the round's own prompt.
|
|
213
|
+
function slot_prompt(
|
|
214
|
+
round_prompt: PromptOf,
|
|
215
|
+
slot: ReviewSlot,
|
|
216
|
+
slots: ReadonlyArray<ReviewSlot>,
|
|
217
|
+
): PromptOf {
|
|
218
|
+
if (slot === review_attest.REVIEW_SLOT.CODE || slots.length === 1) return round_prompt
|
|
219
|
+
|
|
220
|
+
return report_prompt
|
|
221
|
+
}
|
|
222
|
+
|
|
127
223
|
// The round-2 verification pass: a fresh session over the round-1 fix delta, reading only.
|
|
128
|
-
function verification_prompt(
|
|
224
|
+
function verification_prompt(
|
|
225
|
+
brief_path: string,
|
|
226
|
+
slot: ReviewSlot,
|
|
227
|
+
issue: string,
|
|
228
|
+
findings_path?: string,
|
|
229
|
+
): string {
|
|
129
230
|
return [
|
|
130
|
-
`
|
|
231
|
+
`Review this checkout as a /code-review — the round-2 verification pass over the round-1 fixes: read the`,
|
|
131
232
|
`review brief at ${brief_path} and follow it exactly — the level on its first line, the rubric it`,
|
|
132
233
|
'names, the checkout it pins and its review:attest step. Do not edit any file.',
|
|
234
|
+
IN_SESSION_CLAUSE,
|
|
133
235
|
issue_read_instruction(issue),
|
|
134
|
-
|
|
236
|
+
...review_prior_findings.prompt_clauses(issue),
|
|
237
|
+
findings_instruction(slot, '', findings_path),
|
|
135
238
|
].join(' ')
|
|
136
239
|
}
|
|
137
240
|
|
|
138
241
|
// The spec is what `review:record` reads; the description after it travels in the stage output and,
|
|
139
242
|
// for a finding that stopped the ship, its first sentence in the durable stop log.
|
|
140
|
-
function split_description(unmarked: string): { spec: string; description: string } {
|
|
141
|
-
const boundary = DESCRIPTION_BOUNDARY.exec(unmarked)
|
|
142
|
-
|
|
143
|
-
if (boundary === null) return { spec: unmarked.trim(), description: '' }
|
|
144
|
-
|
|
145
|
-
const rest = unmarked.slice(boundary.index + boundary[0].length)
|
|
146
|
-
|
|
147
|
-
return { spec: unmarked.slice(0, boundary.index).trim(), description: rest.trim() }
|
|
148
|
-
}
|
|
149
|
-
|
|
150
243
|
function finding_of(line: string): Finding {
|
|
151
244
|
const is_fixed = line.startsWith(FIXED_PREFIX)
|
|
152
245
|
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
function first_sentence(description: string): string {
|
|
157
|
-
const [sentence = ''] = description.split(SENTENCE_END, 1)
|
|
246
|
+
const unmarked = is_fixed ? line.slice(FIXED_PREFIX.length) : line
|
|
158
247
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return `${sentence.slice(0, SENTENCE_LIMIT - ELLIPSIS.length)}${ELLIPSIS}`
|
|
248
|
+
return { ...review_finding_text.split_description(unmarked), is_fixed, line }
|
|
162
249
|
}
|
|
163
250
|
|
|
164
251
|
function spec_findings(text: string): ReadonlyArray<Finding> {
|
|
@@ -192,7 +279,11 @@ function kinds_of(findings: ReadonlyArray<Finding>): ReadonlyArray<string> {
|
|
|
192
279
|
function stop_finding_of(finding: Finding): StopFinding {
|
|
193
280
|
const location = review_record_cli.parse_finding(finding.spec)?.file ?? ''
|
|
194
281
|
|
|
195
|
-
return {
|
|
282
|
+
return {
|
|
283
|
+
kind: kind_of(finding),
|
|
284
|
+
location,
|
|
285
|
+
sentence: review_finding_text.first_sentence(finding.description),
|
|
286
|
+
}
|
|
196
287
|
}
|
|
197
288
|
|
|
198
289
|
// `bug-risks:medium` — each kind of finding that decided a stopped stage, once per kind (the stop
|
|
@@ -218,6 +309,14 @@ function blocking_details(text: string): ReadonlyArray<StopFinding> {
|
|
|
218
309
|
return deciding_findings(text).map((finding) => stop_finding_of(finding))
|
|
219
310
|
}
|
|
220
311
|
|
|
312
|
+
// The findings a passing round 1 fixed in place — the stop log's only chance to see them, since no stop
|
|
313
|
+
// follows (joshuafolkken/kit#4780); none for any other round.
|
|
314
|
+
function passing_fixes(verdict: ScoredVerdict, outcome: RoundOutcome): ReadonlyArray<StopFinding> {
|
|
315
|
+
if (!outcome.is_passing || verdict.kind !== VERDICT.FIXED) return []
|
|
316
|
+
|
|
317
|
+
return blocking_details(verdict.report.join('\n'))
|
|
318
|
+
}
|
|
319
|
+
|
|
221
320
|
function scored_kind(findings: ReadonlyArray<Finding>): ScoredVerdict['kind'] {
|
|
222
321
|
if (findings.some((finding) => is_blocking(finding))) return VERDICT.BLOCKING
|
|
223
322
|
|
|
@@ -225,9 +324,10 @@ function scored_kind(findings: ReadonlyArray<Finding>): ScoredVerdict['kind'] {
|
|
|
225
324
|
}
|
|
226
325
|
|
|
227
326
|
// Absent means the reviewer never finished; a line outside the grammar means its verdict cannot be
|
|
228
|
-
// recorded — both stop the ship rather than read as clean.
|
|
229
|
-
//
|
|
230
|
-
//
|
|
327
|
+
// recorded — both stop the ship rather than read as clean. A fixed finding is recorded with its
|
|
328
|
+
// `fixed` mark, the disposition `review:record` keeps in the ledger and `review:round2` reads round 1's
|
|
329
|
+
// closure from (joshuafolkken/kit#5286). The report keeps each line whole — mark and description — for
|
|
330
|
+
// the stage output a resumed lane child reads.
|
|
231
331
|
function read_verdict(text: string | undefined): ReviewVerdict {
|
|
232
332
|
if (text === undefined) return { kind: VERDICT.INVALID, note: MISSING_NOTE }
|
|
233
333
|
|
|
@@ -240,11 +340,23 @@ function read_verdict(text: string | undefined): ReviewVerdict {
|
|
|
240
340
|
|
|
241
341
|
return {
|
|
242
342
|
kind: scored_kind(findings),
|
|
243
|
-
specs: findings.map((finding) =>
|
|
343
|
+
specs: findings.map((finding) =>
|
|
344
|
+
finding.is_fixed ? `${FIXED_PREFIX}${finding.spec}` : finding.spec,
|
|
345
|
+
),
|
|
244
346
|
report: findings.map((finding) => finding.line),
|
|
245
347
|
}
|
|
246
348
|
}
|
|
247
349
|
|
|
350
|
+
// The specs `review:record` is given: a stopped round's `fixed` marks are dropped, since a fix the scoped
|
|
351
|
+
// pair turned down, or one beside a finding still blocking, has not closed what it marks.
|
|
352
|
+
function recorded_specs(verdict: ScoredVerdict, outcome: RoundOutcome): ReadonlyArray<string> {
|
|
353
|
+
if (outcome.is_passing) return verdict.specs
|
|
354
|
+
|
|
355
|
+
return verdict.specs.map((spec) =>
|
|
356
|
+
spec.startsWith(FIXED_PREFIX) ? spec.slice(FIXED_PREFIX.length) : spec,
|
|
357
|
+
)
|
|
358
|
+
}
|
|
359
|
+
|
|
248
360
|
// Round 1 passes clean or with every blocking finding fixed in place; round 2 follows the commit.
|
|
249
361
|
function round_one_outcome(verdict: ScoredVerdict): RoundOutcome {
|
|
250
362
|
if (verdict.kind === VERDICT.BLOCKING) return { is_passing: false, note: BLOCKING_NOTE }
|
|
@@ -279,18 +391,26 @@ function round_two_outcome(verdict: ScoredVerdict): RoundOutcome {
|
|
|
279
391
|
|
|
280
392
|
const run_ship_review = {
|
|
281
393
|
FIXED_PREFIX,
|
|
394
|
+
OTHER_SITES_CLAUSE,
|
|
395
|
+
SWEEP_INSTRUCTION,
|
|
282
396
|
UNVERIFIED_OUTCOME,
|
|
283
397
|
VERDICT,
|
|
284
398
|
blocking_details,
|
|
285
399
|
blocking_kinds,
|
|
286
400
|
has_fixes,
|
|
287
401
|
is_clean_round_one,
|
|
402
|
+
passing_fixes,
|
|
288
403
|
read_verdict,
|
|
404
|
+
recorded_specs,
|
|
405
|
+
report_prompt,
|
|
289
406
|
reviewer_prompt,
|
|
407
|
+
round_one_opening,
|
|
290
408
|
round_one_outcome,
|
|
291
409
|
round_two_outcome,
|
|
410
|
+
slot_prompt,
|
|
411
|
+
submit_command,
|
|
292
412
|
verification_prompt,
|
|
293
413
|
}
|
|
294
414
|
|
|
295
|
-
export type { ReviewVerdict, RoundOutcome, ScoredVerdict, StopFinding }
|
|
415
|
+
export type { PromptOf, ReviewVerdict, RoundOutcome, ScoredVerdict, StopFinding }
|
|
296
416
|
export { run_ship_review }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { agent_argv, type AgentArgv } from '#scripts/agent/agent-argv'
|
|
1
|
+
import { agent_argv, type AgentArgv, type AgentArgvResult } from '#scripts/agent/agent-argv'
|
|
2
2
|
import { agent_role_profile, type AgentProfile } from '#scripts/agent/agent-role-profile'
|
|
3
3
|
import { api_auth } from '#scripts/agent/api-auth'
|
|
4
4
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
@@ -6,8 +6,10 @@ import { josh_command, type JoshResult } from '#scripts/josh/josh-run'
|
|
|
6
6
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
7
7
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
8
8
|
import { lane_session_broker } from '#scripts/lane/lane-session-broker'
|
|
9
|
+
import { review_attest, type ReviewSlot } from '#scripts/review/review-attest'
|
|
9
10
|
import { detached_launch } from '#scripts/run/detached-launch'
|
|
10
|
-
import {
|
|
11
|
+
import { run_ship_brokered_review } from './run-ship-brokered-review'
|
|
12
|
+
import { run_ship_review, type PromptOf } from './run-ship-review'
|
|
11
13
|
import type { Phase } from './run-ship-scoped'
|
|
12
14
|
import { run_ship_stop_cause, type Cause } from './run-ship-stop-cause'
|
|
13
15
|
import type { StepResult } from './run-ship-sync'
|
|
@@ -22,13 +24,24 @@ const should_forward_stderr = true
|
|
|
22
24
|
const ATTEST_CHECK = ['review:attest', '--check']
|
|
23
25
|
const KEPT_REVIEW_NOTE =
|
|
24
26
|
'the reviewer wrote its findings before it failed — its review is kept; attest and record judge it.'
|
|
27
|
+
const MISSING_FINDINGS_NOTE = 'the reviewer submitted no findings; nothing is at the slot path:'
|
|
25
28
|
type Round = '1' | '2'
|
|
26
29
|
|
|
27
30
|
const ROUND_ONE: Round = '1'
|
|
28
31
|
const ROUND_TWO: Round = '2'
|
|
29
|
-
|
|
32
|
+
|
|
33
|
+
interface SlotOpen {
|
|
34
|
+
open: ReadonlyArray<string>
|
|
35
|
+
slot: ReviewSlot
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface Briefed {
|
|
39
|
+
brief: string
|
|
40
|
+
slot: ReviewSlot
|
|
41
|
+
}
|
|
30
42
|
|
|
31
43
|
const { CAUSE } = run_ship_stop_cause
|
|
44
|
+
const { CODE } = review_attest.REVIEW_SLOT
|
|
32
45
|
|
|
33
46
|
// **Every stop is tagged with the step's own cause**, so a round that stopped on a red join, a reviewer
|
|
34
47
|
// that did not finish or a refused attestation is not booked as a finding (joshuafolkken/kit#4431).
|
|
@@ -44,8 +57,8 @@ function tagged_phase(cause: Cause, phase: Phase): Phase {
|
|
|
44
57
|
return async () => tagged(cause, await phase())
|
|
45
58
|
}
|
|
46
59
|
|
|
47
|
-
function paths(): { brief: string; findings: string; log: string } {
|
|
48
|
-
return lane_session_broker.review_paths(PROJECT_ROOT)
|
|
60
|
+
function paths(slot?: ReviewSlot): { brief: string; findings: string; log: string } {
|
|
61
|
+
return lane_session_broker.review_paths(PROJECT_ROOT, slot)
|
|
49
62
|
}
|
|
50
63
|
|
|
51
64
|
async function josh(argv: ReadonlyArray<string>): Promise<JoshResult> {
|
|
@@ -66,17 +79,39 @@ function exited_note(log_path: string): string {
|
|
|
66
79
|
return `${api_auth.AUTH_FAILURE_NOTE}: ${exited}`
|
|
67
80
|
}
|
|
68
81
|
|
|
69
|
-
function current_verdict(): ReturnType<typeof run_ship_review.read_verdict> {
|
|
70
|
-
return run_ship_review.read_verdict(stamp_file.read_stamp_text(paths().findings))
|
|
82
|
+
function current_verdict(slot?: ReviewSlot): ReturnType<typeof run_ship_review.read_verdict> {
|
|
83
|
+
return run_ship_review.read_verdict(stamp_file.read_stamp_text(paths(slot).findings))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// **A session that ended with no findings file names the slot's path** (joshuafolkken/kit#4774) — the
|
|
87
|
+
// one `review:submit` writes, or the one a lane predating it was told to write: a reviewer that never
|
|
88
|
+
// submitted otherwise stops the round later, on a join or a record that never says the file is missing.
|
|
89
|
+
function missing_findings(slots: ReadonlyArray<ReviewSlot>): string | undefined {
|
|
90
|
+
const missing = slots
|
|
91
|
+
.map((slot) => paths(slot).findings)
|
|
92
|
+
.filter((findings) => stamp_file.read_stamp_text(findings) === undefined)
|
|
93
|
+
|
|
94
|
+
return missing.length === 0 ? undefined : `${MISSING_FINDINGS_NOTE} ${missing.join(', ')}`
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function finished_session(slots: ReadonlyArray<ReviewSlot>): JoshResult {
|
|
98
|
+
const missing = missing_findings(slots)
|
|
99
|
+
|
|
100
|
+
return missing === undefined
|
|
101
|
+
? { code: SUCCESS_EXIT_CODE, out: '' }
|
|
102
|
+
: failure(missing, CAUSE.INFRA)
|
|
71
103
|
}
|
|
72
104
|
|
|
73
105
|
// **A session that ran and then failed keeps the review it wrote** (joshuafolkken/kit#4562). The
|
|
74
106
|
// findings file is removed before the launch and written as the reviewer's last step, so a readable one
|
|
75
107
|
// is this session's finished review — a late auth failure or a lost broker reply then costs nothing,
|
|
76
108
|
// where a relaunch would review the whole change again. The attest and record phases still judge it.
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
109
|
+
// A broker answers for every slot it ran at once, so each slot's file must be readable.
|
|
110
|
+
function ended_session(failed_note: string, slots: ReadonlyArray<ReviewSlot> = [CODE]): JoshResult {
|
|
111
|
+
if (slots.some((slot) => current_verdict(slot).kind === run_ship_review.VERDICT.INVALID)) {
|
|
112
|
+
const missing = missing_findings(slots)
|
|
113
|
+
|
|
114
|
+
return failure(missing === undefined ? failed_note : `${failed_note}\n${missing}`, CAUSE.INFRA)
|
|
80
115
|
}
|
|
81
116
|
|
|
82
117
|
note(`${failed_note}\n${KEPT_REVIEW_NOTE}`)
|
|
@@ -86,13 +121,15 @@ function ended_session(failed_note: string): JoshResult {
|
|
|
86
121
|
|
|
87
122
|
// Under the round's reviewer profile — the same model and effort (`JOSH_REVIEWER_*` included) the
|
|
88
123
|
// chain's subagent is given — and waited on, so the join below runs only once the review has finished.
|
|
89
|
-
// Each call is its own process, so round 2 is a fresh session by construction.
|
|
124
|
+
// Each call is its own process, so round 2 is a fresh session by construction. A failed session is
|
|
125
|
+
// judged on its own slot's findings, not on a sibling's still being written.
|
|
90
126
|
async function run_direct_session(
|
|
91
127
|
argv: AgentArgv,
|
|
92
128
|
profile: AgentProfile,
|
|
93
|
-
|
|
129
|
+
slot: ReviewSlot,
|
|
94
130
|
round: Round,
|
|
95
131
|
): Promise<JoshResult> {
|
|
132
|
+
const log_path = paths(slot).log
|
|
96
133
|
const request = { argv, cwd: PROJECT_ROOT, log_path, profile }
|
|
97
134
|
|
|
98
135
|
note(agent_role_profile.describe_review(Number(round), profile))
|
|
@@ -102,9 +139,9 @@ async function run_direct_session(
|
|
|
102
139
|
return failure(`reviewer could not start: ${result.note}`, CAUSE.INFRA)
|
|
103
140
|
}
|
|
104
141
|
|
|
105
|
-
if (result.exit_code !== SUCCESS_EXIT_CODE) return ended_session(exited_note(log_path))
|
|
142
|
+
if (result.exit_code !== SUCCESS_EXIT_CODE) return ended_session(exited_note(log_path), [slot])
|
|
106
143
|
|
|
107
|
-
return
|
|
144
|
+
return finished_session([slot])
|
|
108
145
|
}
|
|
109
146
|
|
|
110
147
|
// A lane child's reviewer is started by the lane's broker: an OpenAI lane's always, since a nested Codex
|
|
@@ -117,77 +154,135 @@ function is_brokered(profile: AgentProfile, issue: string): boolean {
|
|
|
117
154
|
return profile.provider === 'openai' || lane_session_broker.is_serving(PROJECT_ROOT, issue)
|
|
118
155
|
}
|
|
119
156
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
157
|
+
interface SlotSession {
|
|
158
|
+
slot: ReviewSlot
|
|
159
|
+
built: AgentArgvResult
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function session_for(
|
|
163
|
+
prompt_of: PromptOf,
|
|
123
164
|
issue: string,
|
|
124
165
|
round: Round,
|
|
125
|
-
|
|
126
|
-
|
|
166
|
+
slots: { slot: ReviewSlot; all: ReadonlyArray<ReviewSlot> },
|
|
167
|
+
): SlotSession {
|
|
168
|
+
const { slot, all } = slots
|
|
169
|
+
const prompt = run_ship_review.slot_prompt(prompt_of, slot, all)(paths(slot).brief, slot, issue)
|
|
170
|
+
|
|
171
|
+
return { slot, built: agent_argv.review_in(prompt, Number(round), PROJECT_ROOT) }
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function run_slot(session: SlotSession, round: Round): Promise<JoshResult> {
|
|
175
|
+
const { built, slot } = session
|
|
127
176
|
|
|
128
177
|
if (built.kind === 'rejected') {
|
|
129
178
|
return failure(`reviewer profile rejected: ${built.note}`, CAUSE.INFRA)
|
|
130
179
|
}
|
|
131
180
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
181
|
+
return await run_direct_session(built.argv, built.profile, slot, round)
|
|
182
|
+
}
|
|
135
183
|
|
|
136
|
-
|
|
184
|
+
async function run_brokered(
|
|
185
|
+
issue: string,
|
|
186
|
+
round: Round,
|
|
187
|
+
slots: ReadonlyArray<ReviewSlot>,
|
|
188
|
+
): Promise<JoshResult> {
|
|
189
|
+
const answer = await run_ship_brokered_review.request(PROJECT_ROOT, issue, round, slots)
|
|
137
190
|
|
|
138
191
|
return answer.is_success
|
|
139
|
-
?
|
|
140
|
-
: ended_session(`isolated reviewer failed: ${answer.reason}
|
|
192
|
+
? finished_session(slots)
|
|
193
|
+
: ended_session(`isolated reviewer failed: ${answer.reason}`, slots)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// **The slots' reviewers run side by side** (joshuafolkken/kit#4672), and the first failure among
|
|
197
|
+
// them is the result — each slot is launched through the same path a single review takes.
|
|
198
|
+
async function run_sessions(
|
|
199
|
+
prompt_of: PromptOf,
|
|
200
|
+
issue: string,
|
|
201
|
+
round: Round,
|
|
202
|
+
slots: ReadonlyArray<ReviewSlot>,
|
|
203
|
+
): Promise<JoshResult> {
|
|
204
|
+
const sessions = slots.map((slot) => session_for(prompt_of, issue, round, { slot, all: slots }))
|
|
205
|
+
const [first] = sessions
|
|
206
|
+
|
|
207
|
+
if (first?.built.kind === 'argv' && is_brokered(first.built.profile, issue)) {
|
|
208
|
+
return await run_brokered(issue, round, slots)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const results = await Promise.all(sessions.map(async (session) => await run_slot(session, round)))
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
results.find((result) => result.code !== SUCCESS_EXIT_CODE) ?? {
|
|
215
|
+
code: SUCCESS_EXIT_CODE,
|
|
216
|
+
out: '',
|
|
217
|
+
}
|
|
218
|
+
)
|
|
141
219
|
}
|
|
142
220
|
|
|
143
221
|
// The brief goes to a file and the previous round's findings are removed, so a reviewer that writes
|
|
144
222
|
// nothing reads as unfinished rather than as the last round's verdict.
|
|
145
|
-
async function
|
|
146
|
-
|
|
223
|
+
async function launch_reviewers(
|
|
224
|
+
briefs: ReadonlyArray<Briefed>,
|
|
147
225
|
prompt_of: PromptOf,
|
|
148
226
|
issue: string,
|
|
149
227
|
round: Round,
|
|
150
228
|
): Promise<JoshResult> {
|
|
151
|
-
const
|
|
229
|
+
for (const { brief, slot } of briefs) {
|
|
230
|
+
const target = paths(slot)
|
|
152
231
|
|
|
153
|
-
|
|
154
|
-
|
|
232
|
+
stamp_file.write_text_stamp(target.brief, brief)
|
|
233
|
+
stamp_file.remove_stamp(target.findings)
|
|
234
|
+
}
|
|
155
235
|
|
|
156
|
-
return await
|
|
157
|
-
prompt_of
|
|
158
|
-
target.log,
|
|
236
|
+
return await run_sessions(
|
|
237
|
+
prompt_of,
|
|
159
238
|
issue,
|
|
160
239
|
round,
|
|
240
|
+
briefs.map(({ slot }) => slot),
|
|
161
241
|
)
|
|
162
242
|
}
|
|
163
243
|
|
|
164
244
|
// A refused attestation — the issue changed after the brief, an update left unread, no attestation —
|
|
165
|
-
// is no finding: the round read what it was briefed on.
|
|
245
|
+
// is no finding: the round read what it was briefed on. `review:attest --check` asks every slot.
|
|
166
246
|
async function attest_phase(): Promise<StepResult> {
|
|
167
247
|
return tagged(CAUSE.ATTEST, await josh(ATTEST_CHECK))
|
|
168
248
|
}
|
|
169
249
|
|
|
170
|
-
//
|
|
171
|
-
|
|
172
|
-
|
|
250
|
+
// Each slot's brief-minting command in turn, then their reviewers side by side, each handed what its
|
|
251
|
+
// command printed. The slots are the ones asked for, not the ones whose command has run so far.
|
|
252
|
+
function reviewed_together(
|
|
253
|
+
opens: ReadonlyArray<SlotOpen>,
|
|
173
254
|
prompt_of: PromptOf,
|
|
174
255
|
issue: string,
|
|
175
256
|
round: Round,
|
|
176
257
|
): ReadonlyArray<Phase> {
|
|
177
|
-
const
|
|
258
|
+
const printed = new Map<ReviewSlot, string>()
|
|
259
|
+
|
|
260
|
+
function briefs(): ReadonlyArray<Briefed> {
|
|
261
|
+
return opens.map(({ slot }) => ({ brief: printed.get(slot) ?? '', slot }))
|
|
262
|
+
}
|
|
178
263
|
|
|
179
264
|
return [
|
|
180
|
-
async () => {
|
|
265
|
+
...opens.map(({ open, slot }) => async () => {
|
|
181
266
|
const result = await josh(open)
|
|
182
267
|
|
|
183
|
-
|
|
268
|
+
printed.set(slot, result.out)
|
|
184
269
|
|
|
185
270
|
return tagged(CAUSE.CHECK, result)
|
|
186
|
-
},
|
|
187
|
-
async () => await
|
|
271
|
+
}),
|
|
272
|
+
async () => await launch_reviewers(briefs(), prompt_of, issue, round),
|
|
188
273
|
]
|
|
189
274
|
}
|
|
190
275
|
|
|
276
|
+
// A brief-minting command, then a reviewer handed what it printed.
|
|
277
|
+
function reviewed(
|
|
278
|
+
open: ReadonlyArray<string>,
|
|
279
|
+
prompt_of: PromptOf,
|
|
280
|
+
issue: string,
|
|
281
|
+
round: Round,
|
|
282
|
+
): ReadonlyArray<Phase> {
|
|
283
|
+
return reviewed_together([{ open, slot: CODE }], prompt_of, issue, round)
|
|
284
|
+
}
|
|
285
|
+
|
|
191
286
|
const run_ship_reviewer = {
|
|
192
287
|
attest_phase,
|
|
193
288
|
current_verdict,
|
|
@@ -196,6 +291,7 @@ const run_ship_reviewer = {
|
|
|
196
291
|
note,
|
|
197
292
|
paths,
|
|
198
293
|
reviewed,
|
|
294
|
+
reviewed_together,
|
|
199
295
|
ROUND_ONE,
|
|
200
296
|
ROUND_TWO,
|
|
201
297
|
SUCCESS_EXIT_CODE,
|