@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// How often a waiting reservation re-reads the ledger: short enough that a freed place is taken up
|
|
2
|
+
// promptly, long enough that the wait itself burns no measurable CPU.
|
|
3
|
+
const POLL_INTERVAL_MS = 50
|
|
4
|
+
// The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
|
|
5
|
+
// make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
|
|
6
|
+
// for good. Two minutes is well past a unit suite's worst measured time under six-way load. A claim a
|
|
7
|
+
// swap stall holds is the exception (`core_admission.is_swap_held`).
|
|
8
|
+
const WAIT_CAP_MS = 120_000
|
|
9
|
+
|
|
10
|
+
// The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
|
|
11
|
+
// the complexity limit — each default is a branch.
|
|
12
|
+
interface TimingConfig {
|
|
13
|
+
now: () => number
|
|
14
|
+
sleep: (ms: number) => Promise<void>
|
|
15
|
+
poll_interval_ms: number
|
|
16
|
+
wait_cap_ms: number
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function default_sleep(ms: number): Promise<void> {
|
|
20
|
+
await new Promise<void>((resolve) => {
|
|
21
|
+
setTimeout(resolve, ms)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function resolve_timing(options: Partial<TimingConfig>): TimingConfig {
|
|
26
|
+
return {
|
|
27
|
+
now: options.now ?? Date.now,
|
|
28
|
+
sleep: options.sleep ?? default_sleep,
|
|
29
|
+
poll_interval_ms: options.poll_interval_ms ?? POLL_INTERVAL_MS,
|
|
30
|
+
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const core_budget_timing = { resolve_timing }
|
|
35
|
+
|
|
36
|
+
export type { TimingConfig }
|
|
37
|
+
export { core_budget_timing }
|
|
@@ -9,8 +9,12 @@ import { stamp_file } from '#scripts/josh/stamp-file'
|
|
|
9
9
|
import { json_value } from '#scripts/lib/json-value'
|
|
10
10
|
import { unit_worker_share } from '#scripts/test/unit-worker-share'
|
|
11
11
|
import { z } from 'zod'
|
|
12
|
+
import { busy_average, type BusySample } from './busy-average'
|
|
12
13
|
import { core_admission, type Admission, type LedgerEntry, type Overflow } from './core-admission'
|
|
14
|
+
import { core_budget_timing, type TimingConfig } from './core-budget-timing'
|
|
13
15
|
import { core_wait, type BudgetWait, type WaitReason } from './core-wait'
|
|
16
|
+
import { core_wait_record, type WaitSink } from './core-wait-record'
|
|
17
|
+
import { core_weights } from './core-weights'
|
|
14
18
|
import { held_mark } from './held-mark'
|
|
15
19
|
import { machine_capacity, type MachineBudget, type MachineReading } from './machine-capacity'
|
|
16
20
|
|
|
@@ -25,8 +29,9 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
|
|
|
25
29
|
//
|
|
26
30
|
// **A solo run is bit-for-bit unchanged, and that is arithmetic rather than a branch.** The gate's
|
|
27
31
|
// weights are its `reserved_cores` (the static checks) and its `unit_worker_cap` (the unit suite), and
|
|
28
|
-
// `reserved(2 +
|
|
29
|
-
// to the whole budget and
|
|
32
|
+
// `reserved(2 + 2 + 2) + unit_cap(cores - 6)` is exactly `cores` — so a single gate's four claims sum
|
|
33
|
+
// to the whole budget and, while the busy cores stay within what the ledger holds, every one is
|
|
34
|
+
// admitted the instant it is made, with no poll and no wait. Under
|
|
30
35
|
// concurrency the same weights sum past the budget and the ledger is what holds the machine down.
|
|
31
36
|
//
|
|
32
37
|
// **Liveness is `process_identity`'s, reused rather than re-invented.** A run
|
|
@@ -41,66 +46,21 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
|
|
|
41
46
|
|
|
42
47
|
const RESERVED_PREFIX = 'josh-core-reserved-'
|
|
43
48
|
const RESERVED_SUFFIX = '.json'
|
|
44
|
-
//
|
|
45
|
-
// promptly, long enough that the wait itself burns no measurable CPU.
|
|
46
|
-
const POLL_INTERVAL_MS = 50
|
|
47
|
-
// The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
|
|
48
|
-
// make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
|
|
49
|
-
// for good. Two minutes is well past a unit suite's worst measured time under six-way load.
|
|
50
|
-
const WAIT_CAP_MS = 120_000
|
|
51
|
-
// The head of the ledger is always admitted, so the smallest budget worth planning against is one core.
|
|
49
|
+
// The head of an unsaturated ledger is always admitted, so the smallest declared budget is one core.
|
|
52
50
|
const MIN_BUDGET = 1
|
|
53
51
|
|
|
54
|
-
// **The cores each heavy tool occupies, declared once for both places that reserve them**
|
|
55
|
-
// `gate-plan.ts`'s checks and the `josh` commands that run the same tools
|
|
56
|
-
// directly read these, so a direct `josh lint` claims what the gate's lint claims. The lint, type check
|
|
57
|
-
// and spell check numbers are `gate-plan.ts`'s measured table, floored. The whole-tree eslint scan
|
|
58
|
-
// behind `josh lines` and `josh refactor:scan` runs in one process: measured cold on the 11-core
|
|
59
|
-
// machine on 2026-10-06, 113s of CPU over 98s of wall, so it gets one core.
|
|
60
|
-
//
|
|
61
|
-
// The rest ran outside the ledger until joshuafolkken/kit#3944, measured with `/usr/bin/time -l` on the
|
|
62
|
-
// same machine on 2026-10-17 under a load average of 16. Every one stays under one core, so each takes
|
|
63
|
-
// one: `prettier --check` over 40 staged files 2.1s of CPU over 1.7s of wall (`format`), `josh
|
|
64
|
-
// retrospective` 16.5s over 19.8s, and a fresh lane's `pnpm install --frozen-lockfile` 1.9s over 6.1s.
|
|
65
|
-
// `e2e` is the Playwright worker count `josh test:e2e` passes locally — the two-worker run CI already
|
|
66
|
-
// sizes for its four-core runner — since kit has no e2e suite of its own to time.
|
|
67
|
-
const CORE_WEIGHTS = {
|
|
68
|
-
lint: 2,
|
|
69
|
-
type_check: 1,
|
|
70
|
-
spell_check: 1,
|
|
71
|
-
eslint_scan: 1,
|
|
72
|
-
format: 1,
|
|
73
|
-
retrospective: 1,
|
|
74
|
-
install: 1,
|
|
75
|
-
e2e: 2,
|
|
76
|
-
} as const
|
|
77
|
-
|
|
78
|
-
// **The memory each heavy tool holds, declared beside its cores**: peak
|
|
79
|
-
// resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
|
|
80
|
-
// 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
|
|
81
|
-
// files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
|
|
82
|
-
// `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
|
|
83
|
-
// On 2026-10-17: prettier 260 MB, the retrospective 862 MB and a lane install 65 MB.
|
|
84
|
-
const MEMORY_MB = {
|
|
85
|
-
lint: 2400,
|
|
86
|
-
type_check: 1300,
|
|
87
|
-
spell_check: 350,
|
|
88
|
-
eslint_scan: 2400,
|
|
89
|
-
unit_worker: 350,
|
|
90
|
-
format: 300,
|
|
91
|
-
retrospective: 900,
|
|
92
|
-
install: 100,
|
|
93
|
-
} as const
|
|
94
|
-
|
|
95
52
|
// `memory_mb` and `admitted_at` are optional so a marker an older `josh` wrote still reads: it holds no
|
|
96
53
|
// declared memory, and it counts as load from outside the ledger until it is gone.
|
|
97
54
|
// `command`, `checkout`, `lane`, `lanes_root` and `wait_reason` name a waiting claim on `run:board`
|
|
98
|
-
// (`core-wait.ts`).
|
|
55
|
+
// (`core-wait.ts`). `is_unit` marks a unit suite's claim, which may be admitted narrowed to `granted`
|
|
56
|
+
// past the wait cap (`core_admission.narrowed_weight`).
|
|
99
57
|
const reservation_schema = process_owner_schema.extend({
|
|
100
58
|
weight: z.number(),
|
|
101
59
|
claimed_at: z.number(),
|
|
102
60
|
memory_mb: z.number().optional(),
|
|
103
61
|
admitted_at: z.number().optional(),
|
|
62
|
+
is_unit: z.boolean().optional(),
|
|
63
|
+
granted: z.number().optional(),
|
|
104
64
|
command: z.string().optional(),
|
|
105
65
|
checkout: z.string().optional(),
|
|
106
66
|
lane: z.string().optional(),
|
|
@@ -121,6 +81,8 @@ interface ReserveOptions {
|
|
|
121
81
|
memory_mb?: number | undefined
|
|
122
82
|
// What the claim is for, named on the waiting line and on `run:board`.
|
|
123
83
|
command?: string | undefined
|
|
84
|
+
// A unit suite's claim, whose weight is its worker count.
|
|
85
|
+
is_unit?: boolean | undefined
|
|
124
86
|
report?: (line: string) => void
|
|
125
87
|
read_machine?: () => Promise<MachineReading>
|
|
126
88
|
wait_cap_ms?: number
|
|
@@ -128,6 +90,8 @@ interface ReserveOptions {
|
|
|
128
90
|
directory?: string
|
|
129
91
|
now?: () => number
|
|
130
92
|
sleep?: (ms: number) => Promise<void>
|
|
93
|
+
// Where a claim that waited records how long, once admitted (`core-wait-record.ts`).
|
|
94
|
+
record_wait?: WaitSink
|
|
131
95
|
}
|
|
132
96
|
|
|
133
97
|
interface Handle {
|
|
@@ -139,7 +103,7 @@ function marker_name(key: string): string {
|
|
|
139
103
|
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`
|
|
140
104
|
}
|
|
141
105
|
|
|
142
|
-
// **"Cannot tell" counts as live**, the same direction `unit-
|
|
106
|
+
// **"Cannot tell" counts as live**, the same direction `unit-run-marker.ts` takes: being wrong that
|
|
143
107
|
// way costs a reservation a slower admission, while the other way admits past a run that is still there.
|
|
144
108
|
function is_running(reservation: Reservation): boolean {
|
|
145
109
|
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false
|
|
@@ -155,7 +119,7 @@ function read_reservation(source: string): Reservation | undefined {
|
|
|
155
119
|
|
|
156
120
|
// **A dead marker is removed, not merely skipped** — otherwise a reissued pid turns a leaked place into
|
|
157
121
|
// a phantom that fills the budget for good. The unlink never throws: a marker this account may not
|
|
158
|
-
// remove is left alone, exactly as `unit-
|
|
122
|
+
// remove is left alone, exactly as `unit-run-marker.ts` leaves it.
|
|
159
123
|
function sweep_marker(source: string): void {
|
|
160
124
|
try {
|
|
161
125
|
stamp_file.remove_stamp(source)
|
|
@@ -202,12 +166,6 @@ function normalize_budget(budget: number): number {
|
|
|
202
166
|
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET
|
|
203
167
|
}
|
|
204
168
|
|
|
205
|
-
async function default_sleep(ms: number): Promise<void> {
|
|
206
|
-
await new Promise<void>((resolve) => {
|
|
207
|
-
setTimeout(resolve, ms)
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
|
|
211
169
|
// **Replaced atomically, never unlinked and recreated**: the admitted rewrite lands on a marker other
|
|
212
170
|
// lanes are polling, and a reader that hit the gap between an unlink and its create would see the ledger
|
|
213
171
|
// without this place and admit past it.
|
|
@@ -219,57 +177,52 @@ function report_wait(line: string): void {
|
|
|
219
177
|
process.stderr.write(`${line}\n`)
|
|
220
178
|
}
|
|
221
179
|
|
|
222
|
-
// The clock and cadence a wait runs on, resolved apart from the ledger fields so `reserve` stays under
|
|
223
|
-
// the complexity limit — each default is a branch.
|
|
224
|
-
interface TimingConfig {
|
|
225
|
-
now: () => number
|
|
226
|
-
sleep: (ms: number) => Promise<void>
|
|
227
|
-
poll_interval_ms: number
|
|
228
|
-
wait_cap_ms: number
|
|
229
|
-
}
|
|
230
|
-
|
|
231
180
|
interface WaitContext extends TimingConfig {
|
|
232
181
|
read_machine: () => Promise<MachineReading>
|
|
233
182
|
report: (line: string) => void
|
|
183
|
+
record_wait: WaitSink | undefined
|
|
234
184
|
key: string
|
|
235
185
|
target: string
|
|
236
186
|
directory: string
|
|
237
187
|
budget: number
|
|
238
188
|
deadline: number
|
|
239
189
|
fields: ReservationFields
|
|
190
|
+
busy_samples: Array<BusySample>
|
|
240
191
|
}
|
|
241
192
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// **A claim alone in the ledger reads nothing from the machine**: the head is admitted whatever the
|
|
252
|
-
// budget says, so a solo run pays no sampling window and starts exactly as it did before.
|
|
193
|
+
// **A claim alone in the ledger reads the machine too** (joshuafolkken/kit#4238): load outside the
|
|
194
|
+
// ledger saturates the CPU whether or not another claim is in it. The busy cores are the mean of this
|
|
195
|
+
// wait's recent readings of load outside the ledger (`busy-average.ts`). That load holds every claim but
|
|
196
|
+
// the first waiter, which it narrows instead (`core_admission.is_admitted`, joshuafolkken/kit#4313) unless
|
|
197
|
+
// the run queue reads the machine overloaded (`machine_capacity.machine_budget`, joshuafolkken/kit#4361).
|
|
253
198
|
async function current_budget(
|
|
254
199
|
context: WaitContext,
|
|
255
200
|
reservations: ReadonlyArray<LiveReservation>,
|
|
256
201
|
): Promise<MachineBudget> {
|
|
257
|
-
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity }
|
|
258
|
-
|
|
259
202
|
const reading = await context.read_machine()
|
|
260
203
|
const ledger = core_admission.ledger_load(reservations, context.now())
|
|
261
|
-
const budget = machine_capacity.machine_budget(context.budget, reading, ledger)
|
|
262
204
|
|
|
263
|
-
|
|
205
|
+
context.busy_samples = busy_average.with_reading(
|
|
206
|
+
context.busy_samples,
|
|
207
|
+
reading,
|
|
208
|
+
ledger.cores,
|
|
209
|
+
context.now(),
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
const mean = busy_average.averaged(reading, context.busy_samples, ledger.cores)
|
|
213
|
+
|
|
214
|
+
return machine_capacity.machine_budget(context.budget, mean, ledger)
|
|
264
215
|
}
|
|
265
216
|
|
|
266
217
|
// The claim is admitted: its marker records when, which moves its load from "load outside the ledger"
|
|
267
218
|
// to "load the ledger holds" for every later reader — its cores at once, its memory once its tool has
|
|
268
219
|
// had time to ramp up.
|
|
269
|
-
function admit(context: WaitContext, overflow?: Overflow): Admission {
|
|
270
|
-
|
|
220
|
+
function admit(context: WaitContext, overflow?: Overflow, granted?: number): Admission {
|
|
221
|
+
const admitted_at = context.now()
|
|
271
222
|
|
|
272
|
-
|
|
223
|
+
write_reservation(context.target, { ...context.fields, admitted_at, granted })
|
|
224
|
+
|
|
225
|
+
return { overflow, granted, waited_ms: admitted_at - context.fields.claimed_at }
|
|
273
226
|
}
|
|
274
227
|
|
|
275
228
|
function overflow_of(
|
|
@@ -300,14 +253,24 @@ function mark_waiting(context: WaitContext, reason: WaitReason): void {
|
|
|
300
253
|
async function poll_admission(context: WaitContext): Promise<Admission | undefined> {
|
|
301
254
|
const reservations = live_reservations(context.directory)
|
|
302
255
|
const budget = await current_budget(context, reservations)
|
|
256
|
+
// A unit claim is admitted at the room the budget leaves rather than at full width — the first
|
|
257
|
+
// waiter, which load outside the ledger does not hold, as well as one past the wait cap.
|
|
258
|
+
const granted = core_admission.narrowed_weight(context.key, reservations, budget.cores)
|
|
259
|
+
const reason = core_wait.hold_reason(context.key, reservations, budget, granted)
|
|
260
|
+
|
|
261
|
+
if (reason === undefined) return admit(context, undefined, granted)
|
|
303
262
|
|
|
304
|
-
|
|
263
|
+
// Past the cap a held claim runs regardless, except one a swap stall holds.
|
|
264
|
+
if (
|
|
265
|
+
context.now() >= context.deadline &&
|
|
266
|
+
!core_admission.is_swap_held(context.key, reservations, budget)
|
|
267
|
+
) {
|
|
268
|
+
const held = core_admission.with_grant(context.key, reservations, granted)
|
|
305
269
|
|
|
306
|
-
|
|
307
|
-
return admit(context, overflow_of(context, reservations, budget))
|
|
270
|
+
return admit(context, overflow_of(context, held, budget), granted)
|
|
308
271
|
}
|
|
309
272
|
|
|
310
|
-
mark_waiting(context,
|
|
273
|
+
mark_waiting(context, reason)
|
|
311
274
|
|
|
312
275
|
return undefined
|
|
313
276
|
}
|
|
@@ -325,14 +288,19 @@ async function await_admission(context: WaitContext): Promise<Admission> {
|
|
|
325
288
|
admission = await poll_admission(context)
|
|
326
289
|
}
|
|
327
290
|
|
|
291
|
+
await core_wait_record.record_admitted(context.fields, context.now(), context.record_wait)
|
|
292
|
+
|
|
328
293
|
return admission
|
|
329
294
|
}
|
|
330
295
|
|
|
331
|
-
// What a wait reads the machine through
|
|
332
|
-
function resolve_ports(
|
|
296
|
+
// What a wait reads the machine through, reports its start to and records its length in.
|
|
297
|
+
function resolve_ports(
|
|
298
|
+
options: ReserveOptions,
|
|
299
|
+
): Pick<WaitContext, 'read_machine' | 'report' | 'record_wait'> {
|
|
333
300
|
return {
|
|
334
301
|
read_machine: options.read_machine ?? machine_capacity.read_machine,
|
|
335
302
|
report: options.report ?? report_wait,
|
|
303
|
+
record_wait: options.record_wait,
|
|
336
304
|
}
|
|
337
305
|
}
|
|
338
306
|
|
|
@@ -343,13 +311,13 @@ function claim_fields(
|
|
|
343
311
|
claimed_at: number,
|
|
344
312
|
options: ReserveOptions,
|
|
345
313
|
): ReservationFields {
|
|
346
|
-
const { memory_mb, command } = options
|
|
314
|
+
const { memory_mb, command, is_unit } = options
|
|
347
315
|
|
|
348
|
-
return { weight, claimed_at, memory_mb, command, ...core_wait.where_of(process.cwd()) }
|
|
316
|
+
return { weight, claimed_at, memory_mb, command, is_unit, ...core_wait.where_of(process.cwd()) }
|
|
349
317
|
}
|
|
350
318
|
|
|
351
319
|
async function reserve(weight: number, options: ReserveOptions = {}): Promise<Handle> {
|
|
352
|
-
const timing = resolve_timing(options)
|
|
320
|
+
const timing = core_budget_timing.resolve_timing(options)
|
|
353
321
|
const directory = options.directory ?? PLATFORM_TEMP_ROOT
|
|
354
322
|
const claimed_at = timing.now()
|
|
355
323
|
const name = marker_name(randomUUID())
|
|
@@ -365,6 +333,7 @@ async function reserve(weight: number, options: ReserveOptions = {}): Promise<Ha
|
|
|
365
333
|
budget: normalize_budget(options.budget ?? availableParallelism()),
|
|
366
334
|
deadline: claimed_at + timing.wait_cap_ms,
|
|
367
335
|
fields,
|
|
336
|
+
busy_samples: [],
|
|
368
337
|
...resolve_ports(options),
|
|
369
338
|
})
|
|
370
339
|
|
|
@@ -421,16 +390,29 @@ async function with_command_reservation<T>(
|
|
|
421
390
|
)
|
|
422
391
|
}
|
|
423
392
|
|
|
393
|
+
// The unit claim the parent command holds for this process (`with_command_reservation`), or
|
|
394
|
+
// `undefined` where none does. A held claim that is not a unit suite's says nothing about workers.
|
|
395
|
+
function held_unit_claim(directory: string = PLATFORM_TEMP_ROOT): Reservation | undefined {
|
|
396
|
+
const key = held_mark.held_reservation()
|
|
397
|
+
|
|
398
|
+
if (key === undefined) return undefined
|
|
399
|
+
|
|
400
|
+
const held = live_reservations(directory).find((entry) => entry.key === key)
|
|
401
|
+
|
|
402
|
+
return held?.reservation.is_unit === true ? held.reservation : undefined
|
|
403
|
+
}
|
|
404
|
+
|
|
424
405
|
const core_budget = {
|
|
425
|
-
CORE_WEIGHTS,
|
|
406
|
+
CORE_WEIGHTS: core_weights.CORE_WEIGHTS,
|
|
426
407
|
HELD_KEY: held_mark.HELD_KEY,
|
|
427
408
|
HELD_VALUE: held_mark.HELD_VALUE,
|
|
428
|
-
MEMORY_MB,
|
|
409
|
+
MEMORY_MB: core_weights.MEMORY_MB,
|
|
429
410
|
RESERVED_PREFIX,
|
|
430
411
|
admitted_keys: core_admission.admitted_keys,
|
|
431
412
|
admitted_load: core_admission.admitted_load,
|
|
432
413
|
budget_waits,
|
|
433
414
|
describe_overflow: core_admission.describe_overflow,
|
|
415
|
+
held_unit_claim,
|
|
434
416
|
is_held: held_mark.is_held,
|
|
435
417
|
live_reservations,
|
|
436
418
|
release,
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { lane_ledger, type CoreWaitRecord } from '#scripts/lane/lane-ledger'
|
|
2
|
+
|
|
3
|
+
// How long a claim waited for the core budget, written to the lane ledger once it is admitted, so
|
|
4
|
+
// `josh lane:stats` can split a lane's time into work and waiting (joshuafolkken/kit#4382). The
|
|
5
|
+
// waiting line on stderr says a wait started; this says what it cost.
|
|
6
|
+
//
|
|
7
|
+
// **Only a claim that waited is recorded** — one admitted on its first read cost nothing, and a line per
|
|
8
|
+
// command would bury the waits a lane's time is split by. The lane is the claim's own checkout's, the
|
|
9
|
+
// one `run:board` names the waiting claim by.
|
|
10
|
+
|
|
11
|
+
const UNNAMED_COMMAND = 'a step'
|
|
12
|
+
|
|
13
|
+
// What `core-budget.ts` knows of the claim when it is admitted.
|
|
14
|
+
interface AdmittedClaim {
|
|
15
|
+
command?: string | undefined
|
|
16
|
+
lane?: string | undefined
|
|
17
|
+
wait_reason?: string | undefined
|
|
18
|
+
claimed_at: number
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type WaitSink = (wait: CoreWaitRecord) => Promise<void>
|
|
22
|
+
|
|
23
|
+
async function to_ledger(wait: CoreWaitRecord): Promise<void> {
|
|
24
|
+
await lane_ledger.record_core_wait(wait)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function wait_of(claim: AdmittedClaim, now: number): CoreWaitRecord | undefined {
|
|
28
|
+
if (claim.wait_reason === undefined) return undefined
|
|
29
|
+
|
|
30
|
+
const wait = { command: claim.command ?? UNNAMED_COMMAND, waited_ms: now - claim.claimed_at }
|
|
31
|
+
|
|
32
|
+
return claim.lane === undefined ? wait : { ...wait, issue: Number(claim.lane) }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function record_admitted(
|
|
36
|
+
claim: AdmittedClaim,
|
|
37
|
+
now: number,
|
|
38
|
+
sink: WaitSink = to_ledger,
|
|
39
|
+
): Promise<void> {
|
|
40
|
+
const wait = wait_of(claim, now)
|
|
41
|
+
|
|
42
|
+
if (wait !== undefined) await sink(wait)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const core_wait_record = { record_admitted, wait_of }
|
|
46
|
+
|
|
47
|
+
export type { WaitSink }
|
|
48
|
+
export { core_wait_record }
|
|
@@ -9,13 +9,15 @@ import type { MachineBudget } from './machine-capacity'
|
|
|
9
9
|
// says it once on its own output; `run:board` draws every marker still waiting. Everything here is a
|
|
10
10
|
// pure function of the ledger and the budget it is handed.
|
|
11
11
|
|
|
12
|
-
const WAIT_REASONS = ['cores', 'memory', 'pressure'] as const
|
|
12
|
+
const WAIT_REASONS = ['cores', 'cpu', 'memory', 'pressure'] as const
|
|
13
13
|
|
|
14
14
|
type WaitReason = (typeof WAIT_REASONS)[number]
|
|
15
15
|
|
|
16
|
-
// The one wording of each reason,
|
|
16
|
+
// The one wording of each reason, on the waiting command's own line; the board draws the reason as the
|
|
17
|
+
// header's icon instead (joshuafolkken/kit#4052).
|
|
17
18
|
const REASON_TEXT: Record<WaitReason, string> = {
|
|
18
19
|
cores: 'not enough free cores',
|
|
20
|
+
cpu: 'CPU saturated',
|
|
19
21
|
memory: 'not enough free memory',
|
|
20
22
|
pressure: 'memory under pressure',
|
|
21
23
|
}
|
|
@@ -49,6 +51,18 @@ interface BudgetWait extends BudgetPlace {
|
|
|
49
51
|
reason: WaitReason
|
|
50
52
|
}
|
|
51
53
|
|
|
54
|
+
// A claim short of cores waits on the CPU when it would fit on what the ledger declares — the cores it
|
|
55
|
+
// lacks are taken by busy load beyond the ledger (joshuafolkken/kit#4238) — and on the ledger otherwise.
|
|
56
|
+
function core_reason(
|
|
57
|
+
key: string,
|
|
58
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
59
|
+
budget: MachineBudget,
|
|
60
|
+
): WaitReason {
|
|
61
|
+
const declared = { cores: budget.cores + (budget.busy_excess ?? 0), memory_mb: Infinity }
|
|
62
|
+
|
|
63
|
+
return core_admission.is_admitted(key, reservations, declared) ? 'cpu' : 'cores'
|
|
64
|
+
}
|
|
65
|
+
|
|
52
66
|
// **The cores decide first**: a claim that would not fit even with unlimited memory waits for cores;
|
|
53
67
|
// one that fits on cores waits for memory, named as pressure when the reading saw compression or swap.
|
|
54
68
|
function wait_reason(
|
|
@@ -56,13 +70,31 @@ function wait_reason(
|
|
|
56
70
|
reservations: ReadonlyArray<LedgerEntry>,
|
|
57
71
|
budget: MachineBudget,
|
|
58
72
|
): WaitReason {
|
|
59
|
-
const cores_only = {
|
|
73
|
+
const cores_only = { ...budget, memory_mb: Infinity }
|
|
60
74
|
|
|
61
|
-
if (!core_admission.is_admitted(key, reservations, cores_only))
|
|
75
|
+
if (!core_admission.is_admitted(key, reservations, cores_only)) {
|
|
76
|
+
return core_reason(key, reservations, budget)
|
|
77
|
+
}
|
|
62
78
|
|
|
63
79
|
return budget.memory_pressured === true ? 'pressure' : 'memory'
|
|
64
80
|
}
|
|
65
81
|
|
|
82
|
+
// Why a claim is not admitted yet, or `undefined` once it is: a unit claim the budget admits only too
|
|
83
|
+
// narrow (`core_admission.is_too_narrow`) still waits, on the CPU — admitted, it fits what the ledger
|
|
84
|
+
// declares, so only busy load beyond the ledger narrowed it (`core_reason`).
|
|
85
|
+
function hold_reason(
|
|
86
|
+
key: string,
|
|
87
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
88
|
+
budget: MachineBudget,
|
|
89
|
+
granted: number | undefined,
|
|
90
|
+
): WaitReason | undefined {
|
|
91
|
+
if (!core_admission.is_admitted(key, reservations, budget)) {
|
|
92
|
+
return wait_reason(key, reservations, budget)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return core_admission.is_too_narrow(key, reservations, granted) ? 'cpu' : undefined
|
|
96
|
+
}
|
|
97
|
+
|
|
66
98
|
// The line a waiting command prints once, when its wait starts.
|
|
67
99
|
function wait_line(command: string | undefined, reason: WaitReason): string {
|
|
68
100
|
return `⏳ ${command ?? 'a step'} waits for the core budget — ${REASON_TEXT[reason]}`
|
|
@@ -118,8 +150,8 @@ function waits_of(
|
|
|
118
150
|
}
|
|
119
151
|
|
|
120
152
|
const core_wait = {
|
|
121
|
-
REASON_TEXT,
|
|
122
153
|
WAIT_REASONS,
|
|
154
|
+
hold_reason,
|
|
123
155
|
wait_line,
|
|
124
156
|
wait_reason,
|
|
125
157
|
waits_of,
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// The weights heavy tools declare to the core budget (`core-budget.ts`), in their own module so the
|
|
2
|
+
// ledger's file stays under its line ceiling.
|
|
3
|
+
|
|
4
|
+
// One tool's measured run: its CPU seconds over its wall seconds, the cores it kept busy on average.
|
|
5
|
+
interface Measurement {
|
|
6
|
+
cpu_s: number
|
|
7
|
+
wall_s: number
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// **What each heavy tool was measured at, on the 11-core machine.** The whole-tree eslint scan behind
|
|
11
|
+
// `josh lines` and `josh refactor:scan`, cold on 2026-10-06. eslint over 40 staged files
|
|
12
|
+
// (`pre-commit-lint.ts`), which the gate's lint also runs beside its sibling linters, so it is the
|
|
13
|
+
// lint's floor; whole runs were observed at 124–147% CPU. The type check and the spell check with
|
|
14
|
+
// `/usr/bin/time -l` on 2026-10-21 under a load average of 14. `prettier --check` over 40 staged
|
|
15
|
+
// files, `josh retrospective` and a fresh lane's `pnpm install --frozen-lockfile` with
|
|
16
|
+
// `/usr/bin/time -l` on 2026-10-17 under a load average of 16. The gate ledger records each check's
|
|
17
|
+
// CPU beside its duration (`check-cpu.ts`), so these can be re-measured from it.
|
|
18
|
+
const MEASURED = {
|
|
19
|
+
lint: { cpu_s: 16.9, wall_s: 14 },
|
|
20
|
+
type_check: { cpu_s: 31.2, wall_s: 27.3 },
|
|
21
|
+
spell_check: { cpu_s: 6, wall_s: 5.6 },
|
|
22
|
+
eslint_scan: { cpu_s: 113, wall_s: 98 },
|
|
23
|
+
format: { cpu_s: 2.1, wall_s: 1.7 },
|
|
24
|
+
retrospective: { cpu_s: 16.5, wall_s: 19.8 },
|
|
25
|
+
install: { cpu_s: 1.9, wall_s: 6.1 },
|
|
26
|
+
} as const satisfies Readonly<Record<string, Measurement>>
|
|
27
|
+
|
|
28
|
+
// **Rounded up, never down** (joshuafolkken/kit#4362): a weight is a whole number of cores, and the
|
|
29
|
+
// floored table of joshuafolkken/kit#3354 let a 1.15-core eslint scan claim one, so the budget admitted
|
|
30
|
+
// more than the machine had.
|
|
31
|
+
function rounded_up(measurement: Measurement): number {
|
|
32
|
+
return Math.ceil(measurement.cpu_s / measurement.wall_s)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// **The cores each heavy tool occupies, declared once for both places that reserve them**
|
|
36
|
+
// `gate-plan.ts`'s checks and the `josh` commands that run the same tools
|
|
37
|
+
// directly read these, so a direct `josh lint` claims what the gate's lint claims. Each is its
|
|
38
|
+
// measurement rounded up. `e2e` is the Playwright worker count `josh test:e2e` passes locally — the
|
|
39
|
+
// two-worker run CI already sizes for its four-core runner — since kit has no e2e suite of its own to
|
|
40
|
+
// time.
|
|
41
|
+
const CORE_WEIGHTS = {
|
|
42
|
+
lint: rounded_up(MEASURED.lint),
|
|
43
|
+
type_check: rounded_up(MEASURED.type_check),
|
|
44
|
+
spell_check: rounded_up(MEASURED.spell_check),
|
|
45
|
+
eslint_scan: rounded_up(MEASURED.eslint_scan),
|
|
46
|
+
format: rounded_up(MEASURED.format),
|
|
47
|
+
retrospective: rounded_up(MEASURED.retrospective),
|
|
48
|
+
install: rounded_up(MEASURED.install),
|
|
49
|
+
e2e: 2,
|
|
50
|
+
} as const
|
|
51
|
+
|
|
52
|
+
// **The memory each heavy tool holds, declared beside its cores**: peak
|
|
53
|
+
// resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
|
|
54
|
+
// 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
|
|
55
|
+
// files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
|
|
56
|
+
// `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
|
|
57
|
+
// On 2026-10-17: prettier 260 MB, the retrospective 862 MB and a lane install 65 MB. On 2026-10-22
|
|
58
|
+
// (joshuafolkken/kit#4528) the whole suite, 1,830 files at `--maxWorkers=3` beside four lanes, sampled
|
|
59
|
+
// each worker's resident size once a second: the largest peaked at 381 MB, so the 54-file
|
|
60
|
+
// measurement had read a worker short of the files it lives through.
|
|
61
|
+
const MEMORY_MB = {
|
|
62
|
+
lint: 2400,
|
|
63
|
+
type_check: 1300,
|
|
64
|
+
spell_check: 350,
|
|
65
|
+
eslint_scan: 2400,
|
|
66
|
+
unit_worker: 400,
|
|
67
|
+
format: 300,
|
|
68
|
+
retrospective: 900,
|
|
69
|
+
install: 100,
|
|
70
|
+
} as const
|
|
71
|
+
|
|
72
|
+
// **The program a command launches, mapped to the `MEMORY_MB` row it holds** — the one table
|
|
73
|
+
// `command-memory.ts` reads a wrapped command's memory off. `install` is `pnpm install` read past its
|
|
74
|
+
// `pnpm` wrapper (`git_argv.program_of`).
|
|
75
|
+
const TOOL_MEMORY: Readonly<Partial<Record<string, keyof typeof MEMORY_MB>>> = {
|
|
76
|
+
eslint: 'lint',
|
|
77
|
+
tsc: 'type_check',
|
|
78
|
+
cspell: 'spell_check',
|
|
79
|
+
vitest: 'unit_worker',
|
|
80
|
+
prettier: 'format',
|
|
81
|
+
install: 'install',
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const core_weights = { CORE_WEIGHTS, MEASURED, MEMORY_MB, TOOL_MEMORY }
|
|
85
|
+
|
|
86
|
+
export { core_weights }
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { availableParallelism } from 'node:os'
|
|
2
|
+
import type { FreeCapacity } from '#scripts/test/unit-worker-share'
|
|
2
3
|
import { core_admission } from './core-admission'
|
|
3
4
|
import { core_budget, type LiveReservation } from './core-budget'
|
|
5
|
+
import { core_weights } from './core-weights'
|
|
4
6
|
import { held_mark } from './held-mark'
|
|
5
7
|
import { machine_capacity, type MachineReading } from './machine-capacity'
|
|
6
8
|
|
|
7
9
|
// The cores a unit suite may open workers on: the core count less the load from outside the core
|
|
8
10
|
// budget's ledger, the figure the ledger admits against (`machine_capacity.machine_budget`). The run
|
|
9
|
-
// count in `unit-
|
|
11
|
+
// count in `unit-run-marker.ts` divides the machine between unit runs; this is what bounds that
|
|
10
12
|
// division when something else holds the cores.
|
|
11
13
|
//
|
|
12
14
|
// Its own module because the reading needs the ledger, and `core-budget.ts` already imports
|
|
@@ -29,9 +31,7 @@ function running_claims(directory: string | undefined): Array<LiveReservation> {
|
|
|
29
31
|
|
|
30
32
|
// `undefined` where the machine could not be read — a CI runner, a CPU quota narrower than the host —
|
|
31
33
|
// which `unit_worker_share.cap_to_free` reads as the share as it was.
|
|
32
|
-
|
|
33
|
-
const reading = await (options.read_machine ?? machine_capacity.read_machine)()
|
|
34
|
-
|
|
34
|
+
function free_of(reading: MachineReading, options: FreeCoresOptions): number | undefined {
|
|
35
35
|
if (reading.busy_cores === undefined) return undefined
|
|
36
36
|
|
|
37
37
|
const ledger = core_admission.ledger_load(running_claims(options.directory), Date.now())
|
|
@@ -43,6 +43,29 @@ async function read(options: FreeCoresOptions = {}): Promise<number | undefined>
|
|
|
43
43
|
).cores
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// **The workers the free memory holds** (joshuafolkken/kit#4528): the free memory over one worker's
|
|
47
|
+
// peak (`core_weights.MEMORY_MB.unit_worker`, where its measurement is recorded). Divided here, not in
|
|
48
|
+
// `unit-run-marker.ts`, which the vitest config imports — `core-weights.ts` there would widen every
|
|
49
|
+
// related run on it to the whole suite. The memory is the reading's own available figure, not the
|
|
50
|
+
// budget's: the ledger's held memory is added back there for admission's walk, and it is not free for
|
|
51
|
+
// this run's workers. `undefined` — a platform `machine-capacity.ts` reads no memory on — leaves the
|
|
52
|
+
// share as it was; a Linux CI runner reads `/proc/meminfo`, whose memory holds more workers than cores.
|
|
53
|
+
function workers_in_memory(available_mb: number | undefined): number | undefined {
|
|
54
|
+
if (available_mb === undefined) return undefined
|
|
55
|
+
|
|
56
|
+
return available_mb / core_weights.MEMORY_MB.unit_worker
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// One reading answers both halves: the sample window is waited out once.
|
|
60
|
+
async function read(options: FreeCoresOptions = {}): Promise<FreeCapacity> {
|
|
61
|
+
const reading = await (options.read_machine ?? machine_capacity.read_machine)()
|
|
62
|
+
|
|
63
|
+
return {
|
|
64
|
+
cores: free_of(reading, options),
|
|
65
|
+
memory_workers: workers_in_memory(reading.available_mb),
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
46
69
|
const free_cores = { read }
|
|
47
70
|
|
|
48
71
|
export type { FreeCoresOptions }
|