@joshuafolkken/kit 1.1455.0 → 1.1514.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/settings.json +6 -6
- package/.claude/skills/dependency-update/SKILL.md +26 -55
- package/.claude/skills/epic-commands/SKILL.md +83 -156
- package/.claude/skills/epic-commands/epic-bundle.md +51 -79
- package/.claude/skills/epic-commands/execution-waves.md +43 -81
- package/.claude/skills/verify-ui/SKILL.md +24 -50
- package/.claude/skills/workflow-commands/SKILL.md +7 -9
- package/.claude/skills/workflow-commands/background-commands.md +31 -46
- package/.claude/skills/workflow-commands/backlogrun-child.md +65 -85
- package/.claude/skills/workflow-commands/backlogrun-lanes.md +86 -125
- package/.claude/skills/workflow-commands/backlogrun-park.md +68 -118
- package/.claude/skills/workflow-commands/backlogrun-progress.md +17 -28
- package/.claude/skills/workflow-commands/backlogrun-recovery.md +17 -26
- package/.claude/skills/workflow-commands/backlogrun-steps.md +35 -52
- package/.claude/skills/workflow-commands/backlogrun.md +31 -50
- package/.claude/skills/workflow-commands/chain-rule.md +31 -40
- package/.claude/skills/workflow-commands/delegation.md +12 -8
- package/.claude/skills/workflow-commands/entry-sequence.md +1 -3
- package/.claude/skills/workflow-commands/followup.md +55 -77
- package/.claude/skills/workflow-commands/fullrun-steps.md +3 -5
- package/.claude/skills/workflow-commands/fullrun.md +4 -6
- package/.claude/skills/workflow-commands/halfrun.md +3 -7
- package/.claude/skills/workflow-commands/into-target.md +1 -2
- package/.claude/skills/workflow-commands/issue-comments.md +43 -60
- package/.claude/skills/workflow-commands/issue-scout.md +3 -2
- package/.claude/skills/workflow-commands/kickoff.md +65 -74
- package/.claude/skills/workflow-commands/latest-gate.md +2 -6
- package/.claude/skills/workflow-commands/needs-human-review.md +2 -5
- package/.claude/skills/workflow-commands/observation-filing.md +59 -118
- package/.claude/skills/workflow-commands/observation-ledger.md +52 -112
- package/.claude/skills/workflow-commands/pre-gate-cut.md +88 -142
- package/.claude/skills/workflow-commands/prerequisite.md +11 -17
- package/.claude/skills/workflow-commands/progress-watcher.md +23 -33
- package/.claude/skills/workflow-commands/prrun.md +3 -5
- package/.claude/skills/workflow-commands/retrospective.md +35 -54
- package/.claude/skills/workflow-commands/split-assessment.md +32 -58
- package/.claude/skills/workflow-commands/target-repository.md +1 -2
- package/.claude/skills/workflow-commands/working-tree-hold.md +54 -73
- package/.codex/hooks.json +6 -6
- package/.github/actions/setup-node/action.yml +1 -1
- package/.github/workflows/ci.yml +1 -1
- package/.github/workflows/publish.yml +2 -2
- package/CLAUDE.md +7 -6
- package/cspell/index.yaml +7 -0
- package/dist/CLAUDE.md +7 -6
- package/dist/commands/document-section-cli.js +67 -34
- package/dist/hooks/batch-guard.js +6 -6
- package/dist/hooks/chunk-4KKD2UTK.js +66 -0
- package/dist/hooks/{chunk-GPLGZ6IC.js → chunk-6TS2JD6D.js} +14 -3
- package/dist/hooks/chunk-7DSBJVFH.js +50 -0
- package/dist/hooks/{chunk-5H4SSDSD.js → chunk-A65Y4YOR.js} +3 -3
- package/dist/hooks/{chunk-3C4XRYG6.js → chunk-APUO6U4J.js} +102 -19
- package/dist/hooks/{chunk-IX6TTTI6.js → chunk-EFXE6C37.js} +8 -22
- package/dist/hooks/chunk-GP4IEC4O.js +20 -0
- package/dist/hooks/chunk-JP45SOCJ.js +56 -0
- package/dist/hooks/{chunk-OLMO72ON.js → chunk-LAOV7NLM.js} +1 -1
- package/dist/hooks/chunk-M4HGZV7U.js +83 -0
- package/dist/hooks/{chunk-TBJFTSUY.js → chunk-O6GDRNJB.js} +9 -7
- package/dist/hooks/{chunk-HFGWYGUV.js → chunk-PF2NZL2A.js} +5 -5
- package/dist/hooks/{chunk-WNLVGT7E.js → chunk-PTICX4OL.js} +4 -5
- package/dist/hooks/{chunk-HHI6FO3R.js → chunk-RT27QRJW.js} +763 -1515
- package/dist/hooks/{chunk-7WQBPLUN.js → chunk-SYOTDYCI.js} +1149 -1095
- package/dist/hooks/{chunk-LIAFCXL7.js → chunk-TNUMY6NL.js} +1519 -1332
- package/dist/hooks/chunk-UPUZF3AN.js +279 -0
- package/dist/hooks/{chunk-Z4XI7CZS.js → chunk-WK6SMBIC.js} +1932 -784
- package/dist/hooks/codex-hook-adapter.js +17 -14
- package/dist/hooks/duplicate-read-guard.js +7 -7
- package/dist/hooks/format-edited.js +5 -4
- package/dist/hooks/inputs.json +302 -247
- package/dist/hooks/investigation-guard.js +8 -11
- package/dist/hooks/pretool-guard.js +16 -13
- package/dist/hooks/session-lang.js +372 -26
- package/dist/hooks/stop-guard.js +2593 -189
- package/dist/josh.js +2128 -282
- package/dist/managed-marker/index.js +1 -2
- package/dist/version/index.js +15 -12
- package/eslint/base.js +2 -1
- package/eslint/rules/unicorn.js +16 -0
- package/lefthook/base.yml +5 -3
- package/package.json +14 -12
- package/prompts/coding-standards.md +12 -22
- package/prompts/collaboration-workflow/file-edits.md +25 -45
- package/prompts/collaboration-workflow/gh-rest.md +19 -36
- package/prompts/collaboration-workflow/glossary.md +5 -7
- package/prompts/collaboration-workflow/issue-citation.md +6 -14
- package/prompts/collaboration-workflow/issue-template.md +40 -32
- package/prompts/collaboration-workflow/lane-instructions.md +35 -0
- package/prompts/collaboration-workflow/operating-rules.md +33 -46
- package/prompts/collaboration-workflow/output-bounds.md +15 -15
- package/prompts/collaboration-workflow/overview.md +14 -19
- package/prompts/collaboration-workflow/plan-comment.md +13 -13
- package/prompts/collaboration-workflow/principles.md +57 -54
- package/prompts/collaboration-workflow/proposal-request.md +1 -9
- package/prompts/collaboration-workflow/report-format.md +41 -49
- package/prompts/collaboration-workflow/residency.md +15 -11
- package/prompts/collaboration-workflow/rule-delivery.md +7 -15
- package/prompts/collaboration-workflow/shell-body.md +10 -20
- package/prompts/collaboration-workflow/turn-batching.md +8 -14
- package/prompts/collaboration-workflow/upstream-interrupt.md +26 -34
- package/prompts/collaboration-workflow/wip-cap.md +26 -32
- package/prompts/collaboration-workflow.md +25 -25
- package/prompts/refactoring.md +33 -43
- package/prompts/review-rubric.md +84 -129
- package/prompts/review.md +110 -141
- package/prompts/sonar-hotspot-handling.md +22 -50
- package/prompts/testing-guide.md +48 -99
- package/scripts/adopt/adopt-toolkits.ts +2 -4
- package/scripts/agent/agent-argv.ts +20 -4
- package/scripts/agent/agent-exit-record.ts +23 -1
- package/scripts/agent/agent-role-profile.ts +101 -45
- package/scripts/agent/agent-safe-text.ts +60 -0
- package/scripts/agent/claude-agent-argv.ts +14 -0
- package/scripts/agent/codex-agent-argv.ts +9 -2
- package/scripts/agent/lane-instructions.ts +144 -0
- package/scripts/backlog/backlog-budget-cli.ts +1 -2
- package/scripts/backlog/backlog-budget.ts +4 -4
- package/scripts/backlog/backlog-drive-carried.ts +26 -0
- package/scripts/backlog/backlog-drive-cli.ts +10 -5
- package/scripts/backlog/backlog-drive-named.ts +3 -5
- package/scripts/backlog/backlog-drive-restore.ts +28 -2
- package/scripts/backlog/backlog-drive-seats.ts +27 -0
- package/scripts/backlog/backlog-drive.ts +11 -6
- package/scripts/backlog/backlog-occupied.ts +56 -0
- package/scripts/backlog/backlog-ready.ts +59 -15
- package/scripts/behavior/behavior-rules.ts +3 -2
- package/scripts/cost-runtime/codex-usage.ts +4 -2
- package/scripts/cost-runtime/cost-cli.ts +1 -2
- package/scripts/delegation/duplicate-read-guard.ts +2 -2
- package/scripts/delegation/investigation-guard.ts +15 -65
- package/scripts/delegation/investigation-reads.ts +1 -2
- package/scripts/discovery/repo-discovery.ts +4 -2
- package/scripts/discovery/repo-origin.ts +2 -4
- package/scripts/doctor/doctor-logic.ts +6 -3
- package/scripts/document/document-byte-budget.ts +28 -27
- package/scripts/document/document-byte-check.ts +1 -2
- package/scripts/document/document-section-cli.ts +17 -5
- package/scripts/document/entry-read-budget.ts +3 -3
- package/scripts/document/read-set-cli.ts +4 -1
- package/scripts/epic/epic-audit-orphans.ts +5 -8
- package/scripts/epic/epic-audit-rationale.ts +8 -2
- package/scripts/epic/epic-audit.ts +52 -1
- package/scripts/epic/epic-bundle-cli.ts +1 -2
- package/scripts/epic/epic-bundle-evidence.ts +49 -26
- package/scripts/epic/epic-bundle-referenced.ts +14 -3
- package/scripts/epic/epic-bundle.ts +17 -9
- package/scripts/epic/epic-chains.ts +6 -2
- package/scripts/epic/epic-close-comment.ts +1 -2
- package/scripts/followup/git-followup-workflow.ts +19 -1
- package/scripts/gate/check-inputs.ts +129 -0
- package/scripts/gate/check-reuse.ts +162 -0
- package/scripts/gate/core-budget.ts +93 -44
- package/scripts/gate/core-wait.ts +130 -0
- package/scripts/gate/free-cores.ts +49 -0
- package/scripts/gate/gate-ledger.ts +17 -3
- package/scripts/gate/gate-plan.ts +23 -1
- package/scripts/gate/gate-report.ts +15 -2
- package/scripts/gate/gate-run-steps.ts +150 -0
- package/scripts/gate/held-mark.ts +55 -0
- package/scripts/gate/machine-capacity.ts +70 -11
- package/scripts/gate/pre-commit-type-check.ts +14 -1
- package/scripts/gate/verification-gate.ts +65 -127
- package/scripts/gh/git-gh-issue-rest.ts +1 -0
- package/scripts/gh/git-gh-issue-write.ts +24 -2
- package/scripts/gh/git-pr.ts +19 -3
- package/scripts/git/git-common-directory.ts +3 -3
- package/scripts/git/git-diff-reads.ts +16 -9
- package/scripts/git/git-execa-error.ts +1 -2
- package/scripts/git/main-merge-regenerate.ts +78 -0
- package/scripts/git/main-merge.ts +14 -5
- package/scripts/hooks/batch-guard.ts +5 -8
- package/scripts/hooks/format-edited-file.ts +10 -4
- package/scripts/hooks/pre-commit-lint.ts +91 -0
- package/scripts/hooks/pre-push-unit.ts +15 -4
- package/scripts/hooks/pretool-guard.ts +48 -79
- package/scripts/hooks/reserved-run.ts +1 -0
- package/scripts/hooks/run-hook.sh +10 -12
- package/scripts/hooks/step-zero-notice.ts +3 -2
- package/scripts/hooks/stop-actions.ts +204 -0
- package/scripts/hooks/stop-guard.ts +62 -21
- package/scripts/init/hook-command-rewrite.ts +6 -2
- package/scripts/init/hook-launch.ts +12 -7
- package/scripts/init/init-logic-deploy-vps.ts +4 -2
- package/scripts/issue/behavior-change-lint.ts +12 -6
- package/scripts/issue/expected-effect-lint.ts +59 -0
- package/scripts/issue/issue-cite-cli.ts +35 -15
- package/scripts/issue/issue-classification.ts +1 -1
- package/scripts/issue/issue-lint-cli.ts +5 -3
- package/scripts/issue/issue-scout-cli.ts +22 -16
- package/scripts/issue/markdown-section.ts +19 -5
- package/scripts/josh/command-usage.ts +110 -0
- package/scripts/josh/file-map-stamp.ts +1 -3
- package/scripts/josh/hook-decision.ts +17 -2
- package/scripts/josh/josh-command-map.ts +2 -0
- package/scripts/josh/josh-command-types.ts +55 -9
- package/scripts/josh/josh-commands-ai.ts +13 -0
- package/scripts/josh/josh-commands-development.ts +1 -1
- package/scripts/josh/josh-commands-hooks.ts +6 -0
- package/scripts/josh/josh-commands-lane.ts +10 -1
- package/scripts/josh/josh-commands-workflow.ts +5 -0
- package/scripts/josh/josh-logic.ts +6 -15
- package/scripts/josh/josh-usage-automation.ts +121 -0
- package/scripts/josh/josh-usage-backlog.ts +180 -0
- package/scripts/josh/josh-usage-developer.ts +230 -0
- package/scripts/josh/josh-usage-hooks.ts +38 -0
- package/scripts/josh/josh-usage-issue.ts +205 -0
- package/scripts/josh/josh-usage-review.ts +101 -0
- package/scripts/josh/josh-usage-run.ts +252 -0
- package/scripts/josh/josh-usage-session.ts +238 -0
- package/scripts/josh/josh-usage-workflow.ts +212 -0
- package/scripts/josh/josh.ts +14 -5
- package/scripts/josh/package-directory.ts +20 -0
- package/scripts/lane/lane-await.ts +3 -2
- package/scripts/lane/lane-capacity.ts +8 -2
- package/scripts/lane/lane-check-stats.ts +56 -0
- package/scripts/lane/lane-child-invocation.ts +49 -5
- package/scripts/lane/lane-dispatch.ts +3 -3
- package/scripts/lane/lane-guard-policy.ts +5 -5
- package/scripts/lane/lane-handoff.ts +8 -1
- package/scripts/lane/lane-install.ts +12 -4
- package/scripts/lane/lane-ledger.ts +52 -1
- package/scripts/lane/lane-limit-cli.ts +8 -9
- package/scripts/lane/lane-load.ts +9 -2
- package/scripts/lane/lane-measure-cli.ts +4 -0
- package/scripts/lane/lane-parked.ts +18 -0
- package/scripts/lane/lane-preserve.ts +29 -1
- package/scripts/lane/lane-process-load.ts +125 -0
- package/scripts/lane/lane-process-stats.ts +93 -0
- package/scripts/lane/lane-registry.ts +17 -10
- package/scripts/lane/lane-restart.ts +5 -26
- package/scripts/lane/lane-session-action.ts +146 -0
- package/scripts/lane/lane-session-broker.ts +68 -125
- package/scripts/lane/lane-spent.ts +14 -3
- package/scripts/lane/lane-stats.ts +1 -0
- package/scripts/lane/lane-withdraw-cli.ts +71 -0
- package/scripts/lane/lane-withdraw.ts +182 -0
- package/scripts/lint/format.ts +4 -4
- package/scripts/lint/lint-parallel.ts +10 -3
- package/scripts/lint/lint-related-scope.ts +4 -1
- package/scripts/managed-marker/managed-marker-logic.ts +1 -2
- package/scripts/notify/telegram-test.ts +10 -5
- package/scripts/overrides/lockfile-overrides.ts +1 -3
- package/scripts/propagate/propagate.ts +1 -2
- package/scripts/release/release-progress.ts +3 -2
- package/scripts/report/report-format-reference.ts +2 -0
- package/scripts/report/report-lint.ts +7 -4
- package/scripts/review/acceptance-map-check.ts +61 -0
- package/scripts/review/acceptance-map.ts +205 -0
- package/scripts/review/review-brief-cli.ts +1 -1
- package/scripts/review/review-record-cli.ts +6 -2
- package/scripts/rules/agent-model.ts +59 -0
- package/scripts/rules/delivered-rules.ts +11 -2
- package/scripts/rules/destructive-command.ts +6 -9
- package/scripts/rules/direct-filing.ts +3 -7
- package/scripts/rules/early-heartbeat.ts +7 -18
- package/scripts/rules/file-body.ts +6 -13
- package/scripts/rules/filing-cap.ts +4 -6
- package/scripts/rules/firing-point.ts +6 -5
- package/scripts/rules/git-force.ts +5 -9
- package/scripts/rules/guard-remedy.ts +117 -0
- package/scripts/rules/implementation-cut.ts +37 -35
- package/scripts/rules/index-guard.ts +4 -7
- package/scripts/rules/issue-comments.ts +67 -16
- package/scripts/rules/josh-git-bare.ts +3 -6
- package/scripts/rules/lane-background.ts +10 -21
- package/scripts/rules/lane-carry-conflict.ts +7 -17
- package/scripts/rules/lane-interactive-ask.ts +6 -11
- package/scripts/rules/lane-park.ts +5 -13
- package/scripts/rules/lane-split-park.ts +2 -7
- package/scripts/rules/lane-switch-main.ts +9 -12
- package/scripts/rules/last-prompt.ts +50 -5
- package/scripts/rules/oracle-consulted.ts +4 -5
- package/scripts/rules/oracle-list-cli.ts +7 -0
- package/scripts/rules/piped-verification.ts +84 -32
- package/scripts/rules/poll-loop.ts +7 -17
- package/scripts/rules/pre-gate-cut.ts +7 -21
- package/scripts/rules/prior-comment-read.ts +7 -5
- package/scripts/rules/protected-files.ts +5 -9
- package/scripts/rules/raw-field-body.ts +3 -7
- package/scripts/rules/rule-body-guard.ts +4 -11
- package/scripts/rules/rule-list.ts +4 -1
- package/scripts/rules/rule-registry-rows.ts +10 -0
- package/scripts/rules/rule-registry.ts +7 -4
- package/scripts/rules/rule-rewrite.ts +114 -0
- package/scripts/rules/rule-value.ts +7 -1
- package/scripts/rules/run-tail-rule.ts +6 -22
- package/scripts/rules/shell-body-trigger.ts +4 -6
- package/scripts/rules/shell-segments.ts +22 -0
- package/scripts/rules/stop-decision.ts +77 -0
- package/scripts/rules/stop-rules.ts +164 -77
- package/scripts/rules/tail-commands.ts +15 -1
- package/scripts/rules/test-declared-commit.ts +4 -10
- package/scripts/rules/third-party-write.ts +5 -10
- package/scripts/rules/worktree-guard.ts +5 -12
- package/scripts/run/board/run-board-cli.ts +2 -0
- package/scripts/run/board/run-board-closed.ts +8 -2
- package/scripts/run/board/run-board-github.ts +19 -3
- package/scripts/run/board/run-board-header.ts +4 -1
- package/scripts/run/board/run-board-idle.ts +31 -0
- package/scripts/run/board/run-board-labels.ts +2 -0
- package/scripts/run/board/run-board-layout.ts +1 -1
- package/scripts/run/board/run-board-read.ts +25 -12
- package/scripts/run/board/run-board-reason.ts +17 -4
- package/scripts/run/board/run-board-render-legend.ts +1 -0
- package/scripts/run/board/run-board-render-slot.ts +1 -1
- package/scripts/run/board/run-board-render-waits.ts +41 -0
- package/scripts/run/board/run-board-render.ts +6 -1
- package/scripts/run/board/run-board-row-yield.ts +1 -0
- package/scripts/run/board/run-board-state.ts +9 -0
- package/scripts/run/board/run-board-status.ts +89 -23
- package/scripts/run/board/run-board-thanks.ts +7 -2
- package/scripts/run/board/run-board-tick.ts +37 -8
- package/scripts/run/carry/run-carry-args.ts +1 -3
- package/scripts/run/carry/run-carry-conversation.ts +7 -2
- package/scripts/run/cut/run-cut-cli.ts +18 -22
- package/scripts/run/cut/run-cut-decline.ts +72 -0
- package/scripts/run/cut/run-cut-ready.ts +74 -0
- package/scripts/run/cut/run-cut-report.ts +29 -0
- package/scripts/run/cut/run-cut.ts +10 -1
- package/scripts/run/detached-launch.ts +23 -4
- package/scripts/run/entry/run-entry-cli.ts +8 -1
- package/scripts/run/event/run-event-render.ts +1 -0
- package/scripts/run/event/run-event-scope.ts +19 -1
- package/scripts/run/event/run-event-stream-emit.ts +13 -6
- package/scripts/run/event/run-event-stream.ts +4 -0
- package/scripts/run/hold/run-hold-cli.ts +14 -3
- package/scripts/run/hold/run-hold-session.ts +46 -0
- package/scripts/run/hold/run-hold.ts +13 -4
- package/scripts/run/launch-priority.ts +32 -0
- package/scripts/run/merge/run-merge-cli.ts +16 -42
- package/scripts/run/merge/run-merge-ship.ts +59 -1
- package/scripts/run/merge/run-merge-signals.ts +99 -0
- package/scripts/run/merge/run-merge-steps.ts +11 -1
- package/scripts/run/merge/run-merge.ts +22 -9
- package/scripts/run/run-ending.ts +31 -3
- package/scripts/run/run-liveness.ts +1 -1
- package/scripts/run/run-parent-cut-hook.ts +5 -10
- package/scripts/run/run-poll-hook.ts +157 -0
- package/scripts/run/run-preflight.ts +1 -2
- package/scripts/run/run-step-cli.ts +22 -15
- package/scripts/run/run-step-section.ts +85 -0
- package/scripts/run/run-stop-notify.ts +1 -2
- package/scripts/run/run-watcher-guard.ts +6 -3
- package/scripts/run/ship/run-ship-cli.ts +5 -12
- package/scripts/run/ship/run-ship-detach.ts +9 -0
- package/scripts/run/ship/run-ship-next.ts +10 -2
- package/scripts/run/ship/run-ship-overlap.ts +195 -0
- package/scripts/run/ship/run-ship-pre-detach.ts +33 -15
- package/scripts/run/ship/run-ship-preflight.ts +28 -2
- package/scripts/run/ship/run-ship-return.ts +31 -7
- package/scripts/run/ship/run-ship-review-steps.ts +25 -14
- package/scripts/run/ship/run-ship-review.ts +15 -2
- package/scripts/run/ship/run-ship-steps.ts +1 -1
- package/scripts/run/ship/run-ship-stop-context.ts +206 -0
- package/scripts/run/ship/run-ship-sync.ts +14 -6
- package/scripts/run/tidy/run-tidy-cli.ts +3 -3
- package/scripts/run/tidy/run-tidy-lanes.ts +3 -2
- package/scripts/safe-chain/project-config.ts +7 -2
- package/scripts/sync/sync-hook-safety.ts +8 -2
- package/scripts/test/test-e2e-guard.ts +30 -5
- package/scripts/test/test-unit-guard.ts +16 -1
- package/scripts/test/unit-worker-share.ts +26 -3
- package/scripts/time-runtime/time-batch-guard.ts +3 -3
- package/scripts/time-runtime/time-hook-transcript.ts +3 -2
- package/scripts/time-runtime/time-shell.ts +39 -4
- package/scripts/time-runtime/time-spans.ts +1 -0
- package/scripts/time-runtime/time-tool-call.ts +7 -0
- package/scripts/version/effective-upstream.ts +3 -4
- package/scripts/version/kit-version-config.ts +8 -2
- package/scripts/version/latest-corepack.ts +1 -2
- package/scripts/version/release-hold.ts +11 -4
- package/scripts/version/version-commands.ts +12 -4
- package/templates/gitignore +6 -2
- package/dist/hooks/chunk-D5QBTOCZ.js +0 -68
- package/dist/hooks/chunk-UT7YC3N2.js +0 -56
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { cost_blocks } from '#scripts/cost-runtime/cost-blocks'
|
|
2
|
+
import { json_value } from '#scripts/lib/json-value'
|
|
3
|
+
import type { GuardedCall } from '#scripts/time-runtime/time-batch-guard'
|
|
4
|
+
import { time_shell } from '#scripts/time-runtime/time-shell'
|
|
1
5
|
import { bash_triggers } from './bash-triggers'
|
|
2
6
|
import { gh_api } from './gh-api'
|
|
3
7
|
import { prior_comment_read } from './prior-comment-read'
|
|
@@ -77,6 +81,9 @@ function reads_issue_comments(command: string): boolean {
|
|
|
77
81
|
return shell_segments.segments_of(command).some((segment) => fetches_issue_comments(segment))
|
|
78
82
|
}
|
|
79
83
|
|
|
84
|
+
const RULE_DOC = '`.claude/skills/workflow-commands/issue-comments.md`'
|
|
85
|
+
const COMMENTS_FALLBACK = 'gh api repos/{owner}/{repo}/issues/<N>/comments'
|
|
86
|
+
|
|
80
87
|
// **The refusal hands over the command that fixes it**, because reading is not the same as
|
|
81
88
|
// obeying: a sentence saying "also read the comments" is prose that moves nothing, while a refused
|
|
82
89
|
// body read leaves the run holding the reissue that makes the comments *present*. The conflict rule
|
|
@@ -88,22 +95,62 @@ function reads_issue_comments(command: string): boolean {
|
|
|
88
95
|
// being the Issue the refused call named — so a run that reads only the opening still leaves holding
|
|
89
96
|
// the fix. The label keeps `time_transcript_line.guard_from_refusal` naming this guard, not the command.
|
|
90
97
|
const ISSUE_COMMENTS_REASON =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
98
|
+
`⛔ issue comments: pnpm josh issue:read <N>\n` +
|
|
99
|
+
`Run that in place of this read — an Issue's comments are part of it, and a later comment ` +
|
|
100
|
+
`supersedes the body it contradicts; refused until that command is on the transcript. Without ` +
|
|
101
|
+
`josh, read \`${COMMENTS_FALLBACK}\` beside the body (${RULE_DOC}).`
|
|
102
|
+
|
|
103
|
+
// **A `gh api` body read is rewritten rather than refused** (joshuafolkken/kit#3920): the fix is the
|
|
104
|
+
// same Issue's comments endpoint, read on the same line, and the path the call already names is all
|
|
105
|
+
// it needs. Prepended on lines of their own, so a trailing comment or a `&&` chain on the typed line
|
|
106
|
+
// cannot swallow or skip them, and the typed line stays last — its exit status is still the call's.
|
|
107
|
+
// A `gh issue view` read is left to the refusal — its global flags (`--repo`) and its `--json`
|
|
108
|
+
// projection have no one comments spelling to add.
|
|
109
|
+
const COMMENTS_JQ = String.raw`'.[] | "— \(.user.login) \(.created_at)\n\(.body)\n"'`
|
|
110
|
+
|
|
111
|
+
const COMMENTS_NOTE =
|
|
112
|
+
"↻ issue comments: this read returned only the Issue's body, so the Issue's comments were fetched " +
|
|
113
|
+
`on the same line — a later comment supersedes the body it contradicts (${RULE_DOC}).`
|
|
114
|
+
|
|
115
|
+
// **Only a line that opens with the body read is rewritten.** Prepended ahead of a `cd` or a
|
|
116
|
+
// subshell, the comments read would resolve `{owner}/{repo}` in another directory and print another
|
|
117
|
+
// repository's comments; and the line is cut on its quote-blanked reading, so a body-read spelling
|
|
118
|
+
// quoted in a string or a heredoc body is never prepended as a real call. Every other line keeps the
|
|
119
|
+
// refusal.
|
|
120
|
+
function rewritable_path(command: string): string | undefined {
|
|
121
|
+
const read = shell_segments.first_of(command)
|
|
122
|
+
|
|
123
|
+
if (read === undefined || ISSUE_VIEW_COMMAND.test(read)) return undefined
|
|
124
|
+
|
|
125
|
+
return is_body_read_segment(read) ? ISSUE_BODY_PATH.exec(read)?.[0] : undefined
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function comments_command(command: string): string | undefined {
|
|
129
|
+
if (!is_body_only_issue_read(command)) return undefined
|
|
130
|
+
|
|
131
|
+
const path = rewritable_path(command)
|
|
132
|
+
|
|
133
|
+
if (path === undefined) return undefined
|
|
134
|
+
|
|
135
|
+
return `gh api --paginate ${path}/comments --jq ${COMMENTS_JQ}\n${command}`
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// The call's input with the comments read prepended, or `undefined` where the comments are already on
|
|
139
|
+
// the tail or the read has no rewritable spelling.
|
|
140
|
+
function comments_input(
|
|
141
|
+
call: GuardedCall,
|
|
142
|
+
tail: () => string,
|
|
143
|
+
): Record<string, unknown> | undefined {
|
|
144
|
+
if (call.name !== cost_blocks.BASH_TOOL || !json_value.is_record(call.input)) return undefined
|
|
145
|
+
|
|
146
|
+
const command = comments_command(time_shell.bash_command(call.input))
|
|
147
|
+
|
|
148
|
+
if (command === undefined || prior_comment_read.already_read_for_call(tail(), call)) {
|
|
149
|
+
return undefined
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return { ...call.input, command }
|
|
153
|
+
}
|
|
107
154
|
|
|
108
155
|
// The enumeration row itself, so `delivered-rules.ts` spreads one entry. `already_satisfied` stands it
|
|
109
156
|
// down once the comments are on the transcript tail, and until then it refuses every body-only read.
|
|
@@ -113,13 +160,17 @@ const ROW = {
|
|
|
113
160
|
reason: ISSUE_COMMENTS_REASON,
|
|
114
161
|
already_satisfied: prior_comment_read.already_read_for_call,
|
|
115
162
|
keeps: bash_triggers.on_bash_command(reads_issue_comments),
|
|
163
|
+
rewrite: comments_input,
|
|
164
|
+
rewrite_note: COMMENTS_NOTE,
|
|
116
165
|
// The opening the reason carried before it led with the command.
|
|
117
166
|
former_reasons: ["⛔ an Issue's comments are part of the Issue: read them before implementing"],
|
|
118
167
|
}
|
|
119
168
|
|
|
120
169
|
const issue_comments = {
|
|
170
|
+
COMMENTS_NOTE,
|
|
121
171
|
ISSUE_COMMENTS_REASON,
|
|
122
172
|
ROW,
|
|
173
|
+
comments_input,
|
|
123
174
|
is_body_only_issue_read,
|
|
124
175
|
}
|
|
125
176
|
|
|
@@ -52,12 +52,9 @@ function is_bare_josh_git(command: string): boolean {
|
|
|
52
52
|
// sibling reasons do.
|
|
53
53
|
const JOSH_GIT_BARE_REASON =
|
|
54
54
|
'⛔ bare `pnpm josh git`: this prompts to confirm the staging, and with no TTY the prompt falls to ' +
|
|
55
|
-
'its cancel branch
|
|
56
|
-
'
|
|
57
|
-
'
|
|
58
|
-
'`pnpm josh git -y "<title> #<N>"`. The recovery form that opens the PR for a push that already ' +
|
|
59
|
-
'landed is `pnpm josh git -y --skip-commit --skip-push`. This rule fires on every occurrence, not ' +
|
|
60
|
-
'once per run.'
|
|
55
|
+
'its cancel branch. Run `pnpm josh git -y "<title> #<N>"`, or ' +
|
|
56
|
+
'`pnpm josh git -y --skip-commit --skip-push` to open the PR for a push that already landed. It ' +
|
|
57
|
+
'fires on every occurrence.'
|
|
61
58
|
|
|
62
59
|
// The row itself, so `delivered-rules.ts` spreads one entry. `is_trigger` reads the input through
|
|
63
60
|
// `on_bash_command` — the `Bash` tool-name gate every command row shares — and `decide` returns true so
|
|
@@ -109,9 +109,9 @@ function foreground_input(
|
|
|
109
109
|
call: GuardedCall,
|
|
110
110
|
is_lane_child: () => boolean = () => lane_child_marker.is_child_of(process.cwd()),
|
|
111
111
|
): Record<string, unknown> | undefined {
|
|
112
|
-
if (!is_backgrounded_ship(call) || !json_value.is_record(call.input))
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
if (!is_backgrounded_ship(call) || !json_value.is_record(call.input) || !is_lane_child()) {
|
|
113
|
+
return undefined
|
|
114
|
+
}
|
|
115
115
|
|
|
116
116
|
return { ...call.input, [BACKGROUND_KEY]: false, [TIMEOUT_KEY]: FOREGROUND_TIMEOUT_MS }
|
|
117
117
|
}
|
|
@@ -119,7 +119,7 @@ function foreground_input(
|
|
|
119
119
|
const FOREGROUND_NOTE =
|
|
120
120
|
'lane background: this lane child backgrounded `josh ship`, which would die with the headless turn ' +
|
|
121
121
|
'before its supervisor exists — so it was run in the foreground instead, where it detaches itself ' +
|
|
122
|
-
'after the preflight. End the turn on `launched` / `busy
|
|
122
|
+
'after the preflight. End the turn on `launched` / `busy`.'
|
|
123
123
|
|
|
124
124
|
// The launches `launched_ids` reads off the transcript tail that never saw their finish. A launch is
|
|
125
125
|
// read off its own tool result and a finish off the harness notice, both by `time_transcript_line`.
|
|
@@ -149,26 +149,15 @@ function pending_agent_ids(tail: string): ReadonlyArray<string> {
|
|
|
149
149
|
|
|
150
150
|
const LANE_BACKGROUND_REASON =
|
|
151
151
|
'⛔ lane background: this session is a dispatched lane child (`JOSH_LANE_CHILD`), a headless ' +
|
|
152
|
-
'
|
|
153
|
-
'`
|
|
154
|
-
'
|
|
155
|
-
'
|
|
156
|
-
'supervisor instead: `pnpm josh ship --detach --review "<title> #<N>"` (add `--cite <N>`) issued in ' +
|
|
157
|
-
'the foreground — its preflight runs in this process before the supervisor exists, so a backgrounded ' +
|
|
158
|
-
'`ship` dies with the turn (joshuafolkken/kit#3027; a backgrounded `ship` issued alone is moved to ' +
|
|
159
|
-
'the foreground for you, joshuafolkken/kit#3154) — then end the turn on `launched` / `busy`. ' +
|
|
160
|
-
'`.claude/skills/workflow-commands/chain-rule.md` step 0 is the single source. A ' +
|
|
161
|
-
'single check you must read before continuing runs in the foreground within the tool timeout; the ' +
|
|
162
|
-
'commit-push step does not — in a child it too belongs to the detached ship, in either spelling. This ' +
|
|
163
|
-
'rule fires on every occurrence, not once per run.'
|
|
152
|
+
'process whose background tasks die when the turn ends. Hand over to ' +
|
|
153
|
+
'`pnpm josh ship --detach --review "<title> #<N>"`, issued in the foreground, then end the turn on ' +
|
|
154
|
+
'`launched` / `busy`. It fires on every occurrence ' +
|
|
155
|
+
'(`.claude/skills/workflow-commands/chain-rule.md` step 0).'
|
|
164
156
|
|
|
165
157
|
const LANE_BACKGROUND_STOP_REASON =
|
|
166
158
|
'⛔ lane background stop: this is a dispatched lane child (`JOSH_LANE_CHILD`) and a background task ' +
|
|
167
|
-
'it launched has not finished
|
|
168
|
-
'
|
|
169
|
-
'in the foreground and act on its result, or re-issue the work through `pnpm josh ship --detach`, ' +
|
|
170
|
-
'whose supervisor outlives the turn (`.claude/skills/workflow-commands/chain-rule.md` step 0). Do ' +
|
|
171
|
-
'not repeat your previous reply.'
|
|
159
|
+
'it launched has not finished, and ending this turn kills it. Wait for it in the foreground, or ' +
|
|
160
|
+
're-issue the work through `pnpm josh ship --detach` — do not notify, stop or repeat your reply.'
|
|
172
161
|
|
|
173
162
|
// The row itself, so `delivered-rules.ts` spreads one entry. It fires on every occurrence (`decide`
|
|
174
163
|
// returns true): a child must never background these, so the route is always the detached ship, never
|
|
@@ -89,25 +89,15 @@ function is_carry_conflict(
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
// The instruction in the shape a refusal can carry: what the child cannot do, why the record is not a
|
|
92
|
-
// conflict, and the mechanical branch to take instead — continue, never park or ask.
|
|
93
|
-
//
|
|
94
|
-
//
|
|
95
|
-
// avoided so the single-quoted literal needs no escaping, as the sibling reasons do.
|
|
92
|
+
// conflict, and the mechanical branch to take instead — continue, never park or ask. Its history is
|
|
93
|
+
// `docs/maintainers/rule-delivery-rationale.md` → "Why a refusal is the action and the next command".
|
|
94
|
+
// Apostrophes are avoided so the single-quoted literal needs no escaping, as the sibling reasons do.
|
|
96
95
|
const LANE_CARRY_CONFLICT_REASON =
|
|
97
96
|
'⛔ lane child carry conflict: this session is a dispatched lane child, and ' +
|
|
98
|
-
'`
|
|
99
|
-
'
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
'parent (joshuafolkken/kit#2267, measured 2026-09-21 in backlogrun #2252 — a child read run:merge ' +
|
|
103
|
-
'`busy` as a competitor and parked #2258 unimplemented). Do not run this command, and do not treat ' +
|
|
104
|
-
'it as a conflict: no `needs-decision`, no `confirmation` Telegram, no question to a person — a ' +
|
|
105
|
-
'dispatched child cannot ask, and there is nothing to decide. Continue implementing this Issue; the ' +
|
|
106
|
-
'parent owns the budget and counts the outcome at the return. The procedure is ' +
|
|
107
|
-
'`.claude/skills/workflow-commands/pre-gate-cut.md` and `backlogrun-progress.md` → "The hand-off". ' +
|
|
108
|
-
'Live evidence of `run:carry` is taken with a fresh `JOSH_TEMP_ROOT` prefixed to the call, which this ' +
|
|
109
|
-
'rule lets through (joshuafolkken/kit#3458); `run:merge` is refused under any root, because it also ' +
|
|
110
|
-
'syncs main, closes lanes and writes to GitHub. This rule fires on every occurrence, not once per run.'
|
|
97
|
+
'`run:merge` / `run:carry` are the parent budget commands; the live record belongs to the parent, ' +
|
|
98
|
+
'not to a competing run. Continue implementing this Issue: no `needs-decision`, no Telegram. ' +
|
|
99
|
+
'Live `run:carry` evidence takes a fresh `JOSH_TEMP_ROOT`; `run:merge` is refused under any root, ' +
|
|
100
|
+
'on every occurrence.'
|
|
111
101
|
|
|
112
102
|
// The row itself, so `delivered-rules.ts` spreads one entry. `is_trigger` reads the input through
|
|
113
103
|
// `on_bash_command` — the `Bash` tool-name gate every command row shares — and `decide` returns true
|
|
@@ -41,17 +41,12 @@ function is_interactive_ask(
|
|
|
41
41
|
// `backlogrun-park.md` → "park and continue", and a second copy here would be the clone `CLAUDE.md`
|
|
42
42
|
// prohibits. The one command is spelled so the child is not left to reconstruct it from a doc read.
|
|
43
43
|
const LANE_INTERACTIVE_ASK_REASON =
|
|
44
|
-
'⛔ lane child interactive ask: this session is a dispatched lane child and cannot ask a
|
|
45
|
-
'
|
|
46
|
-
|
|
47
|
-
'
|
|
48
|
-
'`
|
|
49
|
-
|
|
50
|
-
'`pnpm josh issue:comment <N> --body-file <path>` — then send the ' +
|
|
51
|
-
'`confirmation` Telegram and stop. The procedure is ' +
|
|
52
|
-
'`.claude/skills/workflow-commands/pre-gate-cut.md` → "A lane child records its park before it stops", ' +
|
|
53
|
-
'and the park itself is `backlogrun-park.md` → "park and continue". This rule fires on every ' +
|
|
54
|
-
'occurrence, not once per run.'
|
|
44
|
+
'⛔ lane child interactive ask: this session is a dispatched lane child and cannot ask a ' +
|
|
45
|
+
'person, so park instead: ' +
|
|
46
|
+
"`gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=needs-decision'`, " +
|
|
47
|
+
'`pnpm josh issue:comment <N> --body-file <path>`, ' +
|
|
48
|
+
'the `confirmation` Telegram, stop. It fires on every occurrence ' +
|
|
49
|
+
'(`.claude/skills/workflow-commands/pre-gate-cut.md`, `backlogrun-park.md`).'
|
|
55
50
|
|
|
56
51
|
// The row itself, so `delivered-rules.ts` spreads one entry. `decide` returns true so it refuses every
|
|
57
52
|
// occurrence; it declares no `keeps` — not asking is the absence of a call, not a call, so the row is
|
|
@@ -108,19 +108,11 @@ function records_the_park(command: string): boolean {
|
|
|
108
108
|
// single source is `backlogrun-park.md` → "park and continue", and a second copy here would be the
|
|
109
109
|
// clone `CLAUDE.md` prohibits.
|
|
110
110
|
const LANE_PARK_REASON =
|
|
111
|
-
'⛔ lane child park: this session is a dispatched lane child,
|
|
112
|
-
|
|
113
|
-
'
|
|
114
|
-
'
|
|
115
|
-
'
|
|
116
|
-
'the parent to guess from a log. Before you notify and stop: apply `needs-decision` and post a ' +
|
|
117
|
-
'comment carrying the question, the options, and whether work was stashed — ' +
|
|
118
|
-
"`gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=needs-decision'` then " +
|
|
119
|
-
'`pnpm josh issue:comment <N> --body-file <path>`. If this stop is a ' +
|
|
120
|
-
'`needs-human-review` or `already-done` one, that label is already on the Issue and there is nothing ' +
|
|
121
|
-
'to add. Then reissue this notify — it fires once per run and cannot repeat on the call in hand. The ' +
|
|
122
|
-
'procedure is `.claude/skills/workflow-commands/pre-gate-cut.md` → "A lane child records its park ' +
|
|
123
|
-
'before it stops", and the park itself is `backlogrun-park.md` → "park and continue".'
|
|
111
|
+
'⛔ lane child park: this session is a dispatched lane child, so a stop for a person parks first: ' +
|
|
112
|
+
"`gh api repos/{owner}/{repo}/issues/<N>/labels -f 'labels[]=needs-decision'`; " +
|
|
113
|
+
'`pnpm josh issue:comment <N> --body-file <path>` (question, options, stash); a ' +
|
|
114
|
+
'`needs-human-review` / `already-done` stop already is. Reissue this notify, once per run ' +
|
|
115
|
+
'(`.claude/skills/workflow-commands/pre-gate-cut.md`).'
|
|
124
116
|
|
|
125
117
|
// The row itself, so `delivered-rules.ts` spreads one entry. **Once per run rather than `decide`, and
|
|
126
118
|
// no `already_satisfied`.** The stop ends the turn, so it is not the recurring act `decide` is for. It carries no `already_satisfied` because the park it asks for is a GitHub label a
|
|
@@ -101,13 +101,8 @@ function decide(_call: unknown, run: GuardRun): boolean {
|
|
|
101
101
|
|
|
102
102
|
const LANE_SPLIT_PARK_REASON =
|
|
103
103
|
'⛔ lane split park: this session is a dispatched lane child that promoted its own Issue to an epic ' +
|
|
104
|
-
'this run, and a split is not a park
|
|
105
|
-
'
|
|
106
|
-
'continues through its children; a question here has nobody to answer it (joshuafolkken/kit#3296, ' +
|
|
107
|
-
'measured 2026-10-06 when the child for #3255 parked its promoted epic). If what remains of the ' +
|
|
108
|
-
'original work needs a person, park that child issue instead, then end the turn. The procedure is ' +
|
|
109
|
-
'`.claude/skills/workflow-commands/backlogrun-park.md` → "Splitting a child mid-run". This rule fires ' +
|
|
110
|
-
'on every occurrence, not once per run.'
|
|
104
|
+
'this run, and a split is not a park: no `needs-decision` on the epic, no `confirmation` Telegram, ' +
|
|
105
|
+
'on every occurrence. Park a child issue if the rest needs a person, else end the turn (`.claude/skills/workflow-commands/backlogrun-park.md` → "Splitting a child mid-run").'
|
|
111
106
|
|
|
112
107
|
// It declares no `keeps`: not parking is the absence of a call, so the row is reported unmeasured
|
|
113
108
|
// rather than scored on an act that does not exist (`lane-carry-conflict.ts`).
|
|
@@ -61,8 +61,12 @@ const FLAG_PREFIX = '-'
|
|
|
61
61
|
function switch_target(segment: string): string | undefined {
|
|
62
62
|
const call = git_argv.parse(segment)
|
|
63
63
|
|
|
64
|
-
if (
|
|
65
|
-
|
|
64
|
+
if (
|
|
65
|
+
call?.subcommand !== SWITCH_SUBCOMMAND ||
|
|
66
|
+
call.args.some((argument) => NON_COLLIDING_FLAGS.has(argument))
|
|
67
|
+
) {
|
|
68
|
+
return undefined
|
|
69
|
+
}
|
|
66
70
|
|
|
67
71
|
return call.args.find((argument) => !argument.startsWith(FLAG_PREFIX))
|
|
68
72
|
}
|
|
@@ -103,16 +107,9 @@ function is_switch_away_from_lane(
|
|
|
103
107
|
// prohibits. Apostrophes are avoided so the single-quoted literal needs no escaping, as the siblings do.
|
|
104
108
|
const LANE_SWITCH_MAIN_REASON =
|
|
105
109
|
'⛔ lane child on `git switch main`: this session is a dispatched lane child, and switching to the ' +
|
|
106
|
-
'default branch here always fails
|
|
107
|
-
'
|
|
108
|
-
'
|
|
109
|
-
'switch: the lane is already on its own issue branch, branched from a fresh default before it opened, ' +
|
|
110
|
-
'and the latest default is brought in during the gate by `pnpm josh main:merge`. So skip this step ' +
|
|
111
|
-
'and keep implementing on the current branch — no `git switch`, no `git pull`. `pnpm josh main:sync` ' +
|
|
112
|
-
'(`josh ms`) is refused in a lane for the same reason, and a lane is finished with `pnpm josh ' +
|
|
113
|
-
'lane:close <issue-number>`. The parent runs `pnpm josh ms` in the primary checkout ' +
|
|
114
|
-
'before each lane opens, never the child — `backlogrun-lanes.md` and `backlogrun-child.md` are the ' +
|
|
115
|
-
'single sources. This rule fires on every occurrence, not once per run.'
|
|
110
|
+
'default branch here always fails (`already used by worktree`: the primary checkout holds it). Skip ' +
|
|
111
|
+
'this step and keep implementing on the current branch; `pnpm josh main:merge` brings the default ' +
|
|
112
|
+
'in during the gate. Refused on every occurrence (`backlogrun-lanes.md`, `backlogrun-child.md`).'
|
|
116
113
|
|
|
117
114
|
// The row itself, so `delivered-rules.ts` spreads one entry. `is_trigger` reads the input through
|
|
118
115
|
// `on_bash_command` — the `Bash` tool-name gate every command row shares — and `decide` returns true so
|
|
@@ -30,10 +30,13 @@ const KEYWORD_BEFORE_ARGUMENT = -2
|
|
|
30
30
|
|
|
31
31
|
const PROMPT_LINE_SCHEMA = z.object({
|
|
32
32
|
isMeta: z.boolean().nullish(),
|
|
33
|
+
timestamp: z.string().nullish(),
|
|
33
34
|
origin: z.object({ kind: z.string().nullish() }).nullish(),
|
|
34
35
|
message: z.object({ content: z.unknown() }),
|
|
35
36
|
})
|
|
36
37
|
|
|
38
|
+
const TIMED_LINE_SCHEMA = z.object({ timestamp: z.string() })
|
|
39
|
+
|
|
37
40
|
type PromptLine = z.infer<typeof PROMPT_LINE_SCHEMA>
|
|
38
41
|
|
|
39
42
|
function is_person(line: PromptLine): boolean {
|
|
@@ -42,13 +45,20 @@ function is_person(line: PromptLine): boolean {
|
|
|
42
45
|
return line.origin === null || line.origin === undefined || line.origin.kind === HUMAN_ORIGIN
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
// The prompt line
|
|
46
|
-
|
|
48
|
+
// The prompt line as the person wrote it, or `undefined` when the harness wrote it or it does not
|
|
49
|
+
// read as one.
|
|
50
|
+
function person_line(line: string): PromptLine | undefined {
|
|
47
51
|
const parsed = PROMPT_LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line))
|
|
48
52
|
|
|
49
|
-
|
|
53
|
+
return parsed.success && is_person(parsed.data) ? parsed.data : undefined
|
|
54
|
+
}
|
|
50
55
|
|
|
51
|
-
|
|
56
|
+
// The prompt line's text, or `undefined` when the harness wrote it or it does not read as one.
|
|
57
|
+
function person_text(line: string): string | undefined {
|
|
58
|
+
const person = person_line(line)
|
|
59
|
+
if (person === undefined) return undefined
|
|
60
|
+
|
|
61
|
+
return time_reported_failure.result_text(person.message.content)
|
|
52
62
|
}
|
|
53
63
|
|
|
54
64
|
// A keyword opening the prompt is what a person types; a keyword before its one trailing argument is a
|
|
@@ -75,6 +85,41 @@ function prompt_text(tail: string): string {
|
|
|
75
85
|
return text === undefined || is_invocation(text) ? NO_PROMPT : text
|
|
76
86
|
}
|
|
77
87
|
|
|
78
|
-
|
|
88
|
+
// **The prompt that opened this turn, when a person typed it** — '' when the harness opened it (a task
|
|
89
|
+
// notification, a subagent's hand-back), so a question asked turns ago does not answer for a stop the
|
|
90
|
+
// run reached on its own since (`stop-decision.ts` → `is_question`).
|
|
91
|
+
function turn_prompt(tail: string): string {
|
|
92
|
+
const opener = tail.split('\n').findLast((line) => filing_cap.is_prompt_line(line))
|
|
93
|
+
if (opener === undefined) return NO_PROMPT
|
|
94
|
+
|
|
95
|
+
return person_text(opener) ?? NO_PROMPT
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// When the person last prompted on the tail, or `undefined` when no prompt of theirs is on it.
|
|
99
|
+
function prompt_time(tail: string): string | undefined {
|
|
100
|
+
return tail
|
|
101
|
+
.split('\n')
|
|
102
|
+
.filter((line) => filing_cap.is_prompt_line(line))
|
|
103
|
+
.map((line) => person_line(line)?.timestamp ?? undefined)
|
|
104
|
+
.findLast((time) => time !== undefined)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// The first dated line on the tail, or `undefined` when none is.
|
|
108
|
+
function tail_time(tail: string): string | undefined {
|
|
109
|
+
return tail
|
|
110
|
+
.split('\n')
|
|
111
|
+
.map((line) => TIMED_LINE_SCHEMA.safeParse(json_value.parse_or_undefined(line)).data?.timestamp)
|
|
112
|
+
.find((time) => time !== undefined)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// **When the current pause began, as far as the tail shows** — what a recorded notify is compared
|
|
116
|
+
// against. A person's prompt ends the pause it reported, so the last one opens the next; with none on
|
|
117
|
+
// the tail, only a send dated inside the tail is provably after every prompt, and an older send is
|
|
118
|
+
// announced again (joshuafolkken/kit#3961).
|
|
119
|
+
function pause_start(tail: string): string | undefined {
|
|
120
|
+
return prompt_time(tail) ?? tail_time(tail)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const last_prompt = { pause_start, prompt_text, turn_prompt }
|
|
79
124
|
|
|
80
125
|
export { last_prompt }
|
|
@@ -48,11 +48,10 @@ function command_line(oracle: Oracle): string {
|
|
|
48
48
|
// the single source of the procedure.
|
|
49
49
|
function reason_for(oracle: Oracle, firing_point: FiringPoint): string {
|
|
50
50
|
return (
|
|
51
|
-
`⛔ decision oracle not consulted: this is ${firing_point.describes}
|
|
52
|
-
`\`${command_line(oracle)}\` first —
|
|
53
|
-
|
|
54
|
-
`
|
|
55
|
-
`the transcript.`
|
|
51
|
+
`⛔ decision oracle not consulted: this is ${firing_point.describes}. Run ` +
|
|
52
|
+
`\`${command_line(oracle)}\` first — it decides ${oracle.decision.toLowerCase()} and answers ` +
|
|
53
|
+
`${oracle.vocabulary.join(' | ')} (${oracle.single_source}). Every such call is refused until ` +
|
|
54
|
+
`that command is on the transcript.`
|
|
56
55
|
)
|
|
57
56
|
}
|
|
58
57
|
|
|
@@ -12,6 +12,10 @@ import { oracle_firing } from './oracle-firing'
|
|
|
12
12
|
const ARGV_OFFSET = 2
|
|
13
13
|
const INDENT = ' '
|
|
14
14
|
const FIELD_WIDTH = 10
|
|
15
|
+
// The rule-prose guard sends a rule author here first, so the list closes on the placement order a new
|
|
16
|
+
// rule is weighed against before it becomes a guard or a document line.
|
|
17
|
+
const AUTOMATION_ORDER =
|
|
18
|
+
'automate first: a command > a hook that runs it > a refusal guard > a document — a lower rung states why the higher cannot hold (`principles.md` → "automate-first"; a guard\'s `why` is `scripts/rules/guard-remedy.ts`)'
|
|
15
19
|
|
|
16
20
|
function pad_field(label: string): string {
|
|
17
21
|
return label.padEnd(FIELD_WIDTH)
|
|
@@ -51,6 +55,8 @@ function print_list(): void {
|
|
|
51
55
|
for (const oracle of decision_oracle.DECISION_ORACLES) {
|
|
52
56
|
console.info(format_oracle(oracle))
|
|
53
57
|
}
|
|
58
|
+
|
|
59
|
+
console.info(AUTOMATION_ORDER)
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
function run(argv: ReadonlyArray<string>): number {
|
|
@@ -70,6 +76,7 @@ function main(argv: ReadonlyArray<string>): void {
|
|
|
70
76
|
}
|
|
71
77
|
|
|
72
78
|
const oracle_list_cli = {
|
|
79
|
+
AUTOMATION_ORDER,
|
|
73
80
|
print_list,
|
|
74
81
|
}
|
|
75
82
|
|