@joshuafolkken/kit 1.1471.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 +6 -6
- package/.claude/skills/epic-commands/SKILL.md +26 -77
- package/.claude/skills/epic-commands/epic-bundle.md +12 -6
- package/.claude/skills/epic-commands/execution-waves.md +1 -2
- package/.claude/skills/verify-ui/SKILL.md +1 -2
- package/.claude/skills/workflow-commands/SKILL.md +12 -14
- package/.claude/skills/workflow-commands/background-commands.md +8 -12
- package/.claude/skills/workflow-commands/backlogrun-child.md +13 -18
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +7 -25
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +23 -28
- package/.claude/skills/workflow-commands/backlogrun-park.md +16 -31
- package/.claude/skills/workflow-commands/backlogrun-progress.md +12 -21
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +12 -12
- package/.claude/skills/workflow-commands/backlogrun-steps.md +12 -20
- package/.claude/skills/workflow-commands/backlogrun.md +32 -51
- package/.claude/skills/workflow-commands/chain-rule.md +18 -11
- package/.claude/skills/workflow-commands/delegation.md +13 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +10 -12
- package/.claude/skills/workflow-commands/followup.md +10 -35
- package/.claude/skills/workflow-commands/fullrun-steps.md +38 -49
- package/.claude/skills/workflow-commands/fullrun.md +6 -8
- package/.claude/skills/workflow-commands/halfrun.md +20 -32
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +19 -15
- package/.claude/skills/workflow-commands/issue-scout.md +5 -4
- package/.claude/skills/workflow-commands/kickoff.md +24 -23
- package/.claude/skills/workflow-commands/latest-gate.md +9 -18
- package/.claude/skills/workflow-commands/needs-human-review.md +11 -19
- package/.claude/skills/workflow-commands/observation-filing.md +4 -50
- package/.claude/skills/workflow-commands/observation-ledger.md +5 -10
- package/.claude/skills/workflow-commands/pre-gate-cut.md +22 -44
- package/.claude/skills/workflow-commands/prerequisite.md +11 -18
- package/.claude/skills/workflow-commands/progress-watcher.md +3 -8
- package/.claude/skills/workflow-commands/prrun.md +6 -12
- package/.claude/skills/workflow-commands/retrospective.md +5 -5
- package/.claude/skills/workflow-commands/split-assessment.md +14 -4
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -13
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +10 -1
- 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 +121 -11
- package/.github/workflows/publish.yml +10 -3
- package/.github/workflows/sonar-qube.yml +1 -0
- package/.prettierignore +2 -0
- package/.vscode/tasks.json +1 -2
- package/CLAUDE.md +4 -8
- package/README.md +4 -2
- package/SECURITY.md +1 -1
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +4 -8
- package/dist/commands/document-read-cli.js +882 -0
- package/dist/commands/{document-section-cli.js → document-section-main.js} +137 -62
- 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-AS74OU3D.js → chunk-PT5R6UJD.js} +4582 -2118
- package/dist/hooks/chunk-TUIFS5E7.js +72 -0
- package/dist/hooks/{chunk-723HKZO5.js → chunk-VWWCFGWK.js} +1 -1
- package/dist/hooks/{chunk-E7OIKX5Z.js → chunk-WR2KQAYZ.js} +1863 -382
- package/dist/hooks/{chunk-KC5AK2GF.js → chunk-XGBNSWEI.js} +248 -46
- package/dist/hooks/chunk-YCDOIR3I.js +3456 -0
- package/dist/hooks/codex-hook-adapter.js +10 -19
- package/dist/hooks/format-edited.js +5 -5
- package/dist/hooks/inputs.json +436 -257
- package/dist/hooks/pretool-guard.js +7 -22
- package/dist/hooks/session-lang.js +380 -42
- package/dist/hooks/stop-guard.js +8711 -782
- package/dist/josh.js +5263 -997
- 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 +8 -4
- package/package.json +17 -53
- package/pnpm-workspace.yaml +4 -2
- package/prompts/coding-standards.md +1 -1
- package/prompts/collaboration-workflow/file-edits.md +1 -9
- package/prompts/collaboration-workflow/gh-rest.md +1 -2
- package/prompts/collaboration-workflow/issue-citation.md +2 -4
- package/prompts/collaboration-workflow/issue-template.md +42 -17
- package/prompts/collaboration-workflow/lane-instructions.md +34 -0
- package/prompts/collaboration-workflow/measurement.md +37 -0
- package/prompts/collaboration-workflow/operating-rules.md +6 -12
- package/prompts/collaboration-workflow/output-bounds.md +4 -9
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +3 -42
- package/prompts/collaboration-workflow/principles.md +19 -8
- package/prompts/collaboration-workflow/report-format.md +37 -57
- package/prompts/collaboration-workflow/residency.md +12 -8
- package/prompts/collaboration-workflow/rule-delivery.md +3 -11
- package/prompts/collaboration-workflow/shell-body.md +8 -18
- package/prompts/collaboration-workflow/turn-batching.md +4 -6
- package/prompts/collaboration-workflow/upstream-interrupt.md +16 -6
- package/prompts/collaboration-workflow/wip-cap.md +7 -7
- package/prompts/collaboration-workflow.md +4 -7
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +1 -2
- package/prompts/review.md +45 -26
- package/prompts/testing-guide.md +10 -45
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-event.ts +15 -15
- package/scripts/agent/agent-exit-record.ts +13 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/api-auth.ts +41 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +2 -0
- package/scripts/agent/lane-instructions.ts +144 -0
- 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 +6 -7
- 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 +54 -7
- 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 +39 -8
- 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 +69 -0
- 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 +137 -18
- 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 +2 -10
- package/scripts/delegation/investigation-guard.ts +15 -73
- package/scripts/delegation/investigation-reads.ts +3 -5
- 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 +9 -6
- package/scripts/document/document-scan.ts +1 -1
- package/scripts/document/document-section-cli.ts +17 -13
- package/scripts/document/document-section-main.ts +12 -0
- package/scripts/document/entry-read-budget.ts +2 -2
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-cli.ts +12 -6
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-apply.ts +137 -0
- package/scripts/epic/epic-bundle-cli.ts +32 -121
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-format.ts +116 -0
- package/scripts/epic/epic-bundle-main.ts +17 -0
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- 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 +31 -60
- 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 +73 -0
- package/scripts/gate/check-reuse.ts +141 -0
- 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 +150 -119
- package/scripts/gate/core-wait-record.ts +48 -0
- package/scripts/gate/core-wait.ts +162 -0
- package/scripts/gate/core-weights.ts +86 -0
- package/scripts/gate/free-cores.ts +72 -0
- package/scripts/gate/gate-ledger.ts +49 -7
- package/scripts/gate/gate-plan.ts +44 -15
- package/scripts/gate/gate-report.ts +29 -4
- package/scripts/gate/gate-run-steps.ts +195 -0
- package/scripts/gate/gate-skip.ts +12 -2
- package/scripts/gate/gate-steps.ts +12 -1
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/input-fingerprint.ts +42 -0
- package/scripts/gate/machine-capacity.ts +124 -31
- package/scripts/gate/moved-paths.ts +67 -0
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- 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 +65 -129
- 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-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +77 -17
- 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/gh/git-pr.ts +13 -1
- 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 +78 -0
- package/scripts/git/main-merge.ts +39 -14
- 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 +5 -16
- 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 +118 -0
- package/scripts/hooks/pre-push-unit.ts +4 -2
- package/scripts/hooks/pretool-guard-cli.ts +1 -8
- package/scripts/hooks/pretool-guard.ts +57 -69
- package/scripts/hooks/reserved-run.ts +67 -8
- package/scripts/hooks/run-hook.sh +18 -11
- package/scripts/hooks/shell-rules-notice.ts +37 -0
- package/scripts/hooks/stop-actions.ts +185 -0
- package/scripts/hooks/stop-guard.ts +72 -27
- package/scripts/init/hook-command-rewrite.ts +19 -5
- package/scripts/init/hook-launch.ts +15 -12
- 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 +60 -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 +33 -22
- package/scripts/issue/issue-cite-main.ts +12 -0
- package/scripts/issue/issue-classification.ts +13 -8
- 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 +7 -13
- 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 +19 -25
- 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/markdown-section.ts +19 -5
- 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 +82 -0
- package/scripts/josh/file-map-stamp.ts +49 -16
- package/scripts/josh/hook-decision.ts +32 -20
- package/scripts/josh/josh-command-map.ts +6 -1
- package/scripts/josh/josh-command-types.ts +65 -13
- package/scripts/josh/josh-commands-agent-hooks.ts +83 -0
- package/scripts/josh/josh-commands-ai.ts +169 -157
- 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 +31 -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 +112 -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 +149 -6
- package/scripts/josh/josh-logic.ts +11 -27
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +18 -0
- 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 +19 -22
- package/scripts/lane/lane-check-stats.ts +97 -0
- package/scripts/lane/lane-child-invocation.ts +43 -4
- 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 +27 -6
- package/scripts/lane/lane-gap-stats.ts +156 -0
- package/scripts/lane/lane-guard-policy.ts +2 -2
- package/scripts/lane/lane-handoff.ts +76 -1
- package/scripts/lane/lane-held-stats.ts +129 -0
- package/scripts/lane/lane-install.ts +16 -15
- 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 +108 -97
- package/scripts/lane/lane-limit-cli.ts +19 -9
- package/scripts/lane/lane-measure-cli.ts +58 -10
- 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-preserve.ts +29 -1
- 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 +33 -10
- package/scripts/lane/lane-residents.ts +162 -0
- package/scripts/lane/lane-restart.ts +26 -27
- 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 +160 -0
- package/scripts/lane/lane-session-broker.ts +134 -134
- 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 +72 -0
- package/scripts/lane/lane-withdraw.ts +183 -0
- 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 +14 -5
- 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 +72 -33
- package/scripts/lint/lint-related-scope.ts +33 -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 +12 -11
- 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 +4 -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-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +206 -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 +82 -16
- 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 +67 -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 +90 -3
- 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 +8 -0
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-argv.ts +72 -14
- package/scripts/rules/git-force.ts +12 -2
- package/scripts/rules/guard-remedy.ts +121 -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 +76 -7
- 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/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +10 -0
- package/scripts/rules/oracle-firing.ts +1 -0
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/permission-guards.ts +3 -0
- package/scripts/rules/piped-verification.ts +4 -2
- 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 +12 -28
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value-cache.ts +4 -9
- package/scripts/rules/rule-value-cli.ts +51 -32
- package/scripts/rules/rule-value.ts +8 -2
- package/scripts/rules/shell-segments.ts +50 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rule-rows.ts +64 -0
- package/scripts/rules/stop-rules.ts +150 -51
- package/scripts/rules/tail-commands.ts +15 -1
- 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 -30
- package/scripts/run/board/run-board-closed.ts +8 -2
- 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 +119 -31
- package/scripts/run/board/run-board-header.ts +86 -21
- 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 +118 -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 +240 -61
- 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 +153 -13
- package/scripts/run/board/run-board-reason.ts +238 -45
- 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 -47
- 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 +125 -0
- package/scripts/run/board/run-board-render.ts +206 -259
- package/scripts/run/board/run-board-roots.ts +54 -0
- package/scripts/run/board/run-board-row-yield.ts +10 -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 +23 -29
- package/scripts/run/board/run-board-status.ts +206 -79
- package/scripts/run/board/run-board-thanks-read.ts +2 -2
- package/scripts/run/board/run-board-tick.ts +123 -104
- 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-cli.ts +3 -2
- package/scripts/run/cut/run-cut-handoff.ts +2 -2
- package/scripts/run/cut/run-cut-report.ts +16 -0
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- 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 +7 -10
- package/scripts/run/event/run-event-scope.ts +20 -2
- package/scripts/run/event/run-event-stream-emit.ts +78 -11
- package/scripts/run/event/run-event-stream.ts +37 -7
- 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-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +7 -1
- package/scripts/run/hold/run-stop-notify.ts +183 -0
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-auth.ts +31 -0
- package/scripts/run/merge/run-merge-cli.ts +72 -107
- 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 +123 -0
- package/scripts/run/merge/run-merge-steps.ts +128 -83
- package/scripts/run/merge/run-merge.ts +53 -40
- 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 +61 -30
- package/scripts/run/run-next.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +2 -2
- package/scripts/run/run-poll-hook.ts +157 -0
- 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-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -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 +67 -151
- package/scripts/run/ship/run-ship-detach.ts +27 -7
- package/scripts/run/ship/run-ship-infra-retry.ts +59 -0
- package/scripts/run/ship/run-ship-next.ts +27 -3
- package/scripts/run/ship/run-ship-overlap.ts +232 -0
- 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 +102 -27
- package/scripts/run/ship/run-ship-preflight.ts +161 -30
- 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 +123 -15
- package/scripts/run/ship/run-ship-review-steps.ts +105 -149
- 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-context.ts +206 -0
- package/scripts/run/ship/run-ship-stop-text.ts +11 -6
- package/scripts/run/ship/run-ship-sync.ts +57 -12
- 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 +55 -6
- 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 +54 -21
- 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 +71 -137
- 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 +126 -14
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- 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 +10 -3
- 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-43ZHT22P.js +0 -3495
- package/dist/hooks/chunk-CDY4NFQG.js +0 -15
- package/dist/hooks/chunk-EUMACUK2.js +0 -2038
- package/dist/hooks/chunk-H5HVWYXK.js +0 -359
- package/dist/hooks/chunk-IIGFYXKC.js +0 -7104
- package/dist/hooks/chunk-IX6TTTI6.js +0 -95
- package/dist/hooks/chunk-J47HU5H5.js +0 -237
- package/dist/hooks/chunk-K4EOONYM.js +0 -45
- package/dist/hooks/chunk-K4LMBQC2.js +0 -68
- package/dist/hooks/chunk-SHGPANFB.js +0 -56
- package/dist/hooks/chunk-YHBZAJSV.js +0 -79
- package/dist/hooks/chunk-YYPI7SJZ.js +0 -131
- package/dist/hooks/duplicate-read-guard.js +0 -30
- package/dist/hooks/investigation-guard.js +0 -32
- 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/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 -282
- package/scripts/rules/rule-registry.ts +0 -109
- package/scripts/run/run-stranded-cli.ts +0 -27
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { availableParallelism } from 'node:os'
|
|
2
|
+
import { bounded_pool } from '#scripts/lib/bounded-pool'
|
|
3
|
+
import { buffered_process } from '#scripts/lib/buffered-process'
|
|
4
|
+
import { unit_worker_share } from '#scripts/test/unit-worker-share'
|
|
5
|
+
import { check_cpu, type CheckCpu } from './check-cpu'
|
|
6
|
+
import { core_budget, type Admission } from './core-budget'
|
|
7
|
+
import { free_cores } from './free-cores'
|
|
8
|
+
import { gate_plan, type GatePlan } from './gate-plan'
|
|
9
|
+
import type { CheckClaim, GateStep, GateStepResult } from './gate-report'
|
|
10
|
+
import { build_gate_step, with_granted_workers } from './gate-steps'
|
|
11
|
+
import { project_checks } from './project-checks'
|
|
12
|
+
|
|
13
|
+
// Running the gate's checks: each one under its place in the machine-wide budget, a reused one
|
|
14
|
+
// (`check-reuse.ts`) without starting it. `verification-gate.ts` decides what runs and records the
|
|
15
|
+
// outcome; this module only runs it.
|
|
16
|
+
|
|
17
|
+
// `cpu` is the gate's shared reader, so concurrent checks each take their own growth; a lone call
|
|
18
|
+
// reads its child alone from a baseline of its own.
|
|
19
|
+
async function run_gate_step(
|
|
20
|
+
step: GateStep,
|
|
21
|
+
cpu: CheckCpu = check_cpu.check_cpu_reader(),
|
|
22
|
+
): Promise<GateStepResult> {
|
|
23
|
+
if (step.skip_reason !== undefined) {
|
|
24
|
+
return {
|
|
25
|
+
label: step.label,
|
|
26
|
+
command: step.command_args.join(' '),
|
|
27
|
+
output: project_checks.skip_notice('check', step.skip_reason),
|
|
28
|
+
exit_code: 0,
|
|
29
|
+
elapsed_ms: 0,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = await buffered_process.run_buffered_process(
|
|
34
|
+
step.command_args,
|
|
35
|
+
step.cwd === undefined ? {} : { cwd: step.cwd },
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return { label: step.label, command: step.command_args.join(' '), ...result, cpu_ms: cpu() }
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// This gate's share of the machine, resolved once at the gate's entry and carried down as one value.
|
|
42
|
+
// `available_cores` is the budget every check reserves against; `is_reserved`
|
|
43
|
+
// is false for a gate nested inside another gate's unit suite — this repository's own gate tests — so
|
|
44
|
+
// the outer gate reserves and every gate beneath it does not. Captured before this gate sets
|
|
45
|
+
// `JOSH_UNIT_RUN_MARKED`, which is why it is read at entry rather than re-derived here.
|
|
46
|
+
interface BudgetContext {
|
|
47
|
+
available_cores: number
|
|
48
|
+
is_reserved: boolean
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function default_budget(): BudgetContext {
|
|
52
|
+
return {
|
|
53
|
+
available_cores: availableParallelism(),
|
|
54
|
+
is_reserved: !unit_worker_share.is_nested_run() && !core_budget.is_held(),
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A gate step paired with the cores it reserves from the machine-wide budget while it runs.
|
|
59
|
+
// The weight travels with the step so `run_gate_steps` never has to re-pair a
|
|
60
|
+
// step with its check by index.
|
|
61
|
+
interface ReservedStep {
|
|
62
|
+
step: GateStep
|
|
63
|
+
weight: number
|
|
64
|
+
memory_mb: number
|
|
65
|
+
// The plan's `--maxWorkers` for the unit suite, the width the free memory bounds once it is admitted.
|
|
66
|
+
worker_cap: number | undefined
|
|
67
|
+
// When the check's own green record was taken, for a check `check-reuse.ts` found reusable.
|
|
68
|
+
reused_at: string | undefined
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// The checks this gate reuses, each mapped to when it was last green.
|
|
72
|
+
type ReusedChecks = ReadonlyMap<string, string>
|
|
73
|
+
|
|
74
|
+
async function build_reserved_steps(
|
|
75
|
+
plan: GatePlan,
|
|
76
|
+
available_cores: number,
|
|
77
|
+
reused: ReusedChecks,
|
|
78
|
+
): Promise<ReadonlyArray<ReservedStep>> {
|
|
79
|
+
return await Promise.all(
|
|
80
|
+
plan.checks.map(async (check) => ({
|
|
81
|
+
step: await build_gate_step(check, process.cwd(), plan),
|
|
82
|
+
weight: gate_plan.check_weight(check, plan, available_cores),
|
|
83
|
+
memory_mb: gate_plan.check_memory(check, plan, available_cores),
|
|
84
|
+
worker_cap: plan.unit_worker_cap,
|
|
85
|
+
reused_at: reused.get(check.label),
|
|
86
|
+
})),
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// A reused check starts no process and claims no core: its result is the record's, and the empty
|
|
91
|
+
// output is what that record was written from (`gate_report.has_nothing_to_say`).
|
|
92
|
+
function reused_result(step: GateStep, reused_at: string): GateStepResult {
|
|
93
|
+
return {
|
|
94
|
+
label: step.label,
|
|
95
|
+
command: step.command_args.join(' '),
|
|
96
|
+
output: '',
|
|
97
|
+
exit_code: 0,
|
|
98
|
+
elapsed_ms: 0,
|
|
99
|
+
reused_at,
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// What the check asked the budget for and what it ran at, for its ledger row (`gate-ledger.ts`).
|
|
104
|
+
function claim_of(requested: number, admission: Admission): CheckClaim {
|
|
105
|
+
return {
|
|
106
|
+
requested,
|
|
107
|
+
granted: admission.granted ?? requested,
|
|
108
|
+
waited_ms: admission.waited_ms ?? 0,
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// **The unit step's width is bounded by the free memory too** (joshuafolkken/kit#4528). The plan's cap
|
|
113
|
+
// and the granted width are sized from the cores alone, and the `--maxWorkers` they become skips the
|
|
114
|
+
// guard's own reading (`test-unit-guard.ts`), so the memory is read here, once the claim is admitted
|
|
115
|
+
// and the suite is about to start. The free cores are not applied: the admission has already narrowed
|
|
116
|
+
// the claim to them (joshuafolkken/kit#4167).
|
|
117
|
+
async function admitted_step(
|
|
118
|
+
reserved: ReservedStep,
|
|
119
|
+
admission: Admission,
|
|
120
|
+
available_cores: number,
|
|
121
|
+
): Promise<GateStep> {
|
|
122
|
+
if (reserved.step.label !== gate_plan.UNIT_LABEL) return reserved.step
|
|
123
|
+
|
|
124
|
+
const { memory_workers } = await free_cores.read({ available_cores })
|
|
125
|
+
const asked = admission.granted ?? reserved.worker_cap
|
|
126
|
+
const workers = unit_worker_share.cap_to_free(asked, memory_workers, available_cores)
|
|
127
|
+
|
|
128
|
+
return with_granted_workers(reserved.step, workers)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// **A nested gate takes no reservation, and the budget is what makes that necessary rather than
|
|
132
|
+
// merely tidy**. The unit step spawns the suite, which runs this repository's
|
|
133
|
+
// own gate tests; each of those is a gate inside the outer gate's unit reservation, and a place it
|
|
134
|
+
// claimed would wait for cores the outer gate cannot free until the suite — this test included —
|
|
135
|
+
// finishes.
|
|
136
|
+
async function run_reserved_step(
|
|
137
|
+
reserved: ReservedStep,
|
|
138
|
+
budget: BudgetContext,
|
|
139
|
+
cpu: CheckCpu,
|
|
140
|
+
): Promise<GateStepResult> {
|
|
141
|
+
if (reserved.reused_at !== undefined) return reused_result(reserved.step, reserved.reused_at)
|
|
142
|
+
if (!budget.is_reserved) return await run_gate_step(reserved.step, cpu)
|
|
143
|
+
|
|
144
|
+
return await core_budget.with_core_reservation(
|
|
145
|
+
reserved.weight,
|
|
146
|
+
async (admission) => ({
|
|
147
|
+
...(await run_gate_step(
|
|
148
|
+
await admitted_step(reserved, admission, budget.available_cores),
|
|
149
|
+
cpu,
|
|
150
|
+
)),
|
|
151
|
+
budget_note: core_budget.describe_overflow(admission),
|
|
152
|
+
claim: claim_of(reserved.weight, admission),
|
|
153
|
+
}),
|
|
154
|
+
{
|
|
155
|
+
budget: budget.available_cores,
|
|
156
|
+
memory_mb: reserved.memory_mb,
|
|
157
|
+
command: `gate ${reserved.step.label}`,
|
|
158
|
+
is_unit: reserved.step.label === gate_plan.UNIT_LABEL,
|
|
159
|
+
},
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// `bounded_pool` rather than a bare `Promise.all`, so the plan's `concurrency` is what decides how
|
|
164
|
+
// many run at once. **The all-failures-in-one-pass property survives the
|
|
165
|
+
// change** because no check ever rejects: `buffered_process` reports a non-zero exit as a value, so
|
|
166
|
+
// the pool's first-failure abort — written for callers that spawn real Claude sessions — never
|
|
167
|
+
// fires here and every queued check still runs. Results come back in input order however they
|
|
168
|
+
// finished, which is what keeps the printed sections in declaration order. Each step first claims its
|
|
169
|
+
// place in the machine-wide budget and waits while the budget is full.
|
|
170
|
+
async function run_gate_steps(
|
|
171
|
+
plan: GatePlan,
|
|
172
|
+
budget: BudgetContext = default_budget(),
|
|
173
|
+
reused: ReusedChecks = new Map(),
|
|
174
|
+
): Promise<ReadonlyArray<GateStepResult>> {
|
|
175
|
+
const reserved = await build_reserved_steps(plan, budget.available_cores, reused)
|
|
176
|
+
const cpu = check_cpu.check_cpu_reader()
|
|
177
|
+
|
|
178
|
+
// **The checks run under the held mark, so a check's own dispatch claims nothing**.
|
|
179
|
+
// Each check is a `pnpm josh <target>` child, and a target that declares
|
|
180
|
+
// a weight would otherwise claim a second place for the cores reserved for it here. A nested gate
|
|
181
|
+
// sets the mark too, since its checks are covered by the outer gate's reservation.
|
|
182
|
+
return await core_budget.with_held_mark(
|
|
183
|
+
async () =>
|
|
184
|
+
await bounded_pool.bounded_map(
|
|
185
|
+
reserved,
|
|
186
|
+
plan.concurrency,
|
|
187
|
+
async (entry) => await run_reserved_step(entry, budget, cpu),
|
|
188
|
+
),
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const gate_run_steps = { default_budget, run_gate_step, run_gate_steps }
|
|
193
|
+
|
|
194
|
+
export type { BudgetContext, ReusedChecks }
|
|
195
|
+
export { gate_run_steps }
|
|
@@ -64,10 +64,19 @@ const FORCE_FLAG = '--force'
|
|
|
64
64
|
// rewritten by the hook's own install each cost minutes before anyone could tell them apart.
|
|
65
65
|
type GateReuse = { stamp: FileMapStamp } | { miss: string }
|
|
66
66
|
|
|
67
|
+
// The fingerprint of every declared check's tools and environment (`verification-inputs.ts`).
|
|
68
|
+
const INPUTS_MOVED = 'a checked tool or environment variable changed since the green gate'
|
|
69
|
+
|
|
67
70
|
function base_moved(recorded: string | undefined, base: string): string {
|
|
68
71
|
return `the merge base moved since the green gate (${recorded ?? 'none'} → ${base})`
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
function stamp_miss(stamp: FileMapStamp, base: string): string | undefined {
|
|
75
|
+
if (stamp.base !== base) return base_moved(stamp.base, base)
|
|
76
|
+
|
|
77
|
+
return review_stamps.gate_stamp.describes_inputs(stamp) ? undefined : INPUTS_MOVED
|
|
78
|
+
}
|
|
79
|
+
|
|
71
80
|
function gate_reuse(
|
|
72
81
|
tree: Record<string, string>,
|
|
73
82
|
base: string | undefined,
|
|
@@ -79,9 +88,10 @@ function gate_reuse(
|
|
|
79
88
|
const stamp = review_brief.matching_stamp(review_stamps.gate_stamp.read(source), tree)
|
|
80
89
|
|
|
81
90
|
if (stamp === undefined) return { miss: 'no green gate record matches the changed files' }
|
|
82
|
-
if (stamp.base !== base) return { miss: base_moved(stamp.base, base) }
|
|
83
91
|
|
|
84
|
-
|
|
92
|
+
const miss = stamp_miss(stamp, base)
|
|
93
|
+
|
|
94
|
+
return miss === undefined ? { stamp } : { miss }
|
|
85
95
|
}
|
|
86
96
|
|
|
87
97
|
function stamp_of(reuse: GateReuse): FileMapStamp | undefined {
|
|
@@ -42,6 +42,17 @@ async function build_gate_step(
|
|
|
42
42
|
return { label: check.label, command_args, cwd, skip_reason }
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
// The unit step at a narrower worker count: the one its claim was admitted at past the wait cap
|
|
46
|
+
// (`core_admission.narrowed_weight`), or the one the free memory holds (`gate-run-steps.ts`). Any
|
|
47
|
+
// other step, or one left as asked, is returned unchanged.
|
|
48
|
+
function with_granted_workers(step: GateStep, granted: number | undefined): GateStep {
|
|
49
|
+
if (granted === undefined || step.label !== UNIT_LABEL) return step
|
|
50
|
+
|
|
51
|
+
const kept = step.command_args.filter((argument) => !argument.startsWith(`${UNIT_WORKER_FLAG}=`))
|
|
52
|
+
|
|
53
|
+
return { ...step, command_args: [...kept, `${UNIT_WORKER_FLAG}=${String(granted)}`] }
|
|
54
|
+
}
|
|
55
|
+
|
|
45
56
|
async function build_gate_steps(
|
|
46
57
|
start_directory: string,
|
|
47
58
|
plan: GatePlan = gate_plan.resolve_gate_plan(),
|
|
@@ -51,4 +62,4 @@ async function build_gate_steps(
|
|
|
51
62
|
)
|
|
52
63
|
}
|
|
53
64
|
|
|
54
|
-
export { build_gate_step, build_gate_steps, UNIT_WORKER_FLAG }
|
|
65
|
+
export { build_gate_step, build_gate_steps, UNIT_WORKER_FLAG, with_granted_workers }
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// **The environment mark that says a parent already holds this process's cores**
|
|
2
|
+
// `josh gate` reserves per check and then spawns `pnpm josh lint`. Without
|
|
3
|
+
// the mark, that child's own dispatch would claim a second place for the cores its parent already
|
|
4
|
+
// holds. Every holder sets it, and every child inherits it through the environment and claims nothing.
|
|
5
|
+
const HELD_KEY = 'JOSH_CORE_RESERVED'
|
|
6
|
+
const HELD_VALUE = '1'
|
|
7
|
+
// The ledger key of the claim a command holds for its children (`core_budget.with_command_reservation`),
|
|
8
|
+
// so a child reading the machine can tell that claim's admitted, not-yet-busy weight from running load.
|
|
9
|
+
const HELD_RESERVATION_KEY = 'JOSH_CORE_RESERVATION'
|
|
10
|
+
|
|
11
|
+
function is_held(): boolean {
|
|
12
|
+
return process.env[HELD_KEY] === HELD_VALUE
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// The ledger key of the one claim a parent command holds for this process, `undefined` where none does.
|
|
16
|
+
function held_reservation(): string | undefined {
|
|
17
|
+
const key = process.env[HELD_RESERVATION_KEY] ?? ''
|
|
18
|
+
|
|
19
|
+
return key === '' ? undefined : key
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// A function of its own so the restoring write does not sit after an `await`, where
|
|
23
|
+
// `require-atomic-updates` reads any write to `process` as a possible race — the reason `josh.ts`
|
|
24
|
+
// gives `record_exit_code`.
|
|
25
|
+
function set_held_mark(value: string, reservation: string): void {
|
|
26
|
+
process.env[HELD_KEY] = value
|
|
27
|
+
process.env[HELD_RESERVATION_KEY] = reservation
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Marks this process, and every child it spawns, as running inside a held reservation — `reservation`
|
|
31
|
+
// names its ledger key where one claim covers them all. The previous values come back afterwards, so a
|
|
32
|
+
// nested holder never clears the mark its outer holder set.
|
|
33
|
+
async function with_held_mark<T>(run: () => Promise<T>, reservation = ''): Promise<T> {
|
|
34
|
+
const previous = process.env[HELD_KEY] ?? ''
|
|
35
|
+
const previous_reservation = process.env[HELD_RESERVATION_KEY] ?? ''
|
|
36
|
+
|
|
37
|
+
set_held_mark(HELD_VALUE, reservation)
|
|
38
|
+
|
|
39
|
+
try {
|
|
40
|
+
return await run()
|
|
41
|
+
} finally {
|
|
42
|
+
set_held_mark(previous, previous_reservation)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const held_mark = {
|
|
47
|
+
HELD_KEY,
|
|
48
|
+
HELD_RESERVATION_KEY,
|
|
49
|
+
HELD_VALUE,
|
|
50
|
+
held_reservation,
|
|
51
|
+
is_held,
|
|
52
|
+
with_held_mark,
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { held_mark }
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
4
|
+
|
|
5
|
+
// **The one fingerprint every kept result is computed with** (joshuafolkken/kit#4497). A reuse of a
|
|
6
|
+
// verdict holds only while what it read holds, and each reader of a verdict once computed that on its
|
|
7
|
+
// own — the ESLint cache's import closure, the test-read map's dirty files, the gate's tool versions —
|
|
8
|
+
// so a miss in one (joshuafolkken/kit#4407, #4415, #4423, #4425) was a miss nowhere else. Every one now
|
|
9
|
+
// digests a file, a set of files and a set of named entries here.
|
|
10
|
+
|
|
11
|
+
// The digest of a path that does not exist, or cannot be read, so it still differs from any content.
|
|
12
|
+
const ABSENT = 'absent'
|
|
13
|
+
|
|
14
|
+
function of_content(content: Buffer | string): string {
|
|
15
|
+
return stamp_file.digest(content)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// One digest over `entries`, independent of their order.
|
|
19
|
+
function of_entries(entries: Iterable<string>): string {
|
|
20
|
+
return of_content([...entries].toSorted((left, right) => left.localeCompare(right)).join('\n'))
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function of_file(file_path: string): string {
|
|
24
|
+
try {
|
|
25
|
+
return of_content(readFileSync(file_path))
|
|
26
|
+
} catch {
|
|
27
|
+
return ABSENT
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Each of `relatives` (relative to `root`) keyed to the digest of its content, in path order.
|
|
32
|
+
function of_files(root: string, relatives: Iterable<string>): Record<string, string> {
|
|
33
|
+
const sorted = [...new Set(relatives)].toSorted((left, right) => left.localeCompare(right))
|
|
34
|
+
|
|
35
|
+
return Object.fromEntries(
|
|
36
|
+
sorted.map((relative) => [relative, of_file(path.join(root, relative))]),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const input_fingerprint = { ABSENT, of_entries, of_file, of_files }
|
|
41
|
+
|
|
42
|
+
export { input_fingerprint }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises'
|
|
2
|
-
import { availableParallelism, cpus, totalmem } from 'node:os'
|
|
2
|
+
import { availableParallelism, cpus, loadavg, totalmem } from 'node:os'
|
|
3
3
|
import { PROBE_TIMEOUT_MS } from '#scripts/lib/timeouts'
|
|
4
4
|
import { execa } from 'execa'
|
|
5
5
|
|
|
@@ -24,19 +24,20 @@ import { execa } from 'execa'
|
|
|
24
24
|
// admits without looking at memory, exactly as before.
|
|
25
25
|
//
|
|
26
26
|
// **`run:board` draws its machine gauges from the same reading**, so what the
|
|
27
|
-
// board shows a person is what the gate admits against
|
|
27
|
+
// board shows a person is what the gate admits against — the gate reading the free memory as none
|
|
28
|
+
// while the board's pressure and swap gauges show why. The board takes a sample with no window and
|
|
28
29
|
// draws the difference from its previous one. `lane:sample` records the memory half of it, so the
|
|
29
30
|
// lane-limit measurement sets the same figures beside the lane count.
|
|
30
31
|
|
|
31
32
|
// The window the busy cores are measured over: long enough that one scheduler tick does not dominate it,
|
|
32
33
|
// short enough that a solo admission is not visibly delayed.
|
|
33
34
|
const SAMPLE_WINDOW_MS = 250
|
|
34
|
-
// **
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
const
|
|
35
|
+
// **Run-queue load outside the ledger past this many times the cores holds the first waiter too**
|
|
36
|
+
// (joshuafolkken/kit#4361). The first waiter ignores outside load (joshuafolkken/kit#4313), and lanes took
|
|
37
|
+
// the 11-core machine to a load average of 25–34. Twice the cores is loose on purpose: the one-core
|
|
38
|
+
// editor load #4313 stopped holding a solo gate stays far below it, so neither its starvation nor the
|
|
39
|
+
// lanes' speed comes back, while a machine whose queue beyond the ledger passes two per core waits.
|
|
40
|
+
const OVERLOAD_FACTOR = 2
|
|
40
41
|
const BYTES_PER_MB = 1_048_576
|
|
41
42
|
const KB_PER_MB = 1024
|
|
42
43
|
const PERCENT = 100
|
|
@@ -50,29 +51,56 @@ const PAGE_SIZE_ARGUMENTS = ['PAGESIZE']
|
|
|
50
51
|
// every second. `kern.memorystatus_level` is the kernel's own memory-pressure figure: the percentage of
|
|
51
52
|
// memory still available, compressible and purgeable pages included — what `os.freemem()` leaves out on
|
|
52
53
|
// macOS, where it reads near zero on a machine with gigabytes to spare. The swapper counters are the
|
|
53
|
-
// pages swapped in and out since boot, `vm_stat`'s `Swapins` / `Swapouts
|
|
54
|
+
// pages swapped in and out since boot, `vm_stat`'s `Swapins` / `Swapouts`; `vm.compressor_input_bytes` is
|
|
55
|
+
// the bytes the compressor has taken in since boot, `vm_stat`'s `Compressions`. The names stay in the output
|
|
54
56
|
// (no `-n`), so a name an older macOS lacks drops only its own line.
|
|
55
57
|
const LEVEL_NAME = 'kern.memorystatus_level'
|
|
56
58
|
const SWAP_IN_NAME = 'vm.compressor.swapper.swapins_total'
|
|
57
59
|
const SWAP_OUT_NAME = 'vm.compressor.swapper.swapouts_total'
|
|
60
|
+
const COMPRESSED_NAME = 'vm.compressor_input_bytes'
|
|
58
61
|
const PAGE_SIZE_NAME = 'hw.pagesize'
|
|
59
62
|
// The kernel's memory-pressure verdict — 1 normal, 2 warning, 4 critical — the one Activity Monitor
|
|
60
63
|
// colors its "memory pressure" graph by.
|
|
61
64
|
const PRESSURE_NAME = 'kern.memorystatus_vm_pressure_level'
|
|
62
|
-
|
|
65
|
+
// **Only critical holds; warning is sticky** (joshuafolkken/kit#4199). On macOS the verdict can stay at
|
|
66
|
+
// warning for hours after the pressure passed, so a hold on warning never lifts. What is pressured right
|
|
67
|
+
// now shows in the free figure and the swap and compressor traffic; the verdict adds only critical.
|
|
68
|
+
const PRESSURE_HOLD = 4
|
|
69
|
+
// The swap traffic across one window that reads as pressure — 64 MB a second paged to disk. A machine
|
|
70
|
+
// that swapped once still pages a few megabytes back in as old pages are touched.
|
|
71
|
+
const SWAP_PRESSURE_MB = 16
|
|
72
|
+
// The compressor traffic across one window that reads as pressure. An idle machine compresses nothing
|
|
73
|
+
// across a window; the 2026-10-16 thrash compressed about 240,000 16 KB pages every three seconds, about
|
|
74
|
+
// 310 MB a window, with no swap figure to show for it.
|
|
75
|
+
const COMPRESSION_PRESSURE_MB = 64
|
|
76
|
+
const SYSCTL_ARGUMENTS = [
|
|
77
|
+
LEVEL_NAME,
|
|
78
|
+
SWAP_IN_NAME,
|
|
79
|
+
SWAP_OUT_NAME,
|
|
80
|
+
COMPRESSED_NAME,
|
|
81
|
+
PAGE_SIZE_NAME,
|
|
82
|
+
PRESSURE_NAME,
|
|
83
|
+
]
|
|
63
84
|
const SYSCTL_LINE = /^(?<name>[\w.]+): (?<value>\d+)$/gmu
|
|
64
85
|
|
|
86
|
+
// `memory_pressured` says why `available_mb` read none, so a claim that waits can name the pressure.
|
|
87
|
+
// `run_queue` is the one-minute load average: the busy cores stop at the core count, so only the queue
|
|
88
|
+
// tells a machine at twice its cores from one at once (`is_overloaded`).
|
|
65
89
|
interface MachineReading {
|
|
66
90
|
busy_cores: number | undefined
|
|
67
91
|
available_mb: number | undefined
|
|
92
|
+
memory_pressured?: boolean | undefined
|
|
93
|
+
run_queue?: number | undefined
|
|
68
94
|
}
|
|
69
95
|
|
|
70
96
|
// The memory half of a reading. `swapped_mb` is a counter — every page swapped in or out since boot —
|
|
71
|
-
// so a rate is the difference between two readings
|
|
97
|
+
// so a rate is the difference between two readings, and so is `compressed_mb`, every byte compressed
|
|
98
|
+
// since boot. `pressure_level` and `compressed_mb` are read on macOS only.
|
|
72
99
|
interface MemoryReading {
|
|
73
100
|
available_mb: number | undefined
|
|
74
101
|
swapped_mb: number | undefined
|
|
75
102
|
pressure_level: number | undefined
|
|
103
|
+
compressed_mb?: number | undefined
|
|
76
104
|
}
|
|
77
105
|
|
|
78
106
|
// What the ledger's admitted reservations declare — the part of the machine's load already accounted for.
|
|
@@ -81,9 +109,15 @@ interface LedgerLoad {
|
|
|
81
109
|
memory_mb: number
|
|
82
110
|
}
|
|
83
111
|
|
|
112
|
+
// `busy_excess` is the measured cores beyond what the ledger declares — what `cores` gave up to load the
|
|
113
|
+
// ledger does not hold, so a claim that waits on it can name the CPU as saturated. `is_overloaded` lifts
|
|
114
|
+
// the first waiter's exemption from that load (`core_admission.is_admitted`).
|
|
84
115
|
interface MachineBudget {
|
|
85
116
|
cores: number
|
|
86
117
|
memory_mb: number
|
|
118
|
+
memory_pressured?: boolean | undefined
|
|
119
|
+
busy_excess?: number | undefined
|
|
120
|
+
is_overloaded?: boolean | undefined
|
|
87
121
|
}
|
|
88
122
|
|
|
89
123
|
interface CpuTimes {
|
|
@@ -141,10 +175,10 @@ function swapped_pages(
|
|
|
141
175
|
return pages_in === undefined || pages_out === undefined ? undefined : pages_in + pages_out
|
|
142
176
|
}
|
|
143
177
|
|
|
144
|
-
function
|
|
145
|
-
if (
|
|
178
|
+
function mb_of(units: number | undefined, unit_bytes: number | undefined): number | undefined {
|
|
179
|
+
if (units === undefined || unit_bytes === undefined) return undefined
|
|
146
180
|
|
|
147
|
-
return (
|
|
181
|
+
return (units * unit_bytes) / BYTES_PER_MB
|
|
148
182
|
}
|
|
149
183
|
|
|
150
184
|
// What was swapped between two readings of the counter. A counter that went back — a reboot between
|
|
@@ -163,11 +197,12 @@ function parse_darwin_memory(output: string, total_bytes: number): MemoryReading
|
|
|
163
197
|
return {
|
|
164
198
|
available_mb:
|
|
165
199
|
level === undefined ? undefined : (level / PERCENT) * (total_bytes / BYTES_PER_MB),
|
|
166
|
-
swapped_mb:
|
|
200
|
+
swapped_mb: mb_of(
|
|
167
201
|
swapped_pages(values.get(SWAP_IN_NAME), values.get(SWAP_OUT_NAME)),
|
|
168
202
|
values.get(PAGE_SIZE_NAME),
|
|
169
203
|
),
|
|
170
204
|
pressure_level: values.get(PRESSURE_NAME),
|
|
205
|
+
compressed_mb: mb_of(values.get(COMPRESSED_NAME), 1),
|
|
171
206
|
}
|
|
172
207
|
}
|
|
173
208
|
|
|
@@ -187,7 +222,7 @@ function pages_of(pattern: RegExp, vmstat: string): number | undefined {
|
|
|
187
222
|
function parse_linux_swapped(vmstat: string, page_bytes: number): number | undefined {
|
|
188
223
|
const pages = swapped_pages(pages_of(LINUX_SWAP_IN, vmstat), pages_of(LINUX_SWAP_OUT, vmstat))
|
|
189
224
|
|
|
190
|
-
return
|
|
225
|
+
return mb_of(pages, page_bytes)
|
|
191
226
|
}
|
|
192
227
|
|
|
193
228
|
async function settled<T>(read: () => Promise<T>): Promise<T | undefined> {
|
|
@@ -256,56 +291,114 @@ async function default_sleep(ms: number): Promise<void> {
|
|
|
256
291
|
})
|
|
257
292
|
}
|
|
258
293
|
|
|
294
|
+
// Whether a counter gained more than `limit` MB across the window; an unread counter gained nothing.
|
|
295
|
+
function moved_over(from: number | undefined, to: number | undefined, limit: number): boolean {
|
|
296
|
+
return (swapped_between(from, to) ?? 0) > limit
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
function is_pressured(before: MemoryReading, after: MemoryReading): boolean {
|
|
300
|
+
return (
|
|
301
|
+
(after.pressure_level ?? 0) >= PRESSURE_HOLD ||
|
|
302
|
+
moved_over(before.swapped_mb, after.swapped_mb, SWAP_PRESSURE_MB) ||
|
|
303
|
+
moved_over(before.compressed_mb, after.compressed_mb, COMPRESSION_PRESSURE_MB)
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// **Only a reading the kernel calls critical has nothing free to admit against.** Swap and compressor
|
|
308
|
+
// traffic across the window used to answer no free memory too (joshuafolkken/kit#3943), but this machine
|
|
309
|
+
// swaps out 0.4–1.3 TB a day as a matter of course, so that traffic held about a third of every wait
|
|
310
|
+
// with memory to spare (joshuafolkken/kit#4313). A claim now waits on memory only when the free figure
|
|
311
|
+
// falls short of what it declares; the traffic still names the wait as pressure (`memory_pressured`),
|
|
312
|
+
// and holds a claim past the shortfall that running alone or the wait cap would otherwise start
|
|
313
|
+
// (`core_admission.is_swap_held`, joshuafolkken/kit#4451).
|
|
314
|
+
function pressured_available(after: MemoryReading): number | undefined {
|
|
315
|
+
if (after.available_mb === undefined) return undefined
|
|
316
|
+
|
|
317
|
+
return (after.pressure_level ?? 0) >= PRESSURE_HOLD ? 0 : after.available_mb
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Memory is read at both ends of the window, so the swap counter's difference is the activity during it.
|
|
259
321
|
async function read_machine(
|
|
260
322
|
sleep: (ms: number) => Promise<void> = default_sleep,
|
|
261
323
|
): Promise<MachineReading> {
|
|
262
324
|
const before = cpu_times()
|
|
263
|
-
const [
|
|
264
|
-
const
|
|
265
|
-
|
|
266
|
-
|
|
325
|
+
const [memory_before] = await Promise.all([read_memory(), sleep(SAMPLE_WINDOW_MS)])
|
|
326
|
+
const memory_after = await read_memory()
|
|
327
|
+
const is_host = is_unquoted()
|
|
328
|
+
const busy_cores = is_host ? busy_cores_between(before, cpu_times(), cpus().length) : undefined
|
|
267
329
|
|
|
268
|
-
return {
|
|
330
|
+
return {
|
|
331
|
+
busy_cores,
|
|
332
|
+
run_queue: is_host ? loadavg()[0] : undefined,
|
|
333
|
+
available_mb: pressured_available(memory_after),
|
|
334
|
+
memory_pressured: is_pressured(memory_before, memory_after),
|
|
335
|
+
}
|
|
269
336
|
}
|
|
270
337
|
|
|
271
338
|
async function read_sample(): Promise<MachineSample> {
|
|
272
339
|
return { cpu: cpu_times(), memory: await read_memory(), total_mb: totalmem() / BYTES_PER_MB }
|
|
273
340
|
}
|
|
274
341
|
|
|
275
|
-
// The busy cores the ledger does not account for,
|
|
276
|
-
//
|
|
342
|
+
// The busy cores the ledger does not account for, in whole cores — the budget is in whole cores, and a
|
|
343
|
+
// fraction of a core is not a core to give up.
|
|
344
|
+
//
|
|
345
|
+
// **Every busy core counts, the background included** (joshuafolkken/kit#4238). A baseline of two cores
|
|
346
|
+
// used to be exempt, so with 10 cores reserved and all 11 busy the reading saw no excess and admitted
|
|
347
|
+
// another claim onto a saturated CPU.
|
|
277
348
|
function external_cores(busy_cores: number | undefined, ledger_cores: number): number {
|
|
278
349
|
if (busy_cores === undefined) return 0
|
|
279
350
|
|
|
280
|
-
return Math.floor(Math.max(0, busy_cores - ledger_cores
|
|
351
|
+
return Math.floor(Math.max(0, busy_cores - ledger_cores))
|
|
281
352
|
}
|
|
282
353
|
|
|
283
|
-
//
|
|
284
|
-
//
|
|
285
|
-
//
|
|
286
|
-
//
|
|
287
|
-
|
|
354
|
+
// The run queue beyond what the ledger declares, past `OVERLOAD_FACTOR` times the cores. The ledger's own
|
|
355
|
+
// claims running past their weight count as outside load. The load average trails by a minute, so a
|
|
356
|
+
// first waiter held here waits out the decay — only at a load already this far past the machine. A queue
|
|
357
|
+
// that could not be read, and Windows' constant zero, never hold.
|
|
358
|
+
function is_overloaded(
|
|
359
|
+
run_queue: number | undefined,
|
|
360
|
+
ledger_cores: number,
|
|
361
|
+
cores: number,
|
|
362
|
+
): boolean {
|
|
363
|
+
if (run_queue === undefined) return false
|
|
364
|
+
|
|
365
|
+
return run_queue - ledger_cores > cores * OVERLOAD_FACTOR
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// **The budget the ledger admits against: `cores − max(ledger, busy)` free, plus what the ledger itself
|
|
369
|
+
// already holds.** The admission walk counts the ledger's declared weight again, so it is added back —
|
|
370
|
+
// what is subtracted is only the busy load beyond it. A claim admitted moments ago is not busy yet, and
|
|
371
|
+
// the ledger's declared cores cover it. The caller passes every admitted claim's cores but only the
|
|
372
|
+
// memory of claims past `core_admission.RAMP_UP_MS`, whose tools have had time to allocate.
|
|
288
373
|
// Memory that could not be read is no limit at all, the behavior before memory was read.
|
|
289
374
|
function machine_budget(cores: number, reading: MachineReading, ledger: LedgerLoad): MachineBudget {
|
|
375
|
+
const busy_excess = external_cores(reading.busy_cores, ledger.cores)
|
|
376
|
+
|
|
290
377
|
return {
|
|
291
|
-
cores: cores -
|
|
378
|
+
cores: Math.max(0, cores - busy_excess),
|
|
292
379
|
memory_mb:
|
|
293
380
|
reading.available_mb === undefined ? Infinity : reading.available_mb + ledger.memory_mb,
|
|
381
|
+
memory_pressured: reading.memory_pressured,
|
|
382
|
+
busy_excess,
|
|
383
|
+
is_overloaded: is_overloaded(reading.run_queue, ledger.cores, cores),
|
|
294
384
|
}
|
|
295
385
|
}
|
|
296
386
|
|
|
297
387
|
const machine_capacity = {
|
|
298
|
-
BASELINE_CORES,
|
|
299
388
|
busy_cores_between,
|
|
300
389
|
busy_share_between,
|
|
390
|
+
COMPRESSION_PRESSURE_MB,
|
|
301
391
|
external_cores,
|
|
302
392
|
machine_budget,
|
|
303
393
|
parse_darwin_memory,
|
|
304
394
|
parse_linux_available,
|
|
305
395
|
parse_linux_swapped,
|
|
396
|
+
PRESSURE_HOLD,
|
|
397
|
+
pressured_available,
|
|
306
398
|
read_machine,
|
|
307
399
|
read_memory,
|
|
308
400
|
read_sample,
|
|
401
|
+
SWAP_PRESSURE_MB,
|
|
309
402
|
swapped_between,
|
|
310
403
|
}
|
|
311
404
|
|