@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
|
@@ -9,7 +9,13 @@ 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'
|
|
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'
|
|
18
|
+
import { held_mark } from './held-mark'
|
|
13
19
|
import { machine_capacity, type MachineBudget, type MachineReading } from './machine-capacity'
|
|
14
20
|
|
|
15
21
|
// A machine-wide weighted core budget with admission control.
|
|
@@ -23,8 +29,9 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
|
|
|
23
29
|
//
|
|
24
30
|
// **A solo run is bit-for-bit unchanged, and that is arithmetic rather than a branch.** The gate's
|
|
25
31
|
// weights are its `reserved_cores` (the static checks) and its `unit_worker_cap` (the unit suite), and
|
|
26
|
-
// `reserved(2 +
|
|
27
|
-
// 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
|
|
28
35
|
// concurrency the same weights sum past the budget and the ledger is what holds the machine down.
|
|
29
36
|
//
|
|
30
37
|
// **Liveness is `process_identity`'s, reused rather than re-invented.** A run
|
|
@@ -39,61 +46,31 @@ import { machine_capacity, type MachineBudget, type MachineReading } from './mac
|
|
|
39
46
|
|
|
40
47
|
const RESERVED_PREFIX = 'josh-core-reserved-'
|
|
41
48
|
const RESERVED_SUFFIX = '.json'
|
|
42
|
-
//
|
|
43
|
-
// promptly, long enough that the wait itself burns no measurable CPU.
|
|
44
|
-
const POLL_INTERVAL_MS = 50
|
|
45
|
-
// The longest a reservation waits before it is admitted at minimum width regardless — a heavy step must
|
|
46
|
-
// make progress even if the budget never clears, so a leaked or wedged sibling cannot stall the machine
|
|
47
|
-
// for good. Two minutes is well past a unit suite's worst measured time under six-way load.
|
|
48
|
-
const WAIT_CAP_MS = 120_000
|
|
49
|
-
// 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.
|
|
50
50
|
const MIN_BUDGET = 1
|
|
51
51
|
|
|
52
|
-
// **The cores each heavy tool occupies, declared once for both places that reserve them**
|
|
53
|
-
// `gate-plan.ts`'s checks and the `josh` commands that run the same tools
|
|
54
|
-
// directly read these, so a direct `josh lint` claims what the gate's lint claims. The lint, type check
|
|
55
|
-
// and spell check numbers are `gate-plan.ts`'s measured table, floored. The whole-tree eslint scan
|
|
56
|
-
// behind `josh lines` and `josh refactor:scan` runs in one process: measured cold on the 11-core
|
|
57
|
-
// machine on 2026-10-06, 113s of CPU over 98s of wall, so it gets one core.
|
|
58
|
-
const CORE_WEIGHTS = {
|
|
59
|
-
lint: 2,
|
|
60
|
-
type_check: 1,
|
|
61
|
-
spell_check: 1,
|
|
62
|
-
eslint_scan: 1,
|
|
63
|
-
} as const
|
|
64
|
-
|
|
65
|
-
// **The memory each heavy tool holds, declared beside its cores**: peak
|
|
66
|
-
// resident size in MB, rounded up. Measured with `/usr/bin/time -l` on the 11-core / 18 GB machine on
|
|
67
|
-
// 2026-10-07: the type check 1,244 MB, the spell check 330 MB, and one unit worker 319 MB over 54 test
|
|
68
|
-
// files. Typed eslint was 1,207 MB over one directory and was observed at 1.6–2.4 GB per whole-tree
|
|
69
|
-
// `eslint .` with three lanes running the same day, so lint and the whole-tree scan take that peak.
|
|
70
|
-
const MEMORY_MB = {
|
|
71
|
-
lint: 2400,
|
|
72
|
-
type_check: 1300,
|
|
73
|
-
spell_check: 350,
|
|
74
|
-
eslint_scan: 2400,
|
|
75
|
-
unit_worker: 350,
|
|
76
|
-
} as const
|
|
77
|
-
|
|
78
|
-
// **The environment mark that says a parent already holds this process's cores**
|
|
79
|
-
// `josh gate` reserves per check and then spawns `pnpm josh lint`. Without
|
|
80
|
-
// the mark, that child's own dispatch would claim a second place for the cores its parent already
|
|
81
|
-
// holds. Every holder sets it, and every child inherits it through the environment and claims nothing.
|
|
82
|
-
const HELD_KEY = 'JOSH_CORE_RESERVED'
|
|
83
|
-
const HELD_VALUE = '1'
|
|
84
|
-
|
|
85
52
|
// `memory_mb` and `admitted_at` are optional so a marker an older `josh` wrote still reads: it holds no
|
|
86
53
|
// declared memory, and it counts as load from outside the ledger until it is gone.
|
|
54
|
+
// `command`, `checkout`, `lane`, `lanes_root` and `wait_reason` name a waiting claim on `run:board`
|
|
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`).
|
|
87
57
|
const reservation_schema = process_owner_schema.extend({
|
|
88
58
|
weight: z.number(),
|
|
89
59
|
claimed_at: z.number(),
|
|
90
60
|
memory_mb: z.number().optional(),
|
|
91
61
|
admitted_at: z.number().optional(),
|
|
62
|
+
is_unit: z.boolean().optional(),
|
|
63
|
+
granted: z.number().optional(),
|
|
64
|
+
command: z.string().optional(),
|
|
65
|
+
checkout: z.string().optional(),
|
|
66
|
+
lane: z.string().optional(),
|
|
67
|
+
lanes_root: z.string().optional(),
|
|
68
|
+
wait_reason: z.enum(core_wait.WAIT_REASONS).optional(),
|
|
92
69
|
})
|
|
93
70
|
|
|
94
71
|
type Reservation = z.infer<typeof reservation_schema>
|
|
95
72
|
|
|
96
|
-
type ReservationFields =
|
|
73
|
+
type ReservationFields = Omit<Reservation, 'pid' | 'process_start'>
|
|
97
74
|
|
|
98
75
|
interface LiveReservation extends LedgerEntry {
|
|
99
76
|
reservation: Reservation
|
|
@@ -102,12 +79,19 @@ interface LiveReservation extends LedgerEntry {
|
|
|
102
79
|
interface ReserveOptions {
|
|
103
80
|
budget?: number
|
|
104
81
|
memory_mb?: number | undefined
|
|
82
|
+
// What the claim is for, named on the waiting line and on `run:board`.
|
|
83
|
+
command?: string | undefined
|
|
84
|
+
// A unit suite's claim, whose weight is its worker count.
|
|
85
|
+
is_unit?: boolean | undefined
|
|
86
|
+
report?: (line: string) => void
|
|
105
87
|
read_machine?: () => Promise<MachineReading>
|
|
106
88
|
wait_cap_ms?: number
|
|
107
89
|
poll_interval_ms?: number
|
|
108
90
|
directory?: string
|
|
109
91
|
now?: () => number
|
|
110
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
|
|
111
95
|
}
|
|
112
96
|
|
|
113
97
|
interface Handle {
|
|
@@ -119,7 +103,7 @@ function marker_name(key: string): string {
|
|
|
119
103
|
return `${RESERVED_PREFIX}${key}${RESERVED_SUFFIX}`
|
|
120
104
|
}
|
|
121
105
|
|
|
122
|
-
// **"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
|
|
123
107
|
// way costs a reservation a slower admission, while the other way admits past a run that is still there.
|
|
124
108
|
function is_running(reservation: Reservation): boolean {
|
|
125
109
|
return process_identity.is_same_process(reservation.pid, reservation.process_start) !== false
|
|
@@ -135,7 +119,7 @@ function read_reservation(source: string): Reservation | undefined {
|
|
|
135
119
|
|
|
136
120
|
// **A dead marker is removed, not merely skipped** — otherwise a reissued pid turns a leaked place into
|
|
137
121
|
// a phantom that fills the budget for good. The unlink never throws: a marker this account may not
|
|
138
|
-
// remove is left alone, exactly as `unit-
|
|
122
|
+
// remove is left alone, exactly as `unit-run-marker.ts` leaves it.
|
|
139
123
|
function sweep_marker(source: string): void {
|
|
140
124
|
try {
|
|
141
125
|
stamp_file.remove_stamp(source)
|
|
@@ -182,12 +166,6 @@ function normalize_budget(budget: number): number {
|
|
|
182
166
|
return Number.isFinite(budget) ? Math.max(MIN_BUDGET, Math.floor(budget)) : MIN_BUDGET
|
|
183
167
|
}
|
|
184
168
|
|
|
185
|
-
async function default_sleep(ms: number): Promise<void> {
|
|
186
|
-
await new Promise<void>((resolve) => {
|
|
187
|
-
setTimeout(resolve, ms)
|
|
188
|
-
})
|
|
189
|
-
}
|
|
190
|
-
|
|
191
169
|
// **Replaced atomically, never unlinked and recreated**: the admitted rewrite lands on a marker other
|
|
192
170
|
// lanes are polling, and a reader that hit the gap between an unlink and its create would see the ledger
|
|
193
171
|
// without this place and admit past it.
|
|
@@ -195,56 +173,56 @@ function write_reservation(target: string, fields: ReservationFields): void {
|
|
|
195
173
|
stamp_file.replace_stamp(target, { ...process_identity.own_fields(), ...fields })
|
|
196
174
|
}
|
|
197
175
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
interface TimingConfig {
|
|
201
|
-
now: () => number
|
|
202
|
-
sleep: (ms: number) => Promise<void>
|
|
203
|
-
poll_interval_ms: number
|
|
204
|
-
wait_cap_ms: number
|
|
176
|
+
function report_wait(line: string): void {
|
|
177
|
+
process.stderr.write(`${line}\n`)
|
|
205
178
|
}
|
|
206
179
|
|
|
207
180
|
interface WaitContext extends TimingConfig {
|
|
208
181
|
read_machine: () => Promise<MachineReading>
|
|
182
|
+
report: (line: string) => void
|
|
183
|
+
record_wait: WaitSink | undefined
|
|
209
184
|
key: string
|
|
210
185
|
target: string
|
|
211
186
|
directory: string
|
|
212
187
|
budget: number
|
|
213
188
|
deadline: number
|
|
214
189
|
fields: ReservationFields
|
|
190
|
+
busy_samples: Array<BusySample>
|
|
215
191
|
}
|
|
216
192
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
wait_cap_ms: options.wait_cap_ms ?? WAIT_CAP_MS,
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// **A claim alone in the ledger reads nothing from the machine**: the head is admitted whatever the
|
|
227
|
-
// 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).
|
|
228
198
|
async function current_budget(
|
|
229
199
|
context: WaitContext,
|
|
230
200
|
reservations: ReadonlyArray<LiveReservation>,
|
|
231
201
|
): Promise<MachineBudget> {
|
|
232
|
-
if (reservations.length <= 1) return { cores: context.budget, memory_mb: Infinity }
|
|
233
|
-
|
|
234
202
|
const reading = await context.read_machine()
|
|
235
203
|
const ledger = core_admission.ledger_load(reservations, context.now())
|
|
236
|
-
const budget = machine_capacity.machine_budget(context.budget, reading, ledger)
|
|
237
204
|
|
|
238
|
-
|
|
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)
|
|
239
215
|
}
|
|
240
216
|
|
|
241
217
|
// The claim is admitted: its marker records when, which moves its load from "load outside the ledger"
|
|
242
218
|
// to "load the ledger holds" for every later reader — its cores at once, its memory once its tool has
|
|
243
219
|
// had time to ramp up.
|
|
244
|
-
function admit(context: WaitContext, overflow?: Overflow): Admission {
|
|
245
|
-
|
|
220
|
+
function admit(context: WaitContext, overflow?: Overflow, granted?: number): Admission {
|
|
221
|
+
const admitted_at = context.now()
|
|
222
|
+
|
|
223
|
+
write_reservation(context.target, { ...context.fields, admitted_at, granted })
|
|
246
224
|
|
|
247
|
-
return { overflow }
|
|
225
|
+
return { overflow, granted, waited_ms: admitted_at - context.fields.claimed_at }
|
|
248
226
|
}
|
|
249
227
|
|
|
250
228
|
function overflow_of(
|
|
@@ -259,16 +237,41 @@ function overflow_of(
|
|
|
259
237
|
}
|
|
260
238
|
}
|
|
261
239
|
|
|
240
|
+
// The marker records why the claim waits, rewritten only when the reason changes, and the command says
|
|
241
|
+
// so once, when its wait starts.
|
|
242
|
+
function mark_waiting(context: WaitContext, reason: WaitReason): void {
|
|
243
|
+
const previous = context.fields.wait_reason
|
|
244
|
+
|
|
245
|
+
if (previous === reason) return
|
|
246
|
+
|
|
247
|
+
context.fields = { ...context.fields, wait_reason: reason }
|
|
248
|
+
write_reservation(context.target, context.fields)
|
|
249
|
+
|
|
250
|
+
if (previous === undefined) context.report(core_wait.wait_line(context.fields.command, reason))
|
|
251
|
+
}
|
|
252
|
+
|
|
262
253
|
async function poll_admission(context: WaitContext): Promise<Admission | undefined> {
|
|
263
254
|
const reservations = live_reservations(context.directory)
|
|
264
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)
|
|
265
262
|
|
|
266
|
-
|
|
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)
|
|
267
269
|
|
|
268
|
-
|
|
269
|
-
return admit(context, overflow_of(context, reservations, budget))
|
|
270
|
+
return admit(context, overflow_of(context, held, budget), granted)
|
|
270
271
|
}
|
|
271
272
|
|
|
273
|
+
mark_waiting(context, reason)
|
|
274
|
+
|
|
272
275
|
return undefined
|
|
273
276
|
}
|
|
274
277
|
|
|
@@ -285,16 +288,41 @@ async function await_admission(context: WaitContext): Promise<Admission> {
|
|
|
285
288
|
admission = await poll_admission(context)
|
|
286
289
|
}
|
|
287
290
|
|
|
291
|
+
await core_wait_record.record_admitted(context.fields, context.now(), context.record_wait)
|
|
292
|
+
|
|
288
293
|
return admission
|
|
289
294
|
}
|
|
290
295
|
|
|
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'> {
|
|
300
|
+
return {
|
|
301
|
+
read_machine: options.read_machine ?? machine_capacity.read_machine,
|
|
302
|
+
report: options.report ?? report_wait,
|
|
303
|
+
record_wait: options.record_wait,
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// The checkout the claim runs in, so `run:board` can say whose claim waits. The ledger is the
|
|
308
|
+
// machine's, so the checkout may be another repository's (`core-wait.ts` → `where_of`).
|
|
309
|
+
function claim_fields(
|
|
310
|
+
weight: number,
|
|
311
|
+
claimed_at: number,
|
|
312
|
+
options: ReserveOptions,
|
|
313
|
+
): ReservationFields {
|
|
314
|
+
const { memory_mb, command, is_unit } = options
|
|
315
|
+
|
|
316
|
+
return { weight, claimed_at, memory_mb, command, is_unit, ...core_wait.where_of(process.cwd()) }
|
|
317
|
+
}
|
|
318
|
+
|
|
291
319
|
async function reserve(weight: number, options: ReserveOptions = {}): Promise<Handle> {
|
|
292
|
-
const timing = resolve_timing(options)
|
|
320
|
+
const timing = core_budget_timing.resolve_timing(options)
|
|
293
321
|
const directory = options.directory ?? PLATFORM_TEMP_ROOT
|
|
294
322
|
const claimed_at = timing.now()
|
|
295
323
|
const name = marker_name(randomUUID())
|
|
296
324
|
const target = path.join(directory, name)
|
|
297
|
-
const fields =
|
|
325
|
+
const fields = claim_fields(weight, claimed_at, options)
|
|
298
326
|
|
|
299
327
|
write_reservation(target, fields)
|
|
300
328
|
const admission = await await_admission({
|
|
@@ -305,58 +333,43 @@ async function reserve(weight: number, options: ReserveOptions = {}): Promise<Ha
|
|
|
305
333
|
budget: normalize_budget(options.budget ?? availableParallelism()),
|
|
306
334
|
deadline: claimed_at + timing.wait_cap_ms,
|
|
307
335
|
fields,
|
|
308
|
-
|
|
336
|
+
busy_samples: [],
|
|
337
|
+
...resolve_ports(options),
|
|
309
338
|
})
|
|
310
339
|
|
|
311
340
|
return { target, admission }
|
|
312
341
|
}
|
|
313
342
|
|
|
343
|
+
// The claims waiting in the ledger now, for a `run:board` running in `home`.
|
|
344
|
+
function budget_waits(
|
|
345
|
+
directory: string = PLATFORM_TEMP_ROOT,
|
|
346
|
+
now: number = Date.now(),
|
|
347
|
+
home: string = process.cwd(),
|
|
348
|
+
): Array<BudgetWait> {
|
|
349
|
+
return core_wait.waits_of(live_reservations(directory), now, home)
|
|
350
|
+
}
|
|
351
|
+
|
|
314
352
|
function release(handle: Handle): void {
|
|
315
353
|
sweep_marker(handle.target)
|
|
316
354
|
}
|
|
317
355
|
|
|
318
356
|
// The whole reservation lifetime around a step: claim a place, wait for admission, run, and free the
|
|
319
357
|
// place on any exit. `finally`, so a step that threw still releases its cores. The step is told how it was
|
|
320
|
-
// admitted, so the gate can report one that started past the budget.
|
|
358
|
+
// admitted, so the gate can report one that started past the budget, and the claim's ledger key.
|
|
321
359
|
async function with_core_reservation<T>(
|
|
322
360
|
weight: number,
|
|
323
|
-
run: (admission: Admission) => Promise<T>,
|
|
361
|
+
run: (admission: Admission, key: string) => Promise<T>,
|
|
324
362
|
options: ReserveOptions = {},
|
|
325
363
|
): Promise<T> {
|
|
326
364
|
const handle = await reserve(weight, options)
|
|
327
365
|
|
|
328
366
|
try {
|
|
329
|
-
return await run(handle.admission)
|
|
367
|
+
return await run(handle.admission, path.basename(handle.target))
|
|
330
368
|
} finally {
|
|
331
369
|
release(handle)
|
|
332
370
|
}
|
|
333
371
|
}
|
|
334
372
|
|
|
335
|
-
function is_held(): boolean {
|
|
336
|
-
return process.env[HELD_KEY] === HELD_VALUE
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// A function of its own so the restoring write does not sit after an `await`, where
|
|
340
|
-
// `require-atomic-updates` reads any write to `process` as a possible race — the reason `josh.ts`
|
|
341
|
-
// gives `record_exit_code`.
|
|
342
|
-
function set_held_mark(value: string): void {
|
|
343
|
-
process.env[HELD_KEY] = value
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Marks this process, and every child it spawns, as running inside a held reservation. The previous
|
|
347
|
-
// value comes back afterwards, so a nested holder never clears the mark its outer holder set.
|
|
348
|
-
async function with_held_mark<T>(run: () => Promise<T>): Promise<T> {
|
|
349
|
-
const previous = process.env[HELD_KEY] ?? ''
|
|
350
|
-
|
|
351
|
-
set_held_mark(HELD_VALUE)
|
|
352
|
-
|
|
353
|
-
try {
|
|
354
|
-
return await run()
|
|
355
|
-
} finally {
|
|
356
|
-
set_held_mark(previous)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
|
|
360
373
|
// **A command's reservation: the gate's claim, unless a parent already holds the cores**
|
|
361
374
|
// `josh-logic.ts` calls this around every command that declares a weight.
|
|
362
375
|
// Each command then only declares its weight, and no command carries a copy of the claim, run and
|
|
@@ -368,27 +381,45 @@ async function with_command_reservation<T>(
|
|
|
368
381
|
run: () => Promise<T>,
|
|
369
382
|
options: ReserveOptions = {},
|
|
370
383
|
): Promise<T> {
|
|
371
|
-
if (is_held() || unit_worker_share.is_nested_run()) return await run()
|
|
384
|
+
if (held_mark.is_held() || unit_worker_share.is_nested_run()) return await run()
|
|
385
|
+
|
|
386
|
+
return await with_core_reservation(
|
|
387
|
+
weight,
|
|
388
|
+
async (_admission, key) => await held_mark.with_held_mark(run, key),
|
|
389
|
+
options,
|
|
390
|
+
)
|
|
391
|
+
}
|
|
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)
|
|
372
401
|
|
|
373
|
-
return
|
|
402
|
+
return held?.reservation.is_unit === true ? held.reservation : undefined
|
|
374
403
|
}
|
|
375
404
|
|
|
376
405
|
const core_budget = {
|
|
377
|
-
CORE_WEIGHTS,
|
|
378
|
-
HELD_KEY,
|
|
379
|
-
HELD_VALUE,
|
|
380
|
-
MEMORY_MB,
|
|
406
|
+
CORE_WEIGHTS: core_weights.CORE_WEIGHTS,
|
|
407
|
+
HELD_KEY: held_mark.HELD_KEY,
|
|
408
|
+
HELD_VALUE: held_mark.HELD_VALUE,
|
|
409
|
+
MEMORY_MB: core_weights.MEMORY_MB,
|
|
381
410
|
RESERVED_PREFIX,
|
|
382
411
|
admitted_keys: core_admission.admitted_keys,
|
|
383
412
|
admitted_load: core_admission.admitted_load,
|
|
413
|
+
budget_waits,
|
|
384
414
|
describe_overflow: core_admission.describe_overflow,
|
|
385
|
-
|
|
415
|
+
held_unit_claim,
|
|
416
|
+
is_held: held_mark.is_held,
|
|
386
417
|
live_reservations,
|
|
387
418
|
release,
|
|
388
419
|
reserve,
|
|
389
420
|
with_command_reservation,
|
|
390
421
|
with_core_reservation,
|
|
391
|
-
with_held_mark,
|
|
422
|
+
with_held_mark: held_mark.with_held_mark,
|
|
392
423
|
}
|
|
393
424
|
|
|
394
425
|
export type { LiveReservation, Reservation, ReserveOptions }
|
|
@@ -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 }
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { lane_paths } from '#scripts/lane/lane-paths'
|
|
3
|
+
import { core_admission, type LedgerEntry } from './core-admission'
|
|
4
|
+
import type { MachineBudget } from './machine-capacity'
|
|
5
|
+
|
|
6
|
+
// **Why a claim waits, and who is waiting** (joshuafolkken/kit#3943). A claim held back by the budget
|
|
7
|
+
// used to wait in silence: the command printed nothing and no board showed it, so a lane stalled on
|
|
8
|
+
// memory pressure read the same as one stuck. The waiting claim records its reason on its marker and
|
|
9
|
+
// says it once on its own output; `run:board` draws every marker still waiting. Everything here is a
|
|
10
|
+
// pure function of the ledger and the budget it is handed.
|
|
11
|
+
|
|
12
|
+
const WAIT_REASONS = ['cores', 'cpu', 'memory', 'pressure'] as const
|
|
13
|
+
|
|
14
|
+
type WaitReason = (typeof WAIT_REASONS)[number]
|
|
15
|
+
|
|
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).
|
|
18
|
+
const REASON_TEXT: Record<WaitReason, string> = {
|
|
19
|
+
cores: 'not enough free cores',
|
|
20
|
+
cpu: 'CPU saturated',
|
|
21
|
+
memory: 'not enough free memory',
|
|
22
|
+
pressure: 'memory under pressure',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// What the board reads off a marker. Every field but the claim time is optional, so a marker an older
|
|
26
|
+
// `josh` wrote still reads, and one that never waited is not drawn.
|
|
27
|
+
interface WhereFields {
|
|
28
|
+
checkout?: string | undefined
|
|
29
|
+
lane?: string | undefined
|
|
30
|
+
lanes_root?: string | undefined
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface WaitMarker extends WhereFields {
|
|
34
|
+
claimed_at: number
|
|
35
|
+
admitted_at?: number | undefined
|
|
36
|
+
command?: string | undefined
|
|
37
|
+
wait_reason?: WaitReason | undefined
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Where a waiting claim runs: `lane` is the board's own repository's lane number, which the board
|
|
41
|
+
// links; `elsewhere` names another repository's checkout, which it cannot link. Neither is the board's
|
|
42
|
+
// own main checkout.
|
|
43
|
+
interface BudgetPlace {
|
|
44
|
+
lane: string | undefined
|
|
45
|
+
elsewhere: string | undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface BudgetWait extends BudgetPlace {
|
|
49
|
+
command: string | undefined
|
|
50
|
+
waited_ms: number
|
|
51
|
+
reason: WaitReason
|
|
52
|
+
}
|
|
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
|
+
|
|
66
|
+
// **The cores decide first**: a claim that would not fit even with unlimited memory waits for cores;
|
|
67
|
+
// one that fits on cores waits for memory, named as pressure when the reading saw compression or swap.
|
|
68
|
+
function wait_reason(
|
|
69
|
+
key: string,
|
|
70
|
+
reservations: ReadonlyArray<LedgerEntry>,
|
|
71
|
+
budget: MachineBudget,
|
|
72
|
+
): WaitReason {
|
|
73
|
+
const cores_only = { ...budget, memory_mb: Infinity }
|
|
74
|
+
|
|
75
|
+
if (!core_admission.is_admitted(key, reservations, cores_only)) {
|
|
76
|
+
return core_reason(key, reservations, budget)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return budget.memory_pressured === true ? 'pressure' : 'memory'
|
|
80
|
+
}
|
|
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
|
+
|
|
98
|
+
// The line a waiting command prints once, when its wait starts.
|
|
99
|
+
function wait_line(command: string | undefined, reason: WaitReason): string {
|
|
100
|
+
return `⏳ ${command ?? 'a step'} waits for the core budget — ${REASON_TEXT[reason]}`
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The lanes root a checkout belongs to: a lane's parent, or the root beside a main checkout. Two
|
|
104
|
+
// checkouts of one repository share it; the ledger is machine-wide, so another repository's do not.
|
|
105
|
+
function lanes_root_of(checkout: string): string {
|
|
106
|
+
if (lane_paths.lane_issue_of(checkout) === undefined) return lane_paths.lane_root(checkout)
|
|
107
|
+
|
|
108
|
+
return path.dirname(path.resolve(checkout))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Where a claim runs, read by the claimer under its own environment: `JOSH_LANE_ROOT` is a
|
|
112
|
+
// per-project setting, so a board cannot derive another repository's lanes root from its own.
|
|
113
|
+
function where_of(checkout: string): Required<WhereFields> {
|
|
114
|
+
return { checkout, lane: lane_paths.lane_issue_of(checkout), lanes_root: lanes_root_of(checkout) }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Another repository's checkout is named by its lanes root and lane, or its directory, so its lane
|
|
118
|
+
// number is never linked to the board's repository's issue of that number.
|
|
119
|
+
function place_of(marker: WhereFields, home_root: string): BudgetPlace {
|
|
120
|
+
const { checkout, lane, lanes_root } = marker
|
|
121
|
+
|
|
122
|
+
if (checkout === undefined || lanes_root === undefined || lanes_root === home_root) {
|
|
123
|
+
return { lane, elsewhere: undefined }
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const name = lane === undefined ? path.basename(checkout) : `${path.basename(lanes_root)}/${lane}`
|
|
127
|
+
|
|
128
|
+
return { lane: undefined, elsewhere: name }
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function wait_of(marker: WaitMarker, now: number, home_root: string): Array<BudgetWait> {
|
|
132
|
+
const { command, wait_reason: reason } = marker
|
|
133
|
+
|
|
134
|
+
if (reason === undefined || marker.admitted_at !== undefined) return []
|
|
135
|
+
|
|
136
|
+
return [{ command, ...place_of(marker, home_root), waited_ms: now - marker.claimed_at, reason }]
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// The claims still waiting, longest first, placed against the board's checkout `home`.
|
|
140
|
+
function waits_of(
|
|
141
|
+
entries: ReadonlyArray<{ reservation: WaitMarker }>,
|
|
142
|
+
now: number,
|
|
143
|
+
home: string,
|
|
144
|
+
): Array<BudgetWait> {
|
|
145
|
+
const home_root = lanes_root_of(home)
|
|
146
|
+
|
|
147
|
+
return entries
|
|
148
|
+
.flatMap((entry) => wait_of(entry.reservation, now, home_root))
|
|
149
|
+
.toSorted((left, right) => right.waited_ms - left.waited_ms)
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const core_wait = {
|
|
153
|
+
WAIT_REASONS,
|
|
154
|
+
hold_reason,
|
|
155
|
+
wait_line,
|
|
156
|
+
wait_reason,
|
|
157
|
+
waits_of,
|
|
158
|
+
where_of,
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export type { BudgetWait, WaitReason }
|
|
162
|
+
export { core_wait }
|