@joshuafolkken/kit 1.1784.0 → 1.2114.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/reviewer-verification.md +19 -0
- package/.claude/agents/reviewer.md +19 -0
- package/.claude/settings.json +5 -6
- package/.claude/skills/dependency-update/SKILL.md +9 -10
- package/.claude/skills/workflow-commands/SKILL.md +6 -6
- package/.claude/skills/workflow-commands/background-commands.md +8 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +3 -1
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-park.md +5 -2
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -3
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +1 -1
- package/.claude/skills/workflow-commands/backlogrun-steps.md +3 -2
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +41 -32
- package/.claude/skills/workflow-commands/delegation.md +6 -6
- package/.claude/skills/workflow-commands/entry-sequence.md +2 -2
- package/.claude/skills/workflow-commands/followup.md +7 -5
- package/.claude/skills/workflow-commands/fullrun-steps.md +6 -6
- package/.claude/skills/workflow-commands/fullrun.md +1 -1
- package/.claude/skills/workflow-commands/issue-comments.md +9 -4
- package/.claude/skills/workflow-commands/issue-fold-existing.md +2 -1
- package/.claude/skills/workflow-commands/kickoff.md +2 -2
- package/.claude/skills/workflow-commands/observation-filing.md +1 -1
- package/.claude/skills/workflow-commands/observation-ledger.md +6 -4
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -7
- package/.claude/skills/workflow-commands/prerequisite.md +3 -2
- package/.claude/skills/workflow-commands/retrospective.md +2 -2
- package/.claude/skills/workflow-commands/split-assessment.md +7 -5
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-pnpm/action.yml +9 -16
- package/.github/dependabot.yml +16 -0
- package/.github/workflows/auto-tag.yml +45 -0
- package/.github/workflows/ci.yml +155 -15
- package/.github/workflows/dependabot-auto-merge.yml +63 -4
- package/.github/workflows/production.yml +8 -0
- package/.github/workflows/publish.yml +59 -45
- package/.vscode/settings.json +19 -0
- package/CLAUDE.md +5 -12
- package/SECURITY.md +2 -2
- package/dist/CLAUDE.md +5 -12
- package/dist/commands/document-read-cli.js +2 -1
- package/dist/commands/document-section-main.js +2 -1
- package/dist/commands/read-set-cli.js +194 -134
- package/dist/commands/run-prep-main.js +9694 -10173
- package/dist/commands/run-step-cli.js +22138 -18285
- package/dist/hooks/audit-provision.js +23 -5
- package/dist/hooks/chunk-3GKE653K.js +6204 -0
- package/dist/hooks/chunk-45CJJOO7.js +1243 -0
- package/dist/hooks/{chunk-CWMBGKYW.js → chunk-5PM2JRGV.js} +2153 -856
- package/dist/hooks/{chunk-WR2KQAYZ.js → chunk-7SIUNQXK.js} +1207 -1470
- package/dist/hooks/{chunk-O2YBIDSI.js → chunk-CQD4LJE6.js} +1682 -1130
- package/dist/hooks/{chunk-VWWCFGWK.js → chunk-OPSRGWFU.js} +1 -1
- package/dist/hooks/{chunk-XGBNSWEI.js → chunk-UJ3FPMMM.js} +132 -49
- package/dist/hooks/chunk-VVNYJWEI.js +30 -0
- package/dist/hooks/chunk-Z6DQJKH3.js +2806 -0
- package/dist/hooks/codex-hook-adapter.js +8 -8
- package/dist/hooks/format-edited.js +4 -5
- package/dist/hooks/inputs.json +415 -389
- package/dist/hooks/pretool-guard.js +7 -6
- package/dist/hooks/session-lang.js +101 -258
- package/dist/hooks/stop-guard.js +1744 -2576
- package/dist/josh.js +7133 -6368
- package/dist/version/index.js +161 -1
- package/eslint/rules/comment-why-only.js +108 -0
- package/package.json +15 -8
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +14 -11
- package/prompts/collaboration-workflow/issue-citation.md +0 -4
- package/prompts/collaboration-workflow/issue-template.md +40 -21
- package/prompts/collaboration-workflow/lane-instructions.md +3 -1
- package/prompts/collaboration-workflow/measurement.md +8 -1
- package/prompts/collaboration-workflow/operating-rules.md +11 -2
- package/prompts/collaboration-workflow/output-bounds.md +6 -2
- package/prompts/collaboration-workflow/plan-comment.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow/residency.md +3 -2
- package/prompts/collaboration-workflow/rule-delivery.md +13 -1
- package/prompts/collaboration-workflow/upstream-interrupt.md +2 -2
- package/prompts/collaboration-workflow/wip-cap.md +3 -1
- package/prompts/review-rubric.md +8 -0
- package/prompts/review.md +31 -22
- package/prompts/testing-guide.md +1 -0
- package/scripts/agent/agent-argv.ts +14 -16
- package/scripts/agent/agent-provider.ts +138 -0
- package/scripts/agent/agent-role-profile.ts +108 -156
- package/scripts/agent/agent-safe-text.ts +20 -5
- package/scripts/agent/api-usage-limit.ts +65 -0
- package/scripts/agent/claude-agent-argv.ts +19 -9
- package/scripts/agent/codex-agent-argv.ts +118 -22
- package/scripts/agent/usage-limit-reset.ts +179 -0
- package/scripts/auth/claude-token-output.ts +2 -2
- package/scripts/auto-ok/auto-ok-author.ts +53 -0
- package/scripts/auto-ok/auto-ok-cli.ts +20 -9
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-cli.ts +6 -1
- package/scripts/backlog/backlog-drive-hold.ts +3 -3
- package/scripts/backlog/backlog-drive-idle.ts +10 -0
- package/scripts/backlog/backlog-drive-launch-pass.ts +90 -0
- package/scripts/backlog/backlog-drive-launch.ts +8 -2
- package/scripts/backlog/backlog-drive-named-offer.ts +73 -30
- package/scripts/backlog/backlog-drive-named.ts +28 -7
- package/scripts/backlog/backlog-drive-paused.ts +5 -4
- package/scripts/backlog/backlog-drive-restore.ts +11 -3
- package/scripts/backlog/backlog-drive.ts +21 -60
- package/scripts/backlog/backlog-gate-scope.ts +61 -0
- package/scripts/backlog/backlog-measure-close.ts +112 -0
- package/scripts/backlog/backlog-next.ts +39 -49
- package/scripts/backlog/backlog-occupied.ts +2 -2
- package/scripts/backlog/backlog-overlap.ts +42 -8
- package/scripts/backlog/backlog-plan-cli.ts +4 -1
- package/scripts/backlog/backlog-plan-comment.ts +81 -0
- package/scripts/backlog/backlog-plan-read.ts +19 -6
- package/scripts/backlog/backlog-pool.ts +50 -12
- package/scripts/backlog/backlog-rank.ts +60 -13
- package/scripts/backlog/backlog-stalled-detect.ts +2 -1
- package/scripts/backlog/backlog-waves.ts +17 -2
- package/scripts/backlog/backlogrun-launch.ts +7 -4
- package/scripts/cost-runtime/context-cut-payback.ts +27 -25
- package/scripts/cost-runtime/cost-cli.ts +37 -16
- package/scripts/cost-runtime/cost-pricing.ts +9 -0
- package/scripts/cost-runtime/cost-verdict.ts +4 -1
- package/scripts/delegation/delegation-policy.ts +2 -2
- package/scripts/delegation/duplicate-read-guard.ts +1 -0
- package/scripts/delegation/investigation-guard.ts +14 -2
- package/scripts/delegation/investigation-reads.ts +45 -23
- package/scripts/dependabot/dependabot-cooldown.ts +3 -2
- package/scripts/discovery/repo-party.ts +80 -20
- package/scripts/discovery/session-owner-pin.ts +51 -0
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/command-reference-line-budget.ts +42 -0
- package/scripts/document/document-byte-budget.ts +17 -7
- package/scripts/document/document-checks.ts +20 -0
- package/scripts/document/document-ratchet-check.ts +101 -0
- package/scripts/document/document-section.ts +1 -0
- package/scripts/document/entry-read-budget.ts +7 -3
- package/scripts/document/issue-citation-budget.ts +94 -0
- package/scripts/epic/epic-cli-argv.ts +2 -2
- package/scripts/epic/epic-fetch.ts +4 -2
- package/scripts/epic/epic-graph.ts +7 -2
- package/scripts/epic/epic-issue.ts +3 -1
- package/scripts/epic/epic-rank.ts +5 -0
- package/scripts/exports/unused-members-check.ts +62 -0
- package/scripts/exports/unused-members-cli.ts +6 -51
- package/scripts/followup/followup-ci-path.ts +67 -0
- package/scripts/followup/followup-coderabbit-retrigger.ts +261 -0
- package/scripts/followup/followup-coderabbit-wait.ts +13 -10
- package/scripts/followup/followup-failed-tests.ts +160 -0
- package/scripts/followup/followup-job-needs.ts +100 -0
- package/scripts/followup/followup-job-rerun.ts +303 -0
- package/scripts/followup/followup-main-move.ts +113 -0
- package/scripts/followup/git-followup-finish.ts +43 -11
- package/scripts/followup/git-followup-pending.ts +3 -3
- package/scripts/followup/git-followup-stages.ts +41 -11
- package/scripts/followup/git-pr-followup-checks.ts +55 -16
- package/scripts/followup/git-pr-followup-wrapup.ts +24 -5
- package/scripts/followup/git-pr-followup.ts +62 -27
- package/scripts/fresh-machine/fresh-machine-script.ts +5 -9
- package/scripts/fresh-machine/specs/kit-test-backlogrun-python.json +2 -2
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +2 -2
- package/scripts/gate/busy-average.ts +34 -2
- package/scripts/gate/check-related-pinned.ts +43 -0
- package/scripts/gate/check-related-reuse.ts +64 -0
- package/scripts/gate/check-related-section.ts +57 -0
- package/scripts/gate/check-related-unplanned.ts +34 -0
- package/scripts/gate/check-related.ts +265 -0
- package/scripts/gate/command-memory.ts +1 -1
- package/scripts/gate/core-admission.ts +24 -6
- package/scripts/gate/core-budget-timing.ts +20 -6
- package/scripts/gate/core-budget.ts +40 -11
- package/scripts/gate/core-wait-record.ts +3 -2
- package/scripts/gate/core-wait.ts +25 -2
- package/scripts/gate/core-weights.ts +15 -7
- package/scripts/gate/gate-labels.ts +46 -0
- package/scripts/gate/gate-ledger.ts +14 -6
- package/scripts/gate/gate-plan.ts +103 -58
- package/scripts/gate/gate-report.ts +9 -7
- package/scripts/gate/gate-run-steps.ts +26 -3
- package/scripts/gate/gate-skip.ts +45 -6
- package/scripts/gate/gate-static-group.ts +60 -0
- package/scripts/gate/gate-steps.ts +2 -1
- package/scripts/gate/gate-tree.ts +4 -2
- package/scripts/gate/hook-gate-reuse.ts +19 -2
- package/scripts/gate/metrics-totals.ts +59 -0
- package/scripts/gate/scoped-green.ts +68 -15
- package/scripts/gate/since-green.ts +14 -6
- package/scripts/gate/structural-checks.ts +96 -0
- package/scripts/gate/verification-gate.ts +51 -16
- package/scripts/gate/verification-inputs.ts +21 -6
- package/scripts/gate/verification-tail.ts +52 -0
- package/scripts/gh/gh-author-association.ts +23 -2
- package/scripts/gh/git-ai-review-scan.ts +1 -1
- package/scripts/gh/git-gh-api-path.ts +12 -3
- package/scripts/gh/git-gh-comments-unreadable.ts +36 -0
- package/scripts/gh/git-gh-exec.ts +32 -2
- package/scripts/gh/git-gh-issue-read.ts +4 -2
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +8 -2
- package/scripts/gh/git-gh-issue.ts +12 -5
- package/scripts/gh/git-gh-pr-auto-merge.ts +13 -6
- package/scripts/gh/git-gh-pr-graphql-state.ts +56 -0
- package/scripts/gh/git-gh-pr-read.ts +74 -13
- package/scripts/gh/git-gh-pr-rest.ts +3 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +22 -7
- package/scripts/gh/git-gh-pr-too-large.ts +20 -0
- package/scripts/gh/git-gh-pr.ts +21 -7
- package/scripts/gh/git-gh-retry.ts +141 -0
- package/scripts/gh/git-pr-ai-review.ts +15 -6
- package/scripts/gh/git-pr-checks-eval.ts +3 -0
- package/scripts/gh/git-pr-checks.ts +5 -5
- package/scripts/git/base-tree.ts +30 -0
- package/scripts/git/change-base.ts +4 -10
- package/scripts/git/changed-paths-sync.ts +63 -0
- package/scripts/git/changed-paths.ts +16 -1
- package/scripts/git/git-common-directory.ts +11 -1
- package/scripts/git/git-diff-reads.ts +66 -20
- package/scripts/git/git-error.ts +9 -2
- package/scripts/git/git-schemas.ts +13 -0
- package/scripts/git/git-worktree.ts +13 -0
- package/scripts/git/gone-branch.ts +4 -1
- package/scripts/git/main-merge-budget-conflict.ts +89 -0
- package/scripts/git/main-merge-guard.ts +55 -18
- package/scripts/git/main-merge-regenerate.ts +59 -25
- package/scripts/git/main-merge.ts +53 -5
- package/scripts/git/no-base-checkout.ts +127 -0
- package/scripts/git/stash/git-stash.ts +11 -2
- package/scripts/git/stash/stash-push-cli.ts +10 -0
- package/scripts/hooks/batch-guard.ts +40 -21
- package/scripts/hooks/edited-cspell.ts +37 -11
- package/scripts/hooks/format-edited-file.ts +22 -2
- package/scripts/hooks/lane-plan-guard.ts +50 -0
- package/scripts/hooks/pre-commit-lint-switch.ts +9 -0
- package/scripts/hooks/pre-commit-lint.ts +14 -1
- package/scripts/hooks/pre-push-related-switch.ts +10 -0
- package/scripts/hooks/pre-push-unit.ts +76 -10
- package/scripts/hooks/pretool-guard.ts +2 -0
- package/scripts/hooks/reserved-run.ts +14 -1
- package/scripts/hooks/run-hook.sh +23 -8
- package/scripts/hooks/step-zero-notice.ts +6 -1
- package/scripts/hooks/stop-actions.ts +3 -15
- package/scripts/hooks/stop-guard.ts +7 -6
- package/scripts/init/distributed-paths.ts +1 -0
- package/scripts/init/hook-command-rewrite.ts +5 -1
- package/scripts/init/hook-launch.ts +4 -2
- package/scripts/issue/aggregation-split.ts +52 -0
- package/scripts/issue/defect-origin-line.ts +19 -1
- package/scripts/issue/defect-rate-cli.ts +5 -102
- package/scripts/issue/defect-report.ts +4 -4
- package/scripts/issue/effect-audit-cli.ts +178 -0
- package/scripts/issue/effect-audit.ts +185 -0
- package/scripts/issue/expected-effect-lint.ts +64 -9
- package/scripts/issue/git-next-issues.ts +5 -0
- package/scripts/issue/issue-body-or-comment.ts +38 -4
- package/scripts/issue/issue-cite-cli.ts +1 -3
- package/scripts/issue/issue-classification.ts +1 -0
- package/scripts/issue/issue-closing-pr.ts +8 -1
- package/scripts/issue/issue-evidence-exit.ts +4 -2
- package/scripts/issue/issue-file-cap.ts +58 -0
- package/scripts/issue/issue-file-cli.ts +111 -38
- package/scripts/issue/issue-file-deferral.ts +52 -0
- package/scripts/issue/issue-file-fold.ts +29 -10
- package/scripts/issue/issue-file-interrupt.ts +85 -0
- package/scripts/issue/issue-file-lane-hint.ts +30 -0
- package/scripts/issue/issue-file.ts +43 -6
- package/scripts/issue/issue-labels.ts +19 -2
- package/scripts/issue/issue-lint-cli.ts +27 -2
- package/scripts/issue/issue-measured-cli.ts +13 -35
- package/scripts/issue/issue-measured-close.ts +58 -0
- package/scripts/issue/issue-not-before-label.ts +2 -2
- package/scripts/issue/issue-not-before.ts +4 -1
- package/scripts/issue/issue-priority-cli.ts +60 -0
- package/scripts/issue/issue-priority-raise.ts +55 -0
- package/scripts/issue/issue-priority.ts +174 -43
- package/scripts/issue/issue-rank.ts +21 -4
- package/scripts/issue/issue-read-cli.ts +32 -6
- package/scripts/issue/issue-read.ts +37 -12
- package/scripts/issue/issue-sample-gate.ts +95 -74
- package/scripts/issue/issue-sample-prime.ts +127 -0
- package/scripts/issue/issue-sample-required.ts +57 -0
- package/scripts/issue/issue-sample-source.ts +12 -11
- package/scripts/issue/issue-search.ts +124 -0
- package/scripts/issue/issue-state.ts +13 -1
- package/scripts/issue/issue-template-section.ts +43 -0
- package/scripts/issue/issue-watch-diff.ts +31 -1
- package/scripts/issue/issue-watch-hook.ts +11 -2
- package/scripts/issue/issue-watch.ts +55 -12
- package/scripts/issue/markdown-section.ts +1 -0
- package/scripts/issue/measure-declaration.ts +121 -0
- package/scripts/issue/measure-rerun-cli.ts +7 -70
- package/scripts/issue/plan-consumers-section.ts +22 -1
- package/scripts/issue/reproduction-measure.ts +3 -1
- package/scripts/issue/size-estimate.ts +90 -0
- package/scripts/issue/trusted-measure.ts +84 -0
- package/scripts/josh/command-usage.ts +3 -2
- package/scripts/josh/durable-state-migrate.ts +105 -0
- package/scripts/josh/durable-state.ts +112 -0
- package/scripts/josh/josh-aliases.ts +95 -0
- package/scripts/josh/josh-command-map.ts +1 -82
- package/scripts/josh/josh-commands-agent-hooks.ts +6 -6
- package/scripts/josh/josh-commands-ai.ts +5 -5
- package/scripts/josh/josh-commands-development.ts +59 -58
- package/scripts/josh/josh-commands-issue-write.ts +23 -4
- package/scripts/josh/josh-commands-issue.ts +32 -0
- package/scripts/josh/josh-commands-lane.ts +87 -4
- package/scripts/josh/josh-commands-lint.ts +16 -3
- package/scripts/josh/josh-commands-maintenance.ts +15 -0
- package/scripts/josh/josh-commands-review.ts +41 -6
- package/scripts/josh/josh-commands-ship.ts +56 -8
- package/scripts/josh/josh-commands-test-check.ts +80 -0
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/josh-environment-file.ts +43 -3
- package/scripts/josh/josh-in-process.ts +2 -2
- package/scripts/josh/josh-logic.ts +5 -3
- package/scripts/josh/josh-run.ts +19 -1
- package/scripts/josh/run-record-path.ts +15 -0
- package/scripts/josh/stamp-file.ts +11 -2
- package/scripts/lane/lane-adopt-cli.ts +98 -0
- package/scripts/lane/lane-adopt.ts +208 -0
- package/scripts/lane/lane-await.ts +5 -8
- package/scripts/lane/lane-baseline.ts +123 -0
- package/scripts/lane/lane-breakdown-cli.ts +64 -0
- package/scripts/lane/lane-breakdown-implement.ts +170 -0
- package/scripts/lane/lane-breakdown-laps.ts +107 -0
- package/scripts/lane/lane-breakdown-pinned.ts +76 -0
- package/scripts/lane/lane-breakdown-text.ts +145 -0
- package/scripts/lane/lane-breakdown.ts +239 -0
- package/scripts/lane/lane-check-stats.ts +29 -8
- package/scripts/lane/lane-child-invocation.ts +9 -2
- package/scripts/lane/lane-child-mark-keys.ts +12 -0
- package/scripts/lane/lane-child-marker.ts +20 -1
- package/scripts/lane/lane-ci-path-stats.ts +73 -0
- package/scripts/lane/lane-claim-stats.ts +84 -0
- package/scripts/lane/lane-close.ts +8 -3
- package/scripts/lane/lane-dispatch-log.ts +3 -3
- package/scripts/lane/lane-dispatch.ts +2 -2
- package/scripts/lane/lane-gap-stats.ts +7 -6
- package/scripts/lane/lane-guard-policy.ts +7 -1
- package/scripts/lane/lane-implement-stats.ts +207 -0
- package/scripts/lane/lane-implement-subagents.ts +90 -0
- package/scripts/lane/lane-investigation-switch.ts +16 -0
- package/scripts/lane/lane-ledger-kind.ts +31 -0
- package/scripts/lane/lane-ledger-schema-ship.ts +49 -0
- package/scripts/lane/lane-ledger-schema.ts +119 -36
- package/scripts/lane/lane-ledger-write.ts +257 -0
- package/scripts/lane/lane-ledger.ts +31 -177
- package/scripts/lane/lane-load.ts +1 -1
- package/scripts/lane/lane-measure-cli.ts +176 -59
- package/scripts/lane/lane-net-read.ts +44 -0
- package/scripts/lane/lane-net-time.ts +212 -0
- package/scripts/lane/lane-open.ts +16 -7
- package/scripts/lane/lane-output.ts +2 -4
- package/scripts/lane/lane-overrun-prompt.ts +147 -0
- package/scripts/lane/lane-overrun.ts +274 -0
- package/scripts/lane/lane-paths.ts +24 -1
- package/scripts/lane/lane-pause-cli.ts +4 -1
- package/scripts/lane/lane-paused-spans.ts +97 -0
- package/scripts/lane/lane-plan-check.ts +207 -0
- package/scripts/lane/lane-plan-cli.ts +41 -0
- package/scripts/lane/lane-plan.ts +144 -0
- package/scripts/lane/lane-registry.ts +14 -1
- package/scripts/lane/lane-relaunch.ts +1 -1
- package/scripts/lane/lane-round-one-stats.ts +51 -0
- package/scripts/lane/lane-sampler.ts +23 -4
- package/scripts/lane/lane-session-action.ts +93 -18
- package/scripts/lane/lane-session-broker.ts +49 -21
- package/scripts/lane/lane-session-reread-main.ts +14 -0
- package/scripts/lane/lane-session-reread.ts +51 -0
- package/scripts/lane/lane-ship-lap-stats.ts +74 -0
- package/scripts/lane/lane-sleep.ts +58 -0
- package/scripts/lane/lane-spent.ts +1 -1
- package/scripts/lane/lane-split-stats.ts +28 -0
- package/scripts/lane/lane-stage-stats.ts +13 -1
- package/scripts/lane/lane-state.ts +41 -9
- package/scripts/lane/lane-stats-tables.ts +58 -0
- package/scripts/lane/lane-stats.ts +21 -5
- package/scripts/lane/lane-stop-stats.ts +51 -19
- package/scripts/lane/lane-tail-stats.ts +32 -0
- package/scripts/lane/lane-transcript-calls.ts +67 -10
- package/scripts/lane/lane-transcript-stats.ts +44 -12
- package/scripts/lane/lane-value-cell.ts +72 -0
- package/scripts/lane/lane-value.ts +118 -0
- package/scripts/lane/lane-withdraw-closed.ts +124 -0
- package/scripts/lane/lane-withdraw.ts +108 -31
- package/scripts/lane/lane-yield.ts +85 -0
- package/scripts/lane/openai-lane-ship.ts +12 -11
- package/scripts/lane/openai-lane-supervisor-decision.ts +6 -8
- package/scripts/lane/openai-lane-supervisor-owner.ts +5 -8
- package/scripts/lane/openai-lane-supervisor.ts +5 -4
- package/scripts/lib/poll.ts +38 -9
- package/scripts/lib/settled-together.ts +10 -0
- package/scripts/lib/shell-quote.ts +21 -0
- package/scripts/lib/token-shape.ts +111 -0
- package/scripts/lint/eslint-daemon-sources.ts +79 -0
- package/scripts/lint/eslint-daemon.ts +45 -6
- package/scripts/lint/eslint-warm-cli.ts +7 -0
- package/scripts/lint/eslint-warm.ts +66 -0
- package/scripts/lint/import-graph.ts +141 -11
- package/scripts/lint/lint-gate-scope.ts +2 -2
- package/scripts/lint/lint-parallel.ts +54 -6
- package/scripts/lint/lint-related.ts +154 -33
- package/scripts/lint/rename-cli.ts +179 -0
- package/scripts/lint/rename-identifier.ts +192 -0
- package/scripts/lint/type-only-imports.ts +58 -0
- package/scripts/notify/telegram-notify.ts +12 -3
- package/scripts/observations/observation-record.ts +42 -16
- package/scripts/observations/observations-flush.ts +32 -9
- package/scripts/overrides/overrides-check.ts +9 -1
- package/scripts/release/release-approval-prune.ts +7 -1
- package/scripts/repo/required-checks-logic.ts +4 -1
- package/scripts/repo/ruleset-check.ts +4 -3
- package/scripts/report/markdown-shape.ts +28 -0
- package/scripts/report/report-format-reference.ts +15 -1
- package/scripts/report/report-labels.ts +12 -1
- package/scripts/report/report-lint-child-summary.ts +94 -0
- package/scripts/report/report-lint-cli.ts +26 -7
- package/scripts/report/report-lint.ts +2 -20
- package/scripts/review/prose-stale-cli.ts +88 -0
- package/scripts/review/prose-stale-scan.ts +152 -0
- package/scripts/review/review-attest.ts +73 -23
- package/scripts/review/review-brief-cli.ts +68 -19
- package/scripts/review/review-brief-paths.ts +22 -0
- package/scripts/review/review-brief.ts +14 -7
- package/scripts/review/review-comment-carry.ts +47 -0
- package/scripts/review/review-comment-round.ts +85 -22
- package/scripts/review/review-finding-ledger.ts +109 -7
- package/scripts/review/review-finding-text.ts +43 -0
- package/scripts/review/review-interaction.ts +11 -0
- package/scripts/review/review-lane-handover.ts +68 -0
- package/scripts/review/review-lint-cli.ts +57 -0
- package/scripts/review/review-lint-findings.ts +92 -0
- package/scripts/review/review-lint-sections.ts +80 -0
- package/scripts/review/review-lint.ts +221 -0
- package/scripts/review/review-prior-findings.ts +102 -0
- package/scripts/review/review-readers-scan.ts +4 -2
- package/scripts/review/review-record-cli.ts +177 -54
- package/scripts/review/review-record-code-round.ts +55 -0
- package/scripts/review/review-record-comment.ts +60 -0
- package/scripts/review/review-record-interaction.ts +35 -0
- package/scripts/review/review-record-pinned.ts +108 -0
- package/scripts/review/review-record.ts +25 -1
- package/scripts/review/review-reviewed-tree.ts +307 -0
- package/scripts/review/review-round-one-closure.ts +62 -0
- package/scripts/review/review-round-reuse.ts +106 -0
- package/scripts/review/review-round2-cli.ts +91 -29
- package/scripts/review/review-round2-skip-comment.ts +55 -0
- package/scripts/review/review-round2.ts +24 -8
- package/scripts/review/review-stamps.ts +7 -3
- package/scripts/review/review-stop-log.ts +20 -6
- package/scripts/review/review-stops-cli.ts +2 -1
- package/scripts/review/review-submit-cli.ts +101 -0
- package/scripts/rules/agent-model.ts +1 -1
- package/scripts/rules/bash-triggers.ts +3 -3
- package/scripts/rules/concise-reply.ts +88 -0
- package/scripts/rules/credential-body.ts +77 -0
- package/scripts/rules/decision-oracle.ts +1 -1
- package/scripts/rules/delivered-rules.ts +36 -17
- package/scripts/rules/destructive-command.ts +3 -11
- package/scripts/rules/direct-issue-comment.ts +34 -12
- package/scripts/rules/direct-issue-read.ts +191 -0
- package/scripts/rules/direct-pr-create.ts +4 -24
- package/scripts/rules/early-heartbeat.ts +2 -0
- package/scripts/rules/edit-tool.ts +27 -0
- package/scripts/rules/file-edit-rows.ts +17 -0
- package/scripts/rules/file-rewrite.ts +146 -0
- package/scripts/rules/firing-point.ts +3 -2
- package/scripts/rules/gh-api.ts +128 -7
- package/scripts/rules/gh-repo-selector.ts +84 -0
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/guard-remedy.ts +14 -5
- package/scripts/rules/implementation-cut.ts +61 -28
- package/scripts/rules/investigator-foreground.ts +231 -0
- package/scripts/rules/issue-citation.ts +15 -60
- package/scripts/rules/issue-comments.ts +9 -4
- package/scripts/rules/josh-git-bare.ts +1 -1
- package/scripts/rules/lane-background.ts +41 -13
- package/scripts/rules/lane-direct-tool.ts +107 -9
- package/scripts/rules/lane-interactive-ask.ts +4 -1
- package/scripts/rules/lane-park.ts +4 -2
- package/scripts/rules/lane-spilled-read.ts +90 -0
- package/scripts/rules/lane-split-park.ts +1 -1
- package/scripts/rules/lane-switch-main.ts +4 -4
- package/scripts/rules/last-prompt.ts +20 -47
- package/scripts/rules/oracle-consulted.ts +1 -1
- package/scripts/rules/permission-guards.ts +5 -1
- package/scripts/rules/piped-verification-shapes.ts +110 -0
- package/scripts/rules/piped-verification.ts +67 -17
- package/scripts/rules/poll-loop.ts +72 -9
- package/scripts/rules/pr-merge.ts +5 -5
- package/scripts/rules/pre-gate-cut.ts +3 -3
- package/scripts/rules/protected-files.ts +88 -24
- package/scripts/rules/reply-language.ts +3 -17
- package/scripts/rules/reply-prose.ts +34 -0
- package/scripts/rules/repo-admin.ts +132 -0
- package/scripts/rules/reviewer-foreground.ts +88 -0
- package/scripts/rules/round-one-check-related.ts +120 -0
- package/scripts/rules/rule-body-guard.ts +5 -15
- package/scripts/rules/rule-value-cache.ts +53 -5
- package/scripts/rules/rule-value-candidates.ts +84 -0
- package/scripts/rules/rule-value-cli.ts +59 -11
- package/scripts/rules/rule-value.ts +17 -4
- package/scripts/rules/run-tail-rule.ts +1 -1
- package/scripts/rules/sed-in-place.ts +196 -0
- package/scripts/rules/shell-segments.ts +10 -2
- package/scripts/rules/stop-rule-rows.ts +1 -13
- package/scripts/rules/stop-rules.ts +33 -58
- package/scripts/rules/test-declared-commit.ts +1 -1
- package/scripts/rules/third-party-write.ts +110 -23
- package/scripts/rules/timed-rerun.ts +1 -1
- package/scripts/rules/turn-filings.ts +90 -0
- package/scripts/rules/worktree-guard.ts +22 -7
- package/scripts/run/board/run-board-ending-reason.ts +6 -2
- package/scripts/run/board/run-board-fit.ts +24 -1
- package/scripts/run/board/run-board-found.ts +134 -0
- package/scripts/run/board/run-board-header.ts +8 -0
- package/scripts/run/board/run-board-labels.ts +11 -1
- package/scripts/run/board/run-board-lane-time.ts +1 -0
- package/scripts/run/board/run-board-link.ts +15 -2
- package/scripts/run/board/run-board-notes.ts +7 -1
- package/scripts/run/board/run-board-operation.ts +4 -2
- package/scripts/run/board/run-board-phase.ts +2 -5
- package/scripts/run/board/run-board-plan.ts +1 -1
- package/scripts/run/board/run-board-read.ts +46 -1
- package/scripts/run/board/run-board-reason.ts +20 -8
- package/scripts/run/board/run-board-render-checks.ts +3 -2
- package/scripts/run/board/run-board-render-drawn.ts +11 -0
- package/scripts/run/board/run-board-render-found.ts +157 -0
- package/scripts/run/board/run-board-render-lead.ts +9 -0
- package/scripts/run/board/run-board-render-legend.ts +19 -0
- package/scripts/run/board/run-board-render-tail.ts +1 -1
- package/scripts/run/board/run-board-render.ts +82 -18
- package/scripts/run/board/run-board-spin.ts +1 -3
- package/scripts/run/board/run-board-status.ts +2 -0
- package/scripts/run/board/run-board-tick.ts +39 -10
- package/scripts/run/carry/run-carry-ended.ts +3 -2
- package/scripts/run/carry/run-carry.ts +3 -2
- package/scripts/run/cut/run-cut-cli.ts +33 -133
- package/scripts/run/cut/run-cut-digest.ts +152 -0
- package/scripts/run/cut/run-cut-handoff.ts +52 -8
- package/scripts/run/cut/run-cut-report.ts +24 -3
- package/scripts/run/cut/run-cut-resume.ts +129 -0
- package/scripts/run/cut/run-cut-review.ts +105 -0
- package/scripts/run/cut/run-cut.ts +18 -7
- package/scripts/run/detached-launch.ts +1 -1
- package/scripts/run/entry/run-entry-cli.ts +88 -19
- package/scripts/run/entry/run-entry-spill.ts +83 -0
- package/scripts/run/entry/run-entry-stop.ts +5 -1
- package/scripts/run/entry/run-entry-trust.ts +91 -0
- package/scripts/run/event/run-event-baseline.ts +56 -0
- package/scripts/run/event/run-event-filed.ts +9 -3
- package/scripts/run/event/run-event-overrun.ts +197 -0
- package/scripts/run/event/run-event-render.ts +4 -0
- package/scripts/run/event/run-event-stream.ts +25 -3
- package/scripts/run/hold/run-stop-notify.ts +3 -8
- package/scripts/run/merge/run-merge-cap.ts +57 -0
- package/scripts/run/merge/run-merge-cli.ts +66 -23
- package/scripts/run/merge/run-merge-outcome.ts +2 -0
- package/scripts/run/merge/run-merge-ship.ts +13 -3
- package/scripts/run/merge/run-merge-signals.ts +40 -23
- package/scripts/run/merge/run-merge-steps.ts +56 -36
- package/scripts/run/merge/run-merge-usage-limit.ts +53 -0
- package/scripts/run/merge/run-merge-withdrawn.ts +53 -0
- package/scripts/run/merge/run-merge.ts +41 -14
- package/scripts/run/review/run-review-cli.ts +306 -20
- package/scripts/run/review/run-review-early-push.ts +121 -0
- package/scripts/run/review/run-review-join-read.ts +94 -0
- package/scripts/run/review/run-review-pinned-accepted.ts +126 -0
- package/scripts/run/review/run-review-pinned-join.ts +216 -0
- package/scripts/run/review/run-review-pinned-steps.ts +383 -0
- package/scripts/run/review/run-review-pinned-tree.ts +37 -0
- package/scripts/run/review/run-review-pinned.ts +53 -0
- package/scripts/run/review/run-review-steps.ts +70 -34
- package/scripts/run/review/run-review.ts +26 -6
- package/scripts/run/run-parent-cut-hook.ts +3 -4
- package/scripts/run/run-prep.ts +1 -0
- package/scripts/run/run-stage-read.ts +2 -6
- package/scripts/run/run-step-cli.ts +17 -5
- package/scripts/run/run-step-lane-plan.ts +27 -0
- package/scripts/run/run-step-section.ts +26 -7
- package/scripts/run/run-step.ts +5 -2
- package/scripts/run/ship/run-ship-args.ts +19 -0
- package/scripts/run/ship/run-ship-brokered-review.ts +106 -0
- package/scripts/run/ship/run-ship-cli.ts +131 -39
- package/scripts/run/ship/run-ship-conflict-probe.ts +59 -0
- package/scripts/run/ship/run-ship-detach.ts +10 -4
- package/scripts/run/ship/run-ship-handover.ts +106 -0
- package/scripts/run/ship/run-ship-infra-retry.ts +16 -1
- package/scripts/run/ship/run-ship-lap.ts +63 -0
- package/scripts/run/ship/run-ship-next.ts +27 -26
- package/scripts/run/ship/run-ship-overlap.ts +8 -3
- package/scripts/run/ship/run-ship-place.ts +9 -2
- package/scripts/run/ship/run-ship-planned.ts +92 -0
- package/scripts/run/ship/run-ship-pre-detach-pinned.ts +197 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +77 -23
- package/scripts/run/ship/run-ship-preflight.ts +16 -4
- package/scripts/run/ship/run-ship-probe.ts +23 -9
- package/scripts/run/ship/run-ship-relaunch-cap.ts +43 -7
- package/scripts/run/ship/run-ship-relaunch.ts +51 -0
- package/scripts/run/ship/run-ship-return.ts +103 -29
- package/scripts/run/ship/run-ship-review-reason.ts +24 -0
- package/scripts/run/ship/run-ship-review-steps.ts +230 -59
- package/scripts/run/ship/run-ship-review.ts +171 -51
- package/scripts/run/ship/run-ship-reviewer.ts +138 -42
- package/scripts/run/ship/run-ship-scoped.ts +39 -10
- package/scripts/run/ship/run-ship-stage.ts +49 -13
- package/scripts/run/ship/run-ship-steps.ts +24 -4
- package/scripts/run/ship/run-ship-stop-cause.ts +43 -2
- package/scripts/run/ship/run-ship-stop-context.ts +50 -13
- package/scripts/run/ship/run-ship-sync.ts +171 -30
- package/scripts/run/ship/run-ship-synced-scope.ts +178 -0
- package/scripts/run/ship/run-ship-wait-cli.ts +145 -0
- package/scripts/run/ship/run-ship-waiter.ts +114 -0
- package/scripts/run/ship/run-ship.ts +16 -2
- package/scripts/run/wake/run-wake-caffeinate.ts +48 -0
- package/scripts/run/wake/run-wake-cli.ts +6 -113
- package/scripts/run/wake/run-wake-code.ts +53 -11
- package/scripts/run/wake/run-wake-driver.ts +5 -3
- package/scripts/run/wake/run-wake-finish.ts +137 -0
- package/scripts/run/wake/run-wake-loop.ts +5 -3
- package/scripts/run/wake/run-wake-ports.ts +11 -3
- package/scripts/run/wake/run-wake-session.ts +2 -0
- package/scripts/run/wake/run-wake.ts +3 -2
- package/scripts/safe-chain/ci-installer-pin.ts +49 -8
- package/scripts/safe-chain/project-config.ts +3 -2
- package/scripts/security/secretlint-scan.ts +42 -9
- package/scripts/security/security-audit-provision-main.ts +9 -1
- package/scripts/security/security-audit-provision.ts +1 -1
- package/scripts/security/security-audit.ts +21 -1
- package/scripts/security/sonar-file.ts +10 -5
- package/scripts/split/split-assess.ts +12 -3
- package/scripts/split/split-early-notice.ts +116 -0
- package/scripts/split/split-measure.ts +20 -2
- package/scripts/split/split-resolution.ts +107 -0
- package/scripts/test/direct-importers.ts +185 -0
- package/scripts/test/pure-files-entries.ts +83 -0
- package/scripts/test/related-heavy-tests.ts +81 -0
- package/scripts/test/test-no-base.ts +88 -0
- package/scripts/test/test-pinned-cache-logic.ts +363 -0
- package/scripts/test/test-pinned-cache.ts +337 -0
- package/scripts/test/test-pinned-emit.ts +49 -0
- package/scripts/test/test-pinned-functions.ts +116 -0
- package/scripts/test/test-pinned-ledger.ts +80 -0
- package/scripts/test/test-pinned-logic.ts +208 -20
- package/scripts/test/test-pinned-main.ts +84 -18
- package/scripts/test/test-pinned-pool.ts +73 -0
- package/scripts/test/test-pinned-probe.ts +254 -0
- package/scripts/test/test-pinned-prune-logic.ts +118 -0
- package/scripts/test/test-pinned-reach.ts +194 -0
- package/scripts/test/test-pinned-record.ts +196 -0
- package/scripts/test/test-pinned-rewire.ts +148 -0
- package/scripts/test/test-pinned-spawn.ts +81 -0
- package/scripts/test/test-pinned-stage.ts +70 -0
- package/scripts/test/test-pinned.ts +258 -47
- package/scripts/test/test-reach-cli.ts +61 -0
- package/scripts/test/test-read-map.ts +35 -11
- package/scripts/test/test-read-recording.ts +17 -5
- package/scripts/test/test-read-trace.ts +26 -8
- package/scripts/test/test-red-logic.ts +46 -7
- package/scripts/test/test-red.ts +34 -14
- package/scripts/test/test-related-claim.ts +37 -0
- package/scripts/test/test-related-main.ts +4 -1
- package/scripts/test/test-related-moved.ts +91 -0
- package/scripts/test/test-related-record.ts +43 -23
- package/scripts/test/test-related-scope.ts +99 -34
- package/scripts/test/test-related-synced.ts +135 -0
- package/scripts/test/test-related-touched.ts +84 -0
- package/scripts/test/test-related.ts +167 -83
- package/scripts/test/test-unit-guard.ts +28 -5
- package/scripts/test/unit-durations.ts +41 -0
- package/scripts/test/unit-worker-share.ts +5 -4
- package/scripts/test/vitest-cache-directory.ts +19 -0
- package/scripts/test/vitest-cli-excludes.ts +14 -0
- package/scripts/test/vitest-failure-summary.ts +111 -0
- package/scripts/test/whole-suite-files.ts +12 -1
- package/scripts/time-runtime/time-batch-guard.ts +42 -4
- package/scripts/time-runtime/time-bundle-call.ts +1 -1
- package/scripts/time-runtime/time-bundles.ts +36 -5
- package/scripts/time-runtime/time-markers.ts +2 -2
- package/scripts/time-runtime/time-search-call.ts +38 -0
- package/scripts/time-runtime/time-shell.ts +1 -1
- package/scripts/time-runtime/time-transcript-line.ts +17 -5
- package/scripts/version/development-engines-verdict.ts +124 -0
- package/scripts/version/latest-corepack.ts +2 -0
- package/templates/gitignore +2 -0
- package/templates/workflows/ci.yml +41 -0
- package/dist/hooks/chunk-AZX4FGQ3.js +0 -207
- package/dist/hooks/chunk-PT5R6UJD.js +0 -7131
- package/dist/hooks/chunk-TUIFS5E7.js +0 -72
- package/dist/hooks/chunk-YCDOIR3I.js +0 -3456
- package/scripts/cost-runtime/context-cut-threshold.ts +0 -11
- package/scripts/rules/filing-cap.ts +0 -139
|
@@ -35,10 +35,15 @@ import { run_tail_rule } from './run-tail-rule'
|
|
|
35
35
|
|
|
36
36
|
// The josh subcommands that run long enough to be backgrounded, as `time_shell` names them — canonical,
|
|
37
37
|
// so the `ga` / `g` / `fu` aliases are covered by the one spelling.
|
|
38
|
-
|
|
38
|
+
// `ship`, `ship:wait` and `lane:plan` are run in the foreground at the cap rather than refused: a
|
|
39
|
+
// `ship:wait` left at the two-minute default is moved aside mid-chunk and dies with the turn, its verdict
|
|
40
|
+
// unread, and a cut `lane:plan` leaves its plan recorded with the check it gates unanswered.
|
|
41
|
+
const FOREGROUND_COMMANDS: ReadonlySet<string> = new Set(
|
|
42
|
+
['ship', 'ship:wait', 'lane:plan'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
|
|
43
|
+
)
|
|
39
44
|
const LONG_RUNNING_COMMANDS: ReadonlySet<string> = new Set([
|
|
40
45
|
...['gate', 'git', 'followup'].map((name) => `${time_shell.JOSH_PREFIX}${name}`),
|
|
41
|
-
|
|
46
|
+
...FOREGROUND_COMMANDS,
|
|
42
47
|
])
|
|
43
48
|
|
|
44
49
|
const BACKGROUND_KEY = 'run_in_background'
|
|
@@ -57,13 +62,13 @@ function long_commands_of(command: string): Array<string> {
|
|
|
57
62
|
return time_shell.josh_commands_of(command).filter((name) => LONG_RUNNING_COMMANDS.has(name))
|
|
58
63
|
}
|
|
59
64
|
|
|
60
|
-
// A call whose long-running work is `ship` alone. In a child a foreground `ship` already
|
|
61
|
-
// itself after its preflight (`run-ship-cli.ts` → `should_detach`), so the only fault in
|
|
62
|
-
// it is the flag — and the flag is what the hook rewrites.
|
|
65
|
+
// A call whose long-running work is `ship` or `ship:wait` alone. In a child a foreground `ship` already
|
|
66
|
+
// detaches itself after its preflight (`run-ship-cli.ts` → `should_detach`), so the only fault in
|
|
67
|
+
// backgrounding it is the flag — and the flag is what the hook rewrites.
|
|
63
68
|
function ships_alone(command: string): boolean {
|
|
64
69
|
const names = long_commands_of(command)
|
|
65
70
|
|
|
66
|
-
return names.length > 0 && names.every((name) => name
|
|
71
|
+
return names.length > 0 && names.every((name) => FOREGROUND_COMMANDS.has(name))
|
|
67
72
|
}
|
|
68
73
|
|
|
69
74
|
function backgrounded_bash_command(call: GuardedCall): string | undefined {
|
|
@@ -135,10 +140,10 @@ function foreground_input(
|
|
|
135
140
|
}
|
|
136
141
|
|
|
137
142
|
const FOREGROUND_NOTE =
|
|
138
|
-
"lane background: a lane child's `josh ship` backgrounded, by its flag or by
|
|
139
|
-
'timeout, dies with the headless turn
|
|
140
|
-
'
|
|
141
|
-
'`
|
|
143
|
+
"lane background: a lane child's `josh ship`, `josh ship:wait` or `josh lane:plan` backgrounded, by its flag or by " +
|
|
144
|
+
'outrunning the Bash timeout, dies with the headless turn — so it was run in the foreground at the ' +
|
|
145
|
+
'600000 ms cap, where `ship` detaches itself after the preflight. Then follow ' +
|
|
146
|
+
'`chain-rule.md` step 0 (`josh ship:wait` on `launched`).'
|
|
142
147
|
|
|
143
148
|
type LaunchedIds = (block: TranscriptBlock) => ReadonlyArray<string>
|
|
144
149
|
|
|
@@ -182,11 +187,17 @@ function pending_agent_ids(tail: string): ReadonlyArray<string> {
|
|
|
182
187
|
return unfinished_ids(tail, (block) => [block.agent_id])
|
|
183
188
|
}
|
|
184
189
|
|
|
190
|
+
// The backgrounded commands alone — what tells a stop with only subagents left apart from one a
|
|
191
|
+
// command still holds.
|
|
192
|
+
function pending_command_ids(tail: string): ReadonlyArray<string> {
|
|
193
|
+
return unfinished_ids(tail, (block) => [block.background_id])
|
|
194
|
+
}
|
|
195
|
+
|
|
185
196
|
const LANE_BACKGROUND_REASON =
|
|
186
197
|
'⛔ lane background: this session is a dispatched lane child (`JOSH_LANE_CHILD`), a headless ' +
|
|
187
198
|
'process whose background tasks die when the turn ends. Hand over to ' +
|
|
188
|
-
'`pnpm josh ship --detach --review "<title> #<N>"`, issued in the foreground, then
|
|
189
|
-
'`launched`
|
|
199
|
+
'`pnpm josh ship --detach --review "<title> #<N>"`, issued in the foreground, then `josh ship:wait <N>` on ' +
|
|
200
|
+
'`launched` or end the turn. It fires on every occurrence ' +
|
|
190
201
|
'(`.claude/skills/workflow-commands/chain-rule.md` step 0).'
|
|
191
202
|
|
|
192
203
|
const LANE_BACKGROUND_STOP_REASON =
|
|
@@ -194,6 +205,15 @@ const LANE_BACKGROUND_STOP_REASON =
|
|
|
194
205
|
'it launched has not finished, and ending this turn kills it. Wait for it in the foreground, or ' +
|
|
195
206
|
're-issue the work through `pnpm josh ship --detach` — do not notify, stop or repeat your reply.'
|
|
196
207
|
|
|
208
|
+
// **Only subagents left: the wait that receives their answer** (joshuafolkken/kit#4803). Their completion
|
|
209
|
+
// notice is delivered only when a tool call ends, so one long hand-written loop holds it back until the
|
|
210
|
+
// loop itself gives up; short foreground calls, one at a time, let it in at the first one to end.
|
|
211
|
+
const LANE_AGENT_STOP_REASON =
|
|
212
|
+
'⛔ lane agent stop: this is a dispatched lane child (`JOSH_LANE_CHILD`) and a subagent it launched ' +
|
|
213
|
+
'has not finished; ending this turn kills it. Its completion notice arrives only when a tool call ' +
|
|
214
|
+
'ends: wait with one short foreground call at a time (`sleep 20`) until it arrives — never a loop ' +
|
|
215
|
+
'over its `.output`. Do not notify, stop or repeat your reply.'
|
|
216
|
+
|
|
197
217
|
// The row itself, so `delivered-rules.ts` spreads one entry. It fires on every occurrence (`decide`
|
|
198
218
|
// returns true): a child must never background these, so the route is always the detached ship, never
|
|
199
219
|
// a reissue. It declares no `keeps`: the detached ship is a different command, not this call made right.
|
|
@@ -202,17 +222,24 @@ const ROW = {
|
|
|
202
222
|
is_trigger: (call: GuardedCall): boolean => is_background_long_run(call),
|
|
203
223
|
reason: LANE_BACKGROUND_REASON,
|
|
204
224
|
decide: (): boolean => true,
|
|
225
|
+
// `pretool-guard.ts` rewrites a lone `josh ship` to the foreground rather than refusing it; this is
|
|
226
|
+
// the note it attaches, so `rule-value.ts` counts that rewrite as this row's delivery.
|
|
227
|
+
rewrite_note: FOREGROUND_NOTE,
|
|
228
|
+
// The Stop hook delivers the same rule at the turn's end, for the background task or subagent the
|
|
229
|
+
// turn would kill.
|
|
230
|
+
stop_reasons: [LANE_BACKGROUND_STOP_REASON, LANE_AGENT_STOP_REASON],
|
|
205
231
|
about: {
|
|
206
232
|
title: 'Lane child background push',
|
|
207
233
|
topic: '`.claude/skills/workflow-commands/background-commands.md`',
|
|
208
234
|
fires:
|
|
209
|
-
'a dispatched lane child backgrounding `josh gate` / `git` / `followup` / `ship`; it hands over `pnpm josh ship --detach
|
|
235
|
+
'a dispatched lane child backgrounding `josh gate` / `git` / `followup` / `ship`; it hands over `pnpm josh ship --detach`; the Stop hook also blocks ending a turn with its background task or subagent unfinished. Every occurrence',
|
|
210
236
|
quiet: 'not a lane child, or the foreground `ship --detach`',
|
|
211
237
|
},
|
|
212
238
|
}
|
|
213
239
|
|
|
214
240
|
const lane_background = {
|
|
215
241
|
FOREGROUND_NOTE,
|
|
242
|
+
LANE_AGENT_STOP_REASON,
|
|
216
243
|
LANE_BACKGROUND_REASON,
|
|
217
244
|
LANE_BACKGROUND_STOP_REASON,
|
|
218
245
|
ROW,
|
|
@@ -220,6 +247,7 @@ const lane_background = {
|
|
|
220
247
|
is_background_long_run,
|
|
221
248
|
pending_agent_ids,
|
|
222
249
|
pending_background_ids,
|
|
250
|
+
pending_command_ids,
|
|
223
251
|
}
|
|
224
252
|
|
|
225
253
|
export { lane_background }
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import os from 'node:os'
|
|
2
|
+
import { cost_blocks } from '#scripts/cost-runtime/cost-blocks'
|
|
3
|
+
import { command_memory, type ToolCall } from '#scripts/gate/command-memory'
|
|
4
|
+
import { core_weights } from '#scripts/gate/core-weights'
|
|
2
5
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
6
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
7
|
+
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
8
|
+
import { time_shell } from '#scripts/time-runtime/time-shell'
|
|
3
9
|
import { bash_triggers } from './bash-triggers'
|
|
10
|
+
import { timed_rerun } from './timed-rerun'
|
|
4
11
|
|
|
5
12
|
// A dispatched lane child is stopped from running a heavy tool directly. The core budget
|
|
6
13
|
// (`scripts/gate/core-budget.ts`) counts only what a `josh` command reserves, so an `eslint`, `vitest`,
|
|
@@ -20,16 +27,102 @@ import { bash_triggers } from './bash-triggers'
|
|
|
20
27
|
//
|
|
21
28
|
// **Lane children only.** An interactive session outside a lane keeps its direct runs; the overlap this
|
|
22
29
|
// prevents is between concurrently dispatched lanes.
|
|
30
|
+
//
|
|
31
|
+
// **The commonest direct run is rewritten rather than refused** (joshuafolkken/kit#5147): the refusal's
|
|
32
|
+
// reissue was the same line behind `pnpm josh reserved-run <weight> --`, a round trip the hook can make
|
|
33
|
+
// itself. The weight is the gate's own for that tool — `core_weights.CORE_WEIGHTS`, and for vitest the
|
|
34
|
+
// workers `command_memory.workers_of` reads — so the claim matches what the gate claims. `reserved-run`
|
|
35
|
+
// runs its command as an argv, not a shell line, so only a line that is one command is wrapped: any
|
|
36
|
+
// chain, pipe, redirection, group, substitution, comment, env prefix or timer leaves it to the refusal,
|
|
37
|
+
// as does a multi-worker eslint, which no reservation makes safe. The wrapped line runs in the directory
|
|
38
|
+
// it was typed in (`reserved-run.ts` → `command_directory`).
|
|
23
39
|
|
|
24
|
-
const
|
|
40
|
+
const ESLINT = 'eslint'
|
|
41
|
+
const VITEST = 'vitest'
|
|
42
|
+
const HEAVY_TOOLS: ReadonlySet<string> = new Set([ESLINT, VITEST, 'cspell', 'tsc'])
|
|
43
|
+
const TOOL_WEIGHTS: Readonly<Partial<Record<string, number>>> = {
|
|
44
|
+
[ESLINT]: core_weights.CORE_WEIGHTS.lint,
|
|
45
|
+
tsc: core_weights.CORE_WEIGHTS.type_check,
|
|
46
|
+
cspell: core_weights.CORE_WEIGHTS.spell_check,
|
|
47
|
+
}
|
|
48
|
+
const SINGLE_CORE = 1
|
|
49
|
+
const RESERVED_RUN = 'pnpm josh reserved-run'
|
|
50
|
+
// Read on the quote-blanked line: a quoted `;` or `|` is text. `2>&1` applies to the wrapper alike.
|
|
51
|
+
const MULTI_COMMAND_SYNTAX = /[;|&<>()`#\n]|\$\(/u
|
|
52
|
+
const KEPT_REDIRECT = /2>&1/gu
|
|
53
|
+
const ENV_ASSIGNMENT = /^[A-Za-z_]\w*=/u
|
|
25
54
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
55
|
+
const RESERVED_NOTE =
|
|
56
|
+
'↻ lane direct tool: a lane child ran a heavy tool directly, so the line was wrapped in ' +
|
|
57
|
+
'`pnpm josh reserved-run <weight> --` to claim its cores beside the other lanes. Prefer ' +
|
|
58
|
+
'`pnpm josh lint:related` / `test:related` / `cspell:dot` — `docs/josh-commands-automation.md`.'
|
|
59
|
+
|
|
60
|
+
// The heavy tools the line launches outside a `reserved-run`. The cut is quote-aware, so a tool name
|
|
61
|
+
// inside a quoted argument (`git commit -m "run eslint"`) is never read as a command; a quoted script
|
|
62
|
+
// handed to a shell is.
|
|
63
|
+
function direct_calls(command: string): Array<ToolCall> {
|
|
30
64
|
return command_memory
|
|
31
65
|
.tool_calls_of(command)
|
|
32
|
-
.
|
|
66
|
+
.filter((call) => !call.is_reserved && HEAVY_TOOLS.has(call.name))
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// True when any command on the shell line launches one of the heavy tools outside a `reserved-run`.
|
|
70
|
+
function runs_heavy_tool(command: string): boolean {
|
|
71
|
+
return direct_calls(command).length > 0
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function weight_of(call: ToolCall, cores: number): number {
|
|
75
|
+
if (call.name === VITEST) return command_memory.workers_of(call, cores)
|
|
76
|
+
|
|
77
|
+
return TOOL_WEIGHTS[call.name] ?? SINGLE_CORE
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// True when the whole line is one command, so a `reserved-run` can carry it as its argv.
|
|
81
|
+
function is_one_command(command: string): boolean {
|
|
82
|
+
const judged = time_shell.blanked(command)
|
|
83
|
+
|
|
84
|
+
if (judged === undefined) return false
|
|
85
|
+
|
|
86
|
+
return (
|
|
87
|
+
!MULTI_COMMAND_SYNTAX.test(judged.replaceAll(KEPT_REDIRECT, ' ')) &&
|
|
88
|
+
!ENV_ASSIGNMENT.test(judged)
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// A timed line stays as typed: `timed-rerun` reads the timer at the segment start, and a wrapper in front
|
|
93
|
+
// would hide it from that row.
|
|
94
|
+
function can_wrap(line: string, cores: number): boolean {
|
|
95
|
+
if (!is_one_command(line) || timed_rerun.is_timed_run(line)) return false
|
|
96
|
+
|
|
97
|
+
return !command_memory.runs_multi_worker_eslint(line, cores)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// The line behind `reserved-run` at its largest tool's weight, or `undefined` where it must be refused.
|
|
101
|
+
function reserved_command(
|
|
102
|
+
command: string,
|
|
103
|
+
cores: number = os.availableParallelism(),
|
|
104
|
+
): string | undefined {
|
|
105
|
+
const line = command.trim()
|
|
106
|
+
const calls = direct_calls(line)
|
|
107
|
+
|
|
108
|
+
if (!can_wrap(line, cores) || calls.length === 0) return undefined
|
|
109
|
+
|
|
110
|
+
const weight = Math.max(...calls.map((call) => weight_of(call, cores)))
|
|
111
|
+
|
|
112
|
+
return `${RESERVED_RUN} ${String(weight)} -- ${line}`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function is_lane_bash(call: GuardedCall): boolean {
|
|
116
|
+
return call.name === cost_blocks.BASH_TOOL && lane_child_marker.is_child_of(process.cwd())
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// The call's input with its line wrapped, for a lane child alone; `undefined` where nothing is rewritten.
|
|
120
|
+
function reserved_input(call: GuardedCall): Record<string, unknown> | undefined {
|
|
121
|
+
if (!is_lane_bash(call) || !json_value.is_record(call.input)) return undefined
|
|
122
|
+
|
|
123
|
+
const command = reserved_command(time_shell.bash_command(call.input))
|
|
124
|
+
|
|
125
|
+
return command === undefined ? undefined : { ...call.input, command }
|
|
33
126
|
}
|
|
34
127
|
|
|
35
128
|
// True when this session is a dispatched lane child launching a heavy tool directly, or eslint with
|
|
@@ -47,7 +140,7 @@ const LANE_DIRECT_TOOL_REASON =
|
|
|
47
140
|
'⛔ lane child running `eslint` / `vitest` / `cspell` / `tsc` directly, or multi-worker eslint: ' +
|
|
48
141
|
'it overlaps the other lanes. Run `pnpm josh lint:related`, `pnpm josh test:related`, ' +
|
|
49
142
|
'`pnpm josh cspell:dot` or `pnpm josh reserved-run <weight> -- <command>`, eslint at ' +
|
|
50
|
-
'`--concurrency off
|
|
143
|
+
'`--concurrency off`. Only a one-command line is wrapped for you. Refused on every occurrence.'
|
|
51
144
|
|
|
52
145
|
// The row itself, so `delivered-rules.ts` spreads one entry; the shape is `lane-switch-main.ts`'s.
|
|
53
146
|
const ROW = {
|
|
@@ -55,19 +148,24 @@ const ROW = {
|
|
|
55
148
|
is_trigger: bash_triggers.on_bash_command(is_lane_direct_tool),
|
|
56
149
|
reason: LANE_DIRECT_TOOL_REASON,
|
|
57
150
|
decide: (): boolean => true,
|
|
151
|
+
rewrite: reserved_input,
|
|
152
|
+
rewrite_note: RESERVED_NOTE,
|
|
58
153
|
about: {
|
|
59
154
|
title: 'Lane child running a heavy tool directly',
|
|
60
155
|
topic: '`docs/josh-commands-automation.md` → `josh reserved-run`',
|
|
61
156
|
fires:
|
|
62
|
-
|
|
157
|
+
"a dispatched lane child launching `eslint` / `vitest` / `cspell` / `tsc` (bare, `pnpm exec`, `npx`, inside `sh -c`), or eslint with `--concurrency` other than `off` / `1` by any path, `reserved-run` included. A one-command line is rewritten behind `pnpm josh reserved-run <weight> --` at the gate's weight; a chained, piped, redirected or env-prefixed line and a multi-worker eslint are refused, every occurrence",
|
|
63
158
|
quiet: 'not a lane child, or the run goes through `pnpm josh` with single-worker eslint',
|
|
64
159
|
},
|
|
65
160
|
}
|
|
66
161
|
|
|
67
162
|
const lane_direct_tool = {
|
|
68
163
|
LANE_DIRECT_TOOL_REASON,
|
|
164
|
+
RESERVED_NOTE,
|
|
69
165
|
ROW,
|
|
70
166
|
is_lane_direct_tool,
|
|
167
|
+
reserved_command,
|
|
168
|
+
reserved_input,
|
|
71
169
|
runs_heavy_tool,
|
|
72
170
|
}
|
|
73
171
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { interactive_ask } from '#scripts/agent/interactive-ask'
|
|
2
2
|
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
3
3
|
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
4
|
+
import { stop_rules } from './stop-rules'
|
|
4
5
|
|
|
5
6
|
// A dispatched lane child's interactive ask is refused and routed to the park procedure, delivered at
|
|
6
7
|
// the call it binds on.
|
|
@@ -55,12 +56,14 @@ const ROW = {
|
|
|
55
56
|
is_trigger: is_interactive_ask,
|
|
56
57
|
reason: LANE_INTERACTIVE_ASK_REASON,
|
|
57
58
|
decide: (): boolean => true,
|
|
59
|
+
// A reply asking a person for the git index is the same ask, delivered by the Stop hook.
|
|
60
|
+
stop_reasons: [stop_rules.LANE_INDEX_REASON],
|
|
58
61
|
about: {
|
|
59
62
|
title: 'Lane child interactive ask',
|
|
60
63
|
topic:
|
|
61
64
|
'`.claude/skills/workflow-commands/pre-gate-cut.md` → "The interactive ask is refused one call earlier"',
|
|
62
65
|
fires:
|
|
63
|
-
"a dispatched lane child's `AskUserQuestion`; it hands over the park procedure. Every occurrence",
|
|
66
|
+
"a dispatched lane child's `AskUserQuestion`; it hands over the park procedure; the Stop hook also blocks a reply asking a person for the git index. Every occurrence",
|
|
64
67
|
quiet: 'not a lane child, or not an interactive tool',
|
|
65
68
|
},
|
|
66
69
|
}
|
|
@@ -122,14 +122,16 @@ function records_the_park(command: string): boolean {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
// The instruction in the shape a refusal can carry: what the stop must leave behind, how to record it,
|
|
125
|
-
// and the
|
|
125
|
+
// and that the park is the stop itself — no notify follows it, since the `Stop` hook sends one still owed
|
|
126
|
+
// on the hold (`stop-rules.ts` → `needs_notify`). **The park procedure is named, not restated** — the
|
|
126
127
|
// single source is `backlogrun-park.md` → "park and continue", and a second copy here would be the
|
|
127
128
|
// clone `CLAUDE.md` prohibits.
|
|
128
129
|
const LANE_PARK_REASON =
|
|
129
130
|
'⛔ lane child park: this session is a dispatched lane child, so a stop for a person parks first: ' +
|
|
130
131
|
'`pnpm josh run:park <N> --body-file <path>` (question, options, stash — it applies ' +
|
|
131
132
|
'`needs-decision`); a ' +
|
|
132
|
-
'`needs-human-review` / `already-done` stop already is.
|
|
133
|
+
'`needs-human-review` / `already-done` stop already is. The park is the stop: no notify ' +
|
|
134
|
+
'after it. Refused once per run ' +
|
|
133
135
|
'(`.claude/skills/workflow-commands/pre-gate-cut.md`).'
|
|
134
136
|
|
|
135
137
|
// The row itself, so `delivered-rules.ts` spreads one entry. **Once per run rather than `decide`.** The
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { lane_child_marker } from '#scripts/lane/lane-child-marker'
|
|
2
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
3
|
+
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
4
|
+
|
|
5
|
+
// A dispatched lane child's whole `Read` of a spilled Bash result is refused and pointed at a narrowed
|
|
6
|
+
// read (joshuafolkken/kit#5040).
|
|
7
|
+
//
|
|
8
|
+
// **The spill is the largest single result a cut session carries.** A Bash result over the harness cap
|
|
9
|
+
// is saved to `tool-results/<id>.txt` and previewed; reading that file back whole put 10,000–18,000
|
|
10
|
+
// characters into the context in one call, 10–40% of a cut session's tool results. A `grep` or
|
|
11
|
+
// `sed -n` over the same file reads only the lines the run needs.
|
|
12
|
+
//
|
|
13
|
+
// **Lane children only, every occurrence.** The cut that the context growth triggers is a lane
|
|
14
|
+
// child's; a person in an interactive session keeps the whole read. A paginated `Read` (an `offset` or
|
|
15
|
+
// a `limit`) is already narrowed and passes.
|
|
16
|
+
|
|
17
|
+
const SPILLED_RESULT = /\/tool-results\/[^/]+\.txt$/u
|
|
18
|
+
|
|
19
|
+
function read_input(call: GuardedCall): Record<string, unknown> | undefined {
|
|
20
|
+
if (call.name !== 'Read' || !json_value.is_record(call.input)) return undefined
|
|
21
|
+
|
|
22
|
+
return call.input
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function reads_spilled_result(input: Record<string, unknown>): boolean {
|
|
26
|
+
const { file_path } = input
|
|
27
|
+
|
|
28
|
+
return typeof file_path === 'string' && SPILLED_RESULT.test(file_path)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function is_paginated(input: Record<string, unknown>): boolean {
|
|
32
|
+
return input['offset'] !== undefined || input['limit'] !== undefined
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The occasion the rule governs: any `Read` of a spilled result, whole or narrowed.
|
|
36
|
+
function reaches_spilled_result(call: GuardedCall): boolean {
|
|
37
|
+
const input = read_input(call)
|
|
38
|
+
|
|
39
|
+
return input !== undefined && reads_spilled_result(input)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Keeping the rule: the spilled result read with a page, never whole.
|
|
43
|
+
function keeps_narrowed_read(call: GuardedCall): boolean {
|
|
44
|
+
const input = read_input(call)
|
|
45
|
+
|
|
46
|
+
return input !== undefined && reads_spilled_result(input) && is_paginated(input)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function is_whole_spilled_read(
|
|
50
|
+
call: GuardedCall,
|
|
51
|
+
is_lane_child: boolean = lane_child_marker.is_child_of(process.cwd()),
|
|
52
|
+
): boolean {
|
|
53
|
+
if (!reaches_spilled_result(call) || keeps_narrowed_read(call)) return false
|
|
54
|
+
|
|
55
|
+
return is_lane_child
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const LANE_SPILLED_READ_REASON =
|
|
59
|
+
'⛔ lane child reading a spilled Bash result whole: `tool-results/<id>.txt` is the output that ' +
|
|
60
|
+
'overflowed the cap, and reading it back whole fills the context the cut is measured on. Read only ' +
|
|
61
|
+
'the lines you need: `grep -n <pattern> <path>` or `sed -n <from>,<to>p <path>`. ' +
|
|
62
|
+
'Refused on every occurrence.'
|
|
63
|
+
|
|
64
|
+
// The row itself, so `delivered-rules.ts` spreads one entry; the shape is `lane-direct-tool.ts`'s, with
|
|
65
|
+
// the narrowed read as its compliance call.
|
|
66
|
+
const ROW = {
|
|
67
|
+
id: 'lane-spilled-read',
|
|
68
|
+
is_trigger: is_whole_spilled_read,
|
|
69
|
+
reason: LANE_SPILLED_READ_REASON,
|
|
70
|
+
decide: (): boolean => true,
|
|
71
|
+
keeps: keeps_narrowed_read,
|
|
72
|
+
reaches: reaches_spilled_result,
|
|
73
|
+
about: {
|
|
74
|
+
title: 'Lane child reading a spilled Bash result whole',
|
|
75
|
+
topic: '`prompts/collaboration-workflow/output-bounds.md`',
|
|
76
|
+
fires:
|
|
77
|
+
"a dispatched lane child's `Read` of a `tool-results/<id>.txt` file with no `offset` or `limit`. Every occurrence",
|
|
78
|
+
quiet: 'not a lane child, another file, or a paginated `Read`',
|
|
79
|
+
},
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const lane_spilled_read = {
|
|
83
|
+
LANE_SPILLED_READ_REASON,
|
|
84
|
+
ROW,
|
|
85
|
+
is_whole_spilled_read,
|
|
86
|
+
keeps_narrowed_read,
|
|
87
|
+
reaches_spilled_result,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { lane_spilled_read }
|
|
@@ -17,7 +17,7 @@ import { tail_commands } from './tail-commands'
|
|
|
17
17
|
// carries `epic` as a split (`run-merge.ts`), so the label is never what tells it.
|
|
18
18
|
//
|
|
19
19
|
// **The material is the run's own calls.** The promotion is a `josh epic --promote <N>` this run issued,
|
|
20
|
-
// read off the transcript tail as `
|
|
20
|
+
// read off the transcript tail as `turn-filings.ts` reads its filings — a tool call, never prose, so a
|
|
21
21
|
// child that merely read a document quoting the command is not mistaken for one that ran it. Only a
|
|
22
22
|
// promotion of the dispatched issue counts: the epic a mid-run split promotes is the child's own Issue.
|
|
23
23
|
|
|
@@ -19,8 +19,8 @@ import { shell_segments } from './shell-segments'
|
|
|
19
19
|
//
|
|
20
20
|
// **It refuses rather than rewrites, because a `PreToolUse` guard can only `allow` / `deny` a command,
|
|
21
21
|
// never substitute a different one**. So the refusal hands back the next command: the lane is already on its own issue
|
|
22
|
-
// branch, branched from a fresh default before it opened, and the latest default is brought in
|
|
23
|
-
// gate by `
|
|
22
|
+
// branch, branched from a fresh default before it opened, and the latest default is brought in before the
|
|
23
|
+
// gate by `josh ship`'s sync — so skip the step and keep implementing on the current branch.
|
|
24
24
|
//
|
|
25
25
|
// **The branch is judged against the lane's own, not the name `main`.** `already used by worktree` is a
|
|
26
26
|
// property of any branch the primary work tree holds, not of the literal `main`, and the default branch
|
|
@@ -108,8 +108,8 @@ function is_switch_away_from_lane(
|
|
|
108
108
|
const LANE_SWITCH_MAIN_REASON =
|
|
109
109
|
'⛔ lane child on `git switch main`: this session is a dispatched lane child, and switching to the ' +
|
|
110
110
|
'default branch here always fails (`already used by worktree`: the primary checkout holds it). Skip ' +
|
|
111
|
-
|
|
112
|
-
'in
|
|
111
|
+
"this step and keep implementing on the current branch; `pnpm josh ship`'s sync brings the default " +
|
|
112
|
+
'in before its gate. Refused on every occurrence (`backlogrun-lanes.md`, `backlogrun-child.md`).'
|
|
113
113
|
|
|
114
114
|
// The row itself, so `delivered-rules.ts` spreads one entry. `is_trigger` reads the input through
|
|
115
115
|
// `on_bash_command` — the `Bash` tool-name gate every command row shares — and `decide` returns true so
|
|
@@ -1,32 +1,18 @@
|
|
|
1
1
|
import { json_value } from '#scripts/lib/json-value'
|
|
2
2
|
import { time_reported_failure } from '#scripts/time-runtime/time-reported-failure'
|
|
3
3
|
import { z } from 'zod'
|
|
4
|
-
import {
|
|
4
|
+
import { turn_filings } from './turn-filings'
|
|
5
5
|
|
|
6
|
-
// The
|
|
7
|
-
//
|
|
6
|
+
// The person's prompts on a transcript tail — what the stop guard reads to tell a question it answers
|
|
7
|
+
// and the pause a recorded notify belongs to.
|
|
8
8
|
//
|
|
9
|
-
// **A prompt is `
|
|
9
|
+
// **A prompt is `turn_filings`' prompt line, minus what the harness wrote there.** A skill's body is a
|
|
10
10
|
// `user` line with no tool result too, but it carries `isMeta`; a background task's completion notice
|
|
11
11
|
// and a subagent's hand-back carry an `origin` whose `kind` is not `human`. Each is the harness
|
|
12
|
-
// speaking, not the person
|
|
13
|
-
|
|
14
|
-
//
|
|
15
|
-
// **A workflow invocation quotes nothing.** `fullrun #2819` names this repository's own Issue, so a
|
|
16
|
-
// bare `#2819` in that run's report is a citation slip like any other, and the prompt yields no text —
|
|
17
|
-
// a resumed lane child's prompt included, since it ends on the same invocation.
|
|
18
|
-
|
|
19
|
-
const WORKFLOW_KEYWORDS: ReadonlySet<string> = new Set([
|
|
20
|
-
'kickoff',
|
|
21
|
-
'fullrun',
|
|
22
|
-
'halfrun',
|
|
23
|
-
'prrun',
|
|
24
|
-
'backlogrun',
|
|
25
|
-
])
|
|
12
|
+
// speaking, not the person, so only a line with no `origin` (an SDK prompt) or a `human` one is read.
|
|
13
|
+
|
|
26
14
|
const NO_PROMPT = ''
|
|
27
15
|
const HUMAN_ORIGIN = 'human'
|
|
28
|
-
// The word before the prompt's last one — where a trailing `fullrun #N` puts its keyword.
|
|
29
|
-
const KEYWORD_BEFORE_ARGUMENT = -2
|
|
30
16
|
|
|
31
17
|
const PROMPT_LINE_SCHEMA = z.object({
|
|
32
18
|
isMeta: z.boolean().nullish(),
|
|
@@ -61,45 +47,32 @@ function person_text(line: string): string | undefined {
|
|
|
61
47
|
return time_reported_failure.result_text(person.message.content)
|
|
62
48
|
}
|
|
63
49
|
|
|
64
|
-
// A keyword opening the prompt is what a person types; a keyword before its one trailing argument is a
|
|
65
|
-
// lane child's resume prompt, whose preamble ends on `fullrun #N` (`lane-child-invocation.ts`).
|
|
66
|
-
function is_invocation(prompt: string): boolean {
|
|
67
|
-
const words = prompt.trim().split(/\s+/u)
|
|
68
|
-
|
|
69
|
-
return [words.at(0), words.at(KEYWORD_BEFORE_ARGUMENT)].some((word) =>
|
|
70
|
-
WORKFLOW_KEYWORDS.has(word ?? NO_PROMPT),
|
|
71
|
-
)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function prompt_line_text(line: string): string | undefined {
|
|
75
|
-
return filing_cap.is_prompt_line(line) ? person_text(line) : undefined
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// The last person prompt on the tail; '' when none is on it or it is an invocation.
|
|
79
|
-
function prompt_text(tail: string): string {
|
|
80
|
-
const text = tail
|
|
81
|
-
.split('\n')
|
|
82
|
-
.map((line) => prompt_line_text(line))
|
|
83
|
-
.findLast((one) => one !== undefined)
|
|
84
|
-
|
|
85
|
-
return text === undefined || is_invocation(text) ? NO_PROMPT : text
|
|
86
|
-
}
|
|
87
|
-
|
|
88
50
|
// **The prompt that opened this turn, when a person typed it** — '' when the harness opened it (a task
|
|
89
51
|
// notification, a subagent's hand-back), so a question asked turns ago does not answer for a stop the
|
|
90
52
|
// run reached on its own since (`stop-decision.ts` → `is_question`).
|
|
91
53
|
function turn_prompt(tail: string): string {
|
|
92
|
-
const opener = tail.split('\n').findLast((line) =>
|
|
54
|
+
const opener = tail.split('\n').findLast((line) => turn_filings.is_prompt_line(line))
|
|
93
55
|
if (opener === undefined) return NO_PROMPT
|
|
94
56
|
|
|
95
57
|
return person_text(opener) ?? NO_PROMPT
|
|
96
58
|
}
|
|
97
59
|
|
|
60
|
+
// **The person's last prompt on the tail**, past what the harness wrote after it (a skill body, a task
|
|
61
|
+
// notification) — `undefined` when no prompt of theirs is on it, so an unread prompt is told apart
|
|
62
|
+
// from one that asked nothing.
|
|
63
|
+
function person_prompt(tail: string): string | undefined {
|
|
64
|
+
return tail
|
|
65
|
+
.split('\n')
|
|
66
|
+
.filter((line) => turn_filings.is_prompt_line(line))
|
|
67
|
+
.map((line) => person_text(line))
|
|
68
|
+
.findLast((text) => text !== undefined)
|
|
69
|
+
}
|
|
70
|
+
|
|
98
71
|
// When the person last prompted on the tail, or `undefined` when no prompt of theirs is on it.
|
|
99
72
|
function prompt_time(tail: string): string | undefined {
|
|
100
73
|
return tail
|
|
101
74
|
.split('\n')
|
|
102
|
-
.filter((line) =>
|
|
75
|
+
.filter((line) => turn_filings.is_prompt_line(line))
|
|
103
76
|
.map((line) => person_line(line)?.timestamp ?? undefined)
|
|
104
77
|
.findLast((time) => time !== undefined)
|
|
105
78
|
}
|
|
@@ -120,6 +93,6 @@ function pause_start(tail: string): string | undefined {
|
|
|
120
93
|
return prompt_time(tail) ?? tail_time(tail)
|
|
121
94
|
}
|
|
122
95
|
|
|
123
|
-
const last_prompt = { pause_start,
|
|
96
|
+
const last_prompt = { pause_start, person_prompt, turn_prompt }
|
|
124
97
|
|
|
125
98
|
export { last_prompt }
|
|
@@ -80,7 +80,7 @@ function row_for(oracle: Oracle, firing_point: FiringPoint): DeliveredRule {
|
|
|
80
80
|
|
|
81
81
|
// One row per oracle that declared a firing point, in registry order. Spread into `DELIVERED_RULES`
|
|
82
82
|
// after the filing rows, so a firing point that overlaps a filing (`issue:lint`) delivers on the
|
|
83
|
-
// reissue rather than ahead of
|
|
83
|
+
// reissue rather than ahead of the filing rows.
|
|
84
84
|
const ROWS: ReadonlyArray<DeliveredRule> = oracle_firing
|
|
85
85
|
.firing_oracles()
|
|
86
86
|
.map(({ oracle, firing_point }) => row_for(oracle, firing_point))
|
|
@@ -3,6 +3,7 @@ import { direct_pr_create } from './direct-pr-create'
|
|
|
3
3
|
import { index_guard } from './index-guard'
|
|
4
4
|
import { pr_merge } from './pr-merge'
|
|
5
5
|
import { protected_files } from './protected-files'
|
|
6
|
+
import { repo_admin } from './repo-admin'
|
|
6
7
|
|
|
7
8
|
// The three rows that close the deny-list bypasses, gathered so
|
|
8
9
|
// `delivered-rules.ts` spreads one entry. Each reads argv or a file path rather than a glob: an index
|
|
@@ -11,13 +12,16 @@ import { protected_files } from './protected-files'
|
|
|
11
12
|
// other row's — `git restore` is split with `worktree-mutation` by `--staged` alone. The fourth row,
|
|
12
13
|
// `direct-pr-create`, closes the same kind of gap for `gh pr create`, which
|
|
13
14
|
// the deny list never listed: it claims `gh pr create` and a `gh api` write to the pulls collection.
|
|
14
|
-
// The fifth, `pr-merge`, claims a merge in every spelling the `gh pr merge*` glob misses.
|
|
15
|
+
// The fifth, `pr-merge`, claims a merge in every spelling the `gh pr merge*` glob misses. The sixth,
|
|
16
|
+
// `repo-admin`, claims a non-`DELETE` write to the repository's administration, which
|
|
17
|
+
// `destructive-command` leaves open.
|
|
15
18
|
const ROWS = [
|
|
16
19
|
index_guard.ROW,
|
|
17
20
|
destructive_command.ROW,
|
|
18
21
|
protected_files.ROW,
|
|
19
22
|
direct_pr_create.ROW,
|
|
20
23
|
pr_merge.ROW,
|
|
24
|
+
repo_admin.ROW,
|
|
21
25
|
] as const
|
|
22
26
|
|
|
23
27
|
const permission_guards = { ROWS }
|