@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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { git_gh_issue_read } from '#scripts/gh/git-gh-issue-read'
|
|
2
|
+
import { git_gh_issue_write } from '#scripts/gh/git-gh-issue-write'
|
|
3
|
+
import { issue_read, type IssueComment } from '#scripts/issue/issue-read'
|
|
4
|
+
import { review_round2, type RoundTwoAnswer } from './review-round2'
|
|
5
|
+
|
|
6
|
+
// `josh review:round2 --record <N>` — the `## Round 2 skipped` comment `prompts/review.md` asks for,
|
|
7
|
+
// written by the command rather than assembled by the run (joshuafolkken/kit#5286). It names the arm
|
|
8
|
+
// that fired and quotes the reason line verbatim, so a defect found later can be traced to the delta
|
|
9
|
+
// that went unreviewed. **A re-run writes nothing twice**: a trusted comment already carrying the same
|
|
10
|
+
// heading and reason line is the record.
|
|
11
|
+
|
|
12
|
+
const HEADING = '## Round 2 skipped'
|
|
13
|
+
const ARMS: Readonly<Record<string, string>> = {
|
|
14
|
+
[review_round2.CODE.EMPTY]: 'A — the fix delta is empty',
|
|
15
|
+
[review_round2.CODE.INERT]: 'B — every fixed path leaves what executes unchanged',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
type SkipRecord = 'posted' | 'present' | 'unreadable' | 'failed' | 'not-skipped'
|
|
19
|
+
|
|
20
|
+
function body_of(answer: RoundTwoAnswer): string {
|
|
21
|
+
return [
|
|
22
|
+
HEADING,
|
|
23
|
+
'',
|
|
24
|
+
`- arm: ${ARMS[answer.code] ?? answer.code}`,
|
|
25
|
+
`- reason: ${answer.reason}`,
|
|
26
|
+
].join('\n')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function is_recorded(comment: IssueComment, body: string): boolean {
|
|
30
|
+
return comment.is_trusted === true && comment.body.trimStart().startsWith(body)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function read_comments(issue: number): Promise<ReadonlyArray<IssueComment> | undefined> {
|
|
34
|
+
return await issue_read.parse_comments(await git_gh_issue_read.issue_list_comments(String(issue)))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// `not-skipped` for a `required` answer: only a skip is recorded. An unreadable listing posts nothing
|
|
38
|
+
// rather than risk the duplicate the record exists to avoid.
|
|
39
|
+
async function record(issue: number, answer: RoundTwoAnswer): Promise<SkipRecord> {
|
|
40
|
+
if (answer.verdict !== review_round2.SKIPPED_VERDICT) return 'not-skipped'
|
|
41
|
+
|
|
42
|
+
const body = body_of(answer)
|
|
43
|
+
const comments = await read_comments(issue)
|
|
44
|
+
|
|
45
|
+
if (comments === undefined) return 'unreadable'
|
|
46
|
+
|
|
47
|
+
if (comments.some((comment) => is_recorded(comment, body))) return 'present'
|
|
48
|
+
|
|
49
|
+
return (await git_gh_issue_write.issue_try_comment(String(issue), body)) ? 'posted' : 'failed'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const review_round2_skip_comment = { body_of, HEADING, record }
|
|
53
|
+
|
|
54
|
+
export type { SkipRecord }
|
|
55
|
+
export { review_round2_skip_comment }
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { file_map_stamp, type FileMapStamp } from '#scripts/josh/file-map-stamp'
|
|
2
2
|
import { path_decision } from '#scripts/josh/path-decision'
|
|
3
3
|
import { json_value } from '#scripts/lib/json-value'
|
|
4
|
+
import { release_approval_prune } from '#scripts/release/release-approval-prune'
|
|
4
5
|
import { z } from 'zod'
|
|
5
6
|
import { review_level } from './review-level'
|
|
6
7
|
|
|
@@ -13,7 +14,8 @@ import { review_level } from './review-level'
|
|
|
13
14
|
// because round 1's *fix code* is unreviewed, and that is structural. Arm A applies where there is no fix code — the findings closed without an edit — so
|
|
14
15
|
// the premise is absent rather than overridden. Arm B applies where the fix leaves what executes
|
|
15
16
|
// unchanged: `review-level.ts`'s inert set, documentation under `docs/` and the root `README.md`,
|
|
16
|
-
// `prompts/`, and source files whose only change is in comments
|
|
17
|
+
// `prompts/`, `josh metrics` approvals, and source files whose only change is in comments
|
|
18
|
+
// (`review-code-tree.ts`).
|
|
17
19
|
//
|
|
18
20
|
// **Arm B is wider than the review level's inert set, on purpose** (joshuafolkken/kit#3787). Round 1
|
|
19
21
|
// still reviews a documentation or prompt change in full, and the fix to its findings is still made;
|
|
@@ -51,13 +53,13 @@ const json_schema = z.object({
|
|
|
51
53
|
// on a missing record would be the cheapest possible run and the most dangerous — the direction
|
|
52
54
|
// `review-brief.ts` already takes when it widens a round-2 target it cannot name.
|
|
53
55
|
const OPEN_FINDING_REASON =
|
|
54
|
-
'the
|
|
56
|
+
'the ledger does not show every round-1 High/Medium finding closed, so the pass that verifies them is due'
|
|
55
57
|
const NO_SNAPSHOT_REASON =
|
|
56
58
|
'no round-1 snapshot was recorded, so the fix delta cannot be named — the round runs rather than assuming it is empty'
|
|
57
59
|
const EMPTY_DELTA_REASON_PREFIX =
|
|
58
60
|
'the fix delta is empty: round 1 wrote no fix code, so there is no unreviewed fix for a verification pass to read'
|
|
59
61
|
const INERT_DELTA_REASON_PREFIX =
|
|
60
|
-
'every path round 1 fixed leaves what executes unchanged — inert, documentation, a prompt, or a comment-only edit'
|
|
62
|
+
'every path round 1 fixed leaves what executes unchanged — inert, documentation, a prompt, a metrics approval, or a comment-only edit'
|
|
61
63
|
const README_PATH = 'README.md'
|
|
62
64
|
const DOCUMENTATION_PREFIX = 'docs/'
|
|
63
65
|
const MARKDOWN_EXTENSION = '.md'
|
|
@@ -73,10 +75,11 @@ interface RoundTwoInput {
|
|
|
73
75
|
// a `skip`, which is worse than a mistargeted read — nothing gets read at all.
|
|
74
76
|
// `undefined` where it could not be resolved to a commit, which is refused exactly like a mismatch.
|
|
75
77
|
base: string | undefined
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
// pressure — and its absence is the safe answer, so a caller that forgets it pays a round.
|
|
78
|
+
// Read from the issue's ledger, where `review:record` keeps each finding's disposition
|
|
79
|
+
// (`review-round-one-closure.ts`), not asserted by the caller (joshuafolkken/kit#5286).
|
|
79
80
|
is_round_one_closed: boolean
|
|
81
|
+
// Why round 1 is open, quoted into the `required` answer. Absent falls back to the generic reason.
|
|
82
|
+
open_reason?: string
|
|
80
83
|
snapshot: FileMapStamp | undefined
|
|
81
84
|
tree: Record<string, string>
|
|
82
85
|
// The paths whose code round 1's fixes left as it was (`review_code_tree.comment_only`). Absent is
|
|
@@ -130,8 +133,17 @@ function is_documentation(relative: string): boolean {
|
|
|
130
133
|
return relative.startsWith(DOCUMENTATION_PREFIX) && relative.endsWith(MARKDOWN_EXTENSION)
|
|
131
134
|
}
|
|
132
135
|
|
|
136
|
+
// **A `josh metrics` approval is data, not code** (joshuafolkken/kit#4842): the ship's pre-detach
|
|
137
|
+
// re-record rewrites it after round 1, and the gate's own metrics step checks it — the same reason
|
|
138
|
+
// `review-reviewed-tree.ts` reads it as no move.
|
|
133
139
|
function is_unexecuted(relative: string, comment_only: ReadonlyArray<string>): boolean {
|
|
134
|
-
if (
|
|
140
|
+
if (
|
|
141
|
+
review_level.is_inert(relative) ||
|
|
142
|
+
is_documentation(relative) ||
|
|
143
|
+
release_approval_prune.is_approval(relative)
|
|
144
|
+
) {
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
135
147
|
|
|
136
148
|
return comment_only.includes(relative)
|
|
137
149
|
}
|
|
@@ -172,7 +184,10 @@ function fix_delta(
|
|
|
172
184
|
}
|
|
173
185
|
|
|
174
186
|
function decide(input: RoundTwoInput): RoundTwoDecision {
|
|
175
|
-
if (!input.is_round_one_closed)
|
|
187
|
+
if (!input.is_round_one_closed) {
|
|
188
|
+
return required(CODE.OPEN_FINDING, input.open_reason ?? OPEN_FINDING_REASON)
|
|
189
|
+
}
|
|
190
|
+
|
|
176
191
|
if (input.snapshot === undefined) return required(CODE.NO_SNAPSHOT, NO_SNAPSHOT_REASON)
|
|
177
192
|
|
|
178
193
|
const delta = fix_delta(input, input.snapshot)
|
|
@@ -204,6 +219,7 @@ const review_round2 = {
|
|
|
204
219
|
empty_reason,
|
|
205
220
|
INERT_DELTA_REASON_PREFIX,
|
|
206
221
|
inert_reason,
|
|
222
|
+
is_unexecuted,
|
|
207
223
|
JSON_KEY,
|
|
208
224
|
live_reason,
|
|
209
225
|
NO_SNAPSHOT_REASON,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { gate_labels } from '#scripts/gate/gate-labels'
|
|
2
2
|
import { verification_inputs } from '#scripts/gate/verification-inputs'
|
|
3
3
|
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
4
4
|
import { file_map_stamp, type FileMapStampAccess } from '#scripts/josh/file-map-stamp'
|
|
@@ -19,6 +19,7 @@ const IN_FLIGHT_PREFIX = 'josh-gate-running-'
|
|
|
19
19
|
const ROUND_ONE_PREFIX = 'josh-review-round1-'
|
|
20
20
|
const ROUND_ONE_CODE_PREFIX = 'josh-review-round1-code-'
|
|
21
21
|
const BRIEFED_PREFIX = 'josh-review-briefed-'
|
|
22
|
+
const REVIEWED_PREFIX = 'josh-review-recorded-'
|
|
22
23
|
|
|
23
24
|
// The records that vouch for a check carry the fingerprint of its declared inputs
|
|
24
25
|
// (`verification-inputs.ts`): the gate's every declared check, a scoped record its own.
|
|
@@ -40,15 +41,17 @@ const round_one_code_stamp: FileMapStampAccess = file_map_stamp.create(
|
|
|
40
41
|
)
|
|
41
42
|
// Retaken on every brief: the round-1 snapshot is not the tree a later review read.
|
|
42
43
|
const briefed_stamp: FileMapStampAccess = file_map_stamp.create(BRIEFED_PREFIX, PROJECT_ROOT)
|
|
44
|
+
// Retaken on every recorded round: the tree that round's verdict stands for, its fixes included.
|
|
45
|
+
const reviewed_stamp: FileMapStampAccess = file_map_stamp.create(REVIEWED_PREFIX, PROJECT_ROOT)
|
|
43
46
|
const lint_related_stamp: FileMapStampAccess = file_map_stamp.create(
|
|
44
47
|
LINT_RELATED_PREFIX,
|
|
45
48
|
PROJECT_ROOT,
|
|
46
|
-
inputs_of([
|
|
49
|
+
inputs_of([gate_labels.LINT_LABEL]),
|
|
47
50
|
)
|
|
48
51
|
const test_related_stamp: FileMapStampAccess = file_map_stamp.create(
|
|
49
52
|
TEST_RELATED_PREFIX,
|
|
50
53
|
PROJECT_ROOT,
|
|
51
|
-
inputs_of([
|
|
54
|
+
inputs_of([gate_labels.UNIT_LABEL]),
|
|
52
55
|
)
|
|
53
56
|
const e2e_stamp: FileMapStampAccess = file_map_stamp.create(E2E_PREFIX, PROJECT_ROOT)
|
|
54
57
|
|
|
@@ -88,6 +91,7 @@ const review_stamps = {
|
|
|
88
91
|
round_one_code_stamp,
|
|
89
92
|
ROUND_ONE_PREFIX,
|
|
90
93
|
round_one_stamp,
|
|
94
|
+
reviewed_stamp,
|
|
91
95
|
test_related_stamp,
|
|
92
96
|
}
|
|
93
97
|
|
|
@@ -2,14 +2,16 @@ import { mkdirSync } from 'node:fs'
|
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
import { git_common_directory } from '#scripts/git/git-common-directory'
|
|
4
4
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
5
|
-
import {
|
|
5
|
+
import { lane_ledger_write } from '#scripts/lane/lane-ledger-write'
|
|
6
6
|
import { json_value } from '#scripts/lib/json-value'
|
|
7
7
|
import type { StopFinding } from '#scripts/run/ship/run-ship-review'
|
|
8
8
|
import { z } from 'zod'
|
|
9
9
|
|
|
10
10
|
// The durable record of every review finding that stopped a `josh ship` — one JSON line per finding,
|
|
11
11
|
// with its kind, the `<file>[:<line>]` it cites and its first sentence, read back by
|
|
12
|
-
// `josh review:stops` (joshuafolkken/kit#4519). The
|
|
12
|
+
// `josh review:stops` (joshuafolkken/kit#4519). The findings a round did not stop on — a ship round's
|
|
13
|
+
// fixes made in place, and a `review:record` round's findings written with a reason
|
|
14
|
+
// (joshuafolkken/kit#4817) — are in it too, marked fixed, which `review:stops` leaves out. The lane ledger's stop line keeps only the kinds, and
|
|
13
15
|
// the finding's text was only in the ship log in the temp root, which a reboot clears.
|
|
14
16
|
//
|
|
15
17
|
// **It lives in the git common directory**, beside the test-read map: every lane worktree of one clone
|
|
@@ -19,7 +21,6 @@ import { z } from 'zod'
|
|
|
19
21
|
// **A test run writes nothing** unless it passes its own path, the lane ledger's rule: the writer sits on
|
|
20
22
|
// the ship's stop path, which many suites exercise.
|
|
21
23
|
|
|
22
|
-
const LOG_DIRECTORY = 'josh'
|
|
23
24
|
const LOG_FILE = 'review-stops.jsonl'
|
|
24
25
|
const LINE_SEPARATOR = '\n'
|
|
25
26
|
|
|
@@ -30,15 +31,19 @@ const stop_line_schema = z.object({
|
|
|
30
31
|
kind: z.string(),
|
|
31
32
|
location: z.string(),
|
|
32
33
|
sentence: z.string(),
|
|
34
|
+
fixed: z.boolean().optional(),
|
|
33
35
|
})
|
|
34
36
|
|
|
35
37
|
type StopLine = z.infer<typeof stop_line_schema>
|
|
36
38
|
|
|
37
|
-
// One stopped review: the issue, the stage that stopped and the findings that decided it.
|
|
39
|
+
// One stopped review: the issue, the stage that stopped and the findings that decided it. A round that
|
|
40
|
+
// passed on fixes made in place is recorded too, marked `is_fixed`, so the lane's next review still sees
|
|
41
|
+
// the constraint each fix met (joshuafolkken/kit#4780); `review:stops` leaves those lines out.
|
|
38
42
|
interface ReviewStop {
|
|
39
43
|
issue: number
|
|
40
44
|
stage: string
|
|
41
45
|
findings: ReadonlyArray<StopFinding>
|
|
46
|
+
is_fixed?: boolean
|
|
42
47
|
}
|
|
43
48
|
|
|
44
49
|
function target(): string | undefined {
|
|
@@ -46,16 +51,25 @@ function target(): string | undefined {
|
|
|
46
51
|
|
|
47
52
|
const common = git_common_directory.repository()
|
|
48
53
|
|
|
49
|
-
return common === undefined
|
|
54
|
+
return common === undefined
|
|
55
|
+
? undefined
|
|
56
|
+
: path.join(common, git_common_directory.STATE_DIRECTORY, LOG_FILE)
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
function write(destination: string, stop: ReviewStop): void {
|
|
53
60
|
const at = new Date().toISOString()
|
|
61
|
+
const mark = stop.is_fixed === true ? { fixed: true } : {}
|
|
54
62
|
|
|
55
63
|
mkdirSync(path.dirname(destination), { recursive: true })
|
|
56
64
|
|
|
57
65
|
for (const finding of stop.findings) {
|
|
58
|
-
|
|
66
|
+
lane_ledger_write.append(destination, {
|
|
67
|
+
at,
|
|
68
|
+
issue: stop.issue,
|
|
69
|
+
stage: stop.stage,
|
|
70
|
+
...finding,
|
|
71
|
+
...mark,
|
|
72
|
+
})
|
|
59
73
|
}
|
|
60
74
|
}
|
|
61
75
|
|
|
@@ -67,7 +67,8 @@ function run(argv: ReadonlyArray<string>, context: StopsContext = {}): number {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const window = lane_stats.window_of(period_days, context.now_ms ?? Date.now())
|
|
70
|
-
const
|
|
70
|
+
const stopped = review_stop_log.read(context.log_path).filter((line) => line.fixed !== true)
|
|
71
|
+
const stops = lane_stats.in_window(stopped, window)
|
|
71
72
|
|
|
72
73
|
console.info(format_report(stops, period_days))
|
|
73
74
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
import { text } from 'node:stream/consumers'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
4
|
+
import { PROJECT_ROOT } from '#scripts/init/init-paths'
|
|
5
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
6
|
+
import { lane_session_broker } from '#scripts/lane/lane-session-broker'
|
|
7
|
+
import { run_ship_review } from '#scripts/run/ship/run-ship-review'
|
|
8
|
+
import { review_attest, type ReviewSlot } from './review-attest'
|
|
9
|
+
|
|
10
|
+
// `josh review:submit` — the one write path for a ship reviewer's findings (joshuafolkken/kit#4799).
|
|
11
|
+
// The reviewer pipes its findings here on stdin, and this command writes them to the slot's findings
|
|
12
|
+
// file under the same key the supervisor reads it by (`run-ship-reviewer.ts`), so no path is ever
|
|
13
|
+
// copied out of a prompt. A line outside the `review:record` grammar is refused before anything is
|
|
14
|
+
// written, while the reviewer can still fix it.
|
|
15
|
+
//
|
|
16
|
+
// **A clean review is said with `--none`, never with empty stdin**: a reviewer that forgot the pipe,
|
|
17
|
+
// or ran on a terminal, sends nothing, and reading that as clean would lose every finding it had.
|
|
18
|
+
|
|
19
|
+
const ARGV_OFFSET = 2
|
|
20
|
+
const INTERACTION_FLAG = '--interaction'
|
|
21
|
+
const NONE_FLAG = '--none'
|
|
22
|
+
const FLAGS: ReadonlySet<string> = new Set([INTERACTION_FLAG, NONE_FLAG])
|
|
23
|
+
const USAGE =
|
|
24
|
+
'Usage: josh review:submit [--interaction] < findings | josh review:submit [--interaction] --none'
|
|
25
|
+
const EMPTY_NOTE = `nothing written — no findings on stdin; a review with none passes ${NONE_FLAG}`
|
|
26
|
+
const NONE_WITH_FINDINGS_NOTE = `nothing written — ${NONE_FLAG} was passed with findings on stdin`
|
|
27
|
+
const SUCCESS_EXIT_CODE = 0
|
|
28
|
+
const FAILURE_EXIT_CODE = 1
|
|
29
|
+
|
|
30
|
+
interface Submission {
|
|
31
|
+
slot: ReviewSlot
|
|
32
|
+
is_none: boolean
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function submission_of(argv: ReadonlyArray<string>): Submission | undefined {
|
|
36
|
+
const is_valid = argv.every((flag) => FLAGS.has(flag)) && new Set(argv).size === argv.length
|
|
37
|
+
|
|
38
|
+
if (!is_valid) return undefined
|
|
39
|
+
|
|
40
|
+
const { CODE, INTERACTION } = review_attest.REVIEW_SLOT
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
slot: argv.includes(INTERACTION_FLAG) ? INTERACTION : CODE,
|
|
44
|
+
is_none: argv.includes(NONE_FLAG),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function grammar_refusal(findings: string): string | undefined {
|
|
49
|
+
const verdict = run_ship_review.read_verdict(findings)
|
|
50
|
+
|
|
51
|
+
return verdict.kind === run_ship_review.VERDICT.INVALID
|
|
52
|
+
? `nothing written — ${verdict.note}`
|
|
53
|
+
: undefined
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// The refusal for stdin that does not match the flags, or for a line outside the grammar.
|
|
57
|
+
function refusal_of(submission: Submission, findings: string): string | undefined {
|
|
58
|
+
const is_empty = findings.trim() === ''
|
|
59
|
+
|
|
60
|
+
if (submission.is_none) return is_empty ? undefined : NONE_WITH_FINDINGS_NOTE
|
|
61
|
+
|
|
62
|
+
return is_empty ? EMPTY_NOTE : grammar_refusal(findings)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function write(submission: Submission, findings: string): string {
|
|
66
|
+
const { slot, is_none } = submission
|
|
67
|
+
const target = lane_session_broker.review_paths(PROJECT_ROOT, slot).findings
|
|
68
|
+
|
|
69
|
+
stamp_file.write_text_stamp(target, is_none ? '' : findings)
|
|
70
|
+
|
|
71
|
+
return is_none
|
|
72
|
+
? `the ${slot} review is submitted with no findings.`
|
|
73
|
+
: `the ${slot} review's findings are submitted.`
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function run(argv: ReadonlyArray<string>, findings: string): number {
|
|
77
|
+
const submission = submission_of(argv)
|
|
78
|
+
const refusal = submission === undefined ? USAGE : refusal_of(submission, findings)
|
|
79
|
+
|
|
80
|
+
if (submission === undefined || refusal !== undefined) {
|
|
81
|
+
console.error(refusal)
|
|
82
|
+
|
|
83
|
+
return FAILURE_EXIT_CODE
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
console.info(write(submission, findings))
|
|
87
|
+
|
|
88
|
+
return SUCCESS_EXIT_CODE
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function main(): Promise<void> {
|
|
92
|
+
const findings = process.stdin.isTTY ? '' : await text(process.stdin)
|
|
93
|
+
|
|
94
|
+
process.exitCode = run(process.argv.slice(ARGV_OFFSET), findings)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (process.argv[1] === fileURLToPath(import.meta.url)) await main()
|
|
98
|
+
|
|
99
|
+
const review_submit_cli = { EMPTY_NOTE, USAGE, run }
|
|
100
|
+
|
|
101
|
+
export { review_submit_cli }
|
|
@@ -6,8 +6,8 @@ import { shell_segments } from './shell-segments'
|
|
|
6
6
|
|
|
7
7
|
// The trigger helpers the enumeration in `delivered-rules.ts` is built from, held here so a rule
|
|
8
8
|
// that lives in its own module can build its own row without importing the enumeration back.
|
|
9
|
-
// `is_issue_filing` is
|
|
10
|
-
//
|
|
9
|
+
// `is_issue_filing` is shared by the readers of a run's filings off the transcript (`turn-filings.ts`,
|
|
10
|
+
// `stop-guard.ts`), so it could not stay a private function of one of them.
|
|
11
11
|
|
|
12
12
|
// **Only `Bash`, and the omission is deliberate**: Claude Code denies one
|
|
13
13
|
// call of a turn and runs the rest, so a refused `Edit` would leave its siblings applied and itself
|
|
@@ -85,7 +85,7 @@ function is_direct_filing(command: string): boolean {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
// `pnpm josh issue:file`, in either spelling — **the** filing act once a direct one is refused, so the
|
|
88
|
-
//
|
|
88
|
+
// turn's filing count reads it. Segment-wise, so a
|
|
89
89
|
// spelling quoted inside another command's body is not read as a filing.
|
|
90
90
|
const FILING_NAMES: ReadonlySet<string> = new Set(['issue:file'])
|
|
91
91
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { fileURLToPath } from 'node:url'
|
|
3
|
+
import { document_section } from '#scripts/document/document-section'
|
|
4
|
+
import { find_package_directory } from '#scripts/josh/package-directory'
|
|
5
|
+
import type { MeasuredRule } from './delivered-rules'
|
|
6
|
+
import { reply_prose } from './reply-prose'
|
|
7
|
+
import { stop_decision } from './stop-decision'
|
|
8
|
+
|
|
9
|
+
// A chat reply leads with its conclusion and keeps its narrative short: the procedure is
|
|
10
|
+
// `prompts/collaboration-workflow/principles.md` → "concise-reply"; the limit is this file's.
|
|
11
|
+
|
|
12
|
+
// Letters and digits of narrative — prose outside code, tables and lists. Counted, not characters, so
|
|
13
|
+
// markdown markers and punctuation weigh nothing in any language.
|
|
14
|
+
const PROSE_LIMIT = 400
|
|
15
|
+
// A person who asked for the detail is answered with it.
|
|
16
|
+
const EXEMPT_WORDS: ReadonlyArray<string> = ['詳しく', '具体的に', '詳細']
|
|
17
|
+
const COUNTED_PATTERN = /[\p{L}\p{N}]/gu
|
|
18
|
+
|
|
19
|
+
const PRINCIPLES_FILE = 'prompts/collaboration-workflow/principles.md'
|
|
20
|
+
const SECTION = 'concise-reply'
|
|
21
|
+
const PACKAGE_DIRECTORY = find_package_directory(path.dirname(fileURLToPath(import.meta.url)))
|
|
22
|
+
|
|
23
|
+
// The constant opening `rule-value.ts` credits a Stop refusal to this row by.
|
|
24
|
+
const REASON_OPENING = `⛔ concise reply: your reply's prose outside code, tables and lists is over the limit of \`${PRINCIPLES_FILE}\` → "${SECTION}"`
|
|
25
|
+
|
|
26
|
+
const KEEP_DECISION = ' Keep its `Recommended:` / `Alternative:` lines as they are.'
|
|
27
|
+
|
|
28
|
+
function prose_length(message: string): number {
|
|
29
|
+
return reply_prose.narrative_of(message).match(COUNTED_PATTERN)?.length ?? 0
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function is_exempt(prompt: string): boolean {
|
|
33
|
+
return EXEMPT_WORDS.some((word) => prompt.includes(word))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// `prompt` is the person's last prompt — `undefined` when it could not be read, and then whether they
|
|
37
|
+
// asked for the detail is unknown, so nothing is refused.
|
|
38
|
+
function is_over(message: string, prompt: string | undefined): boolean {
|
|
39
|
+
if (prompt === undefined || is_exempt(prompt)) return false
|
|
40
|
+
|
|
41
|
+
return prose_length(message) > PROSE_LIMIT
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function section_text(root: string): string | undefined {
|
|
45
|
+
const markdown = document_section.read_optional(path.join(root, PRINCIPLES_FILE))
|
|
46
|
+
|
|
47
|
+
return markdown === undefined ? undefined : document_section.section(markdown, SECTION)?.text
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// A held run's notify reads the decision off the rewrite, which the loop-breaker lets stop unchecked.
|
|
51
|
+
function decision_note(message: string): string {
|
|
52
|
+
return stop_decision.decision_of(message) === undefined ? '' : KEEP_DECISION
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// The refusal carries the section itself, so the rewrite needs no read.
|
|
56
|
+
function build_reason(message: string, root: string = PACKAGE_DIRECTORY): string {
|
|
57
|
+
const head =
|
|
58
|
+
`${REASON_OPENING} (${String(prose_length(message))} of ${String(PROSE_LIMIT)}). Rewrite it ` +
|
|
59
|
+
`shorter as that section says — do not repeat your previous reply.${decision_note(message)}`
|
|
60
|
+
const body = section_text(root)
|
|
61
|
+
|
|
62
|
+
return body === undefined ? head : `${head}\n\n${body}`
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const ROW: MeasuredRule = {
|
|
66
|
+
id: SECTION,
|
|
67
|
+
reason: REASON_OPENING,
|
|
68
|
+
about: {
|
|
69
|
+
title: 'Concise reply',
|
|
70
|
+
topic: `\`principles.md\` → "${SECTION}"`,
|
|
71
|
+
entry: 'pnpm josh stop:guard',
|
|
72
|
+
fires: `a reply whose narrative outside code, tables and lists is over ${String(PROSE_LIMIT)} letters. Blocks the stop`,
|
|
73
|
+
quiet:
|
|
74
|
+
'a reply under the limit, a prompt asking for the detail (`詳しく` / `具体的に` / `詳細`), a fixed output in a code block, no prompt of the person’s on the transcript tail, or a headless session',
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const concise_reply = {
|
|
79
|
+
EXEMPT_WORDS,
|
|
80
|
+
PROSE_LIMIT,
|
|
81
|
+
REASON_OPENING,
|
|
82
|
+
ROW,
|
|
83
|
+
build_reason,
|
|
84
|
+
is_over,
|
|
85
|
+
prose_length,
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { concise_reply }
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { file_reader } from '#scripts/lib/read-file'
|
|
2
|
+
import { token_shape } from '#scripts/lib/token-shape'
|
|
3
|
+
import { bash_triggers } from './bash-triggers'
|
|
4
|
+
import { direct_pr_create } from './direct-pr-create'
|
|
5
|
+
import { gh_api, type FieldSource } from './gh-api'
|
|
6
|
+
import { git_argv } from './git-argv'
|
|
7
|
+
|
|
8
|
+
// The `credential-body` row of `delivered-rules.ts`. A body kit sends is refused when it holds a
|
|
9
|
+
// token-shaped string (`git-gh-exec.ts`, joshuafolkken/kit#4658), but a `gh api` call a run types on
|
|
10
|
+
// the shell never passes through kit's code, so the same scan runs here before the call does
|
|
11
|
+
// (joshuafolkken/kit#4682). The shapes are `token-shape.ts`'s, read by `token_shape.holds` — the test
|
|
12
|
+
// `token_shape.refuse` throws on — so no second copy of a pattern exists.
|
|
13
|
+
//
|
|
14
|
+
// **The text `gh` would send, not the command line alone**: each field value, and the file a
|
|
15
|
+
// `-F key=@<path>` or `--input <path>` names, read as the hook sees it — a path relative to a
|
|
16
|
+
// directory a `cd` earlier on the line moved to is not found and reads as empty. A JSON body is scanned
|
|
17
|
+
// decoded, as the in-process send does.
|
|
18
|
+
//
|
|
19
|
+
// **It fires on every occurrence**, for the reason `git-force.ts` does.
|
|
20
|
+
|
|
21
|
+
// `gh` sends a typed `\n` as the two characters, so a token after it follows the letter `n` and the
|
|
22
|
+
// shapes' "no letter before it" guard would pass it. So the text is scanned twice — as sent, and with
|
|
23
|
+
// each escape read as a space — since a backslash may also sit right before the token (`\ghp_…`),
|
|
24
|
+
// where the second reading loses its first letter. A non-JSON file is read the same way.
|
|
25
|
+
const TYPED_ESCAPE = /\\./gu
|
|
26
|
+
|
|
27
|
+
function sent_text(source: FieldSource): string {
|
|
28
|
+
if (source.kind === 'text') return source.value
|
|
29
|
+
|
|
30
|
+
return token_shape.decoded(file_reader.read_if_readable(source.value) ?? '')
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function holds_token(text: string): boolean {
|
|
34
|
+
return [text, text.replaceAll(TYPED_ESCAPE, () => ' ')].some((reading) =>
|
|
35
|
+
token_shape.holds(reading),
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function is_credential_segment(segment: string): boolean {
|
|
40
|
+
const args = git_argv.arguments_of(segment, direct_pr_create.GH_COMMAND)
|
|
41
|
+
|
|
42
|
+
if (args === undefined) return false
|
|
43
|
+
|
|
44
|
+
const call = [direct_pr_create.GH_COMMAND, ...args].join(' ')
|
|
45
|
+
|
|
46
|
+
if (!gh_api.is_gh_api(call)) return false
|
|
47
|
+
|
|
48
|
+
return gh_api.field_sources(call).some((source) => holds_token(sent_text(source)))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function sends_credential(command: string): boolean {
|
|
52
|
+
return direct_pr_create.has_run_segment(command, is_credential_segment)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const CREDENTIAL_BODY_REASON =
|
|
56
|
+
'⛔ credential in a gh api body: a field value, or the file `-F key=@<path>` / `--input <path>` ' +
|
|
57
|
+
'names, holds a token-shaped string (`scripts/lib/token-shape.ts`), and the call would publish it. ' +
|
|
58
|
+
'Remove the credential from the body and send it again. ' +
|
|
59
|
+
'**This rule fires on every occurrence, not once per run.**'
|
|
60
|
+
|
|
61
|
+
const ROW = {
|
|
62
|
+
id: 'credential-body',
|
|
63
|
+
is_trigger: bash_triggers.on_bash_command(sends_credential),
|
|
64
|
+
reason: CREDENTIAL_BODY_REASON,
|
|
65
|
+
decide: (): boolean => true,
|
|
66
|
+
about: {
|
|
67
|
+
title: 'Credential in a body',
|
|
68
|
+
topic: '`shell-body.md`',
|
|
69
|
+
fires:
|
|
70
|
+
'a `gh api` call whose field value, or the file `-F key=@<path>` / `--input <path>` names, holds a token-shaped string (`token-shape.ts`). Every occurrence',
|
|
71
|
+
quiet: 'a body with no credential, or a body sent through kit, which runs the same scan',
|
|
72
|
+
},
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const credential_body = { CREDENTIAL_BODY_REASON, ROW, sends_credential }
|
|
76
|
+
|
|
77
|
+
export { credential_body }
|
|
@@ -66,7 +66,7 @@ const DECISION_ORACLES: ReadonlyArray<DecisionOracle> = [
|
|
|
66
66
|
{
|
|
67
67
|
name: 'review:round2',
|
|
68
68
|
decision: 'Whether the second /code-review round is due',
|
|
69
|
-
args: '[--
|
|
69
|
+
args: '[--record <N>]',
|
|
70
70
|
vocabulary: [REQUIRED, SKIP],
|
|
71
71
|
single_source: CHAIN_RULE_MD,
|
|
72
72
|
},
|