@joshuafolkken/kit 1.1514.0 → 1.1784.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/investigator.md +1 -1
- package/.claude/settings.json +5 -5
- package/.claude/skills/epic-commands/SKILL.md +26 -65
- package/.claude/skills/epic-commands/epic-bundle.md +3 -1
- package/.claude/skills/workflow-commands/SKILL.md +5 -5
- package/.claude/skills/workflow-commands/background-commands.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-child.md +10 -8
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +17 -13
- package/.claude/skills/workflow-commands/backlogrun-park.md +14 -23
- package/.claude/skills/workflow-commands/backlogrun-progress.md +2 -2
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +5 -5
- package/.claude/skills/workflow-commands/backlogrun-steps.md +10 -10
- package/.claude/skills/workflow-commands/backlogrun.md +1 -1
- package/.claude/skills/workflow-commands/chain-rule.md +13 -7
- package/.claude/skills/workflow-commands/delegation.md +6 -5
- package/.claude/skills/workflow-commands/entry-sequence.md +9 -9
- package/.claude/skills/workflow-commands/followup.md +9 -31
- package/.claude/skills/workflow-commands/fullrun-steps.md +36 -45
- package/.claude/skills/workflow-commands/fullrun.md +2 -2
- package/.claude/skills/workflow-commands/halfrun.md +17 -25
- package/.claude/skills/workflow-commands/issue-comments.md +16 -12
- package/.claude/skills/workflow-commands/issue-scout.md +2 -2
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +7 -12
- package/.claude/skills/workflow-commands/needs-human-review.md +9 -14
- package/.claude/skills/workflow-commands/observation-filing.md +4 -36
- package/.claude/skills/workflow-commands/observation-ledger.md +1 -1
- package/.claude/skills/workflow-commands/pre-gate-cut.md +13 -30
- package/.claude/skills/workflow-commands/prerequisite.md +10 -16
- package/.claude/skills/workflow-commands/progress-watcher.md +1 -1
- package/.claude/skills/workflow-commands/prrun.md +3 -7
- package/.claude/skills/workflow-commands/retrospective.md +1 -1
- package/.claude/skills/workflow-commands/split-assessment.md +13 -1
- package/.claude/skills/workflow-commands/working-tree-hold.md +9 -9
- package/.codex/hooks.json +5 -5
- package/.github/actions/setup-node/action.yml +9 -0
- package/.github/actions/setup-pnpm/action.yml +1 -1
- package/.github/dependabot.yml +16 -0
- package/.github/release.yml +0 -2
- package/.github/workflows/ci.yml +120 -10
- package/.github/workflows/publish.yml +8 -1
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +3 -7
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +3 -7
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +79 -37
- package/dist/commands/read-set-cli.js +1867 -0
- package/dist/commands/run-prep-main.js +21653 -0
- package/dist/commands/run-step-cli.js +23880 -0
- package/dist/config-merge/index.js +5 -1
- package/dist/hooks/audit-provision.js +20 -35
- package/dist/hooks/{chunk-DGT54IH5.js → chunk-AZX4FGQ3.js} +63 -17
- package/dist/hooks/chunk-CWMBGKYW.js +6483 -0
- package/dist/hooks/chunk-O2YBIDSI.js +4306 -0
- package/dist/hooks/{chunk-TNUMY6NL.js → chunk-PT5R6UJD.js} +4193 -1900
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-APUO6U4J.js → chunk-WR2KQAYZ.js} +1843 -440
- package/dist/hooks/{chunk-O6GDRNJB.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -22
- package/dist/hooks/format-edited.js +5 -6
- package/dist/hooks/inputs.json +443 -317
- package/dist/hooks/pretool-guard.js +7 -25
- package/dist/hooks/session-lang.js +44 -51
- package/dist/hooks/stop-guard.js +7716 -2187
- package/dist/josh.js +6002 -3583
- package/dist/self-sync-guard/index.js +74 -10
- package/dist/version/index.js +115 -406
- package/eslint/base.js +1 -1
- package/lefthook/base.yml +3 -1
- package/package.json +10 -48
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -7
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +33 -16
- package/prompts/collaboration-workflow/lane-instructions.md +1 -2
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +4 -6
- package/prompts/collaboration-workflow/output-bounds.md +2 -7
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +5 -0
- package/prompts/collaboration-workflow/report-format.md +31 -60
- package/prompts/collaboration-workflow/residency.md +2 -2
- package/prompts/collaboration-workflow/shell-body.md +6 -16
- package/prompts/collaboration-workflow/turn-batching.md +0 -2
- package/prompts/collaboration-workflow/upstream-interrupt.md +14 -4
- package/prompts/collaboration-workflow/wip-cap.md +1 -1
- package/prompts/collaboration-workflow.md +3 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +41 -21
- package/prompts/testing-guide.md +8 -43
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/auto-ok/auto-ok-cli.ts +14 -16
- package/scripts/auto-ok/auto-ok-judge-read.ts +12 -3
- package/scripts/auto-ok/auto-ok-judge-write.ts +46 -19
- package/scripts/auto-ok/auto-ok-judge.ts +13 -2
- package/scripts/auto-ok/auto-ok-main.ts +17 -0
- package/scripts/backlog/backlog-arrival.ts +14 -3
- package/scripts/backlog/backlog-budget-cli.ts +7 -33
- package/scripts/backlog/backlog-budget-main.ts +16 -0
- package/scripts/backlog/backlog-budget.ts +2 -3
- package/scripts/backlog/backlog-defect-priority.ts +4 -3
- package/scripts/backlog/backlog-drive-adopt.ts +67 -0
- package/scripts/backlog/backlog-drive-args.ts +4 -5
- package/scripts/backlog/backlog-drive-cli.ts +113 -28
- package/scripts/backlog/backlog-drive-hold.ts +162 -0
- package/scripts/backlog/backlog-drive-idle.ts +151 -0
- package/scripts/backlog/backlog-drive-judge.ts +25 -0
- package/scripts/backlog/backlog-drive-memory.ts +126 -0
- package/scripts/backlog/backlog-drive-named-offer.ts +5 -10
- package/scripts/backlog/backlog-drive-named.ts +53 -6
- package/scripts/backlog/backlog-drive-offer-argv.ts +3 -8
- package/scripts/backlog/backlog-drive-paused.ts +169 -0
- package/scripts/backlog/backlog-drive-restore.ts +30 -7
- package/scripts/backlog/backlog-drive-seats.ts +18 -8
- package/scripts/backlog/backlog-drive-token-handling.ts +38 -0
- package/scripts/backlog/backlog-drive.ts +79 -75
- package/scripts/backlog/backlog-next-main.ts +16 -0
- package/scripts/backlog/backlog-next-shared.ts +73 -0
- package/scripts/backlog/backlog-next.ts +48 -16
- package/scripts/backlog/backlog-occupied.ts +52 -39
- package/scripts/backlog/backlog-offer-cli.ts +6 -21
- package/scripts/backlog/backlog-offer-exclude.ts +15 -0
- package/scripts/backlog/backlog-offer-main.ts +12 -0
- package/scripts/backlog/backlog-offer.ts +36 -3
- package/scripts/backlog/backlog-overlap.ts +22 -4
- package/scripts/backlog/backlog-plan-read.ts +6 -2
- package/scripts/backlog/backlog-plan.ts +18 -4
- package/scripts/backlog/backlog-pool.ts +10 -10
- package/scripts/backlog/backlog-rank.ts +10 -2
- package/scripts/backlog/backlog-ready.ts +112 -30
- package/scripts/backlog/backlog-stalled-detect.ts +109 -36
- package/scripts/backlog/backlog-stalled.ts +52 -16
- package/scripts/backlog/backlog-wait-cause.ts +86 -0
- package/scripts/backlog/backlog-waves.ts +39 -13
- package/scripts/backlog/backlogrun-args.ts +19 -7
- package/scripts/backlog/backlogrun-cli.ts +19 -5
- package/scripts/backlog/backlogrun-launch.ts +6 -0
- package/scripts/backlog/backlogrun-restart.ts +97 -0
- package/scripts/backlog/backlogrun-stop.ts +79 -7
- package/scripts/behavior/behavior-cli.ts +2 -2
- package/scripts/behavior/behavior-rules.ts +47 -24
- package/scripts/build/build-bin.ts +2 -16
- package/scripts/build/build-claude-md.ts +0 -7
- package/scripts/build/build-commands.ts +0 -13
- package/scripts/build/build-hooks.ts +49 -48
- package/scripts/build/hook-bundle-stamp.ts +29 -11
- package/scripts/build/local-bin.ts +1 -1
- package/scripts/cases/cases-cli.ts +25 -13
- package/scripts/cases/cases-interaction-scan.ts +134 -0
- package/scripts/cases/cases-interaction.ts +183 -0
- package/scripts/cases/cases-logic.ts +39 -6
- package/scripts/ci/pr-classification-main.ts +18 -0
- package/scripts/ci/pr-classification.ts +10 -17
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/cost-runtime/cost-blocks.ts +22 -37
- package/scripts/cost-runtime/cost-cli.ts +31 -14
- package/scripts/cost-runtime/cost-main.ts +12 -0
- package/scripts/cost-runtime/cost-transcript.ts +1 -0
- package/scripts/delegation/delegation-policy.ts +17 -4
- package/scripts/delegation/duplicate-read-guard.ts +0 -8
- package/scripts/delegation/investigation-guard.ts +0 -8
- package/scripts/delegation/investigation-reads.ts +3 -4
- package/scripts/dependabot/dependabot-cooldown.ts +194 -0
- package/scripts/discovery/repo-discovery.ts +24 -6
- package/scripts/doctor/doctor-consumer.ts +2 -5
- package/scripts/document/document-byte-budget.ts +8 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +0 -8
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-busy.ts +5 -12
- package/scripts/epic/epic-classify.ts +24 -15
- package/scripts/epic/epic-cli-argv.ts +31 -0
- package/scripts/epic/epic-cli-decide.ts +42 -0
- package/scripts/epic/epic-cli.ts +6 -38
- package/scripts/epic/epic-close.ts +112 -55
- package/scripts/epic/epic-cross-repo.ts +4 -7
- package/scripts/epic/epic-decide.ts +119 -0
- package/scripts/epic/epic-decision.ts +9 -0
- package/scripts/epic/epic-fetch.ts +4 -0
- package/scripts/epic/epic-graph.ts +2 -0
- package/scripts/epic/epic-issue.ts +5 -1
- package/scripts/epic/epic-label-age.ts +1 -1
- package/scripts/epic/epic-lane-offer.ts +39 -4
- package/scripts/epic/epic-next-main.ts +24 -0
- package/scripts/epic/epic-next.ts +6 -24
- package/scripts/epic/epic-outside-blocker.ts +6 -2
- package/scripts/epic/epic-parse.ts +9 -3
- package/scripts/epic/epic-read.ts +1 -0
- package/scripts/epic/epic-reconcile.ts +39 -0
- package/scripts/epic/epic-run.ts +10 -1
- package/scripts/epic/epic-solo.ts +50 -14
- package/scripts/epic/epic.ts +41 -7
- package/scripts/exports/unused-members-cli.ts +2 -2
- package/scripts/followup/followup-checks-event.ts +8 -3
- package/scripts/followup/followup-coderabbit-wait.ts +82 -0
- package/scripts/followup/followup-review-gates.ts +81 -0
- package/scripts/followup/git-followup-stages.ts +13 -3
- package/scripts/followup/git-followup-workflow.ts +19 -66
- package/scripts/followup/git-pr-followup-wrapup.ts +9 -14
- package/scripts/followup/git-pr-followup.ts +36 -8
- package/scripts/fresh-machine/fresh-machine-cli.ts +1 -1
- package/scripts/fresh-machine/fresh-machine-run.ts +8 -8
- package/scripts/fresh-machine/specs/kit-test-backlogrun.json +1 -1
- package/scripts/gate/busy-average.ts +58 -0
- package/scripts/gate/check-cpu.ts +60 -0
- package/scripts/gate/check-inputs.ts +39 -95
- package/scripts/gate/check-reuse.ts +33 -54
- package/scripts/gate/command-memory.ts +192 -0
- package/scripts/gate/core-admission.ts +218 -28
- package/scripts/gate/core-budget-timing.ts +37 -0
- package/scripts/gate/core-budget.ts +80 -98
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +37 -5
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +27 -4
- package/scripts/gate/gate-ledger.ts +32 -4
- package/scripts/gate/gate-plan.ts +41 -34
- package/scripts/gate/gate-report.ts +14 -2
- package/scripts/gate/gate-run-steps.ts +53 -8
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +65 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/project-checks.ts +5 -12
- package/scripts/gate/scoped-green.ts +12 -8
- package/scripts/gate/since-green.ts +62 -0
- package/scripts/gate/toolchain-inputs.ts +115 -0
- package/scripts/gate/verification-gate.ts +27 -24
- package/scripts/gate/verification-inputs.ts +250 -0
- package/scripts/gh/gh-author-association.ts +96 -9
- package/scripts/gh/git-ai-review-scan.ts +4 -2
- package/scripts/gh/git-gh-api-path.ts +15 -0
- package/scripts/gh/git-gh-branch-rules.ts +73 -0
- package/scripts/gh/git-gh-conditional.ts +5 -2
- package/scripts/gh/git-gh-issue-read.ts +5 -1
- package/scripts/gh/git-gh-issue-write.ts +67 -29
- package/scripts/gh/git-gh-issue.ts +7 -3
- package/scripts/gh/git-gh-poll-read.ts +89 -0
- package/scripts/gh/git-gh-pr-auto-merge.ts +8 -3
- package/scripts/gh/git-gh-pr-rest.ts +1 -1
- package/scripts/gh/git-gh-pr-snapshot.ts +33 -20
- package/scripts/gh/git-gh-pr.ts +27 -15
- package/scripts/gh/git-pr-checks-eval.ts +39 -7
- package/scripts/gh/git-pr-checks-parse.ts +39 -9
- package/scripts/gh/git-pr-merge-checked.ts +80 -0
- package/scripts/git/base-tree.ts +19 -2
- package/scripts/git/changed-file-scope.ts +6 -4
- package/scripts/git/changed-paths.ts +18 -1
- package/scripts/git/git-diff-reads.ts +27 -2
- package/scripts/git/git-grep-hits.ts +85 -0
- package/scripts/git/git-location-environment.ts +1 -1
- package/scripts/git/git-merge-conflicts.ts +83 -0
- package/scripts/git/git-preflight.ts +37 -12
- package/scripts/git/git-push-transport.ts +1 -2
- package/scripts/git/git-schemas.ts +17 -7
- package/scripts/git/git-spawn.ts +1 -2
- package/scripts/git/git-status.ts +4 -4
- package/scripts/git/main-merge-main.ts +12 -0
- package/scripts/git/main-merge-regenerate.ts +2 -2
- package/scripts/git/main-merge.ts +25 -9
- package/scripts/git/main-sync-main.ts +12 -0
- package/scripts/git/main-sync.ts +0 -9
- package/scripts/git/stash/git-stash.ts +27 -4
- package/scripts/git/stash/{stash-pop-args.ts → stash-args.ts} +13 -10
- package/scripts/git/stash/stash-pop-cli.ts +6 -12
- package/scripts/git/stash/stash-pop-main.ts +12 -0
- package/scripts/git/stash/stash-push-cli.ts +76 -0
- package/scripts/git/stash/stash-push-main.ts +12 -0
- package/scripts/hooks/batch-guard.ts +0 -8
- package/scripts/hooks/check-commit-message-main.ts +8 -0
- package/scripts/hooks/check-commit-message.ts +4 -7
- package/scripts/hooks/format-edited-file.ts +8 -24
- package/scripts/hooks/pre-commit-lint.ts +30 -3
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +32 -19
- package/scripts/hooks/reserved-run.ts +67 -9
- package/scripts/hooks/run-hook.sh +13 -4
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +2 -21
- package/scripts/hooks/stop-guard.ts +13 -9
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -17
- package/scripts/init/init-actions.ts +0 -6
- package/scripts/init/init-ai-copy.ts +10 -36
- package/scripts/init/init-bootstrap.ts +9 -8
- package/scripts/init/init-dry-run-report.ts +1 -1
- package/scripts/init/init-dry-run.ts +1 -1
- package/scripts/init/init-file-action.ts +7 -9
- package/scripts/init/init-logic-json-merge.ts +2 -2
- package/scripts/init/init-logic-migrate.ts +9 -82
- package/scripts/init/init-logic.ts +3 -2
- package/scripts/init/init-main.ts +12 -0
- package/scripts/init/init.ts +5 -12
- package/scripts/init/kit-development-versions.ts +3 -7
- package/scripts/init/kit-written-paths.ts +2 -2
- package/scripts/init/project-profile.ts +5 -4
- package/scripts/init/tsconfig-preset-migration.ts +2 -1
- package/scripts/init/vscode-tasks.ts +1 -1
- package/scripts/issue/defect-origin-cli.ts +106 -0
- package/scripts/issue/defect-origin-line.ts +60 -0
- package/scripts/issue/defect-origin-main.ts +11 -0
- package/scripts/issue/defect-origin.ts +114 -0
- package/scripts/issue/defect-rate-cli.ts +34 -78
- package/scripts/issue/defect-rate.ts +0 -16
- package/scripts/issue/defect-report-cli.ts +128 -0
- package/scripts/issue/defect-report-format.ts +56 -0
- package/scripts/issue/defect-report-main.ts +11 -0
- package/scripts/issue/defect-report.ts +160 -0
- package/scripts/issue/expected-effect-lint.ts +1 -0
- package/scripts/issue/issue-already-done-cli.ts +62 -0
- package/scripts/issue/issue-body-or-comment.ts +40 -0
- package/scripts/issue/issue-cite-cli.ts +0 -9
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +12 -7
- package/scripts/issue/issue-comment-cli.ts +10 -24
- package/scripts/issue/issue-comment-main.ts +12 -0
- package/scripts/issue/issue-evidence-exit.ts +100 -0
- package/scripts/issue/issue-file-cli.ts +29 -7
- package/scripts/issue/issue-file.ts +19 -19
- package/scripts/issue/issue-fold-cli.ts +2 -11
- package/scripts/issue/issue-fold-main.ts +12 -0
- package/scripts/issue/issue-labels.ts +81 -90
- package/scripts/issue/issue-lint-cli.ts +2 -10
- package/scripts/issue/issue-lint-main.ts +12 -0
- package/scripts/issue/issue-measured-cli.ts +56 -0
- package/scripts/issue/issue-merged.ts +19 -2
- package/scripts/issue/issue-not-before-label.ts +135 -0
- package/scripts/issue/issue-not-before.ts +111 -0
- package/scripts/issue/issue-number-shape.ts +15 -1
- package/scripts/issue/issue-park.ts +28 -0
- package/scripts/issue/issue-plan-cli.ts +151 -0
- package/scripts/issue/issue-priority.ts +151 -0
- package/scripts/issue/issue-rank.ts +7 -1
- package/scripts/issue/issue-read-cli.ts +3 -10
- package/scripts/issue/issue-read-main.ts +12 -0
- package/scripts/issue/issue-read.ts +29 -5
- package/scripts/issue/issue-release-cli.ts +0 -10
- package/scripts/issue/issue-release-main.ts +13 -0
- package/scripts/issue/issue-release.ts +7 -12
- package/scripts/issue/issue-sample-gate.ts +192 -0
- package/scripts/issue/issue-sample-source.ts +76 -0
- package/scripts/issue/issue-scout-cli.ts +0 -11
- package/scripts/issue/issue-scout-main.ts +14 -0
- package/scripts/issue/issue-state-cli.ts +0 -10
- package/scripts/issue/issue-state-main.ts +12 -0
- package/scripts/issue/issue-watch-diff.ts +56 -15
- package/scripts/issue/issue-watch.ts +2 -1
- package/scripts/issue/issue-wip.ts +2 -7
- package/scripts/issue/measure-rerun-cli.ts +13 -8
- package/scripts/issue/plan-consumers-cli.ts +39 -0
- package/scripts/issue/plan-consumers-main.ts +11 -0
- package/scripts/issue/plan-consumers-section.ts +55 -0
- package/scripts/issue/plan-consumers.ts +127 -0
- package/scripts/josh/agent-session-environment.ts +1 -1
- package/scripts/josh/command-usage.ts +15 -43
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +12 -6
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +157 -158
- package/scripts/josh/josh-commands-backlog.ts +82 -16
- package/scripts/josh/josh-commands-clone.ts +1 -0
- package/scripts/josh/josh-commands-development.ts +111 -71
- package/scripts/josh/josh-commands-document.ts +43 -1
- package/scripts/josh/josh-commands-epic.ts +171 -0
- package/scripts/josh/josh-commands-hooks.ts +25 -2
- package/scripts/josh/josh-commands-issue-write.ts +181 -0
- package/scripts/josh/josh-commands-issue.ts +124 -24
- package/scripts/josh/josh-commands-lane.ts +103 -2
- package/scripts/josh/josh-commands-lint.ts +19 -8
- package/scripts/josh/josh-commands-maintenance.ts +112 -4
- package/scripts/josh/josh-commands-pause.ts +29 -0
- package/scripts/josh/josh-commands-progress.ts +87 -0
- package/scripts/josh/josh-commands-project.ts +138 -9
- package/scripts/josh/josh-commands-review.ts +124 -0
- package/scripts/josh/josh-commands-run.ts +211 -23
- package/scripts/josh/josh-commands-ship.ts +169 -0
- package/scripts/josh/josh-commands-split.ts +9 -0
- package/scripts/josh/josh-commands-versioning.ts +49 -2
- package/scripts/josh/josh-commands-workflow.ts +144 -6
- package/scripts/josh/josh-logic.ts +6 -13
- package/scripts/josh/package-directory.ts +2 -4
- package/scripts/josh/process-identity.ts +13 -4
- package/scripts/josh/session-language-cli.ts +4 -8
- package/scripts/josh/session-language-main.ts +13 -0
- package/scripts/josh/session-language.ts +6 -1
- package/scripts/josh/shared-cache.ts +90 -0
- package/scripts/josh/stamp-file.ts +9 -15
- package/scripts/lane/lane-await.ts +51 -12
- package/scripts/lane/lane-cache.ts +5 -30
- package/scripts/lane/lane-capacity.ts +14 -23
- package/scripts/lane/lane-check-stats.ts +62 -21
- package/scripts/lane/lane-child-invocation.ts +8 -0
- package/scripts/lane/lane-cli.ts +15 -5
- package/scripts/lane/lane-close.ts +86 -18
- package/scripts/lane/lane-core-wait-stats.ts +66 -0
- package/scripts/lane/lane-dispatch.ts +24 -3
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-handoff.ts +69 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +4 -11
- package/scripts/lane/lane-launch-cli.ts +0 -9
- package/scripts/lane/lane-launch-main.ts +12 -0
- package/scripts/lane/lane-ledger-schema.ts +266 -0
- package/scripts/lane/lane-ledger.ts +92 -123
- package/scripts/lane/lane-limit-cli.ts +12 -1
- package/scripts/lane/lane-measure-cli.ts +57 -11
- package/scripts/lane/lane-open.ts +9 -1
- package/scripts/lane/lane-parked.ts +3 -3
- package/scripts/lane/lane-pause-cli.ts +130 -0
- package/scripts/lane/lane-pause.ts +158 -0
- package/scripts/lane/lane-process-table.ts +166 -0
- package/scripts/lane/lane-reap-settle.ts +124 -0
- package/scripts/lane/lane-reap.ts +50 -15
- package/scripts/lane/lane-registry.ts +24 -3
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +22 -2
- package/scripts/lane/lane-round-two-stats.ts +49 -0
- package/scripts/lane/lane-sampler.ts +4 -0
- package/scripts/lane/lane-session-action.ts +19 -5
- package/scripts/lane/lane-session-broker.ts +102 -21
- package/scripts/lane/lane-snapshot-trace.ts +84 -0
- package/scripts/lane/lane-spans.ts +51 -0
- package/scripts/lane/lane-spent.ts +6 -3
- package/scripts/lane/lane-stage-stats.ts +7 -2
- package/scripts/lane/lane-state.ts +302 -0
- package/scripts/lane/lane-stats.ts +58 -4
- package/scripts/lane/lane-stop-stats.ts +113 -37
- package/scripts/lane/lane-test-related-stats.ts +127 -0
- package/scripts/lane/lane-transcript-calls.ts +145 -0
- package/scripts/lane/lane-transcript-stats.ts +168 -0
- package/scripts/lane/lane-vacant.ts +13 -3
- package/scripts/lane/lane-withdraw-cli.ts +5 -4
- package/scripts/lane/lane-withdraw.ts +50 -49
- package/scripts/lane/process-directories.ts +70 -0
- package/scripts/lane/process-lane-marks.ts +94 -0
- package/scripts/lib/atomic-write.ts +62 -0
- package/scripts/lib/buffered-process.ts +12 -5
- package/scripts/lib/cli-flags.ts +53 -0
- package/scripts/lib/figure-format.ts +63 -0
- package/scripts/lib/json-value.ts +9 -1
- package/scripts/lib/package-manifest.ts +35 -0
- package/scripts/lib/read-file.ts +3 -1
- package/scripts/lib/stamped-memo.ts +63 -0
- package/scripts/lib/stdout-on-stderr.ts +24 -0
- package/scripts/lib/timeouts.ts +9 -0
- package/scripts/lib/transcript-record.ts +91 -0
- package/scripts/lines/effective-limit.ts +1 -1
- package/scripts/lint/eslint-cache-dependencies.ts +145 -0
- package/scripts/lint/eslint-daemon.ts +265 -0
- package/scripts/lint/format.ts +11 -2
- package/scripts/lint/import-graph.ts +279 -0
- package/scripts/lint/lint-gate-scope.ts +102 -0
- package/scripts/lint/lint-parallel-main.ts +19 -0
- package/scripts/lint/lint-parallel.ts +62 -30
- package/scripts/lint/lint-related-scope.ts +30 -24
- package/scripts/lint/lint-related.ts +38 -6
- package/scripts/notify/confirmation-options.ts +1 -2
- package/scripts/notify/telegram-notify.ts +20 -20
- package/scripts/notify/telegram-test-logic.ts +0 -1
- package/scripts/notify/telegram-test-main.ts +8 -0
- package/scripts/notify/telegram-test.ts +2 -6
- package/scripts/observations/observation-ledger.ts +13 -0
- package/scripts/observations/observations-flush-landing.ts +5 -3
- package/scripts/observations/observations-flush.ts +6 -1
- package/scripts/overrides/overrides-check.ts +2 -5
- package/scripts/overrides/overrides-files.ts +2 -1
- package/scripts/overrides/overrides-logic.ts +3 -6
- package/scripts/package/verify-optional-eslint-install.ts +8 -6
- package/scripts/propagate/propagate-publish.ts +2 -7
- package/scripts/propagate/propagate-targets.ts +4 -12
- package/scripts/refactor/import-graph.ts +9 -7
- package/scripts/release/github-release-runs.ts +17 -6
- package/scripts/release/release-approval-prune.ts +18 -0
- package/scripts/release/release-history.ts +1 -3
- package/scripts/release/release-progress.ts +42 -22
- package/scripts/release/release-publish-run.ts +39 -0
- package/scripts/release/release-publish.ts +6 -6
- package/scripts/release/release-scope-cli.ts +0 -10
- package/scripts/release/release-scope-main.ts +12 -0
- package/scripts/repo/repo-setting.ts +3 -6
- package/scripts/repo/required-checks-logic.ts +6 -15
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-labels.ts +155 -0
- package/scripts/report/report-lint-cli.ts +3 -0
- package/scripts/report/report-lint.ts +85 -110
- package/scripts/report/report-template-cli.ts +59 -0
- package/scripts/report/report-template.ts +112 -0
- package/scripts/review/acceptance-map.ts +1 -0
- package/scripts/review/removed-tests-check.ts +86 -0
- package/scripts/review/removed-tests.ts +149 -0
- package/scripts/review/review-brief-cli.ts +81 -15
- package/scripts/review/review-brief-main.ts +12 -0
- package/scripts/review/review-brief.ts +31 -3
- package/scripts/review/review-code-tree.ts +10 -6
- package/scripts/review/review-comment-round.ts +26 -8
- package/scripts/review/review-finding-ledger.ts +30 -15
- package/scripts/review/review-interaction.ts +94 -0
- package/scripts/review/review-readers-scan.ts +163 -0
- package/scripts/review/review-record-cli.ts +69 -30
- package/scripts/review/review-record-main.ts +12 -0
- package/scripts/review/review-round-one-blobs.ts +221 -0
- package/scripts/review/review-round2-cli.ts +49 -12
- package/scripts/review/review-round2.ts +80 -12
- package/scripts/review/review-stamps.ts +19 -1
- package/scripts/review/review-stop-log.ts +96 -0
- package/scripts/review/review-stops-cli.ts +85 -0
- package/scripts/review/review-tree.ts +6 -17
- package/scripts/review/review-untouched-readers.ts +146 -0
- package/scripts/review/test-titles.ts +118 -0
- package/scripts/rules/agent-model.ts +8 -0
- package/scripts/rules/bash-triggers.ts +46 -3
- package/scripts/rules/decision-oracle-batch.ts +9 -1
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +80 -2
- package/scripts/rules/destructive-command.ts +8 -1
- package/scripts/rules/direct-filing.ts +10 -2
- package/scripts/rules/direct-issue-comment.ts +117 -0
- package/scripts/rules/direct-pr-create.ts +69 -3
- package/scripts/rules/early-heartbeat.ts +2 -1
- package/scripts/rules/file-body.ts +7 -0
- package/scripts/rules/filing-cap.ts +7 -0
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +4 -0
- package/scripts/rules/implementation-cut-verdict.ts +1 -1
- package/scripts/rules/implementation-cut.ts +11 -3
- package/scripts/rules/index-guard.ts +8 -1
- package/scripts/rules/issue-comments.ts +9 -1
- package/scripts/rules/josh-git-bare.ts +7 -0
- package/scripts/rules/lane-background.ts +67 -25
- package/scripts/rules/lane-carry-conflict.ts +6 -0
- package/scripts/rules/lane-direct-tool.ts +74 -0
- package/scripts/rules/lane-interactive-ask.ts +9 -2
- package/scripts/rules/lane-park.ts +45 -23
- package/scripts/rules/lane-split-park.ts +10 -2
- package/scripts/rules/lane-switch-main.ts +7 -0
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +1 -1
- package/scripts/rules/poll-loop.ts +7 -0
- package/scripts/rules/pr-merge.ts +123 -0
- package/scripts/rules/protected-files.ts +32 -5
- package/scripts/rules/raw-field-body.ts +6 -0
- package/scripts/rules/rule-body-guard.ts +8 -0
- package/scripts/rules/rule-list.ts +9 -28
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +1 -1
- package/scripts/rules/shell-segments.ts +35 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +3 -4
- package/scripts/rules/test-declared-commit.ts +11 -1
- package/scripts/rules/third-party-write.ts +7 -0
- package/scripts/rules/timed-rerun.ts +69 -0
- package/scripts/rules/worktree-guard.ts +13 -3
- package/scripts/run/board/run-board-app-name.ts +23 -0
- package/scripts/run/board/run-board-cli.ts +65 -32
- package/scripts/run/board/run-board-earlier.ts +94 -0
- package/scripts/run/board/run-board-ending-reason.ts +67 -0
- package/scripts/run/board/run-board-estimate-schedule.ts +103 -0
- package/scripts/run/board/run-board-estimate.ts +98 -0
- package/scripts/run/board/run-board-fit.ts +153 -36
- package/scripts/run/board/run-board-fold.ts +123 -0
- package/scripts/run/board/run-board-fresh.ts +2 -2
- package/scripts/run/board/run-board-gather-live.ts +29 -0
- package/scripts/run/board/run-board-gather-thread.ts +189 -0
- package/scripts/run/board/run-board-gather-worker.ts +29 -0
- package/scripts/run/board/run-board-gather.ts +187 -0
- package/scripts/run/board/run-board-github.ts +118 -38
- package/scripts/run/board/run-board-header.ts +82 -20
- package/scripts/run/board/run-board-keys.ts +58 -0
- package/scripts/run/board/run-board-kind.ts +20 -6
- package/scripts/run/board/run-board-labels.ts +116 -71
- package/scripts/run/board/run-board-lane-state.ts +109 -0
- package/scripts/run/board/run-board-lane-time.ts +122 -0
- package/scripts/run/board/run-board-layout.ts +239 -60
- package/scripts/run/board/run-board-length.ts +52 -0
- package/scripts/run/board/run-board-machine.ts +8 -4
- package/scripts/run/board/run-board-main.ts +12 -0
- package/scripts/run/board/run-board-notes.ts +52 -31
- package/scripts/run/board/run-board-now.ts +1 -1
- package/scripts/run/board/run-board-operation.ts +15 -33
- package/scripts/run/board/run-board-phase.ts +1 -1
- package/scripts/run/board/run-board-plan-shared.ts +115 -0
- package/scripts/run/board/run-board-plan.ts +55 -3
- package/scripts/run/board/run-board-planning.ts +45 -0
- package/scripts/run/board/run-board-priority.ts +44 -0
- package/scripts/run/board/run-board-process-groups.ts +195 -0
- package/scripts/run/board/run-board-read.ts +151 -27
- package/scripts/run/board/run-board-reason.ts +235 -51
- package/scripts/run/board/run-board-released.ts +35 -0
- package/scripts/run/board/run-board-render-checks.ts +39 -5
- package/scripts/run/board/run-board-render-condition.ts +96 -0
- package/scripts/run/board/run-board-render-drawn.ts +67 -0
- package/scripts/run/board/run-board-render-foot.ts +59 -0
- package/scripts/run/board/run-board-render-icon.ts +35 -0
- package/scripts/run/board/run-board-render-lanes.ts +145 -0
- package/scripts/run/board/run-board-render-lead.ts +80 -0
- package/scripts/run/board/run-board-render-legend.ts +117 -48
- package/scripts/run/board/run-board-render-notes.ts +156 -29
- package/scripts/run/board/run-board-render-processes.ts +196 -0
- package/scripts/run/board/run-board-render-section.ts +119 -0
- package/scripts/run/board/run-board-render-slot.ts +3 -36
- package/scripts/run/board/run-board-render-tail.ts +115 -48
- package/scripts/run/board/run-board-render-time.ts +56 -0
- package/scripts/run/board/run-board-render-title.ts +117 -24
- package/scripts/run/board/run-board-render-waits.ts +104 -20
- package/scripts/run/board/run-board-render.ts +207 -265
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +9 -4
- package/scripts/run/board/run-board-setup.ts +1 -12
- package/scripts/run/board/run-board-snapshot.ts +111 -0
- package/scripts/run/board/run-board-spin.ts +2 -2
- package/scripts/run/board/run-board-state.ts +22 -33
- package/scripts/run/board/run-board-status.ts +147 -71
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +122 -107
- package/scripts/run/board/run-board-usage-board.ts +78 -0
- package/scripts/run/board/run-board-usage-lanes.ts +113 -0
- package/scripts/run/board/run-board-usage-listing.ts +93 -0
- package/scripts/run/board/run-board-usage-read.ts +120 -150
- package/scripts/run/board/run-board-usage-rusage.ts +19 -7
- package/scripts/run/board/run-board-usage-text.ts +139 -51
- package/scripts/run/board/run-board-usage-top.ts +102 -0
- package/scripts/run/board/run-board-usage.ts +89 -72
- package/scripts/run/board/run-board-usual.ts +20 -9
- package/scripts/run/carry/run-carry-args.ts +4 -7
- package/scripts/run/carry/run-carry-conversation.ts +1 -1
- package/scripts/run/carry/run-carry.ts +9 -4
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/event/run-event-cli.ts +1 -5
- package/scripts/run/event/run-event-filed.ts +12 -6
- package/scripts/run/event/run-event-follow.ts +2 -3
- package/scripts/run/event/run-event-render.ts +6 -10
- package/scripts/run/event/run-event-scope.ts +2 -2
- package/scripts/run/event/run-event-stream-emit.ts +82 -22
- package/scripts/run/event/run-event-stream.ts +34 -8
- package/scripts/run/hold/run-hold-adopt.ts +65 -0
- package/scripts/run/hold/run-hold-cli.ts +93 -22
- package/scripts/run/hold/run-hold-main.ts +12 -0
- package/scripts/run/hold/run-hold-member.ts +37 -0
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +62 -48
- package/scripts/run/merge/run-merge-close.ts +74 -0
- package/scripts/run/merge/run-merge-collect.ts +6 -13
- package/scripts/run/merge/run-merge-driver.ts +71 -0
- package/scripts/run/merge/run-merge-main.ts +12 -0
- package/scripts/run/merge/run-merge-outcome.ts +23 -0
- package/scripts/run/merge/run-merge-restart.ts +39 -0
- package/scripts/run/merge/run-merge-ship.ts +20 -4
- package/scripts/run/merge/run-merge-signals.ts +33 -9
- package/scripts/run/merge/run-merge-steps.ts +120 -85
- package/scripts/run/merge/run-merge.ts +38 -37
- package/scripts/run/park/run-park-cli.ts +91 -0
- package/scripts/run/park/run-park.ts +88 -0
- package/scripts/run/park/run-stalled.ts +68 -0
- package/scripts/run/pause/run-pause-cli.ts +73 -0
- package/scripts/run/pause/run-pause.ts +251 -0
- package/scripts/run/progress/run-progress-cli.ts +4 -12
- package/scripts/run/progress/run-progress-clock.ts +1 -1
- package/scripts/run/progress/run-progress-config.ts +6 -14
- package/scripts/run/progress/run-progress-main.ts +12 -0
- package/scripts/run/progress/run-progress.ts +1 -4
- package/scripts/run/review/run-review.ts +2 -1
- package/scripts/run/run-ending.ts +1 -0
- package/scripts/run/run-invocation.ts +5 -6
- package/scripts/run/run-liveness-cli.ts +6 -8
- package/scripts/run/run-liveness.ts +60 -29
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-preflight.ts +18 -3
- package/scripts/run/run-prep-cli.ts +1 -10
- package/scripts/run/run-prep-locate.ts +7 -50
- package/scripts/run/run-prep-main.ts +12 -0
- package/scripts/run/run-prep.ts +6 -0
- package/scripts/run/run-report-cli.ts +101 -13
- package/scripts/run/run-report-handoff.ts +114 -0
- package/scripts/run/run-step.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +13 -0
- package/scripts/run/run-watcher-guard-cli.ts +1 -1
- package/scripts/run/run-watcher-guard.ts +1 -1
- package/scripts/run/ship/run-ship-args.ts +121 -0
- package/scripts/run/ship/run-ship-body-draft.ts +110 -0
- package/scripts/run/ship/run-ship-cli.ts +63 -140
- package/scripts/run/ship/run-ship-detach.ts +19 -8
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +18 -2
- package/scripts/run/ship/run-ship-overlap.ts +42 -5
- package/scripts/run/ship/run-ship-place.ts +96 -0
- package/scripts/run/ship/run-ship-pre-detach-timed.ts +43 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +81 -24
- package/scripts/run/ship/run-ship-preflight.ts +137 -32
- package/scripts/run/ship/run-ship-probe.ts +11 -3
- package/scripts/run/ship/run-ship-relaunch-cap.ts +70 -0
- package/scripts/run/ship/run-ship-removed-rows.ts +61 -0
- package/scripts/run/ship/run-ship-return.ts +107 -23
- package/scripts/run/ship/run-ship-review-steps.ts +105 -151
- package/scripts/run/ship/run-ship-review.ts +73 -6
- package/scripts/run/ship/run-ship-reviewer.ts +207 -0
- package/scripts/run/ship/run-ship-stage.ts +55 -6
- package/scripts/run/ship/run-ship-steps.ts +46 -15
- package/scripts/run/ship/run-ship-stop-cause.ts +135 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +43 -6
- package/scripts/run/ship/run-ship.ts +30 -2
- package/scripts/run/tidy/run-tidy-cli.ts +0 -4
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -0
- package/scripts/run/tidy/run-tidy-main.ts +8 -0
- package/scripts/run/wake/run-wake-cli.ts +119 -100
- package/scripts/run/wake/run-wake-code.ts +83 -0
- package/scripts/run/wake/run-wake-driver.ts +19 -8
- package/scripts/run/wake/run-wake-loop.ts +34 -3
- package/scripts/run/wake/run-wake-main.ts +13 -0
- package/scripts/run/wake/run-wake-ports.ts +90 -0
- package/scripts/run/wake/run-wake-takeover.ts +66 -0
- package/scripts/run/wake/run-wake.ts +2 -1
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -1
- package/scripts/safe-chain/project-config.ts +3 -9
- package/scripts/security/security-audit-main.ts +8 -0
- package/scripts/security/security-audit-provision-logic.ts +0 -11
- package/scripts/security/security-audit-provision-main.ts +12 -0
- package/scripts/security/security-audit-provision.ts +11 -26
- package/scripts/security/security-audit.ts +6 -7
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +6 -13
- package/scripts/split/split-assess-cli.ts +2 -2
- package/scripts/split/split-assess.ts +15 -0
- package/scripts/split/split-measure.ts +65 -0
- package/scripts/sync/claude-settings-merge.ts +8 -15
- package/scripts/sync/directory-copy-guard.ts +4 -9
- package/scripts/sync/file-content.ts +78 -8
- package/scripts/sync/sync-ai-files.ts +3 -5
- package/scripts/sync/sync-configs.ts +11 -23
- package/scripts/sync/sync-hook-safety.ts +4 -10
- package/scripts/sync/sync-main.ts +11 -0
- package/scripts/sync/sync.ts +25 -37
- package/scripts/test/test-declared-changed.ts +2 -2
- package/scripts/test/test-declared.ts +1 -1
- package/scripts/test/test-e2e-guard.ts +25 -1
- package/scripts/test/test-e2e-stamp.ts +38 -0
- package/scripts/test/test-pinned-logic.ts +145 -0
- package/scripts/test/test-pinned-main.ts +78 -0
- package/scripts/test/test-pinned.ts +100 -0
- package/scripts/test/test-read-map.ts +264 -0
- package/scripts/test/test-read-recording.ts +91 -0
- package/scripts/test/test-read-trace.ts +148 -0
- package/scripts/test/test-red-main.ts +12 -0
- package/scripts/test/test-red.ts +12 -30
- package/scripts/test/test-related-main.ts +18 -0
- package/scripts/test/test-related-record.ts +119 -0
- package/scripts/test/test-related-scope.ts +229 -43
- package/scripts/test/test-related.ts +300 -22
- package/scripts/test/test-unit-guard-main.ts +15 -0
- package/scripts/test/test-unit-guard.ts +42 -24
- package/scripts/test/unit-count-file.ts +37 -0
- package/scripts/test/unit-run-marker.ts +162 -0
- package/scripts/test/unit-setup-files.ts +51 -0
- package/scripts/test/unit-worker-share.ts +61 -149
- package/scripts/test/whole-suite-files.ts +63 -0
- package/scripts/time-runtime/time-background.ts +20 -2
- package/scripts/time-runtime/time-bundles.ts +4 -3
- package/scripts/time-runtime/time-density-hook.ts +8 -6
- package/scripts/time-runtime/time-followup-stage.ts +1 -3
- package/scripts/time-runtime/time-format.ts +5 -28
- package/scripts/time-runtime/time-markers.ts +10 -1
- package/scripts/time-runtime/time-shell.ts +97 -10
- package/scripts/time-runtime/time-transcript-line.ts +49 -62
- package/scripts/uninstall/uninstall.ts +1 -1
- package/scripts/version/bump-version-main.ts +12 -0
- package/scripts/version/bump-version.ts +25 -25
- package/scripts/version/effective-upstream.ts +6 -12
- package/scripts/version/latest-corepack.ts +17 -32
- package/scripts/version/latest-if-required-cli.ts +93 -0
- package/scripts/version/latest-lane-guard-main.ts +8 -0
- package/scripts/version/latest-lane-guard.ts +0 -4
- package/scripts/version/latest-scope-cli.ts +0 -9
- package/scripts/version/latest-scope-main.ts +12 -0
- package/scripts/version/latest-update.ts +5 -5
- package/scripts/version/npm-registry.ts +44 -6
- package/scripts/version/publishable-range-check.ts +5 -16
- package/scripts/version/release-age.ts +1 -1
- package/scripts/version/release-hold.ts +1 -1
- package/scripts/version/release-window.ts +38 -0
- package/scripts/version/running-binary.ts +1 -1
- package/scripts/version/safe-chain-version-update.ts +3 -8
- package/scripts/version/version-targets.ts +6 -28
- package/templates/dependabot.yml +29 -0
- package/templates/gitignore +4 -1
- package/templates/pnpm-workspace.basic.yaml +1 -1
- package/templates/sonar-project.properties +3 -2
- package/templates/workflows/ci.yml +12 -4
- package/templates/workflows/github-release.yml +4 -0
- package/tsconfig.sonar.json +1 -1
- package/.ncurc.json +0 -3
- package/dist/hooks/batch-guard.js +0 -29
- package/dist/hooks/chunk-4KKD2UTK.js +0 -66
- package/dist/hooks/chunk-6TS2JD6D.js +0 -237
- package/dist/hooks/chunk-7DSBJVFH.js +0 -50
- package/dist/hooks/chunk-A65Y4YOR.js +0 -79
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EFXE6C37.js +0 -81
- package/dist/hooks/chunk-GP4IEC4O.js +0 -20
- package/dist/hooks/chunk-JP45SOCJ.js +0 -56
- package/dist/hooks/chunk-LAOV7NLM.js +0 -45
- package/dist/hooks/chunk-M4HGZV7U.js +0 -83
- package/dist/hooks/chunk-PF2NZL2A.js +0 -131
- package/dist/hooks/chunk-PTICX4OL.js +0 -358
- package/dist/hooks/chunk-RT27QRJW.js +0 -6247
- package/dist/hooks/chunk-SYOTDYCI.js +0 -3533
- package/dist/hooks/chunk-UPUZF3AN.js +0 -279
- package/dist/hooks/chunk-WK6SMBIC.js +0 -3180
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -29
- package/scripts/backlog/backlog-stalled-cli.ts +0 -30
- package/scripts/cost-runtime/cost-format.ts +0 -29
- package/scripts/init/basic-path-migration.ts +0 -24
- package/scripts/issue/issue-backlinks-cli.ts +0 -93
- package/scripts/josh/josh-commands-guard.ts +0 -38
- package/scripts/josh/josh-usage-automation.ts +0 -121
- package/scripts/josh/josh-usage-backlog.ts +0 -180
- package/scripts/josh/josh-usage-developer.ts +0 -230
- package/scripts/josh/josh-usage-hooks.ts +0 -38
- package/scripts/josh/josh-usage-issue.ts +0 -205
- package/scripts/josh/josh-usage-review.ts +0 -101
- package/scripts/josh/josh-usage-run.ts +0 -252
- package/scripts/josh/josh-usage-session.ts +0 -238
- package/scripts/josh/josh-usage-workflow.ts +0 -212
- package/scripts/lint/cross-file-recheck.ts +0 -155
- package/scripts/registry-migration/migrate-logic.ts +0 -237
- package/scripts/registry-migration/migrate.ts +0 -292
- package/scripts/registry-migration/user-npmrc.ts +0 -15
- package/scripts/rules/rule-guard.ts +0 -23
- package/scripts/rules/rule-registry-rows.ts +0 -292
- package/scripts/rules/rule-registry.ts +0 -112
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { git_gh_command } from '#scripts/gh/git-gh-command'
|
|
2
2
|
import { issue_cite } from '#scripts/issue/issue-cite'
|
|
3
|
-
import {
|
|
3
|
+
import type { JoshResult } from '#scripts/josh/josh-run'
|
|
4
4
|
import { lane_capacity } from '#scripts/lane/lane-capacity'
|
|
5
|
+
import { lane_process_table, type TableRead } from '#scripts/lane/lane-process-table'
|
|
5
6
|
import { lane_registry, type LaneInfo } from '#scripts/lane/lane-registry'
|
|
7
|
+
import { lane_snapshot_trace } from '#scripts/lane/lane-snapshot-trace'
|
|
6
8
|
import { lane_spent } from '#scripts/lane/lane-spent'
|
|
9
|
+
import { lane_state } from '#scripts/lane/lane-state'
|
|
7
10
|
import type { RunCarry } from '#scripts/run/carry/run-carry'
|
|
11
|
+
import { run_event_scope } from '#scripts/run/event/run-event-scope'
|
|
12
|
+
import { run_event_stream } from '#scripts/run/event/run-event-stream'
|
|
8
13
|
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
9
14
|
import { run_headless } from '#scripts/run/run-headless'
|
|
10
15
|
import { run_invocation } from '#scripts/run/run-invocation'
|
|
11
|
-
import {
|
|
16
|
+
import { backlog_drive_restore } from './backlog-drive-restore'
|
|
17
|
+
import { backlog_next_shared } from './backlog-next-shared'
|
|
18
|
+
import { backlog_occupied } from './backlog-occupied'
|
|
19
|
+
import { backlog_offer_exclude } from './backlog-offer-exclude'
|
|
12
20
|
import { backlog_stalled } from './backlog-stalled'
|
|
13
21
|
|
|
14
22
|
// The ready line reports runnable work to the driving backlogrun parent on a watcher wake.
|
|
@@ -21,10 +29,27 @@ interface ReadyReading {
|
|
|
21
29
|
free_lanes: number
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
// How many open lanes hold a place under the limit,
|
|
32
|
+
// How many open lanes hold a place under the limit, how many hold a port seat, and the ones with no
|
|
33
|
+
// lane state record.
|
|
25
34
|
interface LaneUse {
|
|
26
35
|
occupied: number
|
|
27
36
|
seated: number
|
|
37
|
+
unknown: ReadonlyArray<string>
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// The lanes that hold a place under the limit, read once for every count drawn from them.
|
|
41
|
+
interface LaneRoom {
|
|
42
|
+
occupied: ReadonlyArray<LaneInfo>
|
|
43
|
+
// The open lanes no child is working in, read from the same snapshot.
|
|
44
|
+
idle: ReadonlyArray<string>
|
|
45
|
+
// The open lanes with no lane state record, counted as holding a place until one is written.
|
|
46
|
+
unknown: ReadonlyArray<string>
|
|
47
|
+
use: LaneUse
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface LaneCount {
|
|
51
|
+
limit: number
|
|
52
|
+
free: number
|
|
28
53
|
}
|
|
29
54
|
|
|
30
55
|
interface ReadyPorts {
|
|
@@ -32,45 +57,69 @@ interface ReadyPorts {
|
|
|
32
57
|
ready_issues: () => Promise<ReadonlyArray<string>>
|
|
33
58
|
}
|
|
34
59
|
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
60
|
+
// The lanes that hold a place under the limit (`backlog-occupied.ts`), the idle ones and the unknown
|
|
61
|
+
// ones. Paused is each lane's state record's answer; every lane's idle reading is drawn from one
|
|
62
|
+
// asynchronous process snapshot, so the count never blocks its caller's event loop
|
|
63
|
+
// (joshuafolkken/kit#4241, #4245); `run:board` passes the snapshot its redraw already read (#4246).
|
|
64
|
+
async function occupancy_of(
|
|
65
|
+
open: ReadonlyArray<LaneInfo>,
|
|
66
|
+
table: TableRead,
|
|
67
|
+
): Promise<Omit<LaneRoom, 'use'>> {
|
|
68
|
+
const rows = await table()
|
|
69
|
+
const issues = open.map((lane) => lane.issue)
|
|
70
|
+
const trace = { process_trace: await lane_snapshot_trace.traces_of(issues, rows) }
|
|
71
|
+
const records = await lane_state.read_states(issues)
|
|
72
|
+
const is_merge_waiting = await lane_snapshot_trace.merge_waits_of(issues, rows)
|
|
73
|
+
const occupied = backlog_occupied.occupied_lanes(
|
|
74
|
+
open,
|
|
75
|
+
(live) => lane_spent.idle_lanes(live, trace),
|
|
76
|
+
records,
|
|
77
|
+
is_merge_waiting,
|
|
78
|
+
)
|
|
79
|
+
const unknown = backlog_occupied.unknown_lanes(open, records)
|
|
80
|
+
|
|
81
|
+
return { occupied, idle: lane_spent.idle_lanes(open, trace), unknown }
|
|
44
82
|
}
|
|
45
83
|
|
|
46
|
-
// The lanes that hold a place under the limit
|
|
47
|
-
|
|
84
|
+
// The open lanes as the free count reads them: those that hold a place under the limit, and every
|
|
85
|
+
// open one, since an uncounted lane still holds its port seat.
|
|
86
|
+
async function lane_room(
|
|
87
|
+
lanes?: ReadonlyArray<LaneInfo>,
|
|
88
|
+
table: TableRead = lane_process_table.read_table,
|
|
89
|
+
): Promise<LaneRoom> {
|
|
48
90
|
const open = lanes ?? (await lane_registry.list_lanes())
|
|
91
|
+
const occupancy = await occupancy_of(open, table)
|
|
92
|
+
const seated = open.filter((lane) => !lane.is_stranded).length
|
|
49
93
|
|
|
50
|
-
|
|
94
|
+
const use = { occupied: occupancy.occupied.length, seated, unknown: occupancy.unknown }
|
|
95
|
+
|
|
96
|
+
return { ...occupancy, use }
|
|
51
97
|
}
|
|
52
98
|
|
|
53
|
-
// The open lanes as the free count reads them: those that hold a place under the limit, and every
|
|
54
|
-
// open one, since an uncounted lane still holds its port seat.
|
|
55
99
|
async function lane_use(lanes?: ReadonlyArray<LaneInfo>): Promise<LaneUse> {
|
|
56
|
-
const
|
|
57
|
-
const occupied = await occupied_lanes(open)
|
|
100
|
+
const room = await lane_room(lanes)
|
|
58
101
|
|
|
59
|
-
return
|
|
102
|
+
return room.use
|
|
60
103
|
}
|
|
61
104
|
|
|
62
105
|
function free_of(limit: number, use: LaneUse): number {
|
|
63
106
|
return lane_capacity.free_lanes(limit, use.occupied, use.seated)
|
|
64
107
|
}
|
|
65
108
|
|
|
66
|
-
//
|
|
67
|
-
// prints, and the one `run:board` draws, so the two never answer apart.
|
|
68
|
-
async function
|
|
109
|
+
// The limit and the free lanes in `room`, `undefined` where the limit could not be read: the count
|
|
110
|
+
// `lane:limit` prints, and the one `run:board` draws, so the two never answer apart.
|
|
111
|
+
async function count_in(room: LaneRoom): Promise<LaneCount | undefined> {
|
|
69
112
|
const limit = await lane_capacity.lane_limit()
|
|
70
113
|
|
|
71
114
|
if (limit.kind !== 'limit') return undefined
|
|
72
115
|
|
|
73
|
-
return free_of(limit.limit,
|
|
116
|
+
return { limit: limit.limit, free: free_of(limit.limit, room.use) }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function free_lanes_beside(lanes: ReadonlyArray<LaneInfo>): Promise<number | undefined> {
|
|
120
|
+
const count = await count_in(await lane_room(lanes))
|
|
121
|
+
|
|
122
|
+
return count?.free
|
|
74
123
|
}
|
|
75
124
|
|
|
76
125
|
async function free_under(limit: number): Promise<number> {
|
|
@@ -94,12 +143,24 @@ async function free_lane_count(): Promise<number> {
|
|
|
94
143
|
// **The drive's count throws on an unreadable limit**. The drive launches no
|
|
95
144
|
// more than this count, so the safe-direction zero above would leave it launching nothing and reporting
|
|
96
145
|
// nothing for good; a bad setting is the hard error `lane_capacity` says it is, ending the drive loudly.
|
|
97
|
-
async function
|
|
146
|
+
async function drive_limit(): Promise<number> {
|
|
98
147
|
const limit = await lane_capacity.lane_limit()
|
|
99
148
|
|
|
100
149
|
if (limit.kind !== 'limit') throw new Error(limit.problem)
|
|
101
150
|
|
|
102
|
-
return
|
|
151
|
+
return limit.limit
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function drive_free_lane_count(): Promise<number> {
|
|
155
|
+
return await free_under(await drive_limit())
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// The drive's room under the limit alone, for resuming a kept lane, which already holds its port seat.
|
|
159
|
+
async function drive_limit_room(): Promise<number> {
|
|
160
|
+
const limit = await drive_limit()
|
|
161
|
+
const use = await lane_use()
|
|
162
|
+
|
|
163
|
+
return lane_capacity.limit_room(limit, use.occupied)
|
|
103
164
|
}
|
|
104
165
|
|
|
105
166
|
// **A `--only` run has no pool to drain**. `backlog:next` lists the opted-in
|
|
@@ -110,13 +171,32 @@ function drains_pool(carry: RunCarry | undefined): boolean {
|
|
|
110
171
|
return carry === undefined || !run_invocation.has_only(carry.invocation)
|
|
111
172
|
}
|
|
112
173
|
|
|
174
|
+
// The offer's own exclusion, read off this run's stream: a merged child `backlog:next` still reads OPEN,
|
|
175
|
+
// or one in flight, is no ready work (joshuafolkken/kit#4349). Scoped to this invocation, as the drive's
|
|
176
|
+
// list is: the stream is the repository's log, so an earlier run's merge or unsettled launch would
|
|
177
|
+
// otherwise hide a reopened issue for good.
|
|
178
|
+
async function stream_exclude(carry: RunCarry | undefined): Promise<ReadonlyArray<string>> {
|
|
179
|
+
const target = await run_event_stream_emit.stream_target()
|
|
180
|
+
|
|
181
|
+
if (target === undefined || carry === undefined) return []
|
|
182
|
+
|
|
183
|
+
const scope = run_event_scope.scope_of({ kind: 'carried', carry })
|
|
184
|
+
const events = run_event_scope.scoped_events(run_event_stream.read_events(target), scope) ?? []
|
|
185
|
+
|
|
186
|
+
return backlog_drive_restore.offer_exclude(events)
|
|
187
|
+
}
|
|
188
|
+
|
|
113
189
|
// The `backlog:next` read, or `undefined` for a `--only` run, which answers none before paying for the
|
|
114
190
|
// network read. A bounded read keeps stderr piped: the arrival probe reads once
|
|
115
191
|
// a minute, and a forwarded refusal would fill the watcher's output.
|
|
116
192
|
async function read_backlog_next(timeout_ms?: number): Promise<JoshResult | undefined> {
|
|
117
|
-
|
|
193
|
+
const carry = await run_headless.current_carry()
|
|
194
|
+
|
|
195
|
+
if (!drains_pool(carry)) return undefined
|
|
196
|
+
|
|
197
|
+
const argv = ['backlog:next', ...backlog_offer_exclude.exclude_argv(await stream_exclude(carry))]
|
|
118
198
|
|
|
119
|
-
return await
|
|
199
|
+
return await backlog_next_shared.read(argv, timeout_ms === undefined, timeout_ms)
|
|
120
200
|
}
|
|
121
201
|
|
|
122
202
|
// The runnable issues for this checkout, read the way a loop reads them: `backlog:next`'s numeric lines.
|
|
@@ -208,9 +288,11 @@ const backlog_ready = {
|
|
|
208
288
|
print_offer_hint,
|
|
209
289
|
free_lane_count,
|
|
210
290
|
free_lanes_beside,
|
|
291
|
+
count_in,
|
|
292
|
+
lane_room,
|
|
211
293
|
lane_use,
|
|
212
|
-
occupied_lanes,
|
|
213
294
|
drive_free_lane_count,
|
|
295
|
+
drive_limit_room,
|
|
214
296
|
drains_pool,
|
|
215
297
|
print_ready_line,
|
|
216
298
|
read_ready,
|
|
@@ -219,4 +301,4 @@ const backlog_ready = {
|
|
|
219
301
|
}
|
|
220
302
|
|
|
221
303
|
export { backlog_ready }
|
|
222
|
-
export type { LaneUse, ReadyPorts, ReadyReading }
|
|
304
|
+
export type { LaneCount, LaneRoom, LaneUse, ReadyPorts, ReadyReading }
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { lane_ledger, type LedgerEntry } from '#scripts/lane/lane-ledger'
|
|
2
2
|
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
3
3
|
import { run_event_stream_emit } from '#scripts/run/event/run-event-stream-emit'
|
|
4
4
|
import { backlog_ready, type ReadyPorts } from './backlog-ready'
|
|
5
5
|
import { backlog_stalled, type StallReading, type StallVerdict } from './backlog-stalled'
|
|
6
6
|
|
|
7
7
|
// The I/O half of the stall detector: it gathers the three counts the pure
|
|
8
|
-
// judge in `backlog-stalled.ts` weighs, then — on a stall — leaves the marker
|
|
9
|
-
//
|
|
8
|
+
// judge in `backlog-stalled.ts` weighs, then — on a stall — leaves the marker `run:step` reads as
|
|
9
|
+
// `backlog:next`. It sends no Telegram (joshuafolkken/kit#4015): a stall resolves itself at the next
|
|
10
|
+
// dispatch, so the person it reached had nothing to do; the idle notification `backlog:drive` sends
|
|
11
|
+
// when nothing is left to dispatch is the one that wants a hand. `stop-guard.ts` wires it into the Stop hook, so it runs at each loop boundary; the CLI
|
|
10
12
|
// exposes the same call for a person to run by hand.
|
|
11
13
|
//
|
|
12
14
|
// **Cheap first.** The costly read is `backlog:next`, a subprocess that hits the network. The two local
|
|
@@ -14,26 +16,39 @@ import { backlog_stalled, type StallReading, type StallVerdict } from './backlog
|
|
|
14
16
|
// is one `git worktree list`. Neither the lane count nor the backlog read is made unless the cheaper
|
|
15
17
|
// condition ahead of it already holds, so an ordinary stop — a run not idle, or with no free lane —
|
|
16
18
|
// costs a single file read and nothing more.
|
|
19
|
+
//
|
|
20
|
+
// **A stall is aged from when work and a lane first met** (joshuafolkken/kit#4349). Each probe records,
|
|
21
|
+
// on the lane ledger, whether offerable work and a free lane coexist — only when that changes — and the
|
|
22
|
+
// wait runs from the observation that opened the current episode. The dispatch age stays the cheap
|
|
23
|
+
// gate: the wait can never exceed it.
|
|
17
24
|
|
|
18
25
|
const NO_FREE = 0
|
|
19
26
|
const NO_READY = 0
|
|
20
27
|
const NO_AGE = 0
|
|
21
28
|
|
|
22
|
-
// The
|
|
23
|
-
//
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// The seams a test replaces: the stream target and its events, the clock, the two counts, and the two
|
|
27
|
-
// side effects. The defaults are the real readers; a test hands fakes so the gather and report logic run
|
|
28
|
-
// without a git tree, a network or a wall clock.
|
|
29
|
+
// The seams a test replaces: the stream target and its events, the clock, the two counts, the ledger,
|
|
30
|
+
// and the marker. The defaults are the real readers; a test hands fakes so the gather and report logic
|
|
31
|
+
// run without a git tree, a network or a wall clock.
|
|
29
32
|
interface DetectPorts {
|
|
30
33
|
resolve_target: () => Promise<string | undefined>
|
|
31
34
|
read_events: (target: string) => ReadonlyArray<RunEvent>
|
|
32
35
|
now_ms: () => number
|
|
33
36
|
free_lane_count: () => Promise<number>
|
|
34
37
|
ready_count: () => Promise<number>
|
|
38
|
+
read_ledger: () => Promise<ReadonlyArray<LedgerEntry>>
|
|
39
|
+
mark_offerable: (is_offerable: boolean) => Promise<void>
|
|
35
40
|
emit_stall: (text: string) => Promise<boolean>
|
|
36
|
-
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface Counts {
|
|
44
|
+
ready_count: number
|
|
45
|
+
free_lanes: number
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// The dispatch reference the episode is bounded by, and the probe's own time.
|
|
49
|
+
interface Clock {
|
|
50
|
+
reference_ms: number
|
|
51
|
+
now_ms: number
|
|
37
52
|
}
|
|
38
53
|
|
|
39
54
|
// The free-lane and runnable-issue reads are `backlog-ready.ts`'s — the watcher's ready line reads the
|
|
@@ -55,8 +70,15 @@ async function real_emit_stall(text: string): Promise<boolean> {
|
|
|
55
70
|
return await run_event_stream_emit.emit_once_since(STALL, text, CHILD_LAUNCH)
|
|
56
71
|
}
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
|
|
73
|
+
// A test run has no ledger (`lane_ledger.target`), so it reads as empty there.
|
|
74
|
+
async function read_real_ledger(): Promise<ReadonlyArray<LedgerEntry>> {
|
|
75
|
+
const path = await lane_ledger.target()
|
|
76
|
+
|
|
77
|
+
return path === undefined ? [] : lane_ledger.read_entries(path)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function real_mark_offerable(is_offerable: boolean): Promise<void> {
|
|
81
|
+
await lane_ledger.record_offerable(is_offerable)
|
|
60
82
|
}
|
|
61
83
|
|
|
62
84
|
function ports_over(ready: ReadyPorts): DetectPorts {
|
|
@@ -66,26 +88,64 @@ function ports_over(ready: ReadyPorts): DetectPorts {
|
|
|
66
88
|
now_ms: () => Date.now(),
|
|
67
89
|
free_lane_count: ready.free_lane_count,
|
|
68
90
|
ready_count: ready_count_of(ready),
|
|
91
|
+
read_ledger: read_real_ledger,
|
|
92
|
+
mark_offerable: real_mark_offerable,
|
|
69
93
|
emit_stall: real_emit_stall,
|
|
70
|
-
notify_stalled: real_notify_stalled,
|
|
71
94
|
}
|
|
72
95
|
}
|
|
73
96
|
|
|
74
97
|
const DEFAULT_PORTS: DetectPorts = ports_over(backlog_ready.DEFAULT_PORTS)
|
|
75
98
|
|
|
76
|
-
function ok_reading(
|
|
77
|
-
return { ready_count: NO_READY, free_lanes: NO_FREE,
|
|
99
|
+
function ok_reading(): StallReading {
|
|
100
|
+
return { ready_count: NO_READY, free_lanes: NO_FREE, waiting_ms: NO_AGE }
|
|
78
101
|
}
|
|
79
102
|
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
async function probe_reading(ports: DetectPorts, dispatch_age_ms: number): Promise<StallReading> {
|
|
103
|
+
// Count the free lanes, and only if one is free read the backlog. A full pool short-circuits before the
|
|
104
|
+
// network call — a stall needs a lane to go into.
|
|
105
|
+
async function read_counts(ports: DetectPorts): Promise<Counts> {
|
|
84
106
|
const free_lanes = await ports.free_lane_count()
|
|
85
107
|
|
|
86
|
-
if (free_lanes <= NO_FREE) return { ready_count: NO_READY, free_lanes
|
|
108
|
+
if (free_lanes <= NO_FREE) return { ready_count: NO_READY, free_lanes }
|
|
109
|
+
|
|
110
|
+
return { ready_count: await ports.ready_count(), free_lanes }
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function has_both(counts: Counts): boolean {
|
|
114
|
+
return counts.ready_count > NO_READY && counts.free_lanes > NO_FREE
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// How long both have held: from the observation that opened the episode, or zero where this probe opens
|
|
118
|
+
// or closes one — and records that change.
|
|
119
|
+
async function waiting_ms(
|
|
120
|
+
ports: DetectPorts,
|
|
121
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
122
|
+
clock: Clock,
|
|
123
|
+
is_offerable: boolean,
|
|
124
|
+
): Promise<number> {
|
|
125
|
+
const opened_ms = backlog_stalled.open_offerable_ms(entries, clock.reference_ms)
|
|
126
|
+
|
|
127
|
+
if (is_offerable === (opened_ms !== undefined)) return clock.now_ms - (opened_ms ?? clock.now_ms)
|
|
87
128
|
|
|
88
|
-
|
|
129
|
+
await ports.mark_offerable(is_offerable)
|
|
130
|
+
|
|
131
|
+
return NO_AGE
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// The idle-and-past-threshold branch, where the costly reads finally happen.
|
|
135
|
+
async function probe_reading(ports: DetectPorts, clock: Clock): Promise<StallReading> {
|
|
136
|
+
const counts = await read_counts(ports)
|
|
137
|
+
const entries = await ports.read_ledger()
|
|
138
|
+
const waited = await waiting_ms(ports, entries, clock, has_both(counts))
|
|
139
|
+
|
|
140
|
+
return { ...counts, waiting_ms: waited, hold: backlog_stalled.open_hold(entries) }
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// The dispatch reference and the probe's time, or `undefined` when the stream has nothing to age against.
|
|
144
|
+
function clock_of(ports: DetectPorts, target: string): Clock | undefined {
|
|
145
|
+
const now_ms = ports.now_ms()
|
|
146
|
+
const age = backlog_stalled.dispatch_age_ms(ports.read_events(target), now_ms)
|
|
147
|
+
|
|
148
|
+
return age === undefined ? undefined : { reference_ms: now_ms - age, now_ms }
|
|
89
149
|
}
|
|
90
150
|
|
|
91
151
|
// The reading that decides the verdict, assembled cheap-condition-first. `undefined` is the unreadable
|
|
@@ -96,25 +156,38 @@ async function gather(ports: DetectPorts, threshold_ms: number): Promise<StallRe
|
|
|
96
156
|
|
|
97
157
|
if (target === undefined) return undefined
|
|
98
158
|
|
|
99
|
-
const
|
|
159
|
+
const clock = clock_of(ports, target)
|
|
100
160
|
|
|
101
|
-
if (
|
|
102
|
-
if (age <= threshold_ms) return ok_reading(age)
|
|
161
|
+
if (clock === undefined || clock.now_ms - clock.reference_ms <= threshold_ms) return ok_reading()
|
|
103
162
|
|
|
104
|
-
return await probe_reading(ports,
|
|
163
|
+
return await probe_reading(ports, clock)
|
|
105
164
|
}
|
|
106
165
|
|
|
107
|
-
// The
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
async function
|
|
111
|
-
|
|
166
|
+
// The watcher's once-a-minute arrival probe records the same observation from the reading it already
|
|
167
|
+
// made, so an episode opens within a probe interval of work meeting a lane — not at the first stop past
|
|
168
|
+
// the dispatch-age gate, which would hide up to one threshold of the wait. Best-effort, like the check.
|
|
169
|
+
async function observe_offerable(
|
|
170
|
+
is_offerable: boolean,
|
|
171
|
+
ports: DetectPorts = DEFAULT_PORTS,
|
|
172
|
+
): Promise<void> {
|
|
173
|
+
try {
|
|
174
|
+
const target = await ports.resolve_target()
|
|
175
|
+
const clock = target === undefined ? undefined : clock_of(ports, target)
|
|
112
176
|
|
|
113
|
-
|
|
177
|
+
if (clock !== undefined) await waiting_ms(ports, await ports.read_ledger(), clock, is_offerable)
|
|
178
|
+
} catch {
|
|
179
|
+
// A failed observation is dropped: the next probe records it, and the watcher's loop must not break.
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// The marker, once per stall episode: `emit_stall` refuses a second until a dispatch has intervened, so a
|
|
184
|
+
// stall polled every stop lands on the stream once, not once a turn.
|
|
185
|
+
async function report(ports: DetectPorts, reading: StallReading): Promise<void> {
|
|
186
|
+
await ports.emit_stall(backlog_stalled.describe(reading))
|
|
114
187
|
}
|
|
115
188
|
|
|
116
|
-
// Read the three conditions, print nothing, and on a stall leave the marker
|
|
117
|
-
//
|
|
189
|
+
// Read the three conditions, print nothing, and on a stall leave the marker. The verdict is returned for
|
|
190
|
+
// the CLI to print; the side effect is the report's.
|
|
118
191
|
async function detect_and_report(
|
|
119
192
|
ports: DetectPorts = DEFAULT_PORTS,
|
|
120
193
|
threshold_ms: number = backlog_stalled.STALL_THRESHOLD_MS,
|
|
@@ -127,7 +200,7 @@ async function detect_and_report(
|
|
|
127
200
|
return verdict
|
|
128
201
|
}
|
|
129
202
|
|
|
130
|
-
// Best-effort for the Stop hook: the detector is a report, so a failure to gather or
|
|
203
|
+
// Best-effort for the Stop hook: the detector is a report, so a failure to gather or mark is dropped
|
|
131
204
|
// rather than raised into the stop decision it rides alongside.
|
|
132
205
|
async function run_stall_check(ready: ReadyPorts = backlog_ready.DEFAULT_PORTS): Promise<void> {
|
|
133
206
|
try {
|
|
@@ -137,7 +210,7 @@ async function run_stall_check(ready: ReadyPorts = backlog_ready.DEFAULT_PORTS):
|
|
|
137
210
|
}
|
|
138
211
|
}
|
|
139
212
|
|
|
140
|
-
const backlog_stalled_detect = { detect_and_report, run_stall_check }
|
|
213
|
+
const backlog_stalled_detect = { detect_and_report, observe_offerable, run_stall_check }
|
|
141
214
|
|
|
142
215
|
export { backlog_stalled_detect }
|
|
143
216
|
export type { DetectPorts }
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { epic_triage } from '#scripts/epic/epic-triage'
|
|
2
2
|
import { issue_number_shape } from '#scripts/issue/issue-number-shape'
|
|
3
|
+
import { lane_ledger, type LedgerEntry } from '#scripts/lane/lane-ledger'
|
|
4
|
+
import { MS_PER_MINUTE } from '#scripts/lib/timeouts'
|
|
3
5
|
import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-stream'
|
|
4
6
|
|
|
5
7
|
// When ready backlog work sits undispatched while lanes are free, nobody notices until a person asks.
|
|
6
8
|
// This is the mechanical judge of that state: three facts read, never
|
|
7
9
|
// weighed — is there runnable work, is there a free lane, and has nothing been dispatched for a while.
|
|
8
|
-
// The verdict is a report, not a stop: a false positive costs one
|
|
10
|
+
// The verdict is a report, not a stop: a false positive costs one stream marker, never a halted run.
|
|
9
11
|
//
|
|
10
12
|
// **Pure by design.** The clock and the counts are handed in, so the four acceptance cases — work with
|
|
11
13
|
// a free lane, work with no free lane, no work, and an unreadable record — and the elapsed-time
|
|
@@ -13,7 +15,6 @@ import { run_event_stream, type RunEvent } from '#scripts/run/event/run-event-st
|
|
|
13
15
|
// counts is `backlog-stalled-detect.ts`; this file only decides.
|
|
14
16
|
|
|
15
17
|
const STALL_THRESHOLD_MINUTES = 10
|
|
16
|
-
const MS_PER_MINUTE = 60_000
|
|
17
18
|
const STALL_THRESHOLD_MS = STALL_THRESHOLD_MINUTES * MS_PER_MINUTE
|
|
18
19
|
const NONE = 0
|
|
19
20
|
|
|
@@ -28,11 +29,14 @@ const OK: StallVerdict = 'ok'
|
|
|
28
29
|
const UNREADABLE: StallVerdict = 'unreadable'
|
|
29
30
|
|
|
30
31
|
// The three facts, read and never judged: how many issues could start now, how many lanes are free, and
|
|
31
|
-
// how long since the last dispatch
|
|
32
|
+
// how long both have held together since the last dispatch — never the idle time before work arrived or
|
|
33
|
+
// a long child ran (joshuafolkken/kit#4349). `hold` is the driver's open hold reason (`memory`, …), so a
|
|
34
|
+
// deliberate hold reads apart from a slow dispatch. Assembled by the detect layer; consumed only here.
|
|
32
35
|
interface StallReading {
|
|
33
36
|
ready_count: number
|
|
34
37
|
free_lanes: number
|
|
35
|
-
|
|
38
|
+
waiting_ms: number
|
|
39
|
+
hold?: string | undefined
|
|
36
40
|
}
|
|
37
41
|
|
|
38
42
|
// All three together, and only together. Separated from `assess` so the short-circuit gate in the
|
|
@@ -40,9 +44,7 @@ interface StallReading {
|
|
|
40
44
|
// same condition rather than a second copy of it.
|
|
41
45
|
function is_stalled(reading: StallReading, threshold_ms: number): boolean {
|
|
42
46
|
return (
|
|
43
|
-
reading.ready_count > NONE &&
|
|
44
|
-
reading.free_lanes > NONE &&
|
|
45
|
-
reading.dispatch_age_ms > threshold_ms
|
|
47
|
+
reading.ready_count > NONE && reading.free_lanes > NONE && reading.waiting_ms > threshold_ms
|
|
46
48
|
)
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -68,23 +70,55 @@ function dispatch_reference_iso(events: ReadonlyArray<RunEvent>): string | undef
|
|
|
68
70
|
return last_launch?.at ?? events[0]?.at
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
function dispatch_age_ms(events: ReadonlyArray<RunEvent>, now_ms: number): number | undefined {
|
|
73
|
+
// That reference as epoch milliseconds, or `undefined` when there is none or the stamp is unparseable.
|
|
74
|
+
function dispatch_reference_ms(events: ReadonlyArray<RunEvent>): number | undefined {
|
|
74
75
|
const iso = dispatch_reference_iso(events)
|
|
76
|
+
const at = iso === undefined ? NaN : Date.parse(iso)
|
|
77
|
+
|
|
78
|
+
return Number.isNaN(at) ? undefined : at
|
|
79
|
+
}
|
|
75
80
|
|
|
76
|
-
|
|
81
|
+
// Milliseconds since that reference, or `undefined` when there is no reference — the caller reads it as
|
|
82
|
+
// "nothing to age against" and returns no stall. A stall cannot be older than this, so it gates the
|
|
83
|
+
// costly reads.
|
|
84
|
+
function dispatch_age_ms(events: ReadonlyArray<RunEvent>, now_ms: number): number | undefined {
|
|
85
|
+
const at = dispatch_reference_ms(events)
|
|
86
|
+
|
|
87
|
+
return at === undefined ? undefined : now_ms - at
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// When the current coexistence of offerable work and a free lane was first observed: the newest
|
|
91
|
+
// observation since the reference, if it saw both. `undefined` when it did not or none was made — an
|
|
92
|
+
// observation before the last dispatch belongs to an episode that dispatch ended.
|
|
93
|
+
function open_offerable_ms(
|
|
94
|
+
entries: ReadonlyArray<LedgerEntry>,
|
|
95
|
+
reference_ms: number,
|
|
96
|
+
): number | undefined {
|
|
97
|
+
const newest = entries.findLast(
|
|
98
|
+
(entry) => entry.kind === lane_ledger.KIND.OFFERABLE && Date.parse(entry.at) >= reference_ms,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if (newest?.kind !== lane_ledger.KIND.OFFERABLE || !newest.is_offerable) return undefined
|
|
102
|
+
|
|
103
|
+
return Date.parse(newest.at)
|
|
104
|
+
}
|
|
77
105
|
|
|
78
|
-
|
|
106
|
+
// The driver's open hold reason: the newest of its hold, release and dispatch records, when a hold.
|
|
107
|
+
function open_hold(entries: ReadonlyArray<LedgerEntry>): string | undefined {
|
|
108
|
+
const { HELD, RELEASED, DISPATCH } = lane_ledger.KIND
|
|
109
|
+
const hold_kinds: ReadonlySet<string> = new Set([HELD, RELEASED, DISPATCH])
|
|
110
|
+
const newest = entries.findLast((entry) => hold_kinds.has(entry.kind))
|
|
79
111
|
|
|
80
|
-
return
|
|
112
|
+
return newest?.kind === lane_ledger.KIND.HELD ? newest.reason : undefined
|
|
81
113
|
}
|
|
82
114
|
|
|
83
|
-
// The one line a person reads in the notification and on the stream: what is waiting
|
|
115
|
+
// The one line a person reads in the notification and on the stream: what is waiting, how long, and the
|
|
116
|
+
// driver's hold reason when it holds deliberately.
|
|
84
117
|
function describe(reading: StallReading): string {
|
|
85
|
-
const minutes = Math.floor(reading.
|
|
118
|
+
const minutes = Math.floor(reading.waiting_ms / MS_PER_MINUTE)
|
|
119
|
+
const held = reading.hold === undefined ? '' : ` (held: ${reading.hold})`
|
|
86
120
|
|
|
87
|
-
return `${String(reading.ready_count)} ready, ${String(reading.free_lanes)} free lane(s), ${String(minutes)}m
|
|
121
|
+
return `${String(reading.ready_count)} ready, ${String(reading.free_lanes)} free lane(s), ${String(minutes)}m waiting with both${held}`
|
|
88
122
|
}
|
|
89
123
|
|
|
90
124
|
// The runnable issue numbers `backlog:next` printed: one token per line, a bare number per runnable
|
|
@@ -118,6 +152,8 @@ const backlog_stalled = {
|
|
|
118
152
|
describe,
|
|
119
153
|
dispatch_age_ms,
|
|
120
154
|
needs_triage,
|
|
155
|
+
open_hold,
|
|
156
|
+
open_offerable_ms,
|
|
121
157
|
ready_tokens,
|
|
122
158
|
}
|
|
123
159
|
|