@joshuafolkken/kit 1.1784.0 → 1.2116.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 +60 -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 +386 -360
- 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 +16 -9
- 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,16 +1,24 @@
|
|
|
1
|
-
import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
|
|
2
1
|
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
2
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
3
|
import { cli_flags } from '#scripts/lib/cli-flags'
|
|
4
4
|
import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
|
|
5
|
-
import {
|
|
5
|
+
import type { StopFinding } from '#scripts/run/ship/run-ship-review'
|
|
6
|
+
import { review_comment_carry } from './review-comment-carry'
|
|
6
7
|
import { review_finding_ledger, type Finding, type LineKind } from './review-finding-ledger'
|
|
8
|
+
import { review_finding_text } from './review-finding-text'
|
|
7
9
|
import { review_interaction } from './review-interaction'
|
|
10
|
+
import { review_lane_handover } from './review-lane-handover'
|
|
8
11
|
import { review_record, type RecordVerdict } from './review-record'
|
|
12
|
+
import { review_record_code_round } from './review-record-code-round'
|
|
13
|
+
import { review_record_comment } from './review-record-comment'
|
|
14
|
+
import { review_record_interaction } from './review-record-interaction'
|
|
15
|
+
import type { ReuseAnswer } from './review-round-reuse'
|
|
16
|
+
import { review_stop_log } from './review-stop-log'
|
|
9
17
|
|
|
10
18
|
// `josh review:record --issue <N> [<category>:<severity>:<file> ...]` — the one write path for a
|
|
11
|
-
// `/code-review` round's findings. It appends a `- rf:` line per finding to
|
|
19
|
+
// `/code-review` round's findings. It appends a `- rb:` round boundary and a `- rf:` line per finding to
|
|
12
20
|
// the issue's own file of the observation ledger, which the run's commit carries like any other
|
|
13
|
-
// ledger change. **A call with no findings is a zero-finding round, and it still writes one line** — so the
|
|
21
|
+
// ledger change. **A call with no findings is a zero-finding round, and it still writes one `- rf:` line** — so the
|
|
14
22
|
// round that found nothing is recorded rather than mistaken for a round nobody reviewed.
|
|
15
23
|
//
|
|
16
24
|
// **`--comment` records a round that ran after the pull request opened**: the same lines go to the
|
|
@@ -21,26 +29,50 @@ import { review_record, type RecordVerdict } from './review-record'
|
|
|
21
29
|
//
|
|
22
30
|
// `josh review:record --check --issue <N>` is the read half `pnpm josh followup` runs before it
|
|
23
31
|
// merges: `ok` / `not-required` exit zero, `missing` exits non-zero so the
|
|
24
|
-
// merge is refused until the round is recorded. It mirrors `josh review:attest --check`.
|
|
32
|
+
// merge is refused until the round is recorded. It mirrors `josh review:attest --check`. A recorded
|
|
33
|
+
// code round adds whether the ship reuses it (`review-round-reuse.ts`); the exit code does not change.
|
|
25
34
|
//
|
|
26
35
|
// **`--interaction` records and checks the interaction review's pass instead** (`review-interaction.ts`):
|
|
27
36
|
// the same grammar under `- ri:`. It takes no `--comment` — the pass runs before the pull request, and
|
|
28
37
|
// a pass kept only on the issue would leave the merge gate reading it as missing.
|
|
38
|
+
//
|
|
39
|
+
// **A finding written with its reason — `<spec> — <sentence>` — also lands in the durable stop log**,
|
|
40
|
+
// marked fixed (joshuafolkken/kit#4817). The ledger keeps the spec alone, as it always has; the stop
|
|
41
|
+
// log is the one record that keeps a finding's location and reason, so a lane's own round reaches the
|
|
42
|
+
// next stop's fix and the next review (`review-prior-findings.ts`) the way a ship's round already does.
|
|
29
43
|
|
|
30
44
|
const FAILURE_EXIT_CODE = 1
|
|
31
45
|
const USAGE =
|
|
32
|
-
'Usage: josh review:record --issue <N> [--comment | --interaction] [<category>:<severity>:<file> ...] | josh review:record --check [--interaction] --issue <N>'
|
|
46
|
+
'Usage: josh review:record --issue <N> [--comment | --interaction] [[<disposition> ]<category>:<severity>:<file>[ — <reason>] ...] | josh review:record --check [--interaction] --issue <N>'
|
|
33
47
|
const FILE_HINT = ' <file>: the cited path, optionally with :line'
|
|
48
|
+
const DISPOSITION_HINT =
|
|
49
|
+
' <disposition>: optional — fixed | false-positive | filed:#<M> | deferred:#<M>; josh review:round2 skips only when every High/Medium is fixed or false-positive'
|
|
50
|
+
const REASON_HINT =
|
|
51
|
+
' <reason>: optional, one sentence on what was wrong, kept for the lane’s next review and fix — pass each finding with its reason as one single-quoted argument'
|
|
52
|
+
const RECORD_STAGE = 'review:record'
|
|
34
53
|
const CHECK_USAGE = 'Usage: josh review:record --check [--interaction] --issue <N>'
|
|
35
54
|
const RECORDED_LINE = 'Recorded: the review round for this issue is in the ledger.'
|
|
55
|
+
const REUSED_LINE =
|
|
56
|
+
'Reused: josh ship takes this round as its round 1 — the files this round covers hold still since the record. A default branch the ship’s sync merges in moves them only where it changed a file this round covers, and the ship then reviews round 1 again itself.'
|
|
57
|
+
const DELTA_LINE =
|
|
58
|
+
'Reused, delta to round 2: josh ship takes this round as its round 1 and does not review it again — every file moved since the record is one round 2 reads after the commit, or the ship’s own round 1 stopped on it.'
|
|
59
|
+
|
|
60
|
+
// The condition that re-runs round 1, and the path that met it, named rather than listed among every
|
|
61
|
+
// condition that could (joshuafolkken/kit#4941).
|
|
62
|
+
function review_again_line(cause = 'the reuse question gave no reason'): string {
|
|
63
|
+
return `Not reused: josh ship reviews round 1 again — ${cause}. Run \`pnpm josh run:review\` and the round-1 \`/code-review\` here (chain-rule.md step 0).`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function reuse_line(answer: ReuseAnswer): string {
|
|
67
|
+
if (answer.reuse === 'again') return review_again_line(answer.cause)
|
|
68
|
+
|
|
69
|
+
return answer.reuse === 'delta' ? DELTA_LINE : REUSED_LINE
|
|
70
|
+
}
|
|
71
|
+
|
|
36
72
|
const NOT_REQUIRED_LINE =
|
|
37
73
|
'No review-finding ledger is kept in this checkout, so there is nothing to check.'
|
|
38
|
-
const
|
|
39
|
-
'
|
|
40
|
-
const CARRIED_LINE =
|
|
41
|
-
'review-finding line(s) recorded on closed issues after their pull requests opened into the ledger.'
|
|
42
|
-
const CARRY_FAILED_LINE =
|
|
43
|
-
'Could not carry the closed issues’ comment rounds into the ledger; the next round retries:'
|
|
74
|
+
const LANE_CARRY_LINE =
|
|
75
|
+
'Not carrying the closed issues’ comment rounds: a lane child leaves them to `pnpm josh observations:flush`.'
|
|
44
76
|
const OPTIONS = {
|
|
45
77
|
issue: { type: 'string' },
|
|
46
78
|
check: { type: 'boolean' },
|
|
@@ -83,15 +115,31 @@ function parse_finding(spec: string): Finding | undefined {
|
|
|
83
115
|
return to_finding(spec.slice(0, first), spec.slice(first + 1, second), spec.slice(second + 1))
|
|
84
116
|
}
|
|
85
117
|
|
|
86
|
-
|
|
118
|
+
interface Positional {
|
|
119
|
+
finding: Finding
|
|
120
|
+
description: string
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// A positional is `[<disposition> ]<spec>[ — <reason>]`; the disposition rides into the ledger line.
|
|
124
|
+
function parse_positional(positional: string): Positional | undefined {
|
|
125
|
+
const { spec: marked, description } = review_finding_text.split_description(positional)
|
|
126
|
+
const { disposition, spec } = review_finding_ledger.split_disposition(marked)
|
|
127
|
+
const finding = parse_finding(spec)
|
|
128
|
+
|
|
129
|
+
if (finding === undefined) return undefined
|
|
130
|
+
|
|
131
|
+
return { finding: disposition === undefined ? finding : { ...finding, disposition }, description }
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function parse_findings(positionals: ReadonlyArray<string>): ReadonlyArray<Finding> | undefined {
|
|
87
135
|
const findings: Array<Finding> = []
|
|
88
136
|
|
|
89
|
-
for (const
|
|
90
|
-
const
|
|
137
|
+
for (const positional of positionals) {
|
|
138
|
+
const parsed = parse_positional(positional)
|
|
91
139
|
|
|
92
|
-
if (
|
|
140
|
+
if (parsed === undefined) return undefined
|
|
93
141
|
|
|
94
|
-
findings.push(finding)
|
|
142
|
+
findings.push(parsed.finding)
|
|
95
143
|
}
|
|
96
144
|
|
|
97
145
|
return findings
|
|
@@ -133,6 +181,8 @@ function usage_text(): string {
|
|
|
133
181
|
accepted_values('<category>', review_finding_ledger.CATEGORIES),
|
|
134
182
|
accepted_values('<severity>', review_finding_ledger.SEVERITIES),
|
|
135
183
|
FILE_HINT,
|
|
184
|
+
DISPOSITION_HINT,
|
|
185
|
+
REASON_HINT,
|
|
136
186
|
].join('\n')
|
|
137
187
|
}
|
|
138
188
|
|
|
@@ -158,10 +208,25 @@ type CheckStatus = RecordVerdict['status']
|
|
|
158
208
|
|
|
159
209
|
interface CheckMode {
|
|
160
210
|
status: (issue: number, root: string) => Promise<CheckStatus>
|
|
211
|
+
recorded: (issue: number) => Promise<string>
|
|
161
212
|
refusal: (issue: number) => string
|
|
162
213
|
not_required: string
|
|
163
214
|
}
|
|
164
215
|
|
|
216
|
+
// **A recorded code round also says whether `josh ship` reuses it** (joshuafolkken/kit#4763), from the
|
|
217
|
+
// ship's own predicate, in the ship's three outcomes (joshuafolkken/kit#4878): reused as it stands,
|
|
218
|
+
// reused with the moved files left to round 2, or reviewed again — so the lane runs it itself rather
|
|
219
|
+
// than reading "recorded" as "done".
|
|
220
|
+
async function code_recorded(issue: number): Promise<string> {
|
|
221
|
+
const answer = await review_lane_handover.answer_here(issue)
|
|
222
|
+
|
|
223
|
+
return [RECORDED_LINE, reuse_line(answer)].join('\n')
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function interaction_recorded(): Promise<string> {
|
|
227
|
+
return RECORDED_LINE
|
|
228
|
+
}
|
|
229
|
+
|
|
165
230
|
async function code_status(issue: number, root: string): Promise<CheckStatus> {
|
|
166
231
|
const verdict = await review_record.check(issue, root)
|
|
167
232
|
|
|
@@ -172,13 +237,15 @@ async function code_status(issue: number, root: string): Promise<CheckStatus> {
|
|
|
172
237
|
const CHECK_MODES: Record<LineKind, CheckMode> = {
|
|
173
238
|
code: {
|
|
174
239
|
status: code_status,
|
|
240
|
+
recorded: code_recorded,
|
|
175
241
|
refusal: review_record.refusal_message,
|
|
176
242
|
not_required: NOT_REQUIRED_LINE,
|
|
177
243
|
},
|
|
178
244
|
interaction: {
|
|
179
245
|
status: review_interaction.status,
|
|
246
|
+
recorded: interaction_recorded,
|
|
180
247
|
refusal: review_interaction.refusal_message,
|
|
181
|
-
not_required:
|
|
248
|
+
not_required: review_record_interaction.NOT_REQUIRED_LINE,
|
|
182
249
|
},
|
|
183
250
|
}
|
|
184
251
|
|
|
@@ -195,7 +262,7 @@ async function report_check(issue: number, mode: CheckMode, root: string): Promi
|
|
|
195
262
|
return FAILURE_EXIT_CODE
|
|
196
263
|
}
|
|
197
264
|
|
|
198
|
-
console.info(status === 'ok' ?
|
|
265
|
+
console.info(status === 'ok' ? await mode.recorded(issue) : mode.not_required)
|
|
199
266
|
|
|
200
267
|
return 0
|
|
201
268
|
}
|
|
@@ -212,54 +279,109 @@ async function run_check(parsed: Parsed, root: string): Promise<number> {
|
|
|
212
279
|
return await report_check(Number(issue), CHECK_MODES[kind_of(parsed)], root)
|
|
213
280
|
}
|
|
214
281
|
|
|
215
|
-
//
|
|
216
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
)
|
|
282
|
+
// The closed issues' comment rounds ride this round's commit (`review-comment-round.ts`) — **except in a
|
|
283
|
+
// lane child** (joshuafolkken/kit#5326): parallel lanes each wrote the same newly closed issue's file,
|
|
284
|
+
// so their ships waited on each other's overlap and their merges with main conflicted on it.
|
|
285
|
+
// `observations:flush` carries them for the lanes, on the default branch, in one pull request.
|
|
286
|
+
async function carry_comment_rounds(root: string): Promise<void> {
|
|
287
|
+
if (lane_child_marker.is_child_of(root)) {
|
|
288
|
+
console.info(LANE_CARRY_LINE)
|
|
223
289
|
|
|
224
|
-
|
|
290
|
+
return
|
|
291
|
+
}
|
|
225
292
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
console.error(error instanceof Error ? error.message : String(error))
|
|
293
|
+
await review_comment_carry.carry_reported(root)
|
|
294
|
+
}
|
|
229
295
|
|
|
230
|
-
|
|
231
|
-
|
|
296
|
+
// The round lands in its own issue's file, so two lanes recording at once
|
|
297
|
+
// write two files, and their pull requests never conflict on the ledger.
|
|
298
|
+
interface AppendedRound {
|
|
299
|
+
issue: number
|
|
300
|
+
lines: ReadonlyArray<string>
|
|
301
|
+
root: string
|
|
302
|
+
kind: LineKind
|
|
303
|
+
findings: ReadonlyArray<Finding>
|
|
304
|
+
date: string
|
|
232
305
|
}
|
|
233
306
|
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
async function carry_comment_rounds(root: string): Promise<void> {
|
|
238
|
-
try {
|
|
239
|
-
const count = await review_comment_round.carry(root)
|
|
307
|
+
// A code round opens with its boundary line (`review-finding-ledger.ts`), not counted as a finding line.
|
|
308
|
+
function ledger_lines({ issue, lines, kind, date }: AppendedRound): ReadonlyArray<string> {
|
|
309
|
+
if (kind === 'interaction') return lines
|
|
240
310
|
|
|
241
|
-
|
|
242
|
-
} catch (error) {
|
|
243
|
-
console.warn(`${CARRY_FAILED_LINE} ${error instanceof Error ? error.message : String(error)}`)
|
|
244
|
-
}
|
|
311
|
+
return [review_finding_ledger.round_line(date, issue), ...lines]
|
|
245
312
|
}
|
|
246
313
|
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
issue: number,
|
|
251
|
-
lines: ReadonlyArray<string>,
|
|
252
|
-
root: string,
|
|
253
|
-
): Promise<number> {
|
|
314
|
+
// A code round goes on to what its tree means for the ship (`review-record-code-round.ts`).
|
|
315
|
+
async function append_round(round: AppendedRound): Promise<number> {
|
|
316
|
+
const { issue, lines, root, kind, findings } = round
|
|
254
317
|
const ledger_path = observation_ledger_home.issue_path(issue, root)
|
|
255
318
|
|
|
256
|
-
await observation_ledger_home.append(ledger_path,
|
|
319
|
+
await observation_ledger_home.append(ledger_path, ledger_lines(round))
|
|
257
320
|
console.info(confirmation(lines.length, ledger_path))
|
|
258
321
|
await carry_comment_rounds(root)
|
|
259
322
|
|
|
323
|
+
if (kind === 'code') await review_record_code_round.follow(issue, root, findings)
|
|
324
|
+
|
|
260
325
|
return 0
|
|
261
326
|
}
|
|
262
327
|
|
|
328
|
+
// A code round recorded after the push goes to the issue unasked (`review-record-comment.ts`).
|
|
329
|
+
async function write_round(
|
|
330
|
+
parsed: Parsed,
|
|
331
|
+
request: Request,
|
|
332
|
+
now: Date,
|
|
333
|
+
root: string,
|
|
334
|
+
): Promise<number> {
|
|
335
|
+
const kind = kind_of(parsed)
|
|
336
|
+
const date = observation_ledger_home.ledger_date(now)
|
|
337
|
+
const lines = build_lines(request, date, kind)
|
|
338
|
+
const { issue, findings } = request
|
|
339
|
+
|
|
340
|
+
if (parsed.comment) return await review_record_comment.post(issue, lines)
|
|
341
|
+
|
|
342
|
+
if (kind === 'code' && (await review_record_comment.is_after_push())) {
|
|
343
|
+
return await review_record_comment.post_after_push({ issue, lines, root, findings })
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
return await append_round({
|
|
347
|
+
issue: request.issue,
|
|
348
|
+
lines,
|
|
349
|
+
root,
|
|
350
|
+
kind,
|
|
351
|
+
findings: request.findings,
|
|
352
|
+
date,
|
|
353
|
+
})
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// The stop-log finding a positional carries, or `undefined` for one written without a reason.
|
|
357
|
+
function reason_of(positional: string): StopFinding | undefined {
|
|
358
|
+
const parsed = parse_positional(positional)
|
|
359
|
+
|
|
360
|
+
if (parsed === undefined || parsed.description.length === 0) return undefined
|
|
361
|
+
|
|
362
|
+
const { finding, description } = parsed
|
|
363
|
+
|
|
364
|
+
return {
|
|
365
|
+
kind: `${finding.category}:${finding.severity}`,
|
|
366
|
+
location: finding.file,
|
|
367
|
+
sentence: review_finding_text.first_sentence(description),
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function is_reason(finding: StopFinding | undefined): finding is StopFinding {
|
|
372
|
+
return finding !== undefined
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
// Recorded only once the round itself is, so the stop log never holds a round the ledger refused.
|
|
376
|
+
function record_reasons(issue: number, positionals: ReadonlyArray<string>): void {
|
|
377
|
+
review_stop_log.record({
|
|
378
|
+
issue,
|
|
379
|
+
stage: RECORD_STAGE,
|
|
380
|
+
findings: positionals.map((positional) => reason_of(positional)).filter(is_reason),
|
|
381
|
+
is_fixed: true,
|
|
382
|
+
})
|
|
383
|
+
}
|
|
384
|
+
|
|
263
385
|
async function run_record(parsed: Parsed, now: Date, root: string): Promise<number> {
|
|
264
386
|
const request = parsed.comment && parsed.interaction ? undefined : to_request(parsed)
|
|
265
387
|
|
|
@@ -269,11 +391,11 @@ async function run_record(parsed: Parsed, now: Date, root: string): Promise<numb
|
|
|
269
391
|
return FAILURE_EXIT_CODE
|
|
270
392
|
}
|
|
271
393
|
|
|
272
|
-
const
|
|
394
|
+
const code = await write_round(parsed, request, now, root)
|
|
273
395
|
|
|
274
|
-
if (
|
|
396
|
+
if (code === 0) record_reasons(request.issue, parsed.positionals)
|
|
275
397
|
|
|
276
|
-
return
|
|
398
|
+
return code
|
|
277
399
|
}
|
|
278
400
|
|
|
279
401
|
// **The default is the work tree the command runs in, a lane's inside a lane**.
|
|
@@ -301,6 +423,7 @@ const review_record_cli = {
|
|
|
301
423
|
accepted_values,
|
|
302
424
|
build_lines,
|
|
303
425
|
parse_finding,
|
|
426
|
+
parse_positional,
|
|
304
427
|
run,
|
|
305
428
|
usage_text,
|
|
306
429
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { run_ship_detach } from '#scripts/run/ship/run-ship-detach'
|
|
2
|
+
import type { Finding } from './review-finding-ledger'
|
|
3
|
+
import { review_lane_handover } from './review-lane-handover'
|
|
4
|
+
import { review_record_interaction } from './review-record-interaction'
|
|
5
|
+
import { review_record_pinned } from './review-record-pinned'
|
|
6
|
+
import { review_reviewed_tree } from './review-reviewed-tree'
|
|
7
|
+
|
|
8
|
+
// What `josh review:record` does once a code round is on the ledger: it records the tree the verdict
|
|
9
|
+
// stands for, which `josh ship` reuses while the tree holds still (`review-reviewed-tree.ts`), names
|
|
10
|
+
// the ship next for a lane child (`review-lane-handover.ts`), names an interaction review its fixes
|
|
11
|
+
// made due (`review-record-interaction.ts`), reads a `josh run:review --join` the lane skipped, and
|
|
12
|
+
// starts `josh test:pinned` again on a tree its fixes moved (`review-record-pinned.ts`).
|
|
13
|
+
|
|
14
|
+
const HIGH_SEVERITY = 'high'
|
|
15
|
+
|
|
16
|
+
// The files whose finding the round could not have fixed in place — a High never is.
|
|
17
|
+
function unsettled_files(findings: ReadonlyArray<Finding>): ReadonlyArray<string> {
|
|
18
|
+
return findings
|
|
19
|
+
.filter((finding) => finding.severity === HIGH_SEVERITY)
|
|
20
|
+
.map((finding) => finding.file)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// A lane child's round the ship reuses names the ship next (joshuafolkken/kit#4850), read after the
|
|
24
|
+
// tree is stamped; the lines that follow name what is done before that ship.
|
|
25
|
+
async function report_handover(issue: number): Promise<boolean> {
|
|
26
|
+
const is_handed_over = await review_lane_handover.is_handed_over(issue)
|
|
27
|
+
|
|
28
|
+
if (is_handed_over) console.info(review_lane_handover.NEXT_STEP_LINE)
|
|
29
|
+
|
|
30
|
+
return is_handed_over
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Only a lane child's round the ship will reuse restarts the check: the ship's own rounds run under its
|
|
34
|
+
// supervisor, where nothing reads the answer and the check would hold cores the ship's gate waits on.
|
|
35
|
+
function is_restarted_here(is_handed_over: boolean): boolean {
|
|
36
|
+
return is_handed_over && !run_ship_detach.is_supervised()
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function follow(
|
|
40
|
+
issue: number,
|
|
41
|
+
root: string,
|
|
42
|
+
findings: ReadonlyArray<Finding>,
|
|
43
|
+
): Promise<void> {
|
|
44
|
+
await review_reviewed_tree.record(unsettled_files(findings))
|
|
45
|
+
const is_handed_over = await report_handover(issue)
|
|
46
|
+
|
|
47
|
+
await review_record_interaction.report_due(issue, root)
|
|
48
|
+
if (!is_restarted_here(is_handed_over)) return
|
|
49
|
+
await review_record_pinned.read_skipped_join(root)
|
|
50
|
+
await review_record_pinned.restart_if_moved(root)
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const review_record_code_round = { follow }
|
|
54
|
+
|
|
55
|
+
export { review_record_code_round }
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
|
|
2
|
+
import { run_ship_probe } from '#scripts/run/ship/run-ship-probe'
|
|
3
|
+
import { review_comment_round } from './review-comment-round'
|
|
4
|
+
import type { Finding } from './review-finding-ledger'
|
|
5
|
+
import { review_record_code_round } from './review-record-code-round'
|
|
6
|
+
|
|
7
|
+
// The issue-comment half of `josh review:record`: a round kept on the issue rather than in the
|
|
8
|
+
// observation ledger (`review-comment-round.ts` carries it there once the issue closes).
|
|
9
|
+
|
|
10
|
+
const FAILURE_EXIT_CODE = 1
|
|
11
|
+
const AFTER_PUSH_LINE =
|
|
12
|
+
'The branch is pushed and the tree is clean, so this round is recorded on the issue, not in the ledger — a ledger line would need a push of its own and restart CI.'
|
|
13
|
+
|
|
14
|
+
interface CommentRound {
|
|
15
|
+
issue: number
|
|
16
|
+
lines: ReadonlyArray<string>
|
|
17
|
+
root: string
|
|
18
|
+
findings: ReadonlyArray<Finding>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// **A comment that could not be posted fails the record**: it is the round's only copy, so a
|
|
22
|
+
// swallowed refusal would read as a recorded round that exists nowhere.
|
|
23
|
+
async function post(issue: number, lines: ReadonlyArray<string>): Promise<number> {
|
|
24
|
+
try {
|
|
25
|
+
const url = await git_gh_issue_write.issue_comment(
|
|
26
|
+
String(issue),
|
|
27
|
+
review_comment_round.body_of(lines),
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
console.info(`Recorded ${String(lines.length)} review-finding line(s) in ${url.trim()}.`)
|
|
31
|
+
|
|
32
|
+
return 0
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error(error instanceof Error ? error.message : String(error))
|
|
35
|
+
|
|
36
|
+
return FAILURE_EXIT_CODE
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// **A code round recorded once the branch is pushed and the tree clean goes to the issue unasked**
|
|
41
|
+
// (joshuafolkken/kit#4907): `josh run:review` pushed at the first green gate, and a ledger line now
|
|
42
|
+
// would ride no commit of the run's but a push of its own, restarting CI. `--check` reads the issue's
|
|
43
|
+
// comment rounds too (`review-record.ts`). The round still stamps its tree, so `josh ship` reuses it
|
|
44
|
+
// as round 1.
|
|
45
|
+
async function is_after_push(): Promise<boolean> {
|
|
46
|
+
return await run_ship_probe.is_pushed_clean()
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function post_after_push(round: CommentRound): Promise<number> {
|
|
50
|
+
console.info(AFTER_PUSH_LINE)
|
|
51
|
+
const code = await post(round.issue, round.lines)
|
|
52
|
+
|
|
53
|
+
if (code === 0) await review_record_code_round.follow(round.issue, round.root, round.findings)
|
|
54
|
+
|
|
55
|
+
return code
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const review_record_comment = { is_after_push, post, post_after_push }
|
|
59
|
+
|
|
60
|
+
export { review_record_comment }
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
2
|
+
import { review_interaction } from './review-interaction'
|
|
3
|
+
|
|
4
|
+
// What `josh review:record` says about the interaction review (`review-interaction.ts`).
|
|
5
|
+
//
|
|
6
|
+
// **A round-1 fix can make the pass due after its brief opened** (joshuafolkken/kit#4835): the fix
|
|
7
|
+
// reaches the run tooling the original change did not, so round 1 opened with `/code-review`'s brief
|
|
8
|
+
// alone. A recorded code round reads the pass's status over the fixed tree and names its brief, so the
|
|
9
|
+
// lane runs it before `josh ship` instead of the ship's review stage running it alone and stopping on
|
|
10
|
+
// its finding. A status git could not read prints nothing — the merge gate still refuses a missing pass.
|
|
11
|
+
|
|
12
|
+
const NOT_REQUIRED_LINE =
|
|
13
|
+
'No interaction review is due: the change touches no run tooling, or this checkout keeps no ledger.'
|
|
14
|
+
const DUE_HEAD = 'Interaction review now due'
|
|
15
|
+
|
|
16
|
+
// An interaction reviewer that already ran beside round 1 is only recorded, never run twice.
|
|
17
|
+
function due_line(issue: number): string {
|
|
18
|
+
return `${DUE_HEAD}: this round’s change touches the run tooling and no interaction pass is recorded. Before \`josh ship\`, record it with \`pnpm josh review:record --interaction --issue ${String(issue)} [<finding> ...]\` — if no interaction reviewer ran beside this round, first open its brief with \`pnpm josh review:brief --interaction\` and run that \`reviewer\` — so a finding is fixed in this lane rather than stopping the ship.`
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function report_due(issue: number, root: string): Promise<void> {
|
|
22
|
+
try {
|
|
23
|
+
if ((await review_interaction.status(issue, root)) === 'missing') console.info(due_line(issue))
|
|
24
|
+
} catch (error) {
|
|
25
|
+
error_text.trace_swallowed('review_record_interaction.report_due', error)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const review_record_interaction = {
|
|
30
|
+
due_line,
|
|
31
|
+
NOT_REQUIRED_LINE,
|
|
32
|
+
report_due,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { review_record_interaction }
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
2
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
|
+
import { error_text } from '#scripts/lib/error-message'
|
|
4
|
+
import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
|
|
5
|
+
import { run_review_join_read, type JoinVerdict } from '#scripts/run/review/run-review-join-read'
|
|
6
|
+
import { run_review_pinned_join } from '#scripts/run/review/run-review-pinned-join'
|
|
7
|
+
import { run_ship_detach } from '#scripts/run/ship/run-ship-detach'
|
|
8
|
+
import { test_pinned_logic } from '#scripts/test/test-pinned-logic'
|
|
9
|
+
import { review_finding_ledger } from './review-finding-ledger'
|
|
10
|
+
|
|
11
|
+
// What `josh review:record` does about the background `josh test:pinned` (joshuafolkken/kit#4834).
|
|
12
|
+
//
|
|
13
|
+
// **A round-1 fix can add hunks the check never read**: `josh run:review` launched it on the briefed
|
|
14
|
+
// tree, and its join closed before the fix. The ship's pre-detach was then the first to name the fixed
|
|
15
|
+
// tree's unpinned places, and stopped on them. A recorded code round compares the fixed tree with the
|
|
16
|
+
// launch's and, where they differ, starts the check again with the launch's `--unpinned-ok` reason and
|
|
17
|
+
// says who reads its answer. **Nothing waits on it in the foreground** (joshuafolkken/kit#4895): the
|
|
18
|
+
// ship's pre-detach reads that same check's answer on that tree rather than running its own
|
|
19
|
+
// (`run-review-pinned-join.ts`). A foreground read stalled the lane for minutes, and pinning what it
|
|
20
|
+
// named moved the tree again under the next probe.
|
|
21
|
+
//
|
|
22
|
+
// **The same tree starts nothing**, and so does a tree either side could not read, or a checkout with
|
|
23
|
+
// no launch. The fix's first `josh check:related` runs this same restart (joshuafolkken/kit#4948), so a
|
|
24
|
+
// record on the tree it checked takes over the check already running there. `check:related` alone
|
|
25
|
+
// waits on the check it started (joshuafolkken/kit#4987), within a bound that keeps the verdict line
|
|
26
|
+
// under a foreground Bash call's cap (`check-related-pinned.ts`).
|
|
27
|
+
|
|
28
|
+
function started_line(): string {
|
|
29
|
+
return `test:pinned restarted in the background on the tree this round's fixes moved. Where it names unpinned places, the ship's pre-detach stops on them: pin each with a test that turns red without it, or ship with \`--unpinned-ok "<reason>"\`.`
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// `root` is the checkout `josh run:review` keyed its launch to: the ledger root `review:record` writes
|
|
33
|
+
// under is the same working directory, and a test's temporary root holds no launch. Answers whether a
|
|
34
|
+
// check was started.
|
|
35
|
+
async function restart_if_moved(root: string = PROJECT_ROOT): Promise<boolean> {
|
|
36
|
+
try {
|
|
37
|
+
const is_started = await run_review_pinned_join.restart_if_moved(root)
|
|
38
|
+
|
|
39
|
+
if (is_started) console.info(started_line())
|
|
40
|
+
|
|
41
|
+
return is_started
|
|
42
|
+
} catch (error) {
|
|
43
|
+
error_text.trace_swallowed('review_record_pinned.restart_if_moved', error)
|
|
44
|
+
|
|
45
|
+
return false
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// **A join the lane skipped is read here** (joshuafolkken/kit#5212): `josh run:review --join` was never
|
|
50
|
+
// run, so the unpinned places would surface only as the ship's pre-detach failure. It reads only an
|
|
51
|
+
// answer already left on this tree, so nothing waits on it either. A read that stops nothing prints
|
|
52
|
+
// nothing, and a join already read changes nothing.
|
|
53
|
+
const CHOICE_LINE =
|
|
54
|
+
'Unpinned before the ship: pin each place above with a test that turns red without it, or ship with `--unpinned-ok "<reason>"`.\n'
|
|
55
|
+
|
|
56
|
+
function show_stop(joined: JoinVerdict | undefined): void {
|
|
57
|
+
if (joined?.is_stop !== true) return
|
|
58
|
+
console.info(test_pinned_logic.report_text(joined.summary, CHOICE_LINE).trimEnd())
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function read_skipped_join(root: string = PROJECT_ROOT): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
if (run_review_join_read.is_due(root)) show_stop(await run_review_join_read.read_finished(root))
|
|
64
|
+
} catch (error) {
|
|
65
|
+
error_text.trace_swallowed('review_record_pinned.read_skipped_join', error)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Whether the lane's code round is on the ledger: from then on `review:record` owns the restart, behind
|
|
70
|
+
// its own handover guard.
|
|
71
|
+
async function is_round_recorded(root: string): Promise<boolean> {
|
|
72
|
+
const issue = lane_child_marker.marked_issue()
|
|
73
|
+
if (issue === undefined) return false
|
|
74
|
+
const content = await observation_ledger_home.read(root)
|
|
75
|
+
|
|
76
|
+
return content !== undefined && review_finding_ledger.has_issue_record(content, Number(issue))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// `josh check:related`'s restart (joshuafolkken/kit#4948) runs only in a lane child outside a ship's
|
|
80
|
+
// supervisor and before its round 1 is recorded: a launch record outlives its issue in a reused
|
|
81
|
+
// checkout, and a child relaunched after a ship stop may re-detach without `--review`, which reads no
|
|
82
|
+
// answer.
|
|
83
|
+
async function is_restartable_before_record(root: string): Promise<boolean> {
|
|
84
|
+
if (!lane_child_marker.is_child_of(root) || run_ship_detach.is_supervised()) return false
|
|
85
|
+
|
|
86
|
+
return !(await is_round_recorded(root))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Answers whether a check was started, so `check:related` waits on its answer (joshuafolkken/kit#4987).
|
|
90
|
+
async function restart_in_lane(root: string = PROJECT_ROOT): Promise<boolean> {
|
|
91
|
+
try {
|
|
92
|
+
return (await is_restartable_before_record(root)) && (await restart_if_moved(root))
|
|
93
|
+
} catch (error) {
|
|
94
|
+
error_text.trace_swallowed('review_record_pinned.restart_in_lane', error)
|
|
95
|
+
|
|
96
|
+
return false
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const review_record_pinned = {
|
|
101
|
+
CHOICE_LINE,
|
|
102
|
+
read_skipped_join,
|
|
103
|
+
restart_if_moved,
|
|
104
|
+
restart_in_lane,
|
|
105
|
+
started_line,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export { review_record_pinned }
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { session_cite } from '#scripts/issue/session-cite'
|
|
2
2
|
import { observation_ledger_home } from '#scripts/observations/observation-ledger-home'
|
|
3
|
+
import { review_comment_round } from './review-comment-round'
|
|
3
4
|
import { review_finding_ledger } from './review-finding-ledger'
|
|
4
5
|
|
|
5
6
|
// The gate that refuses a merge until the `/code-review` round was recorded.
|
|
@@ -33,14 +34,37 @@ interface RecordVerdict {
|
|
|
33
34
|
// lane. Every file of the directory is read, so the round is found whichever
|
|
34
35
|
// file holds it; a directory that is not there answers `undefined`, a ledger this checkout does not
|
|
35
36
|
// keep, which becomes `not-required`.
|
|
37
|
+
//
|
|
38
|
+
// **A round recorded on the issue counts too** (`josh review:record --comment`): a round that ran after
|
|
39
|
+
// the branch was pushed keeps its lines there so CI does not restart (joshuafolkken/kit#4907). Comments
|
|
40
|
+
// that could not be read are no record — the refusal stands.
|
|
41
|
+
type CommentLines = (issue: number) => Promise<ReadonlyArray<string>>
|
|
42
|
+
|
|
43
|
+
async function has_comment_record(issue: number, read: CommentLines): Promise<boolean> {
|
|
44
|
+
try {
|
|
45
|
+
const lines = await read(issue)
|
|
46
|
+
|
|
47
|
+
return review_finding_ledger.has_issue_record(lines.join('\n'), issue)
|
|
48
|
+
} catch {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function is_recorded(content: string, issue: number, read: CommentLines): Promise<boolean> {
|
|
54
|
+
if (review_finding_ledger.has_issue_record(content, issue)) return true
|
|
55
|
+
|
|
56
|
+
return await has_comment_record(issue, read)
|
|
57
|
+
}
|
|
58
|
+
|
|
36
59
|
async function check(
|
|
37
60
|
issue: number,
|
|
38
61
|
root: string = observation_ledger_home.ledger_root(),
|
|
62
|
+
read_comment_lines: CommentLines = review_comment_round.issue_lines,
|
|
39
63
|
): Promise<RecordVerdict> {
|
|
40
64
|
const content = await observation_ledger_home.read(root)
|
|
41
65
|
|
|
42
66
|
if (content === undefined) return { status: 'not-required' }
|
|
43
|
-
if (
|
|
67
|
+
if (await is_recorded(content, issue, read_comment_lines)) return { status: 'ok', issue }
|
|
44
68
|
|
|
45
69
|
return { status: 'missing', issue }
|
|
46
70
|
}
|