@joshuafolkken/kit 1.1240.0 → 1.1373.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 -0
- package/.claude/settings.json +4 -0
- package/.claude/skills/dependency-update/SKILL.md +5 -3
- package/.claude/skills/epic-commands/SKILL.md +82 -113
- package/.claude/skills/epic-commands/epic-bundle.md +38 -63
- package/.claude/skills/epic-commands/execution-waves.md +30 -51
- package/.claude/skills/verify-ui/SKILL.md +13 -20
- package/.claude/skills/workflow-commands/SKILL.md +10 -10
- package/.claude/skills/workflow-commands/background-commands.md +4 -4
- package/.claude/skills/workflow-commands/backlogrun-child.md +30 -105
- package/.claude/skills/workflow-commands/backlogrun-handoff-report.md +29 -0
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +45 -131
- package/.claude/skills/workflow-commands/backlogrun-park.md +36 -53
- package/.claude/skills/workflow-commands/backlogrun-progress.md +81 -331
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +29 -83
- package/.claude/skills/workflow-commands/backlogrun-steps.md +105 -424
- package/.claude/skills/workflow-commands/backlogrun.md +52 -61
- package/.claude/skills/workflow-commands/chain-rule.md +36 -40
- package/.claude/skills/workflow-commands/entry-sequence.md +6 -6
- package/.claude/skills/workflow-commands/followup.md +19 -20
- package/.claude/skills/workflow-commands/fullrun-steps.md +23 -27
- package/.claude/skills/workflow-commands/fullrun.md +10 -10
- package/.claude/skills/workflow-commands/halfrun.md +9 -8
- package/.claude/skills/workflow-commands/into-target.md +12 -18
- package/.claude/skills/workflow-commands/issue-comments.md +11 -26
- package/.claude/skills/workflow-commands/kickoff.md +26 -16
- package/.claude/skills/workflow-commands/latest-gate.md +17 -28
- package/.claude/skills/workflow-commands/needs-human-review.md +13 -24
- package/.claude/skills/workflow-commands/observation-filing.md +37 -28
- package/.claude/skills/workflow-commands/observation-ledger.md +48 -38
- package/.claude/skills/workflow-commands/pre-gate-cut.md +9 -9
- package/.claude/skills/workflow-commands/prerequisite.md +23 -15
- package/.claude/skills/workflow-commands/progress-watcher.md +17 -11
- package/.claude/skills/workflow-commands/prrun.md +3 -3
- package/.claude/skills/workflow-commands/retrospective.md +13 -18
- package/.claude/skills/workflow-commands/split-assessment.md +6 -4
- package/.claude/skills/workflow-commands/target-repository.md +25 -28
- package/.claude/skills/workflow-commands/working-tree-hold.md +11 -17
- package/.gitattributes +2 -1
- package/.github/workflows/ci.yml +14 -0
- package/.vscode/tasks.json +14 -0
- package/CLAUDE.md +10 -61
- package/README.md +23 -66
- package/SECURITY.md +1 -1
- package/dist/CLAUDE.md +10 -61
- package/dist/commands/document-section-cli.js +43 -11
- package/dist/config-merge/index.js +11 -2
- package/dist/hooks/audit-provision.js +2 -2
- package/dist/hooks/batch-guard.js +7 -7
- package/dist/hooks/{chunk-KHGB5S3Y.js → chunk-7UBFU3CL.js} +18 -20
- package/dist/hooks/{chunk-ZQGD4GBY.js → chunk-7WKYHEGU.js} +8 -44
- package/dist/hooks/{chunk-4TZVB44A.js → chunk-AKGCP4LX.js} +285 -363
- package/dist/hooks/{chunk-QVSWU24O.js → chunk-BZMPVFDY.js} +7 -5
- package/dist/hooks/{chunk-5VNDSNG3.js → chunk-FZ6FUSBM.js} +1 -1
- package/dist/hooks/{chunk-GPTFMK5E.js → chunk-GG72ANKI.js} +1 -1
- package/dist/hooks/{chunk-XZYKEM6J.js → chunk-JCRDBQXB.js} +13 -11
- package/dist/hooks/{chunk-F3ELQ2AF.js → chunk-JGW24KKM.js} +4 -4
- package/dist/hooks/{chunk-ELCN5LCH.js → chunk-NEC4AT4Z.js} +34 -12
- package/dist/hooks/chunk-NZN2UFI6.js +2409 -0
- package/dist/hooks/{chunk-WK2XSHSI.js → chunk-SLSFIWTX.js} +550 -875
- package/dist/hooks/chunk-UTHMB4O2.js +1590 -0
- package/dist/hooks/{chunk-KRBERBBI.js → chunk-V4TKZHER.js} +4 -4
- package/dist/hooks/chunk-YLBBSSTF.js +3705 -0
- package/dist/hooks/chunk-Z5TMJIPW.js +45 -0
- package/dist/hooks/codex-hook-adapter.js +26 -21
- package/dist/hooks/duplicate-read-guard.js +8 -8
- package/dist/hooks/format-edited.js +4 -4
- package/dist/hooks/inputs.json +195 -181
- package/dist/hooks/investigation-guard.js +8 -8
- package/dist/hooks/pretool-guard.js +15 -15
- package/dist/hooks/session-lang.js +406 -8
- package/dist/hooks/stop-guard.js +122 -187
- package/dist/josh.js +282 -95
- package/dist/version/index.js +15 -13
- package/eslint/base.js +43 -5
- package/eslint/rules/english-only-prose.js +3 -3
- package/eslint/rules/import.js +12 -0
- package/eslint/rules/namespace-object-export.js +2 -2
- package/package.json +17 -11
- package/pnpm-workspace.yaml +2 -4
- package/prompts/coding-standards.md +14 -48
- package/prompts/collaboration-workflow/file-edits.md +1 -1
- package/prompts/collaboration-workflow/issue-citation.md +1 -1
- package/prompts/collaboration-workflow/issue-template.md +3 -10
- package/prompts/collaboration-workflow/operating-rules.md +7 -8
- package/prompts/collaboration-workflow/output-bounds.md +1 -1
- package/prompts/collaboration-workflow/overview.md +1 -1
- package/prompts/collaboration-workflow/plan-comment.md +2 -1
- package/prompts/collaboration-workflow/principles.md +21 -3
- package/prompts/collaboration-workflow/report-format.md +16 -29
- package/prompts/collaboration-workflow/residency.md +1 -1
- package/prompts/collaboration-workflow/rule-delivery.md +7 -95
- package/prompts/collaboration-workflow/shell-body.md +3 -23
- package/prompts/collaboration-workflow/turn-batching.md +4 -13
- package/prompts/collaboration-workflow/wip-cap.md +5 -11
- package/prompts/refactoring.md +1 -1
- package/prompts/review-rubric.md +3 -22
- package/prompts/review.md +15 -38
- package/prompts/testing-guide.md +2 -4
- package/scripts/adopt/adopt-logic.ts +5 -5
- package/scripts/adopt/adopt-toolkits.ts +4 -5
- package/scripts/adopt/adopt.ts +2 -3
- package/scripts/agent/agent-argv.ts +7 -7
- package/scripts/agent/agent-diagnostics.ts +2 -2
- package/scripts/agent/agent-exit-record.ts +1 -1
- package/scripts/agent/agent-headless.ts +1 -1
- package/scripts/agent/agent-launch-environment.ts +6 -1
- package/scripts/agent/agent-role-profile.ts +49 -22
- package/scripts/agent/agent-session-role.ts +32 -0
- package/scripts/agent/api-outage.ts +1 -1
- package/scripts/agent/claude-agent-argv.ts +4 -4
- package/scripts/agent/claude-result-event.ts +4 -4
- package/scripts/agent/codex-hooks.ts +2 -2
- package/scripts/agent/interactive-ask.ts +3 -6
- package/scripts/auto-ok/auto-ok-cli.ts +46 -60
- package/scripts/backlog/backlog-arrival-added.ts +34 -0
- package/scripts/backlog/backlog-arrival.ts +54 -17
- package/scripts/backlog/backlog-budget-cli.ts +34 -6
- package/scripts/backlog/backlog-budget.ts +17 -24
- package/scripts/backlog/backlog-defect-priority.ts +1 -1
- package/scripts/backlog/backlog-drive-args.ts +5 -4
- package/scripts/backlog/backlog-drive-cli.ts +14 -10
- package/scripts/backlog/backlog-drive-epic.ts +85 -0
- package/scripts/backlog/backlog-drive-launch.ts +1 -1
- package/scripts/backlog/backlog-drive-named-offer.ts +60 -9
- package/scripts/backlog/backlog-drive-named.ts +39 -9
- package/scripts/backlog/backlog-drive-offer-argv.ts +1 -1
- package/scripts/backlog/backlog-drive-restore.ts +1 -1
- package/scripts/backlog/backlog-drive-retrospective.ts +2 -2
- package/scripts/backlog/backlog-drive.ts +43 -28
- package/scripts/backlog/backlog-idle.ts +88 -0
- package/scripts/backlog/backlog-named.ts +11 -15
- package/scripts/backlog/backlog-next.ts +26 -30
- package/scripts/backlog/backlog-offer-cli.ts +28 -23
- package/scripts/backlog/backlog-offer.ts +7 -7
- package/scripts/backlog/backlog-overlap.ts +178 -0
- package/scripts/backlog/backlog-plan-cli.ts +14 -90
- package/scripts/backlog/backlog-plan-read.ts +111 -0
- package/scripts/backlog/backlog-plan.ts +11 -10
- package/scripts/backlog/backlog-pool.ts +13 -14
- package/scripts/backlog/backlog-rank.ts +11 -11
- package/scripts/backlog/backlog-ready.ts +15 -10
- package/scripts/backlog/backlog-scope.ts +14 -15
- package/scripts/backlog/backlog-stalled-cli.ts +2 -2
- package/scripts/backlog/backlog-stalled-detect.ts +4 -4
- package/scripts/backlog/backlog-stalled.ts +5 -6
- package/scripts/backlog/backlog-waves.ts +4 -4
- package/scripts/backlog/backlogrun-args.ts +74 -0
- package/scripts/backlog/backlogrun-cli.ts +113 -0
- package/scripts/backlog/backlogrun-launch.ts +178 -0
- package/scripts/behavior/behavior-assertion.ts +6 -8
- package/scripts/behavior/behavior-cli.ts +1 -1
- package/scripts/behavior/behavior-rules.ts +3 -3
- package/scripts/build/build-claude-md.ts +4 -4
- package/scripts/build/build-codex-hooks.ts +2 -2
- package/scripts/build/build-commands.ts +1 -1
- package/scripts/build/build-hooks.ts +5 -5
- package/scripts/build/build.ts +1 -1
- package/scripts/build/hook-bundle-stamp.ts +109 -7
- package/scripts/build/local-bin.ts +2 -2
- package/scripts/cases/cases-cli.ts +1 -1
- package/scripts/cases/cases-logic.ts +2 -2
- package/scripts/ci/composite-actions.ts +1 -2
- package/scripts/ci/pr-classification.ts +2 -2
- package/scripts/claude/workflow-destination.ts +1 -1
- package/scripts/clone/clone-aggregate.ts +1 -1
- package/scripts/clone/clone-fingerprint.ts +1 -1
- package/scripts/clone/clone-scan-cli.ts +1 -1
- package/scripts/clone/clone-scan.ts +1 -1
- package/scripts/config-merge/index.ts +1 -1
- package/scripts/config-merge/json-format.ts +1 -3
- package/scripts/config-merge/patch-json-array.ts +90 -0
- package/scripts/config-merge/patch-json-key.ts +6 -3
- package/scripts/config-merge/patch-json-list.ts +1 -1
- package/scripts/cost-runtime/codex-usage.ts +1 -1
- package/scripts/cost-runtime/context-cut-payback.ts +4 -5
- package/scripts/cost-runtime/context-cut-threshold.ts +4 -6
- package/scripts/cost-runtime/cost-attribute.ts +3 -3
- package/scripts/cost-runtime/cost-blocks.ts +3 -4
- package/scripts/cost-runtime/cost-cli.ts +14 -11
- package/scripts/cost-runtime/cost-corpus.ts +11 -11
- package/scripts/cost-runtime/cost-pricing.ts +4 -4
- package/scripts/cost-runtime/cost-tokens.ts +1 -2
- package/scripts/cost-runtime/cost-transcript.ts +29 -29
- package/scripts/cost-runtime/cost-usage.ts +6 -7
- package/scripts/cost-runtime/cost-verdict.ts +10 -11
- package/scripts/cost-runtime/own-session.ts +1 -1
- package/scripts/cost-runtime/transcript-cwd.ts +2 -2
- package/scripts/delegation/delegation-cli.ts +4 -4
- package/scripts/delegation/delegation-policy.ts +13 -15
- package/scripts/delegation/duplicate-read-guard.ts +9 -10
- package/scripts/delegation/fanout-cli.ts +1 -1
- package/scripts/delegation/fanout.ts +1 -1
- package/scripts/delegation/investigation-guard.ts +18 -22
- package/scripts/delegation/investigation-reads.ts +48 -238
- package/scripts/discovery/repo-discovery.ts +1 -1
- package/scripts/discovery/repo-map-logic.ts +1 -2
- package/scripts/discovery/repo-origin.ts +3 -3
- package/scripts/discovery/repo-party-cli.ts +2 -2
- package/scripts/discovery/repo-party.ts +2 -2
- package/scripts/doctor/doctor-consumer.ts +1 -1
- package/scripts/doctor/doctor-io.ts +6 -7
- package/scripts/doctor/doctor-logic.ts +1 -1
- package/scripts/doctor/doctor-ports.ts +1 -1
- package/scripts/doctor/doctor.ts +8 -9
- package/scripts/document/backlogrun-parent-read-set.ts +5 -6
- package/scripts/document/bash-output-cap.ts +5 -7
- package/scripts/document/capped-print-part.ts +1 -1
- package/scripts/document/capped-print.ts +1 -1
- package/scripts/document/document-byte-budget.ts +33 -64
- package/scripts/document/document-byte-check.ts +4 -4
- package/scripts/document/document-reachability.ts +7 -8
- package/scripts/document/document-read-cli.ts +2 -2
- package/scripts/document/document-scan.ts +30 -5
- package/scripts/document/document-section-cli.ts +6 -8
- package/scripts/document/document-section.ts +8 -12
- package/scripts/document/edit-files-cli.ts +3 -4
- package/scripts/document/entry-read-budget.ts +8 -70
- package/scripts/document/entry-read-set.ts +51 -34
- package/scripts/document/lane-child-read-set.ts +9 -9
- package/scripts/document/read-files-cli.ts +1 -2
- package/scripts/document/read-set-cli.ts +16 -19
- package/scripts/document/read-set-cost.ts +4 -4
- package/scripts/document/read-set-point-of-use.ts +28 -38
- package/scripts/document/read-set-pricing.ts +1 -1
- package/scripts/document/read-set-trim.ts +3 -3
- package/scripts/document/resident-budget.ts +8 -10
- package/scripts/epic/epic-add-body.ts +15 -18
- package/scripts/epic/epic-add-plan.ts +26 -28
- package/scripts/epic/epic-add.ts +32 -25
- package/scripts/epic/epic-audit-checks.ts +27 -37
- package/scripts/epic/epic-audit-cli.ts +21 -22
- package/scripts/epic/epic-audit-orphans.ts +16 -17
- package/scripts/epic/epic-audit-rationale.ts +10 -15
- package/scripts/epic/epic-audit-report.ts +2 -5
- package/scripts/epic/epic-audit.ts +18 -14
- package/scripts/epic/epic-body.ts +10 -10
- package/scripts/epic/epic-bundle-cli.ts +36 -34
- package/scripts/epic/epic-bundle-evidence.ts +5 -5
- package/scripts/epic/epic-bundle-gaps.ts +6 -9
- package/scripts/epic/epic-bundle-poll.ts +1 -1
- package/scripts/epic/epic-bundle-referenced.ts +11 -14
- package/scripts/epic/epic-bundle.ts +19 -20
- package/scripts/epic/epic-busy.ts +44 -21
- package/scripts/epic/epic-candidate-confirm.ts +15 -18
- package/scripts/epic/epic-chains.ts +18 -23
- package/scripts/epic/epic-classify.ts +11 -12
- package/scripts/epic/epic-cli-argv.ts +5 -6
- package/scripts/epic/epic-cli-remove.ts +9 -4
- package/scripts/epic/epic-cli.ts +38 -26
- package/scripts/epic/epic-close-comment.ts +14 -15
- package/scripts/epic/epic-close.ts +25 -29
- package/scripts/epic/epic-cross-repo.ts +18 -21
- package/scripts/epic/epic-decision.ts +14 -18
- package/scripts/epic/epic-fetch.ts +25 -31
- package/scripts/epic/epic-graph.ts +15 -17
- package/scripts/epic/epic-index.ts +14 -16
- package/scripts/epic/epic-issue.ts +9 -11
- package/scripts/epic/epic-label-age.ts +74 -0
- package/scripts/epic/epic-lane-offer.ts +35 -24
- package/scripts/epic/epic-nested.ts +1 -1
- package/scripts/epic/epic-next-read.ts +8 -8
- package/scripts/epic/epic-next-views.ts +12 -12
- package/scripts/epic/epic-next.ts +29 -33
- package/scripts/epic/epic-outside-blocker.ts +11 -10
- package/scripts/epic/epic-parse.ts +22 -24
- package/scripts/epic/epic-promote.ts +3 -2
- package/scripts/epic/epic-rank.ts +1 -1
- package/scripts/epic/epic-read.ts +10 -8
- package/scripts/epic/epic-reconcile.ts +8 -6
- package/scripts/epic/epic-reference.ts +5 -4
- package/scripts/epic/epic-relation-recheck.ts +10 -11
- package/scripts/epic/epic-relations.ts +9 -8
- package/scripts/epic/epic-remove-plan.ts +4 -5
- package/scripts/epic/epic-remove.ts +7 -5
- package/scripts/epic/epic-report.ts +18 -20
- package/scripts/epic/epic-run.ts +6 -5
- package/scripts/epic/epic-sections.ts +2 -2
- package/scripts/epic/epic-shape.ts +3 -3
- package/scripts/epic/epic-solo-stale.ts +3 -2
- package/scripts/epic/epic-solo.ts +8 -8
- package/scripts/epic/epic-triage.ts +5 -4
- package/scripts/epic/epic-validate.ts +8 -7
- package/scripts/epic/epic.ts +5 -5
- package/scripts/exports/unused-members-cli.ts +1 -1
- package/scripts/followup/followup-issue-number.ts +1 -2
- package/scripts/followup/git-followup-cleanup.ts +6 -7
- package/scripts/followup/git-followup-finish.ts +11 -13
- package/scripts/followup/git-followup-flush.ts +11 -7
- package/scripts/followup/git-followup-issue-close.ts +16 -13
- package/scripts/followup/git-followup-label.ts +9 -6
- package/scripts/followup/git-followup-merged.ts +1 -1
- package/scripts/followup/git-followup-pending.ts +7 -9
- package/scripts/followup/git-followup-stages.ts +28 -17
- package/scripts/followup/git-followup-workflow.ts +19 -21
- package/scripts/followup/git-pr-followup-checks.ts +13 -20
- package/scripts/followup/git-pr-followup-wrapup.ts +7 -7
- package/scripts/followup/git-pr-followup.ts +18 -17
- package/scripts/gate/core-admission.ts +2 -2
- package/scripts/gate/core-budget.ts +15 -26
- package/scripts/gate/gate-ledger.ts +114 -0
- package/scripts/gate/gate-log.ts +7 -9
- package/scripts/gate/gate-plan.ts +70 -35
- package/scripts/gate/gate-report.ts +14 -15
- package/scripts/gate/gate-skip.ts +11 -13
- package/scripts/gate/gate-steps.ts +5 -1
- package/scripts/gate/gate-tree.ts +3 -4
- package/scripts/gate/hook-gate-reuse.ts +9 -9
- package/scripts/gate/machine-capacity.ts +168 -30
- package/scripts/gate/pre-commit-type-check.ts +4 -4
- package/scripts/gate/project-checks.ts +12 -4
- package/scripts/gate/scoped-green.ts +11 -18
- package/scripts/gate/type-check-command.ts +2 -2
- package/scripts/gate/type-check-step.ts +4 -4
- package/scripts/gate/verification-gate.ts +53 -51
- package/scripts/gh/gh-spawn.ts +2 -2
- package/scripts/gh/git-ai-review-scan.ts +3 -2
- package/scripts/gh/git-gh-api-path.ts +10 -11
- package/scripts/gh/git-gh-exec.ts +43 -48
- package/scripts/gh/git-gh-failure.ts +6 -9
- package/scripts/gh/git-gh-helpers.ts +1 -1
- package/scripts/gh/git-gh-issue-list.ts +15 -19
- package/scripts/gh/git-gh-issue-read.ts +43 -60
- package/scripts/gh/git-gh-issue-rest.ts +14 -15
- package/scripts/gh/git-gh-issue-write.ts +52 -40
- package/scripts/gh/git-gh-issue.ts +23 -24
- package/scripts/gh/git-gh-pr-auto-merge.ts +3 -3
- package/scripts/gh/git-gh-pr-read.ts +46 -50
- package/scripts/gh/git-gh-pr-rest.ts +23 -26
- package/scripts/gh/git-gh-pr-review.ts +2 -2
- package/scripts/gh/git-gh-pr-rollup.ts +4 -4
- package/scripts/gh/git-gh-pr-snapshot.ts +8 -10
- package/scripts/gh/git-gh-pr.ts +16 -16
- package/scripts/gh/git-gh-reachability.ts +11 -12
- package/scripts/gh/git-gh-repo.ts +2 -3
- package/scripts/gh/git-gh-rest-state.ts +1 -1
- package/scripts/gh/git-pr-ai-review.ts +6 -5
- package/scripts/gh/git-pr-checks-eval.ts +28 -30
- package/scripts/gh/git-pr-checks-parse.ts +14 -16
- package/scripts/gh/git-pr-checks-watch.ts +17 -17
- package/scripts/gh/git-pr-checks.ts +20 -23
- package/scripts/gh/git-pr-coderabbit.ts +8 -6
- package/scripts/gh/git-pr-confirmation.ts +5 -5
- package/scripts/gh/git-pr-managed-config.ts +7 -9
- package/scripts/gh/git-pr-messages.ts +1 -1
- package/scripts/gh/git-pr.ts +15 -16
- package/scripts/gh/github-issue-url.ts +8 -9
- package/scripts/git/base-tree.ts +66 -0
- package/scripts/git/change-base.ts +42 -2
- package/scripts/git/changed-file-scope.ts +5 -5
- package/scripts/git/changed-paths.ts +1 -2
- package/scripts/git/constants.ts +2 -2
- package/scripts/git/git-branch.ts +1 -1
- package/scripts/git/git-closes-keyword.ts +3 -3
- package/scripts/git/git-command.ts +53 -41
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +14 -15
- package/scripts/git/git-error.ts +1 -1
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/git-issue.ts +10 -8
- package/scripts/git/git-location-environment.ts +3 -4
- package/scripts/git/git-ls-remote.ts +6 -8
- package/scripts/git/git-pre-push-hook.ts +11 -10
- package/scripts/git/git-preflight.ts +5 -5
- package/scripts/git/git-push-transport.ts +2 -2
- package/scripts/git/git-remote-branch.ts +1 -2
- package/scripts/git/git-schemas.ts +16 -23
- package/scripts/git/git-spawn-sync.ts +1 -1
- package/scripts/git/git-spawn.ts +37 -14
- package/scripts/git/git-ssh-keepalive.ts +12 -5
- package/scripts/git/git-staging.ts +7 -8
- package/scripts/git/git-workflow.ts +1 -1
- package/scripts/git/git-worktree.ts +35 -27
- package/scripts/git/gone-branch.ts +2 -2
- package/scripts/git/listing-cutoff.ts +1 -2
- package/scripts/git/lockfile-sync.ts +65 -0
- package/scripts/git/main-merge-guard.ts +1 -2
- package/scripts/git/main-merge.ts +7 -7
- package/scripts/git/main-sync.ts +23 -8
- package/scripts/git/parse-json-array.ts +18 -23
- package/scripts/git/repository-lock.ts +34 -2
- package/scripts/git/stash/git-stash.ts +4 -5
- package/scripts/git/stash/stash-orphans.ts +5 -3
- package/scripts/git/stash/stash-pop-args.ts +1 -1
- package/scripts/git/stash/stash-pop-cli.ts +3 -3
- package/scripts/git/stash/stash-sweep-lock.ts +2 -2
- package/scripts/hooks/batch-guard.ts +11 -13
- package/scripts/hooks/check-commit-message.ts +12 -9
- package/scripts/hooks/codex-hook-adapter.ts +16 -10
- package/scripts/hooks/edited-cspell.ts +3 -4
- package/scripts/hooks/format-edited-cli.ts +1 -1
- package/scripts/hooks/format-edited-file.ts +11 -17
- package/scripts/hooks/format-rewrite-notice.ts +19 -17
- package/scripts/hooks/pre-push-unit.ts +10 -14
- package/scripts/hooks/pretool-guard-cli.ts +4 -4
- package/scripts/hooks/pretool-guard.ts +93 -18
- package/scripts/hooks/reserved-run.ts +2 -2
- package/scripts/hooks/step-zero-notice.ts +1 -1
- package/scripts/hooks/stop-guard.ts +21 -10
- package/scripts/init/basic-path-migration.ts +2 -2
- package/scripts/init/claude-kit-only-settings.ts +2 -2
- package/scripts/init/claude-plugin-config.ts +2 -2
- package/scripts/init/distributed-paths.ts +4 -4
- package/scripts/init/hook-command-rewrite.ts +3 -3
- package/scripts/init/hook-launch.ts +5 -5
- package/scripts/init/init-actions.ts +13 -0
- package/scripts/init/init-ai-copy.ts +11 -11
- package/scripts/init/init-bootstrap.ts +3 -3
- package/scripts/init/init-copy-content.ts +4 -4
- package/scripts/init/init-logic-json-merge.ts +7 -9
- package/scripts/init/init-logic-migrate.ts +1 -1
- package/scripts/init/init-logic-templates.ts +1 -1
- package/scripts/init/init-logic-workspace.ts +4 -4
- package/scripts/init/init-logic-yaml-merge.ts +2 -2
- package/scripts/init/init-logic.ts +19 -22
- package/scripts/init/init.ts +7 -7
- package/scripts/init/kit-base-preset.ts +1 -1
- package/scripts/init/kit-setup-state.ts +1 -1
- package/scripts/init/kit-written-paths.ts +1 -2
- package/scripts/init/package-manager-pin.ts +1 -1
- package/scripts/init/project-profile-cli.ts +1 -1
- package/scripts/init/project-profile.ts +3 -3
- package/scripts/init/session-language-environment.ts +1 -1
- package/scripts/init/start-exec.ts +3 -4
- package/scripts/init/start-plan.ts +2 -2
- package/scripts/init/start-setup-pr.ts +3 -2
- package/scripts/init/start-steps.ts +2 -2
- package/scripts/init/tsconfig-preset-migration.ts +1 -1
- package/scripts/init/vscode-tasks.ts +62 -0
- package/scripts/issue/baseline-measure.ts +2 -2
- package/scripts/issue/behavior-change-lint.ts +2 -2
- package/scripts/issue/defect-rate-cli.ts +6 -7
- package/scripts/issue/defect-rate.ts +37 -27
- package/scripts/issue/git-next-issues.ts +9 -8
- package/scripts/issue/issue-auto-ok.ts +24 -11
- package/scripts/issue/issue-backlinks-cli.ts +5 -5
- package/scripts/issue/issue-backlinks.ts +6 -6
- package/scripts/issue/issue-cite-cli.ts +20 -18
- package/scripts/issue/issue-cite.ts +18 -8
- package/scripts/issue/issue-closing-pr.ts +4 -4
- package/scripts/issue/issue-comment-cli.ts +6 -4
- package/scripts/issue/issue-file-cli.ts +52 -15
- package/scripts/issue/issue-file-fold.ts +155 -0
- package/scripts/issue/issue-file.ts +9 -6
- package/scripts/issue/issue-fold-cli.ts +14 -9
- package/scripts/issue/issue-fold.ts +23 -8
- package/scripts/issue/issue-labels.ts +34 -38
- package/scripts/issue/issue-lint-cli.ts +2 -2
- package/scripts/issue/issue-lint.ts +1 -1
- package/scripts/issue/issue-merged.ts +10 -4
- package/scripts/issue/issue-number-shape.ts +27 -0
- package/scripts/issue/issue-rank.ts +1 -1
- package/scripts/issue/issue-read-cli.ts +4 -5
- package/scripts/issue/issue-read.ts +4 -5
- package/scripts/issue/issue-reference.ts +5 -5
- package/scripts/issue/issue-release-cli.ts +17 -7
- package/scripts/issue/issue-release.ts +3 -3
- package/scripts/issue/issue-report-failures.ts +7 -4
- package/scripts/issue/issue-scout-cli.ts +11 -11
- package/scripts/issue/issue-scout-closed.ts +4 -4
- package/scripts/issue/issue-scout.ts +4 -5
- package/scripts/issue/issue-state-cli.ts +17 -10
- package/scripts/issue/issue-state.ts +12 -13
- package/scripts/issue/issue-wip.ts +7 -7
- package/scripts/issue/markdown-section.ts +3 -3
- package/scripts/issue/measure-rerun-cli.ts +10 -9
- package/scripts/issue/reproduction-measure.ts +3 -3
- package/scripts/issue/session-cite.ts +56 -0
- package/scripts/josh/agent-session-environment.ts +10 -8
- package/scripts/josh/cli-body.ts +2 -2
- package/scripts/josh/command-suggest.ts +1 -1
- package/scripts/josh/file-map-stamp.ts +20 -23
- package/scripts/josh/hook-decision.ts +24 -28
- package/scripts/josh/josh-command-map.ts +4 -1
- package/scripts/josh/josh-command-types.ts +30 -35
- package/scripts/josh/josh-commands-ai.ts +6 -6
- package/scripts/josh/josh-commands-backlog.ts +15 -3
- package/scripts/josh/josh-commands-clone.ts +1 -1
- package/scripts/josh/josh-commands-development.ts +25 -4
- package/scripts/josh/josh-commands-document.ts +3 -3
- package/scripts/josh/josh-commands-guard.ts +3 -3
- package/scripts/josh/josh-commands-issue.ts +4 -5
- package/scripts/josh/josh-commands-lane.ts +14 -4
- package/scripts/josh/josh-commands-lint.ts +1 -1
- package/scripts/josh/josh-commands-run.ts +21 -7
- package/scripts/josh/josh-commands-split.ts +1 -2
- package/scripts/josh/josh-commands-versioning.ts +5 -5
- package/scripts/josh/josh-commands-workflow.ts +30 -22
- package/scripts/josh/josh-environment-file.ts +1 -1
- package/scripts/josh/josh-in-process.ts +3 -3
- package/scripts/josh/josh-logic.ts +6 -7
- package/scripts/josh/josh-run.ts +3 -3
- package/scripts/josh/josh-verdict.ts +9 -12
- package/scripts/josh/josh.ts +3 -3
- package/scripts/josh/kit-only.ts +2 -2
- package/scripts/josh/path-decision.ts +3 -3
- package/scripts/josh/platform-temporary.ts +7 -5
- package/scripts/josh/process-identity.ts +24 -6
- package/scripts/josh/process-owner.ts +4 -4
- package/scripts/josh/session-language-cli.ts +53 -11
- package/scripts/josh/session-language.ts +1 -1
- package/scripts/josh/stamp-file.ts +48 -29
- package/scripts/josh/stamp-record.ts +57 -0
- package/scripts/lane/lane-await.ts +35 -11
- package/scripts/lane/lane-cache.ts +6 -6
- package/scripts/lane/lane-capacity.ts +32 -17
- package/scripts/lane/lane-child-invocation.ts +17 -15
- package/scripts/lane/lane-child-marker.ts +12 -12
- package/scripts/lane/lane-cli.ts +12 -13
- package/scripts/lane/lane-close.ts +6 -6
- package/scripts/lane/lane-dispatch.ts +61 -72
- package/scripts/lane/lane-environment.ts +5 -5
- package/scripts/lane/lane-guard-policy.ts +7 -21
- package/scripts/lane/lane-handoff.ts +2 -2
- package/scripts/lane/lane-install.ts +9 -10
- package/scripts/lane/lane-launch-cli.ts +13 -8
- package/scripts/lane/lane-ledger.ts +73 -11
- package/scripts/lane/lane-leftover.ts +2 -2
- package/scripts/lane/lane-limit-cli.ts +160 -0
- package/scripts/lane/lane-limit-override.ts +74 -0
- package/scripts/lane/lane-load.ts +19 -68
- package/scripts/lane/lane-measure-cli.ts +15 -25
- package/scripts/lane/lane-occupancy.ts +6 -4
- package/scripts/lane/lane-open.ts +20 -19
- package/scripts/lane/lane-output.ts +4 -3
- package/scripts/lane/lane-paths.ts +12 -11
- package/scripts/lane/lane-phase.ts +33 -0
- package/scripts/lane/lane-reap.ts +2 -2
- package/scripts/lane/lane-registry.ts +16 -15
- package/scripts/lane/lane-relaunch.ts +9 -9
- package/scripts/lane/lane-report.ts +5 -4
- package/scripts/lane/lane-resume.ts +2 -2
- package/scripts/lane/lane-sampler.ts +55 -0
- package/scripts/lane/lane-seed.ts +7 -7
- package/scripts/lane/lane-stage-stats.ts +135 -0
- package/scripts/lane/lane-start-point.ts +8 -11
- package/scripts/lane/lane-stats.ts +60 -15
- package/scripts/lane/lane-stray.ts +1 -1
- package/scripts/lane/lane-vacant.ts +1 -1
- package/scripts/lane/openai-lane-supervisor-decision.ts +3 -7
- package/scripts/lane/openai-lane-supervisor-owner.ts +3 -9
- package/scripts/lane/openai-review-broker.ts +2 -4
- package/scripts/lib/ancestor-directories.ts +1 -1
- package/scripts/lib/bounded-pool.ts +2 -2
- package/scripts/lib/buffered-process.ts +4 -6
- package/scripts/lib/caddy-logs.sh +0 -0
- package/scripts/lib/cli-flags.ts +39 -6
- package/scripts/lib/error-message.ts +1 -1
- package/scripts/lib/json-value.ts +17 -3
- package/scripts/lib/poll.ts +1 -1
- package/scripts/lib/status-icons.ts +3 -3
- package/scripts/lib/timed-fetch.ts +1 -1
- package/scripts/lib/timeouts.ts +1 -1
- package/scripts/lines/bytes-command.ts +3 -4
- package/scripts/lines/effective-limit.ts +25 -12
- package/scripts/lines/line-budget.ts +47 -55
- package/scripts/lines/line-targets.ts +6 -2
- package/scripts/lines/lines-command.ts +3 -3
- package/scripts/lint/cross-file-recheck.ts +155 -0
- package/scripts/lint/cspell-cached.ts +1 -1
- package/scripts/lint/format.ts +1 -2
- package/scripts/lint/lint-parallel.ts +35 -19
- package/scripts/lint/lint-related-scope.ts +25 -15
- package/scripts/lint/lint-related.ts +6 -7
- package/scripts/managed-marker/index.ts +1 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/git-notify.ts +9 -7
- package/scripts/notify/telegram-notify.ts +53 -37
- package/scripts/notify/telegram-test-logic.ts +3 -3
- package/scripts/notify/telegram-test.ts +45 -30
- package/scripts/observations/observation-ledger-home.ts +14 -8
- package/scripts/observations/observation-ledger-line.ts +3 -2
- package/scripts/observations/observation-ledger-migrate.ts +3 -4
- package/scripts/observations/observation-ledger-prepare.ts +4 -4
- package/scripts/observations/observation-ledger.ts +14 -15
- package/scripts/observations/observation-record-cli.ts +83 -0
- package/scripts/observations/observation-record.ts +91 -0
- package/scripts/observations/observations-flush-cli.ts +1 -1
- package/scripts/observations/observations-flush-landing.ts +7 -6
- package/scripts/observations/observations-flush.ts +26 -27
- package/scripts/overrides/overrides-check.ts +18 -8
- package/scripts/package/package-scout-cli.ts +1 -1
- package/scripts/package/package-scout-format.ts +2 -2
- package/scripts/package/package-scout.ts +1 -1
- package/scripts/propagate/propagate-git-failure.ts +1 -1
- package/scripts/propagate/propagate-git.ts +7 -7
- package/scripts/propagate/propagate-plan.ts +2 -2
- package/scripts/propagate/propagate-publish.ts +2 -3
- package/scripts/propagate/propagate-run.ts +5 -7
- package/scripts/propagate/propagate-select.ts +1 -1
- package/scripts/propagate/propagate-steps.ts +19 -20
- package/scripts/propagate/propagate-targets.ts +6 -10
- package/scripts/propagate/propagate.ts +5 -5
- package/scripts/refactor/import-graph.ts +1 -1
- package/scripts/refactor/refactor-lint.ts +4 -10
- package/scripts/refactor/refactor-scan-cli.ts +1 -1
- package/scripts/refactor/refactor-scan.ts +2 -2
- package/scripts/refactor/refactor-targets.ts +1 -1
- package/scripts/release/github-release-cli.ts +25 -3
- package/scripts/release/github-release-runs.ts +1 -1
- package/scripts/release/release-cli.ts +21 -4
- package/scripts/release/release-history.ts +6 -10
- package/scripts/release/release-plan.ts +3 -3
- package/scripts/release/release-progress.ts +3 -4
- package/scripts/release/release-publish.ts +8 -9
- package/scripts/release/release-scope-cli.ts +8 -10
- package/scripts/release/release-tag.ts +6 -8
- package/scripts/release/release-worktree.ts +5 -5
- package/scripts/repo/auto-merge-setting-logic.ts +7 -9
- package/scripts/repo/auto-merge-setting.ts +1 -1
- package/scripts/repo/repo-setting.ts +4 -4
- package/scripts/repo/repository-labels.ts +1 -1
- package/scripts/repo/required-checks-logic.ts +3 -3
- package/scripts/repo/required-checks-report.ts +1 -1
- package/scripts/repo/ruleset-check-cli.ts +1 -1
- package/scripts/repo/ruleset-check.ts +1 -1
- package/scripts/report/report-format-reference.ts +26 -0
- package/scripts/report/report-lint-cli.ts +2 -2
- package/scripts/report/report-lint.ts +16 -2
- package/scripts/review/disposition-cli.ts +2 -2
- package/scripts/review/disposition-logic.ts +1 -1
- package/scripts/review/live-evidence.ts +9 -6
- package/scripts/review/review-attest-cli.ts +1 -2
- package/scripts/review/review-attest.ts +3 -3
- package/scripts/review/review-brief-cli.ts +19 -20
- package/scripts/review/review-brief.ts +29 -32
- package/scripts/review/review-checkout.ts +2 -2
- package/scripts/review/review-diff-parts.ts +3 -5
- package/scripts/review/review-diff-write.ts +1 -1
- package/scripts/review/review-finding-ledger.ts +7 -4
- package/scripts/review/review-findings-cli.ts +2 -2
- package/scripts/review/review-level.ts +4 -7
- package/scripts/review/review-record-cli.ts +73 -16
- package/scripts/review/review-record.ts +5 -4
- package/scripts/review/review-round2-cli.ts +2 -3
- package/scripts/review/review-round2.ts +13 -21
- package/scripts/review/review-stamps.ts +9 -71
- package/scripts/review/review-tree.ts +4 -5
- package/scripts/rules/bash-triggers.ts +4 -4
- package/scripts/rules/decision-oracle-batch.ts +6 -7
- package/scripts/rules/decision-oracle-stage.ts +1 -1
- package/scripts/rules/decision-oracle-tokens.ts +1 -2
- package/scripts/rules/decision-oracle.ts +2 -2
- package/scripts/rules/delivered-rules.ts +61 -406
- package/scripts/rules/destructive-command.ts +2 -2
- package/scripts/rules/direct-filing.ts +4 -4
- package/scripts/rules/direct-pr-create.ts +2 -2
- package/scripts/rules/early-heartbeat.ts +15 -19
- package/scripts/rules/file-body.ts +5 -6
- package/scripts/rules/filing-cap.ts +6 -7
- package/scripts/rules/filing-offer.ts +1 -1
- package/scripts/rules/firing-point.ts +6 -6
- package/scripts/rules/gh-api.ts +2 -2
- package/scripts/rules/git-argv.ts +3 -3
- package/scripts/rules/git-force.ts +2 -2
- package/scripts/rules/hook-context-line.ts +31 -0
- package/scripts/rules/implementation-cut-verdict.ts +5 -8
- package/scripts/rules/implementation-cut.ts +35 -32
- package/scripts/rules/index-guard.ts +2 -2
- package/scripts/rules/issue-citation.ts +7 -7
- package/scripts/rules/issue-comments.ts +21 -13
- package/scripts/rules/josh-git-bare.ts +2 -2
- package/scripts/rules/lane-background.ts +14 -16
- package/scripts/rules/lane-carry-conflict.ts +41 -5
- package/scripts/rules/lane-interactive-ask.ts +6 -9
- package/scripts/rules/lane-park.ts +12 -16
- package/scripts/rules/lane-split-park.ts +1 -2
- package/scripts/rules/lane-switch-main.ts +10 -13
- package/scripts/rules/last-prompt.ts +1 -1
- package/scripts/rules/oracle-consulted.ts +5 -5
- package/scripts/rules/oracle-firing.ts +6 -9
- package/scripts/rules/oracle-list-cli.ts +2 -2
- package/scripts/rules/permission-guards.ts +2 -2
- package/scripts/rules/piped-verification.ts +79 -9
- package/scripts/rules/poll-loop.ts +9 -11
- package/scripts/rules/pre-gate-cut.ts +33 -30
- package/scripts/rules/prior-comment-read.ts +3 -3
- package/scripts/rules/protected-files.ts +25 -13
- package/scripts/rules/raw-field-body.ts +3 -4
- package/scripts/rules/reply-language.ts +1 -1
- package/scripts/rules/rule-body-guard.ts +10 -12
- package/scripts/rules/rule-guard.ts +1 -1
- package/scripts/rules/rule-list.ts +51 -0
- package/scripts/rules/rule-registry-rows.ts +282 -0
- package/scripts/rules/rule-registry.ts +109 -0
- package/scripts/rules/rule-value-cache.ts +2 -2
- package/scripts/rules/rule-value-cli.ts +6 -4
- package/scripts/rules/rule-value.ts +61 -22
- package/scripts/rules/run-tail-rule.ts +11 -15
- package/scripts/rules/shell-body-trigger.ts +7 -7
- package/scripts/rules/shell-segments.ts +2 -4
- package/scripts/rules/stop-rules.ts +54 -41
- package/scripts/rules/tail-commands.ts +1 -1
- package/scripts/rules/test-declared-commit.ts +2 -2
- package/scripts/rules/third-party-write.ts +3 -3
- package/scripts/rules/worktree-guard.ts +12 -5
- package/scripts/run/add/run-add-cli.ts +165 -0
- package/scripts/run/add/run-add.ts +124 -0
- package/scripts/run/board/run-board-cli.ts +207 -0
- package/scripts/run/board/run-board-closed.ts +95 -0
- package/scripts/run/board/run-board-every.ts +60 -0
- package/scripts/run/board/run-board-fetch.ts +38 -0
- package/scripts/run/board/run-board-fit.ts +219 -0
- package/scripts/run/board/run-board-github.ts +162 -0
- package/scripts/run/board/run-board-header.ts +275 -0
- package/scripts/run/board/run-board-kind.ts +35 -0
- package/scripts/run/board/run-board-labels.ts +299 -0
- package/scripts/run/board/run-board-layout.ts +222 -0
- package/scripts/run/board/run-board-link.ts +31 -0
- package/scripts/run/board/run-board-machine.ts +198 -0
- package/scripts/run/board/run-board-notes.ts +103 -0
- package/scripts/run/board/run-board-phase.ts +136 -0
- package/scripts/run/board/run-board-plan.ts +129 -0
- package/scripts/run/board/run-board-read.ts +62 -0
- package/scripts/run/board/run-board-render-legend.ts +82 -0
- package/scripts/run/board/run-board-render-notes.ts +77 -0
- package/scripts/run/board/run-board-render-slot.ts +50 -0
- package/scripts/run/board/run-board-render.ts +407 -0
- package/scripts/run/board/run-board-scope.ts +17 -0
- package/scripts/run/board/run-board-screen.ts +43 -0
- package/scripts/run/board/run-board-span.ts +66 -0
- package/scripts/run/board/run-board-spin.ts +115 -0
- package/scripts/run/board/run-board-state.ts +113 -0
- package/scripts/run/board/run-board-status.ts +279 -0
- package/scripts/run/board/run-board-tick.ts +210 -0
- package/scripts/run/board/run-board-track.ts +22 -0
- package/scripts/run/board/run-board-usage-read.ts +255 -0
- package/scripts/run/board/run-board-usage-rusage.ts +124 -0
- package/scripts/run/board/run-board-usage-text.ts +80 -0
- package/scripts/run/board/run-board-usage.ts +165 -0
- package/scripts/run/carry/run-carry-added.ts +62 -0
- package/scripts/run/carry/run-carry-args.ts +25 -22
- package/scripts/run/carry/run-carry-change.ts +1 -1
- package/scripts/run/carry/run-carry-cli.ts +71 -48
- package/scripts/run/carry/run-carry-conversation.ts +6 -7
- package/scripts/run/carry/run-carry-ended.ts +85 -0
- package/scripts/run/carry/run-carry-reclaim.ts +1 -1
- package/scripts/run/carry/run-carry-stash.ts +3 -2
- package/scripts/run/carry/run-carry-streak.ts +8 -10
- package/scripts/run/carry/run-carry.ts +85 -89
- package/scripts/run/cut/run-cut-args.ts +7 -7
- package/scripts/run/cut/run-cut-cli.ts +54 -36
- package/scripts/run/cut/run-cut-handoff.ts +15 -15
- package/scripts/run/cut/run-cut-report.ts +37 -16
- package/scripts/run/cut/run-cut.ts +63 -77
- package/scripts/run/detached-launch.ts +35 -50
- package/scripts/run/entry/run-entry-cli.ts +48 -27
- package/scripts/run/entry/run-entry-stop.ts +7 -9
- package/scripts/run/entry/run-entry.ts +5 -6
- package/scripts/run/event/run-event-cli.ts +5 -6
- package/scripts/run/event/run-event-filed.ts +69 -0
- package/scripts/run/event/run-event-follow.ts +3 -3
- package/scripts/run/event/run-event-plan.ts +38 -0
- package/scripts/run/event/run-event-render.ts +9 -4
- package/scripts/run/event/run-event-scope.ts +47 -18
- package/scripts/run/event/run-event-stream-emit.ts +64 -11
- package/scripts/run/event/run-event-stream.ts +171 -46
- package/scripts/run/event/run-event-watch.ts +4 -6
- package/scripts/run/hold/run-hold-cli.ts +65 -62
- package/scripts/run/hold/run-hold.ts +88 -46
- package/scripts/run/merge/run-merge-cli.ts +116 -77
- package/scripts/run/merge/run-merge-collect.ts +107 -0
- package/scripts/run/merge/run-merge-steps.ts +112 -65
- package/scripts/run/merge/run-merge-token.ts +30 -0
- package/scripts/run/merge/run-merge.ts +31 -22
- package/scripts/run/progress/run-progress-args.ts +4 -4
- package/scripts/run/progress/run-progress-cli.ts +39 -50
- package/scripts/run/progress/run-progress-clock.ts +25 -32
- package/scripts/run/progress/run-progress-config.ts +6 -9
- package/scripts/run/progress/run-progress-read.ts +9 -10
- package/scripts/run/progress/run-progress.ts +48 -53
- package/scripts/run/review/run-review-cli.ts +6 -6
- package/scripts/run/review/run-review-steps.ts +6 -6
- package/scripts/run/review/run-review.ts +9 -11
- package/scripts/run/run-cli-fault.ts +29 -0
- package/scripts/run/run-ending-cli.ts +3 -3
- package/scripts/run/run-ending.ts +10 -14
- package/scripts/run/run-halfrun-resume.ts +6 -8
- package/scripts/run/run-headless.ts +26 -12
- package/scripts/run/run-invocation.ts +17 -22
- package/scripts/run/run-label.ts +7 -5
- package/scripts/run/run-liveness-cli.ts +19 -6
- package/scripts/run/run-liveness.ts +27 -38
- package/scripts/run/run-next-cli.ts +5 -9
- package/scripts/run/run-next.ts +4 -5
- package/scripts/run/run-parent-cut-hook.ts +10 -12
- package/scripts/run/run-preflight.ts +25 -29
- package/scripts/run/run-prep-cli.ts +17 -13
- package/scripts/run/run-prep-locate.ts +4 -5
- package/scripts/run/run-prep.ts +7 -10
- package/scripts/run/run-prrun-resume.ts +2 -2
- package/scripts/run/run-report-cli.ts +4 -4
- package/scripts/run/run-report.ts +9 -14
- package/scripts/run/run-retrospective.ts +3 -3
- package/scripts/run/run-section.ts +42 -0
- package/scripts/run/run-stage-read.ts +2 -2
- package/scripts/run/run-stage.ts +6 -4
- package/scripts/run/run-status-cli.ts +7 -5
- package/scripts/run/run-status.ts +6 -7
- package/scripts/run/run-step-cli.ts +64 -18
- package/scripts/run/run-step.ts +107 -51
- package/scripts/run/run-stop-notify.ts +7 -8
- package/scripts/run/run-stranded-cli.ts +1 -1
- package/scripts/run/run-stranded-detect.ts +4 -4
- package/scripts/run/run-stranded.ts +11 -13
- package/scripts/run/run-tail-cli.ts +15 -16
- package/scripts/run/run-tail.ts +14 -33
- package/scripts/run/run-watcher-guard-cli.ts +3 -4
- package/scripts/run/run-watcher-guard.ts +11 -12
- package/scripts/run/run-watcher-hook.ts +6 -12
- package/scripts/run/ship/run-ship-cli.ts +67 -33
- package/scripts/run/ship/run-ship-detach.ts +15 -13
- package/scripts/run/ship/run-ship-lock.ts +1 -1
- package/scripts/run/ship/run-ship-next.ts +7 -8
- package/scripts/run/ship/run-ship-pre-detach.ts +27 -11
- package/scripts/run/ship/run-ship-preflight.ts +10 -11
- package/scripts/run/ship/run-ship-probe.ts +4 -4
- package/scripts/run/ship/run-ship-return.ts +1 -1
- package/scripts/run/ship/run-ship-review-steps.ts +43 -24
- package/scripts/run/ship/run-ship-review.ts +12 -14
- package/scripts/run/ship/run-ship-scoped.ts +15 -6
- package/scripts/run/ship/run-ship-stage.ts +80 -26
- package/scripts/run/ship/run-ship-steps.ts +26 -16
- package/scripts/run/ship/run-ship-stop-text.ts +4 -2
- package/scripts/run/ship/run-ship-sync.ts +9 -8
- package/scripts/run/ship/run-ship.ts +17 -32
- package/scripts/run/tidy/run-tidy-cli.ts +9 -5
- package/scripts/run/tidy/run-tidy-lanes.ts +18 -7
- package/scripts/run/tidy/run-tidy-stashes.ts +8 -8
- package/scripts/run/tidy/run-tidy.ts +4 -3
- package/scripts/run/wake/run-wake-cli.ts +27 -32
- package/scripts/run/wake/run-wake-describe.ts +24 -28
- package/scripts/run/wake/run-wake-driver.ts +14 -14
- package/scripts/run/wake/run-wake-handoff.ts +6 -6
- package/scripts/run/wake/run-wake-loop.ts +9 -9
- package/scripts/run/wake/run-wake-restart.ts +4 -5
- package/scripts/run/wake/run-wake-session.ts +23 -27
- package/scripts/run/wake/run-wake.ts +57 -279
- package/scripts/safe-chain/ci-installer-pin.ts +3 -3
- package/scripts/safe-chain/pack-hook.ts +2 -2
- package/scripts/safe-chain/preinstall-command.ts +2 -2
- package/scripts/security/security-audit-logic.ts +1 -1
- package/scripts/security/security-audit-provision-logic.ts +1 -1
- package/scripts/security/security-audit-provision.ts +2 -2
- package/scripts/security/security-audit.ts +5 -5
- package/scripts/security/security-updates-logic.ts +2 -3
- package/scripts/security/security-updates.ts +2 -4
- package/scripts/self-sync-guard/index.ts +1 -1
- package/scripts/self-sync-guard/self-sync-guard-logic.ts +2 -2
- package/scripts/self-sync-guard/self-sync-refusal.ts +1 -1
- package/scripts/sonar/sonar-hotspots-cli.ts +1 -1
- package/scripts/sonar/sonar-hotspots.ts +1 -1
- package/scripts/sonar/sonar-new-code-cli.ts +1 -1
- package/scripts/sonar/sonar-new-code.ts +1 -1
- package/scripts/sonar/sonar-project.ts +1 -1
- package/scripts/split/split-assess-cli.ts +1 -1
- package/scripts/split/split-assess.ts +3 -3
- package/scripts/sync/directory-copy-guard.ts +2 -3
- package/scripts/sync/managed-config-scope-cli.ts +1 -2
- package/scripts/sync/managed-config-scope.ts +4 -4
- package/scripts/sync/plugin-skill-directories.ts +2 -2
- package/scripts/sync/reconcile-templates.ts +17 -8
- package/scripts/sync/removed-skill-manifest.ts +2 -3
- package/scripts/sync/sync-ai-files.ts +7 -7
- package/scripts/sync/sync-configs.ts +30 -3
- package/scripts/sync/sync-hook-safety.ts +2 -2
- package/scripts/sync/sync.ts +23 -10
- package/scripts/sync/synced-paths.ts +2 -1
- package/scripts/sync/workflow-pin-logic.ts +1 -1
- package/scripts/test/test-declared-changed.ts +4 -4
- package/scripts/test/test-declared-logic.ts +2 -3
- package/scripts/test/test-declared-match.ts +25 -4
- package/scripts/test/test-declared.ts +26 -9
- package/scripts/test/test-red-commit.ts +3 -2
- package/scripts/test/test-red-logic.ts +7 -14
- package/scripts/test/test-red.ts +12 -47
- package/scripts/test/test-related-scope.ts +2 -3
- package/scripts/test/test-related.ts +3 -3
- package/scripts/test/test-type-logic.ts +1 -2
- package/scripts/test/test-unit-guard.ts +13 -17
- package/scripts/test/unit-worker-share.ts +7 -8
- package/scripts/time-runtime/time-agent-bundles.ts +2 -4
- package/scripts/time-runtime/time-background.ts +17 -21
- package/scripts/time-runtime/time-batch-guard.ts +67 -342
- package/scripts/time-runtime/time-bundle-call.ts +26 -28
- package/scripts/time-runtime/time-bundles.ts +11 -12
- package/scripts/time-runtime/time-call-identity.ts +1 -1
- package/scripts/time-runtime/time-command-key.ts +2 -2
- package/scripts/time-runtime/time-density-hook.ts +8 -11
- package/scripts/time-runtime/time-density.ts +5 -5
- package/scripts/time-runtime/time-followup-stage.ts +7 -7
- package/scripts/time-runtime/time-format.ts +5 -5
- package/scripts/time-runtime/time-hook-transcript.ts +3 -3
- package/scripts/time-runtime/time-instant.ts +1 -1
- package/scripts/time-runtime/time-markers.ts +15 -19
- package/scripts/time-runtime/time-phase-names.ts +3 -3
- package/scripts/time-runtime/time-reported-failure.ts +15 -19
- package/scripts/time-runtime/time-round-trips.ts +20 -23
- package/scripts/time-runtime/time-shell.ts +8 -8
- package/scripts/time-runtime/time-single-check.ts +1 -2
- package/scripts/time-runtime/time-spans.ts +35 -40
- package/scripts/time-runtime/time-tool-call.ts +15 -16
- package/scripts/time-runtime/time-transcript-line.ts +53 -34
- package/scripts/time-runtime/time-writes.ts +5 -5
- package/scripts/ui/ui-routes-cli.ts +1 -2
- package/scripts/ui/ui-routes.ts +1 -2
- package/scripts/version/bump-version.ts +1 -1
- package/scripts/version/fresh-metadata-cache.ts +2 -2
- package/scripts/version/latest-corepack.ts +26 -26
- package/scripts/version/latest-lane-guard.ts +1 -1
- package/scripts/version/latest-scope-cli.ts +2 -2
- package/scripts/version/latest-stamp.ts +1 -2
- package/scripts/version/latest-update.ts +2 -2
- package/scripts/version/npm-registry.ts +2 -2
- package/scripts/version/package-manager-version.ts +18 -0
- package/scripts/version/publishable-range-check.ts +2 -1
- package/scripts/version/publishable-range.ts +1 -1
- package/scripts/version/release-age.ts +11 -11
- package/scripts/version/release-hold.ts +2 -2
- package/scripts/version/safe-chain-version-update.ts +3 -3
- package/scripts/version/version-check-logic.ts +2 -3
- package/scripts/version/version-check.ts +1 -2
- package/scripts/version/version-command-config.ts +2 -2
- package/scripts/version/version-commands.ts +3 -3
- package/scripts/version/version-remote.ts +4 -4
- package/scripts/version/version-targets.ts +2 -2
- package/templates/gitignore +7 -0
- package/dist/hooks/chunk-KHX4U3BG.js +0 -6400
- package/dist/hooks/chunk-RKUAD3I6.js +0 -90
- package/dist/hooks/chunk-WPALEIRX.js +0 -18
- package/scripts/backlog/backlog-restructure.ts +0 -152
- package/scripts/rules/issue-fold-rule.ts +0 -72
- package/scripts/rules/wip-cap.ts +0 -63
- package/scripts/run/run-issue-number.ts +0 -19
|
@@ -3,154 +3,63 @@ import { backlog_budget } from '#scripts/backlog/backlog-budget'
|
|
|
3
3
|
import { process_identity } from '#scripts/josh/process-identity'
|
|
4
4
|
import { process_owner_schema } from '#scripts/josh/process-owner'
|
|
5
5
|
import { stamp_file } from '#scripts/josh/stamp-file'
|
|
6
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
6
7
|
import type { CarryRead } from '#scripts/run/carry/run-carry'
|
|
7
8
|
import { z } from 'zod'
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
// This is that starter — a process outside the conversation, which the cut does not end.
|
|
16
|
-
//
|
|
17
|
-
// **Whether to wake is the record's answer, never a judgement.** `carried` *and* handed off is the one
|
|
18
|
-
// state that wakes; `none`, `expired` and `unreadable` stop the supervisor. So the 8-hour whole-run
|
|
19
|
-
// bound needs no check of its own here: it **is** the carry record's expiry, so a run past it reads
|
|
20
|
-
// `expired` and the supervisor stops (`run-carry.ts` → `CARRY_MAX_AGE_MS`, itself imported from
|
|
21
|
-
// `backlog-budget.ts` rather than restated). A bound re-derived here is one that drifts, and it drifts
|
|
22
|
-
// silently in the direction that matters — the supervisor would go on waking past a budget the record
|
|
23
|
-
// already calls spent.
|
|
24
|
-
//
|
|
25
|
-
// **A hand-off is what separates a cut from a session that is simply working.** `is_handed_off` is set
|
|
26
|
-
// by `run:carry --cut`, and by this supervisor only when it recovers a record whose owner has *died*
|
|
27
|
-
// (`run-wake-handoff.ts`, joshuafolkken/kit#2437) — so a live session's record never reads as waiting to
|
|
28
|
-
// be woken, and a crash is carried on as if the dead session had cut rather than left standing.
|
|
29
|
-
//
|
|
30
|
-
// **The supervisor owns the record while its deterministic driver spends the budget.** After a cut or
|
|
31
|
-
// dead-owner recovery it adopts the record as this process, so `run:merge` has one live owner to
|
|
32
|
-
// count against. A judgment branch first hands the record off; `classify_claim` reads that explicit
|
|
33
|
-
// handoff before liveness, allowing one AI session to adopt it even while the supervisor is alive.
|
|
34
|
-
// The supervisor does not keep running the driver while that session owns the record.
|
|
10
|
+
// The process outside the conversation that starts the next session after a `backlogrun` cut.
|
|
11
|
+
// Whether to wake is the carry record's answer, never a judgement: `carried` and handed off wakes;
|
|
12
|
+
// `none`, `expired` (the whole-run bound) and `unreadable` stop. A hand-off is set by `run:carry --cut`,
|
|
13
|
+
// or by this supervisor when it recovers a record whose owner died, so a live session never reads as
|
|
14
|
+
// waiting. The supervisor owns the record while its deterministic driver spends the budget; a judgment
|
|
15
|
+
// branch hands it off so one AI session can adopt it.
|
|
35
16
|
|
|
36
17
|
const WAKE_PREFIX = 'josh-run-wake-'
|
|
37
|
-
//
|
|
38
|
-
// `detached` is what puts a child outside the conversation; discarding its output was a second choice
|
|
39
|
-
// riding along with it, and the two are separate requirements. Discarded, a session that exits without
|
|
40
|
-
// claiming the carry record leaves nothing at all to diagnose it by — which is the state
|
|
41
|
-
// joshuafolkken/kit#1746 was filed from, where three sessions died silently and the record could say
|
|
42
|
-
// only that none of them had arrived.
|
|
43
|
-
//
|
|
44
|
-
// One file per repository, appended to, so every attempt of every cut is in one place; keyed exactly
|
|
45
|
-
// as the wake and carry records are, so the three are found together. `.log` rather than `.json`
|
|
46
|
-
// because it holds another process's output verbatim — the distinction `stamp_file.stamp_path`'s
|
|
47
|
-
// `suffix` argument exists for.
|
|
18
|
+
// The output of every session this starts, appended per repository so a silent death is diagnosable.
|
|
48
19
|
const WAKE_LOG_PREFIX = 'josh-run-wake-log-'
|
|
49
20
|
const WAKE_LOG_SUFFIX = '.log'
|
|
50
|
-
// How long a woken session has to claim the carry record
|
|
51
|
-
//
|
|
52
|
-
// **The window is measured from the spawn, so it has to cover everything before the session's first
|
|
53
|
-
// `run:carry --begin`** — the agent CLI's cold start, the resident preamble, and reading `SKILL.md`,
|
|
54
|
-
// `backlogrun.md`, `backlogrun.md` and the `fullrun` set. Ten minutes is several times the observed cost
|
|
55
|
-
// of that and still far inside the roughly 50-minute cut interval this exists to bridge. It was two
|
|
56
|
-
// minutes first, which is inside the range a merely *slow* start occupies — and a slow start booked as
|
|
57
|
-
// a failure ends the whole overnight run.
|
|
58
|
-
//
|
|
59
|
-
// **This one window is the only launch-failure detector, deliberately.** Reading the spawned process's
|
|
60
|
-
// exit code would catch a missing binary and miss the two failures that actually recur — a session
|
|
61
|
-
// that starts and dies during boot, and one that runs but never picks the run up. Asking instead
|
|
62
|
-
// whether the record was claimed catches all three, because it tests the thing that was wanted rather
|
|
63
|
-
// than the thing that was easy to observe.
|
|
21
|
+
// How long a woken session has to claim the carry record — the only launch-failure detector, since a
|
|
22
|
+
// claim also catches a session that dies in boot or never picks the run up. It covers a slow cold start.
|
|
64
23
|
const WAKE_GRACE_MS = 600_000
|
|
65
|
-
//
|
|
66
|
-
// it ends a run nobody is watching, for the night. Three attempts against a ten-minute window is
|
|
67
|
-
// half an hour of trying, which outlasts every transient cause worth surviving; past that the cause
|
|
68
|
-
// is not transient and a person has to see it.
|
|
24
|
+
// Retried before failing: stopping ends a run nobody is watching.
|
|
69
25
|
const MAX_WAKE_ATTEMPTS = 3
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
// drain, the retrospective and `run:carry --end` are a session's to do, not this process's — so a
|
|
73
|
-
// deferral without a ceiling would leave the record carried until its 8-hour expiry and end on a
|
|
74
|
-
// warning instead of a report. The ceiling is the `backlogrun` idle watch's own default, imported
|
|
75
|
-
// rather than restated: the supervisor watches the empty backlog for exactly as long as a woken session
|
|
76
|
-
// would have, only without paying a session to do it.
|
|
26
|
+
// An empty backlog still needs one session to finish the run, so a deferral is bounded by the
|
|
27
|
+
// `backlogrun` idle watch's own default.
|
|
77
28
|
const IDLE_CEILING_MS = backlog_budget.DEFAULT_IDLE_MS
|
|
78
29
|
const NO_WAKES = 0
|
|
79
30
|
const ONE_WAKE = 1
|
|
80
31
|
|
|
81
|
-
// The supervisor's own record: which invocation it is watching, which process it is, and how many
|
|
82
|
-
// times it has woken a session.
|
|
83
32
|
interface RunWake {
|
|
84
|
-
// Copied from the carry record at `--start
|
|
85
|
-
// continued. It is what the woken session is handed as its prompt.
|
|
33
|
+
// Copied from the carry record at `--start`; it is the woken session's prompt.
|
|
86
34
|
invocation: string
|
|
87
35
|
profile?: AgentProfile | undefined
|
|
88
36
|
started_at: string
|
|
89
|
-
//
|
|
90
|
-
// this one is read: `--list` reports whether the supervisor is still running and `--stop` needs
|
|
91
|
-
// something to signal. The start-time token is what tells a reissued pid from the original.
|
|
37
|
+
// Read back by `--list` and `--stop`; the start-time token tells a reissued pid from the original.
|
|
92
38
|
pid: number
|
|
93
39
|
process_start?: string | undefined
|
|
94
|
-
//
|
|
95
|
-
//
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
// **A recovery is a wake without a cut, so `woke` may run ahead of `cuts`** (joshuafolkken/kit#2336).
|
|
99
|
-
// When a session claims the record and then dies without cutting, the supervisor re-wakes and the
|
|
100
|
-
// replacement's claim is counted here too — so `woke == cuts` becomes `woke >= cuts`, the gap being
|
|
101
|
-
// the recoveries whose replacement claim a poll observed. `woke < cuts` still means a cut went
|
|
102
|
-
// unserved, and `outstanding_line` remains the authoritative signal of a launch not yet claimed.
|
|
103
|
-
//
|
|
104
|
-
// **A cut is served when the woken session claims the carry record, not when a process starts**
|
|
105
|
-
// (joshuafolkken/kit#1746). Counted at the spawn, the number asserted the very thing the supervisor
|
|
106
|
-
// had not yet checked: on 2026-09-10 three sessions were launched for one cut and none of them ever
|
|
107
|
-
// claimed the record, while `--list` went on reporting `woke 1 session(s) across 1 cut(s)` for forty
|
|
108
|
-
// minutes — the published invariant reading as held throughout the failure it exists to expose. So
|
|
109
|
-
// the increment moved to the one pass that observes a claim, and a wake nobody claimed now leaves
|
|
110
|
-
// `woke` behind `cuts`, which is what the invariant was always meant to say.
|
|
111
|
-
//
|
|
112
|
-
// **It is observed at a poll, so it lags a claim by up to one polling interval** — a minute by
|
|
113
|
-
// default. A shortfall read within that window is a claim not yet seen rather than one that never
|
|
114
|
-
// happened, and the two are told apart by `attempts`: a cut still being retried has launches
|
|
115
|
-
// outstanding, and one already claimed has none.
|
|
40
|
+
// Cuts served, counted when a woken session claims the record (not at the spawn), so an unclaimed
|
|
41
|
+
// wake leaves `woke` behind `cuts`. A dead-owner recovery is a wake without a cut, so `woke >= cuts`.
|
|
42
|
+
// Observed at a poll, so it lags a claim by up to one interval.
|
|
116
43
|
woke: number
|
|
117
|
-
//
|
|
118
|
-
// presence is what the grace window above is measured from.
|
|
44
|
+
// The grace window is measured from this; cleared when the woken session claims the record.
|
|
119
45
|
woke_at?: string | undefined
|
|
120
|
-
// Launches for the cut
|
|
121
|
-
// from `woke` so a retried cut still reports as one wake against one cut — and, since
|
|
122
|
-
// joshuafolkken/kit#1746, so the two say different things: this counts what was started and `woke`
|
|
123
|
-
// counts what arrived, which is the gap a silent failure lives in.
|
|
46
|
+
// Launches for the current cut: what was started, against `woke`'s what arrived.
|
|
124
47
|
attempts?: number | undefined
|
|
125
|
-
//
|
|
126
|
-
// session that is merely slow is still doing the run's work, and a supervisor that killed what it
|
|
127
|
-
// could not account for would destroy exactly the work it exists to keep going.
|
|
48
|
+
// Named in the failure warning, never killed — a slow session is still doing the run's work.
|
|
128
49
|
woke_pid?: number | undefined
|
|
129
|
-
//
|
|
130
|
-
// (joshuafolkken/kit#2407). `josh time --run` attributes a whiff only to a session in this list, so
|
|
131
|
-
// an unrelated read-only session that moved while the supervisor was alive is no longer counted
|
|
132
|
-
// against the wake role — the $7.68 the Issue read as a ceiling becomes the real figure. Appended
|
|
133
|
-
// once per launch, retries included, since each retry is a real session that woke and may have done
|
|
134
|
-
// nothing, and carried across a supervisor restart exactly like the counters beside it.
|
|
50
|
+
// Every `--session-id` this forced, so `josh time --run` attributes whiffs only to its own sessions.
|
|
135
51
|
spawned?: ReadonlyArray<string> | undefined
|
|
136
|
-
//
|
|
137
|
-
// Marked once and cleared by the next launch or claim, so it measures one unbroken idle stretch: it
|
|
138
|
-
// bounds the deferral at `IDLE_CEILING_MS`, and `run-wake-loop.ts` stretches the polling interval
|
|
139
|
-
// by it, which is the back-off after repeated whiffs.
|
|
52
|
+
// Start of one unbroken idle stretch: bounds the deferral and backs off the polling interval.
|
|
140
53
|
idle_since?: string | undefined
|
|
141
54
|
}
|
|
142
55
|
|
|
143
56
|
type WakeStopReason = 'ended' | 'expired' | 'unreadable' | 'failed' | 'stopped'
|
|
144
57
|
|
|
145
|
-
//
|
|
146
|
-
// `--stop`, `removed` the ordinary end of a loop, and `superseded` the one that has to be said out
|
|
147
|
-
// loud: another supervisor holds the record and this process is the replaced one.
|
|
58
|
+
// `superseded`: another supervisor holds the record and this process is the replaced one.
|
|
148
59
|
type WakeTidyResult = 'absent' | 'removed' | 'superseded'
|
|
149
60
|
|
|
150
|
-
// `wait` and `pending`
|
|
151
|
-
//
|
|
152
|
-
// forget it had already woken and wake again every interval. `idle` is a launch the record called for
|
|
153
|
-
// and the work did not: nothing is started, and the stretch is marked so it can be bounded.
|
|
61
|
+
// `wait` clears the wake mark and `pending` keeps it, or a supervisor would re-wake every interval.
|
|
62
|
+
// `idle` is a launch the record called for and the work did not.
|
|
154
63
|
type WakeDecision =
|
|
155
64
|
| { kind: 'wake' }
|
|
156
65
|
| { kind: 'idle' }
|
|
@@ -163,24 +72,11 @@ interface WakeDecisionInput {
|
|
|
163
72
|
read: CarryRead
|
|
164
73
|
woke_at: string | undefined
|
|
165
74
|
attempts: number
|
|
166
|
-
//
|
|
167
|
-
// handed off, where it tells a session at work from a crashed one (`decide_not_handed_off`).
|
|
168
|
-
//
|
|
169
|
-
// **A handed-off record is launched from whether its cutting process lives or not**
|
|
170
|
-
// (joshuafolkken/kit#3363). The supervisor used to wait that process out, for up to the grace
|
|
171
|
-
// window, because `run-carry.ts` → `classify_claim` once tested liveness before the hand-off and
|
|
172
|
-
// would have answered the successor `busy`. joshuafolkken/kit#1935 put the hand-off first, so the
|
|
173
|
-
// wait guarded nothing — and an interactive session outlives its own cut, so every cut paid the
|
|
174
|
-
// whole ten minutes before the driver started.
|
|
75
|
+
// Read only for a record no cut handed off; a handed-off record launches whether its cutter lives or not.
|
|
175
76
|
is_owner_live: boolean
|
|
176
|
-
//
|
|
177
|
-
//
|
|
178
|
-
// runnable issue or a lane was free — and a session that found nothing ended without touching
|
|
179
|
-
// anything, which is the whiff. `undefined` is "cannot tell", and it wakes: a failed read is not an
|
|
180
|
-
// empty backlog, and the error that costs a whiff is cheaper than the one that stalls the run.
|
|
181
|
-
// Optional for that reason: an input that does not say reads exactly as the record-only decision did.
|
|
77
|
+
// Whether a woken session would find work. `undefined` ("cannot tell") wakes: a whiff is cheaper
|
|
78
|
+
// than a stalled run.
|
|
182
79
|
has_work?: boolean | undefined
|
|
183
|
-
// When the current idle stretch began, so the deferral can be bounded.
|
|
184
80
|
idle_since?: string | undefined
|
|
185
81
|
now: Date
|
|
186
82
|
}
|
|
@@ -191,9 +87,6 @@ const WAIT_DECISION: WakeDecision = { kind: 'wait' }
|
|
|
191
87
|
const PENDING_DECISION: WakeDecision = { kind: 'pending' }
|
|
192
88
|
const FAILED_DECISION: WakeDecision = { kind: 'failed' }
|
|
193
89
|
|
|
194
|
-
// The three carry reads that are not `carried`, each mapped to why the supervisor stops. `none` is the
|
|
195
|
-
// run having ended normally (`run:carry --end`); `expired` is the whole-run bound; `unreadable` is a
|
|
196
|
-
// record that cannot be trusted to say anything, which is a reason to stop rather than to guess.
|
|
197
90
|
const STOP_REASONS: Record<'none' | 'expired' | 'unreadable', WakeStopReason> = {
|
|
198
91
|
none: 'ended',
|
|
199
92
|
expired: 'expired',
|
|
@@ -205,9 +98,7 @@ const run_wake_schema = process_owner_schema.extend({
|
|
|
205
98
|
started_at: z.string(),
|
|
206
99
|
woke: z.number(),
|
|
207
100
|
woke_at: z.string().optional(),
|
|
208
|
-
//
|
|
209
|
-
// declare, so a field added to the interface alone round-trips through disk as `undefined` — which
|
|
210
|
-
// reads as "no attempt has been made yet" and would restart the retry count on every pass.
|
|
101
|
+
// Every optional `RunWake` field must be listed: `z.object` strips undeclared ones on the round trip.
|
|
211
102
|
attempts: z.number().optional(),
|
|
212
103
|
woke_pid: z.number().optional(),
|
|
213
104
|
spawned: z.array(z.string()).optional(),
|
|
@@ -215,8 +106,7 @@ const run_wake_schema = process_owner_schema.extend({
|
|
|
215
106
|
profile: agent_role_profile.PROFILE_SCHEMA.optional(),
|
|
216
107
|
})
|
|
217
108
|
|
|
218
|
-
// An unparsable stamp
|
|
219
|
-
// is one that cannot be confirmed to have worked, and the safe direction is to report the failure.
|
|
109
|
+
// An unparsable stamp is overdue: a mark that cannot be confirmed is reported as a failure.
|
|
220
110
|
function is_overdue(marked_at: string, now: Date, limit_ms: number = WAKE_GRACE_MS): boolean {
|
|
221
111
|
const marked = Date.parse(marked_at)
|
|
222
112
|
|
|
@@ -225,10 +115,8 @@ function is_overdue(marked_at: string, now: Date, limit_ms: number = WAKE_GRACE_
|
|
|
225
115
|
return now.getTime() - marked > limit_ms
|
|
226
116
|
}
|
|
227
117
|
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
// recovery of a dead owner and a retry alike — because a retry into an empty backlog is the same whiff
|
|
231
|
-
// as a first wake into one. Past the ceiling the session is woken anyway, to finish the run.
|
|
118
|
+
// The one gate every launch (first wake, recovery, retry) passes: launch only where there is work, or
|
|
119
|
+
// once the idle stretch passes its ceiling.
|
|
232
120
|
function launch_or_idle(input: WakeDecisionInput): WakeDecision {
|
|
233
121
|
if (input.has_work !== false) return WAKE_DECISION
|
|
234
122
|
if (input.idle_since === undefined) return IDLE_DECISION
|
|
@@ -236,12 +124,7 @@ function launch_or_idle(input: WakeDecisionInput): WakeDecision {
|
|
|
236
124
|
return is_overdue(input.idle_since, input.now, IDLE_CEILING_MS) ? WAKE_DECISION : IDLE_DECISION
|
|
237
125
|
}
|
|
238
126
|
|
|
239
|
-
//
|
|
240
|
-
// places — a record a cut handed off whose predecessor has gone, and a record no cut handed off whose
|
|
241
|
-
// owner has *died* (the recovery below) — because both ask the same question once the decision to press
|
|
242
|
-
// on has been made: is a wake already out, is it still inside its grace window, and are there retries
|
|
243
|
-
// left. `woke_at === undefined` is "nothing outstanding, launch"; inside the window is `pending`; past
|
|
244
|
-
// it, a retry while attempts remain and otherwise `failed`.
|
|
127
|
+
// Launch, pend, retry or give up, read from the wake mark alone.
|
|
245
128
|
function decide_launch(input: WakeDecisionInput): WakeDecision {
|
|
246
129
|
if (input.woke_at === undefined) return launch_or_idle(input)
|
|
247
130
|
if (!is_overdue(input.woke_at, input.now)) return PENDING_DECISION
|
|
@@ -249,26 +132,14 @@ function decide_launch(input: WakeDecisionInput): WakeDecision {
|
|
|
249
132
|
return input.attempts < MAX_WAKE_ATTEMPTS ? launch_or_idle(input) : FAILED_DECISION
|
|
250
133
|
}
|
|
251
134
|
|
|
252
|
-
//
|
|
253
|
-
//
|
|
254
|
-
// state, and there is nothing to do but wait. A *dead* owner is the defect this branch exists for: a
|
|
255
|
-
// session that claimed the record and then exited without cutting or ending — a woken session that
|
|
256
|
-
// crashed during boot, reported its state and stopped, or was ended by a stray notification — leaves
|
|
257
|
-
// the record `carried`, owned by a gone process, with no hand-off. Before this the supervisor answered
|
|
258
|
-
// `wait` to both and so waited on the dead one until the 8-hour bound, stopping the whole run in
|
|
259
|
-
// silence. Now a dead owner is recovered through the same grace/retry machinery a hand-off uses, so a
|
|
260
|
-
// crash between the claim and the next cut re-wakes rather than stranding the invocation.
|
|
261
|
-
//
|
|
262
|
-
// **`is_owner_live` is `!== false`, so "cannot tell" counts as living** (`run-carry.ts` →
|
|
263
|
-
// `is_owner_live`): a liveness read that cannot prove death keeps the safe answer, `wait`, and never
|
|
264
|
-
// double-wakes a session that is merely unreadable.
|
|
135
|
+
// A live owner is a session at work; a dead one crashed between its claim and the next cut, and is
|
|
136
|
+
// recovered through the hand-off's grace/retry path. "Cannot tell" counts as living.
|
|
265
137
|
function decide_not_handed_off(input: WakeDecisionInput): WakeDecision {
|
|
266
138
|
if (input.is_owner_live) return WAIT_DECISION
|
|
267
139
|
|
|
268
140
|
return decide_launch(input)
|
|
269
141
|
}
|
|
270
142
|
|
|
271
|
-
// The whole policy, in three lines. Nothing else in this module decides whether to wake.
|
|
272
143
|
function decide(input: WakeDecisionInput): WakeDecision {
|
|
273
144
|
if (input.read.kind !== 'carried') return { kind: 'stop', reason: STOP_REASONS[input.read.kind] }
|
|
274
145
|
if (input.read.carry.is_handed_off !== true) return decide_not_handed_off(input)
|
|
@@ -276,24 +147,17 @@ function decide(input: WakeDecisionInput): WakeDecision {
|
|
|
276
147
|
return decide_launch(input)
|
|
277
148
|
}
|
|
278
149
|
|
|
279
|
-
// Keyed on the
|
|
280
|
-
// invocation, and every lane of that repository keys alike. `run_carry.repository_directory` is what
|
|
281
|
-
// resolves it, so the two records can never key differently.
|
|
150
|
+
// Keyed on the common git directory exactly as the carry record is, so every lane keys alike.
|
|
282
151
|
function wake_path(git_directory: string): string {
|
|
283
152
|
return stamp_file.stamp_path(WAKE_PREFIX, git_directory)
|
|
284
153
|
}
|
|
285
154
|
|
|
286
|
-
// Keyed on the same directory as the two records, so a person handed one path can find the others.
|
|
287
155
|
function wake_log_path(git_directory: string): string {
|
|
288
156
|
return stamp_file.stamp_path(WAKE_LOG_PREFIX, git_directory, WAKE_LOG_SUFFIX)
|
|
289
157
|
}
|
|
290
158
|
|
|
291
159
|
function parse_wake(raw: string): RunWake | undefined {
|
|
292
|
-
|
|
293
|
-
return run_wake_schema.parse(JSON.parse(raw))
|
|
294
|
-
} catch {
|
|
295
|
-
return undefined
|
|
296
|
-
}
|
|
160
|
+
return json_value.parse_with(raw, run_wake_schema)
|
|
297
161
|
}
|
|
298
162
|
|
|
299
163
|
function read_wake(target: string): RunWake | undefined {
|
|
@@ -320,23 +184,13 @@ function fresh_wake(invocation: string, now: Date, profile?: AgentProfile): RunW
|
|
|
320
184
|
}
|
|
321
185
|
}
|
|
322
186
|
|
|
323
|
-
//
|
|
324
|
-
// supervisor read as dead means two supervisors waking two sessions into one budget, while a dead one
|
|
325
|
-
// read as live costs a refused `--start` the person can retry after `--stop`. This takes the second.
|
|
187
|
+
// "Cannot tell" counts as running: a refused `--start` is cheaper than two supervisors on one budget.
|
|
326
188
|
function is_supervisor_live(wake: RunWake): boolean {
|
|
327
189
|
return process_identity.is_same_process(wake.pid, wake.process_start) !== false
|
|
328
190
|
}
|
|
329
191
|
|
|
330
|
-
// A
|
|
331
|
-
//
|
|
332
|
-
// that reset it would make `--list` under-report and the published check read as a defect that never
|
|
333
|
-
// happened. **`woke_at` and `attempts` come with it, and dropping them is not cosmetic**: a restart
|
|
334
|
-
// inside the grace window would otherwise see no wake mark, launch a second session for the *same*
|
|
335
|
-
// cut, count it as another cut served, and leave two sessions racing for one record. The invocation
|
|
336
|
-
// has to match — a different one is a different run, and its state is not this one's.
|
|
337
|
-
// **`woke_pid` comes across too.** Without it, a restart inside the grace window that then spends its
|
|
338
|
-
// retries reports "the last one was none" in the warning — the one fact the warning exists to hand the
|
|
339
|
-
// person, dropped exactly where it is needed.
|
|
192
|
+
// A restart of the same invocation inherits the whole wake state, or it would re-wake a cut inside
|
|
193
|
+
// its grace window and under-report `woke` against `cuts`.
|
|
340
194
|
function carried_state(existing: RunWake | undefined, invocation: string): Partial<RunWake> {
|
|
341
195
|
if (existing?.invocation !== invocation) return { woke: NO_WAKES }
|
|
342
196
|
|
|
@@ -345,11 +199,7 @@ function carried_state(existing: RunWake | undefined, invocation: string): Parti
|
|
|
345
199
|
woke_at: existing.woke_at,
|
|
346
200
|
attempts: existing.attempts,
|
|
347
201
|
woke_pid: existing.woke_pid,
|
|
348
|
-
// **`spawned` carries across too, or a restart mid-run would lose the ids of every session it
|
|
349
|
-
// already started** (joshuafolkken/kit#2407) — and `josh time --run`, reading the record after
|
|
350
|
-
// the restart, would under-count the whiffs and read the loss as a saving.
|
|
351
202
|
spawned: existing.spawned,
|
|
352
|
-
// And `idle_since`, or a restart would slide the idle ceiling by the time already spent idle.
|
|
353
203
|
idle_since: existing.idle_since,
|
|
354
204
|
...(existing.profile && { profile: existing.profile }),
|
|
355
205
|
}
|
|
@@ -359,9 +209,7 @@ function is_held_by_live_supervisor(existing: RunWake | undefined): boolean {
|
|
|
359
209
|
return existing !== undefined && is_supervisor_live(existing)
|
|
360
210
|
}
|
|
361
211
|
|
|
362
|
-
//
|
|
363
|
-
// `unit-worker-share.ts` does for the unit-suite share, and then one more exclusive create. The record
|
|
364
|
-
// is re-read first, because between the two creates it may have become a live supervisor's.
|
|
212
|
+
// Sweep a dead marker and create once more, re-reading first in case a live supervisor took it.
|
|
365
213
|
function reclaim(target: string, wake: RunWake): RunWake | undefined {
|
|
366
214
|
if (is_held_by_live_supervisor(read_wake(target))) return undefined
|
|
367
215
|
|
|
@@ -370,15 +218,8 @@ function reclaim(target: string, wake: RunWake): RunWake | undefined {
|
|
|
370
218
|
return stamp_file.create_stamp(target, wake) ? wake : undefined
|
|
371
219
|
}
|
|
372
220
|
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
// **The create is attempted before anything is removed, and that ordering is the exclusion.** Sweeping
|
|
377
|
-
// first — which this did, unconditionally — gives the exclusive create nothing to exclude: two claims
|
|
378
|
-
// that both read an empty target would each delete what the other had just created, and both would
|
|
379
|
-
// then succeed, leaving two supervisors waking two sessions into one carry budget. Attempted first, the
|
|
380
|
-
// create is what decides between them, and the sweep runs only where it found something already there
|
|
381
|
-
// — including a stamp that could not be parsed at all, which is why the sweep is not simply dropped.
|
|
221
|
+
// The exclusive create runs before any sweep — that ordering is what stops two racing `--start`s
|
|
222
|
+
// from both owning the record.
|
|
382
223
|
function claim(
|
|
383
224
|
target: string,
|
|
384
225
|
invocation: string,
|
|
@@ -394,13 +235,7 @@ function claim(
|
|
|
394
235
|
return stamp_file.create_stamp(target, wake) ? wake : reclaim(target, wake)
|
|
395
236
|
}
|
|
396
237
|
|
|
397
|
-
// A launch marks the attempt and
|
|
398
|
-
// started has not yet done the thing `woke` counts — `count_claim` is where that is decided.
|
|
399
|
-
//
|
|
400
|
-
// **The forced session id is recorded here, at the launch, because that is where it is known**
|
|
401
|
-
// (joshuafolkken/kit#2407). It is appended rather than replaced: a run spawns one session per cut plus
|
|
402
|
-
// one per retry, and `josh time --run` needs every id to tell a session it started from an unrelated
|
|
403
|
-
// one that merely moved while it was alive.
|
|
238
|
+
// A launch marks the attempt and appends its session id; `woke` waits for `count_claim`.
|
|
404
239
|
function count_wake(wake: RunWake, now: Date, pid: number, session_id: string): RunWake {
|
|
405
240
|
const attempts = (wake.attempts ?? NO_WAKES) + ONE_WAKE
|
|
406
241
|
const spawned = [...(wake.spawned ?? []), session_id]
|
|
@@ -416,24 +251,13 @@ function count_wake(wake: RunWake, now: Date, pid: number, session_id: string):
|
|
|
416
251
|
}
|
|
417
252
|
}
|
|
418
253
|
|
|
419
|
-
//
|
|
420
|
-
// rewritten each pass, the ceiling would slide and never be reached.
|
|
254
|
+
// Marked once: rewritten each pass, the ceiling would slide and never be reached.
|
|
421
255
|
function mark_idle(wake: RunWake, now: Date): RunWake {
|
|
422
256
|
return wake.idle_since === undefined ? { ...wake, idle_since: now.toISOString() } : wake
|
|
423
257
|
}
|
|
424
258
|
|
|
425
|
-
//
|
|
426
|
-
//
|
|
427
|
-
// off, which `run-carry.ts` → `adopt_carry` does only from the session that took the record over — so
|
|
428
|
-
// the count is of records actually claimed rather than of processes started.
|
|
429
|
-
//
|
|
430
|
-
// **The mark is what says a wake was outstanding.** Without it this same state is an ordinary live
|
|
431
|
-
// session working through its budget, which no supervisor woke and which must not be counted; with
|
|
432
|
-
// it, the wake that was pending has just been answered.
|
|
433
|
-
//
|
|
434
|
-
// `undefined` rather than a deleted key, because `JSON.stringify` drops it on the way to disk and the
|
|
435
|
-
// reader treats absent and undefined alike — the same round-trip `run-carry.ts` documents for its own
|
|
436
|
-
// optional fields.
|
|
259
|
+
// The one place `woke` grows: the record was claimed while a wake mark was outstanding. Without the
|
|
260
|
+
// mark this is an ordinary live session, which no supervisor woke.
|
|
437
261
|
function count_claim(wake: RunWake): RunWake {
|
|
438
262
|
const woke = wake.woke_at === undefined ? wake.woke : wake.woke + ONE_WAKE
|
|
439
263
|
|
|
@@ -446,59 +270,23 @@ function count_claim(wake: RunWake): RunWake {
|
|
|
446
270
|
}
|
|
447
271
|
}
|
|
448
272
|
|
|
449
|
-
//
|
|
450
|
-
//
|
|
451
|
-
//
|
|
452
|
-
// **Existence was standing in for ownership, and the two come apart exactly when it matters.** A
|
|
453
|
-
// `--stop` that removes the record but does not reach the process — `EPERM`, or a liveness read that
|
|
454
|
-
// calls a running process dead — followed by a person's `--start` leaves the old loop awake beside a
|
|
455
|
-
// new supervisor's record. Asked only whether *a* record is there, the old loop writes its own pid
|
|
456
|
-
// and counters into the new one, and two supervisors then wake two sessions into one carry budget:
|
|
457
|
-
// the state `claim`'s exclusive create exists to prevent, reached after the create rather than
|
|
458
|
-
// through it. Asked whether the record is *its own*, it finds it is not and does nothing.
|
|
459
|
-
//
|
|
460
|
-
// **The precedent is `run-carry.ts` alone**, whose `is_owned_by` compares a record's `owner_pid` and
|
|
461
|
-
// `owner_start` against the owner the caller declares, and whose `is_foreign_live_owner` is that
|
|
462
|
-
// comparison deciding what a caller may touch. `run-hold.ts` is **not** a precedent and reading it as
|
|
463
|
-
// one is the mistake this note exists to prevent: it records a pid for the person reading the stop
|
|
464
|
-
// message and explicitly never reads it back (`run-hold.ts` → `describe_holder`), which is the
|
|
465
|
-
// distinction `RunWake.pid` above already draws.
|
|
466
|
-
//
|
|
467
|
-
// The one difference from `run-carry.ts` is who the owner is. There the owner is declared from
|
|
468
|
-
// outside, because the process spending the budget is not the one writing the record; here the writer
|
|
469
|
-
// *is* the owner, so the declaration is `process_identity.own_fields()` and the comparison is against
|
|
470
|
-
// this process.
|
|
273
|
+
// Ownership, not existence, decides every write and removal: after a `--stop` that missed the process
|
|
274
|
+
// and a fresh `--start`, the old loop must not write into the new supervisor's record. The writer is
|
|
275
|
+
// the owner here, unlike `run-carry.ts` where the owner is declared from outside.
|
|
471
276
|
function is_own_wake(wake: RunWake): boolean {
|
|
472
277
|
return process_identity.is_own_process(wake.pid, wake.process_start)
|
|
473
278
|
}
|
|
474
279
|
|
|
475
|
-
//
|
|
476
|
-
// so a supervisor whose record has been taken over ends **before** it decides anything — refusing the
|
|
477
|
-
// write-back alone would still have spawned a session for a run somebody else is already watching.
|
|
280
|
+
// Read at the top of each pass, so a superseded supervisor ends before it spawns anything.
|
|
478
281
|
function read_own_wake(target: string): RunWake | undefined {
|
|
479
282
|
const wake = read_wake(target)
|
|
480
283
|
|
|
481
284
|
return wake !== undefined && is_own_wake(wake) ? wake : undefined
|
|
482
285
|
}
|
|
483
286
|
|
|
484
|
-
//
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
// happen is the loop's own tidy-up taking a live successor's record with it, which leaves the run
|
|
488
|
-
// unwatched with nothing anywhere saying so.
|
|
489
|
-
//
|
|
490
|
-
// **Read-then-remove, so a take-over landing between the two still costs the successor its record.**
|
|
491
|
-
// The same residual window `update_wake` has, and closing it needs an exclusive operation the stamp
|
|
492
|
-
// layer does not offer. What this removes is the case that was certain — the loop ending after a
|
|
493
|
-
// take-over it had already noticed — rather than the one that needs the hand-over to land inside two
|
|
494
|
-
// statements.
|
|
495
|
-
//
|
|
496
|
-
// **Three answers rather than a boolean, because the caller has to tell two of them apart.** An
|
|
497
|
-
// ordinary `--stop` and a take-over both leave this process with nothing to remove, and only the
|
|
498
|
-
// second is worth saying anything about — a `false` covering both put the caller in the position of
|
|
499
|
-
// re-deriving which one it was from a second read, which is a branch that can be written the wrong
|
|
500
|
-
// way round and would then announce a supersession on every ordinary stop. Answered here, the
|
|
501
|
-
// distinction is decided once, in the place that already holds the record.
|
|
287
|
+
// The loop's tidy-up removes only its own record (`--stop` and `reclaim` use `remove_wake` on purpose).
|
|
288
|
+
// Three answers, so the caller announces a supersession without re-reading. Read-then-remove leaves a
|
|
289
|
+
// residual window the stamp layer cannot close.
|
|
502
290
|
function tidy_own_wake(target: string): WakeTidyResult {
|
|
503
291
|
const wake = read_wake(target)
|
|
504
292
|
|
|
@@ -510,18 +298,8 @@ function tidy_own_wake(target: string): WakeTidyResult {
|
|
|
510
298
|
return 'removed'
|
|
511
299
|
}
|
|
512
300
|
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
// recreate a record a person has just deleted, leaving a supervisor that outlives its own stop; the
|
|
516
|
-
// presence check narrows that window rather than closing it outright, and what closes it is that the
|
|
517
|
-
// next pass reads the record again. The ownership check is the second half: a foreign record is
|
|
518
|
-
// never written back, however long the pass took.
|
|
519
|
-
//
|
|
520
|
-
// **That is a claim about the write and about nothing else.** A take-over landing mid-pass is still
|
|
521
|
-
// narrowed rather than closed — the pass spawns a process, so a session can go out for a cut the
|
|
522
|
-
// successor is also serving, and only the write-back that follows it is refused. What closes the
|
|
523
|
-
// window at the top of a pass is `read_own_wake`, and what closes it inside one is nothing here:
|
|
524
|
-
// this is a refusal to make the damage permanent, not a lock.
|
|
301
|
+
// Writes only where the record is still there and this process's own, so a pass never recreates a
|
|
302
|
+
// record `--stop` deleted or overwrites a successor's. A refusal to make damage permanent, not a lock.
|
|
525
303
|
function update_wake(target: string, wake: RunWake): boolean {
|
|
526
304
|
if (read_own_wake(target) === undefined) return false
|
|
527
305
|
|
|
@@ -5,9 +5,9 @@ import { execaSync } from 'execa'
|
|
|
5
5
|
|
|
6
6
|
// Where the workflows that install safe-chain on the runner live. Each carries the release and the
|
|
7
7
|
// installer's SHA-256 as workflow-level env, so one pin per file moves every "Setup safe-chain" step
|
|
8
|
-
// at once
|
|
8
|
+
// at once. The directories are scanned rather than
|
|
9
9
|
// a file list kept, so a workflow another package distributes — app-kit's `dast.yml` and `load.yml`
|
|
10
|
-
// — moves with the rest
|
|
10
|
+
// — moves with the rest; a file without the pin is never a target.
|
|
11
11
|
const WORKFLOW_DIRECTORIES = ['.github/workflows', 'templates/workflows']
|
|
12
12
|
const WORKFLOW_FILE_RE = /\.ya?ml$/u
|
|
13
13
|
// `[ \t]` rather than `\s`: under the `m` flag `\s*` would run across line ends and swallow the
|
|
@@ -27,7 +27,7 @@ function installer_url(version: string): string {
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// The local composite actions follow the workflows: kit's own pin lives in
|
|
30
|
-
// `.github/actions/setup-pnpm`, which every kit workflow installs through
|
|
30
|
+
// `.github/actions/setup-pnpm`, which every kit workflow installs through.
|
|
31
31
|
function list_workflows(): Array<string> {
|
|
32
32
|
const workflows = WORKFLOW_DIRECTORIES.filter((directory) => existsSync(directory)).flatMap(
|
|
33
33
|
(directory) =>
|
|
@@ -6,8 +6,8 @@ import { z } from 'zod'
|
|
|
6
6
|
|
|
7
7
|
// kit writes the Safe Chain `preinstall` into every project it sets up, and a package that publishes
|
|
8
8
|
// would ship it: the consumer's pnpm then refuses it as an unapproved build script and `pnpm add`
|
|
9
|
-
// exits 1
|
|
10
|
-
//
|
|
9
|
+
// exits 1. kit's own `.pnpmfile.mjs` strips it at pack time,
|
|
10
|
+
// so that one file is what a publishing project receives — never a copy of
|
|
11
11
|
// its logic.
|
|
12
12
|
//
|
|
13
13
|
// A private package is left alone: it never packs, and a new pnpmfile changes the lockfile's
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// The `preinstall` kit writes fetches nothing: it only checks that safe-chain is scanning the install
|
|
2
|
-
// and warns when it is not
|
|
2
|
+
// and warns when it is not. It used to run `pnpm dlx @aikidosec/safe-chain
|
|
3
3
|
// setup-ci`, which downloaded an unverified package on every install and — `setup-ci` acting only on
|
|
4
4
|
// a CI runner, where kit installs with `--ignore-scripts` — protected nothing. safe-chain's shell
|
|
5
5
|
// integration runs pnpm behind its registry proxy and hands `GLOBAL_AGENT_HTTP_PROXY` to it, which a
|
|
6
|
-
// bare pnpm never sets — the one signal a lifecycle script can read
|
|
6
|
+
// bare pnpm never sets — the one signal a lifecycle script can read.
|
|
7
7
|
const INSTALL_GUIDE_ANCHOR = 'installing-safe-chain'
|
|
8
8
|
const INSTALL_GUIDE_URL = `https://github.com/joshuafolkken/kit/blob/main/SECURITY.md#${INSTALL_GUIDE_ANCHOR}`
|
|
9
9
|
// `.pnpmfile.mjs` recognizes the command by the package name, so the hint names it.
|
|
@@ -4,7 +4,7 @@ const BINARY_NAME = 'osv-scanner'
|
|
|
4
4
|
const LOCKFILE_PATH = 'pnpm-lock.yaml'
|
|
5
5
|
|
|
6
6
|
// Where `josh audit:provision` puts a scanner it fetched itself, and the second place `josh audit`
|
|
7
|
-
// looks once PATH has come up empty
|
|
7
|
+
// looks once PATH has come up empty. Under `node_modules` because that is
|
|
8
8
|
// the one directory every consumer of this package already ignores: a directory of our own would
|
|
9
9
|
// need a `.gitignore` entry distributed to every repository `josh sync` reaches, and a home-relative
|
|
10
10
|
// cache is refused outright by `no-global-shim-write.test.ts`. Losing the binary to `pnpm install`
|
|
@@ -6,7 +6,7 @@ import { security_audit_logic } from './security-audit-logic'
|
|
|
6
6
|
//
|
|
7
7
|
// v2.6.0 is the floor because every earlier build parses only a fraction of pnpm-lock.yaml — the
|
|
8
8
|
// 2.5.1 and 2.3.5 scanners both read 19 of 584 packages and reported the tree clean while four High
|
|
9
|
-
// advisories sat in it
|
|
9
|
+
// advisories sat in it. A scanner below the floor is a false negative, so
|
|
10
10
|
// the provisioned version and the floor move together.
|
|
11
11
|
const SCANNER_VERSION = '2.6.0'
|
|
12
12
|
const MINIMUM_SCANNER_VERSION = SCANNER_VERSION
|
|
@@ -132,8 +132,8 @@ async function attempt(
|
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
// PATH first, but only when its scanner meets the floor: a below-floor PATH build (or a leftover
|
|
135
|
-
// managed copy from an earlier pinned version) reads a fraction of the lockfile and calls it clean
|
|
136
|
-
//
|
|
135
|
+
// managed copy from an earlier pinned version) reads a fraction of the lockfile and calls it clean,
|
|
136
|
+
// so it must not be reported as "already available" — doing so is what
|
|
137
137
|
// suppresses the fetch of a floor-meeting build. `is_executable_file` still guards the managed path
|
|
138
138
|
// so a zero-byte or non-executable leftover is never spawned just to read its version.
|
|
139
139
|
function existing_scanner(target_path: string): string | undefined {
|