@joshuafolkken/kit 1.1094.0 → 1.1128.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/skills/workflow-commands/SKILL.md +1 -1
- package/.claude/skills/workflow-commands/background-commands.md +36 -85
- package/.claude/skills/workflow-commands/backlogrun-progress.md +29 -32
- package/.claude/skills/workflow-commands/backlogrun-steps.md +2 -2
- package/.claude/skills/workflow-commands/fullrun.md +5 -4
- package/.claude/skills/workflow-commands/halfrun.md +5 -4
- package/.claude/skills/workflow-commands/latest-gate.md +7 -15
- package/.claude/skills/workflow-commands/pre-gate-cut.md +4 -8
- package/.claude/skills/workflow-commands/split-assessment.md +4 -18
- package/.github/actions/setup-node/action.yml +33 -0
- package/.github/actions/setup-pnpm/action.yml +4 -4
- package/.github/workflows/auto-tag.yml +2 -3
- package/.github/workflows/ci.yml +7 -8
- package/.github/workflows/dependabot-auto-merge.yml +1 -0
- package/.github/workflows/pr-classification.yml +1 -3
- package/.github/workflows/production.yml +1 -0
- package/.github/workflows/publish.yml +10 -9
- package/.github/workflows/sonar-qube.yml +17 -13
- package/.pnpmfile.mjs +29 -0
- package/AGENTS.md +4 -11
- package/CLAUDE.md +24 -17
- package/GEMINI.md +4 -13
- package/README.md +8 -3
- package/SECURITY.md +1 -0
- package/cspell/index.yaml +4 -0
- package/dist/CLAUDE.basic.md +6 -6
- package/dist/CLAUDE.md +24 -17
- package/dist/CLAUDE.static.md +6 -6
- package/dist/config-merge/index.js +33 -9
- package/dist/hooks/batch-guard.js +4 -4
- package/dist/hooks/{chunk-NKOG3XAV.js → chunk-4JZDP5X5.js} +2 -2
- package/dist/hooks/{chunk-3C4YCCEF.js → chunk-5SD2YM7Z.js} +4 -4
- package/dist/hooks/{chunk-OIZUHPJI.js → chunk-77J7IEQM.js} +1 -1
- package/dist/hooks/{chunk-KHWHKJOM.js → chunk-7HVB7SZG.js} +3 -3
- package/dist/hooks/{chunk-UD24EAIL.js → chunk-AIOIOMPX.js} +1875 -104
- package/dist/hooks/{chunk-M2XDCUKD.js → chunk-M7QKEKWO.js} +88 -1783
- package/dist/hooks/{chunk-E54KGFEQ.js → chunk-MKVGBQPA.js} +1 -1
- package/dist/hooks/{chunk-7ZPFAVR7.js → chunk-NXYMNPUQ.js} +3 -3
- package/dist/hooks/{chunk-O4LL4HTI.js → chunk-QVLT52OV.js} +2 -2
- package/dist/hooks/{chunk-IL27YTPH.js → chunk-XYUIQOW3.js} +2 -2
- package/dist/hooks/codex-hook-adapter.js +12 -47
- package/dist/hooks/duplicate-read-guard.js +5 -5
- package/dist/hooks/format-edited.js +2 -2
- package/dist/hooks/inputs.json +180 -179
- package/dist/hooks/investigation-guard.js +5 -5
- package/dist/hooks/pretool-guard.js +9 -9
- package/dist/hooks/stop-guard.js +17 -12
- package/dist/josh.js +79 -30
- package/dist/version/index.js +36 -20
- package/eslint/rules/unicorn.js +3 -2
- package/package.json +18 -2
- package/pnpm-workspace.yaml +5 -7
- package/prompts/collaboration-workflow/glossary.md +17 -0
- package/prompts/collaboration-workflow/issue-template.md +1 -1
- package/prompts/collaboration-workflow/operating-rules.md +1 -1
- package/prompts/collaboration-workflow/principles.md +9 -0
- package/prompts/collaboration-workflow.md +1 -0
- package/scripts/backlog/backlog-arrival.ts +30 -10
- package/scripts/backlog/backlog-budget-cli.ts +15 -16
- package/scripts/backlog/backlog-offer-cli.ts +6 -14
- package/scripts/backlog/backlog-plan.ts +29 -18
- package/scripts/backlog/backlog-ready.ts +20 -7
- package/scripts/config-merge/parse-jsonc.ts +33 -3
- package/scripts/config-merge/patch-json-key.ts +13 -6
- package/scripts/cost-runtime/cost-cli.ts +3 -7
- package/scripts/doctor/doctor-consumer.ts +3 -5
- package/scripts/doctor/doctor-io.ts +9 -13
- package/scripts/document/backlogrun-parent-read-set.ts +12 -1
- package/scripts/document/document-byte-budget.ts +1 -0
- package/scripts/document/entry-read-budget.ts +13 -7
- package/scripts/document/entry-read-set.ts +32 -8
- package/scripts/document/lane-child-read-set.ts +7 -0
- package/scripts/document/read-set-point-of-use.ts +8 -3
- package/scripts/document/read-set-trim.ts +3 -1
- package/scripts/epic/epic-audit.ts +3 -18
- package/scripts/gh/git-gh-issue-list.ts +12 -11
- package/scripts/gh/git-gh-issue-write.ts +4 -1
- package/scripts/gh/git-gh-pr-auto-merge.ts +4 -1
- package/scripts/git/git-command.ts +6 -1
- package/scripts/git/git-spawn-sync.ts +65 -0
- package/scripts/git/git-spawn.ts +5 -4
- package/scripts/git/stash/stash-pop-args.ts +1 -6
- package/scripts/init/init-file-action.ts +54 -0
- package/scripts/init/init-logic-migrate.ts +35 -17
- package/scripts/init/init-logic-secretlint.ts +1 -1
- package/scripts/init/init-logic.ts +6 -22
- package/scripts/init/init.ts +11 -68
- package/scripts/init/kit-written-paths.ts +2 -0
- package/scripts/init/project-profile.ts +3 -6
- package/scripts/init/start-steps.ts +2 -1
- package/scripts/issue/defect-rate-cli.ts +61 -20
- package/scripts/issue/issue-backlinks.ts +7 -14
- package/scripts/issue/issue-cite.ts +12 -6
- package/scripts/issue/issue-file.ts +5 -12
- package/scripts/issue/markdown-section.ts +21 -6
- package/scripts/issue/measure-rerun-cli.ts +73 -14
- package/scripts/josh/josh-commands-project.ts +1 -1
- package/scripts/josh/josh-commands-workflow.ts +1 -1
- package/scripts/josh/run-github-prerequisite.ts +3 -6
- package/scripts/lane/lane-await.ts +43 -13
- package/scripts/lane/lane-close.ts +4 -1
- package/scripts/lane/lane-launch-cli.ts +10 -16
- package/scripts/lane/openai-review-broker.ts +4 -1
- package/scripts/lib/cli-flags.ts +31 -2
- package/scripts/lib/error-message.ts +12 -1
- package/scripts/lines/line-targets.ts +0 -11
- package/scripts/lines/lines-command.ts +5 -3
- package/scripts/propagate/propagate-git.ts +3 -8
- package/scripts/refactor/refactor-scan.ts +2 -1
- package/scripts/registry-migration/migrate-logic.ts +28 -19
- package/scripts/registry-migration/migrate.ts +6 -5
- package/scripts/release/github-release-cli.ts +14 -3
- package/scripts/release/release-publish.ts +36 -2
- package/scripts/release/release-worktree.ts +97 -2
- package/scripts/review/review-checkout.ts +3 -2
- package/scripts/review/review-record-cli.ts +9 -16
- package/scripts/rules/early-heartbeat.ts +4 -3
- package/scripts/rules/lane-park.ts +9 -0
- package/scripts/rules/stop-rules.ts +7 -4
- package/scripts/run/run-carry-args.ts +8 -12
- package/scripts/run/run-cut-args.ts +1 -6
- package/scripts/run/run-ending-cli.ts +1 -5
- package/scripts/run/run-entry-cli.ts +40 -9
- package/scripts/run/run-entry-stop.ts +104 -0
- package/scripts/run/run-event-stream-emit.ts +7 -2
- package/scripts/run/run-hold.ts +4 -1
- package/scripts/run/run-liveness-cli.ts +1 -5
- package/scripts/run/run-merge-cli.ts +2 -10
- package/scripts/run/run-parent-cut-hook.ts +4 -1
- package/scripts/run/run-prep-cli.ts +4 -1
- package/scripts/run/run-progress-args.ts +20 -4
- package/scripts/run/run-progress-cli.ts +31 -29
- package/scripts/run/run-progress-clock.ts +4 -1
- package/scripts/run/run-ship-cli.ts +8 -16
- package/scripts/run/run-ship-probe.ts +4 -1
- package/scripts/run/run-status-cli.ts +2 -15
- package/scripts/run/run-tidy-lanes.ts +4 -1
- package/scripts/run/run-wake-cli.ts +2 -10
- package/scripts/run/run-watcher-guard.ts +9 -5
- package/scripts/safe-chain/pack-hook.ts +92 -0
- package/scripts/sync/sync-ai-files.ts +4 -0
- package/scripts/test/test-declared-changed.ts +13 -16
- package/scripts/test/test-declared.ts +3 -7
- package/scripts/version/version-commands.ts +11 -1
- package/templates/CLAUDE.basic.md +6 -6
- package/templates/workflows/ci.yml +16 -82
- package/templates/workflows/dependabot-auto-merge.yml +1 -0
- package/templates/workflows/github-release.yml +1 -3
- package/tsconfig.sonar.json +4 -22
|
@@ -122,7 +122,7 @@ procedure.
|
|
|
122
122
|
| Under `backlogrun`, a stop that would end a batch, or a named non-epic item | Park one child and continue; run a named non-epic item as a `fullrun` | `backlogrun-park.md` → "park and continue"; `backlogrun-child.md` → "When `#N` is not an epic" |
|
|
123
123
|
| `backlogrun`'s authorization | The whole `auto-ok` opted-in pool as well as its named items; `pnpm josh backlog:next` offers them | `backlogrun.md` |
|
|
124
124
|
| First call of any entry | `#N`: `pnpm josh run:entry <N> --to <command>` (claims the tree, except `kickoff`); `new` (not `kickoff`): `pnpm josh run:hold` | §2k; §2f → `working-tree-hold.md` |
|
|
125
|
-
| Same turn as the hold (not a dispatched child, not `kickoff`) | `pnpm josh cost --cut`; `under` continues, `over` stops
|
|
125
|
+
| Same turn as the hold (not a dispatched child, not `kickoff`) | `pnpm josh cost --cut`; `under` continues, `over` stops — `run:entry` notifies and runs `run:release` (by hand for `new`) | `backlogrun-progress.md` → "The hand-off" (shared 135,000 threshold) |
|
|
126
126
|
| Before any work starts (every entry) | The split assessment; the default is not to split — separability **and** a scope clearly over one gate must hold together; a `fullrun` / `halfrun` that finds a split files the epic and **stops** | `split-assessment.md` → "The question" |
|
|
127
127
|
| Another Issue here must land first | A prerequisite is a dependency, not a park (the third of four mid-run discoveries) | §2d → `prerequisite.md` |
|
|
128
128
|
| Something worth filing, none of the three | File it without asking (Tier A, first-party) and carry on; a delegated child returns it to the parent instead | §2i → `observation-filing.md` |
|
|
@@ -28,83 +28,39 @@ command finished.
|
|
|
28
28
|
|
|
29
29
|
**Never hand-write a `while`/`until` … `sleep` loop over the output file.** The loop does not know
|
|
30
30
|
when the command finished: a regex that never matches waits to the block limit, and one that matches
|
|
31
|
-
a mid-run line exits too early
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
landed. `pnpm josh rule:guard` refuses the poll loop and hands back this route, so the guarantee is a
|
|
35
|
-
mechanism rather than prose to remember (`prompts/collaboration-workflow/rule-delivery.md`).
|
|
31
|
+
a mid-run line exits too early. `pnpm josh rule:guard` refuses the poll loop and hands back this route
|
|
32
|
+
(`prompts/collaboration-workflow/rule-delivery.md`). Rationale:
|
|
33
|
+
`docs/maintainers/background-commands-rationale.md` → "Why a poll loop is refused".
|
|
36
34
|
|
|
37
35
|
**To glance at interim output, `Read` the output file once** — the notification names its path — and
|
|
38
36
|
never in a sleep loop. If what you are waiting on is CI, `pnpm josh followup` waits on it for you in
|
|
39
37
|
the foreground; a bare `sleep` that arms a progress heartbeat is `run:progress --wait`'s job, refused
|
|
40
|
-
in front of a hand-armed timer by `early-heartbeat
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
(`SKILL.md` → §1, "Five documents are read at the point of use"). `SKILL.md` → §2h is the resident
|
|
50
|
-
pointer to it, and carries the one thing it does not: the same rule at a batch's scale.
|
|
51
|
-
|
|
52
|
-
**A run's idle time collects in its tail, and the two ways it collects there are one mistake**
|
|
53
|
-
(joshuafolkken/kit#1510). `fullrun #1501` ran 45m03s on about 17 minutes of work. Of the 25 minutes
|
|
54
|
-
nothing was running, **6m28s** was a `pnpm josh git -y` issued in the **foreground** with a
|
|
55
|
-
900-second tool timeout — above the harness's own 600-second cap, so the harness detached it at the
|
|
56
|
-
cap and nothing read the output file for six and a half minutes afterwards — and **6m06s** was bare
|
|
57
|
-
CI: the push landed, the turn ended, and the merge started only once the person asked whether it was
|
|
58
|
-
merging. Both halves handed the deciding of *when to look back* to something that was never going to
|
|
59
|
-
decide it.
|
|
60
|
-
|
|
61
|
-
**Issue it in the background, and never give a foreground call a timeout above the harness cap.**
|
|
62
|
-
The cap decides how long a foreground call waits, not the number passed to it, so a number above the
|
|
63
|
-
cap chooses the detached path without choosing the completion notification that should come with it.
|
|
64
|
-
A call issued detached from the start re-invokes the run when it exits — which is what makes the
|
|
65
|
-
completion *delivered* rather than something to remember to poll for.
|
|
66
|
-
|
|
67
|
-
The measured outliers were a 6m28s foreground `git -y`, 6m06s of unattended CI and a 19m26s push
|
|
68
|
-
transport fault. The operational section above maps those waits to background gate/push and a
|
|
69
|
-
foreground `followup`; `followup.md` remains its command procedure.
|
|
70
|
-
|
|
71
|
-
**A tail does follow the merge, and it is not small** (joshuafolkken/kit#1462). This section first
|
|
72
|
-
gave a different reason for that last bullet — that the merge ends the run, leaving no tail to
|
|
73
|
-
overlap — and the measurement says otherwise. The run-timing report charges to **`post-run`** exactly what runs
|
|
74
|
-
after the last `followup` span ends: **3.0 min, 5.9% of a 50.5-minute run**, in the lane child
|
|
75
|
-
`--issue 1599` (PR #1602); **2 min 31 s, 14% of 20m15s**, in the plain `fullrun #1597` (PR #1603);
|
|
76
|
-
**3.1 min** hand-measured in run #1441's delegated child, which is where this Issue started. **What
|
|
77
|
-
was wrong is the premise, not the conclusion** — `followup` stays foreground, and what changes is
|
|
78
|
-
*where the tail's work is done*.
|
|
79
|
-
|
|
80
|
-
**So the tail is emptied before `followup` is issued, rather than worked through after it returns.**
|
|
38
|
+
in front of a hand-armed timer by `early-heartbeat`.
|
|
39
|
+
|
|
40
|
+
## The tail and what overlaps each wait
|
|
41
|
+
|
|
42
|
+
**Never give a foreground call a timeout above the harness cap** — the cap decides how long a
|
|
43
|
+
foreground call waits, so a larger number detaches the call without the completion notification.
|
|
44
|
+
Rationale: `docs/maintainers/background-commands-rationale.md` → "Why the tail collects idle time".
|
|
45
|
+
|
|
46
|
+
**The tail is emptied before `followup` is issued, rather than worked through after it returns.**
|
|
81
47
|
One question decides each step, and it is asked of the step rather than judged: **does it read the
|
|
82
48
|
merge result?**
|
|
83
49
|
|
|
84
50
|
- **It does — the step stays after `followup`.** `pnpm josh ms`, `pnpm josh issue:state <N>`,
|
|
85
51
|
`pnpm josh epic:next`, `pnpm josh backlog:next --exclude <N>`, and `pnpm josh lane:close` /
|
|
86
|
-
`pnpm josh lane:list`.
|
|
87
|
-
|
|
88
|
-
not removing it**: the parent reads the child's state from GitHub *because* a summary is not a
|
|
89
|
-
verifier ("Each child runs in a delegated unit"), so none of these may be dropped or answered from
|
|
90
|
-
memory.
|
|
52
|
+
`pnpm josh lane:list`. **De-duplicating a step is not removing it**: none of these may be dropped or
|
|
53
|
+
answered from memory.
|
|
91
54
|
- **It does not — the step is composed in the turn that issues `followup`.** The epic progress
|
|
92
|
-
comment's counter *values*
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
on. It is seconds of tail against a guard on session size, so it keeps its documented seam
|
|
102
|
-
(`backlogrun-progress.md` → "The check is asked at every merge").
|
|
103
|
-
|
|
104
|
-
**What runs beside a backgrounded command is the work that writes nothing to the working tree.** That
|
|
105
|
-
is the whole test, and it is the same one that lets the gate and the review overlap (`SKILL.md` →
|
|
106
|
-
§2): a step that edits makes the background command's result stale, so it is not something to overlap
|
|
107
|
-
with. Applied to the three waits a run actually has:
|
|
55
|
+
comment's counter *values* and the completion report body (placed beside `pnpm josh git -y` in the
|
|
56
|
+
table below). **Only the write follows the merge.**
|
|
57
|
+
- **`pnpm josh cost --cut` stays after the merge, and reads nothing from it** — its answer grows with
|
|
58
|
+
the session, so it keeps its documented seam (`backlogrun-progress.md` → "The check is asked at
|
|
59
|
+
every merge").
|
|
60
|
+
|
|
61
|
+
**What runs beside a backgrounded command is the work that writes nothing to the working tree** — a
|
|
62
|
+
step that edits makes the background command's result stale. Applied to the three waits a run
|
|
63
|
+
actually has:
|
|
108
64
|
|
|
109
65
|
| While this runs | Do this beside it |
|
|
110
66
|
| --------------- | ----------------- |
|
|
@@ -115,26 +71,21 @@ with. Applied to the three waits a run actually has:
|
|
|
115
71
|
|
|
116
72
|
**The turn never ends at the push.** The completion notification for `pnpm josh git -y` is what
|
|
117
73
|
resumes the run, and the turn that reads it goes straight through any branch-2 filing and
|
|
118
|
-
`pnpm josh epic:bundle` to `pnpm josh followup`.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
**One turn does end before the push, and only one: a dispatched lane child's pre-gate cut**
|
|
127
|
-
(joshuafolkken/kit#1839). It ends the turn before the gate and relaunches a fresh process in the same
|
|
128
|
-
act, so the run continues rather than stalling — the sanctioned boundary distinct from the push
|
|
129
|
-
turn-end this section forbids. The boundary, its two commands and the resume verification are the
|
|
130
|
-
`pre-gate-cut.md` skill document, its single source.
|
|
74
|
+
`pnpm josh epic:bundle` to `pnpm josh followup`. `pnpm josh rule:guard` refuses the foreground push
|
|
75
|
+
step and states both halves at that call (`prompts/collaboration-workflow/rule-delivery.md`); the push
|
|
76
|
+
reissued detached is not refused again. Rationale: `docs/maintainers/background-commands-rationale.md`
|
|
77
|
+
→ "Why the push is guarded".
|
|
78
|
+
|
|
79
|
+
**One turn does end before the push, and only one: a dispatched lane child's pre-gate cut.** It ends
|
|
80
|
+
the turn before the gate and relaunches a fresh process in the same act — `pre-gate-cut.md` → "Taking
|
|
81
|
+
the cut" is its single source.
|
|
131
82
|
|
|
132
83
|
**A headless lane child (`claude -p`) is where "a background command re-invokes the run" does not
|
|
133
|
-
hold: its background Bash tasks are killed when its turn ends
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
84
|
+
hold: its background Bash tasks are killed when its turn ends.** It hands the gate-to-merge region to
|
|
85
|
+
a foreground `pnpm josh ship --detach` instead (`chain-rule.md` step 0) — its preflight runs before the
|
|
86
|
+
supervisor exists, so a backgrounded `ship` dies with the turn; `pnpm josh rule:guard` refuses a
|
|
87
|
+
backgrounded `josh gate` / `git` / `followup` / `ship` there, and the `Stop` hook sends a child with a
|
|
88
|
+
task still running back to wait.
|
|
138
89
|
|
|
139
90
|
The operational section above is the single source of the rule. `followup.md`, `chain-rule.md` and
|
|
140
91
|
`backlogrun-progress.md` → "Progress while the run is quiet" route here for it rather than restating it.
|
|
@@ -18,14 +18,16 @@ by that supervisor; an AI parent is started only for a driver branch that requir
|
|
|
18
18
|
pnpm josh run:progress --wait --output <the transcript path of each delegated unit> # in the background
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
**Start it once; it reports by itself** (joshuafolkken/kit#3102). Each silence interval appends the
|
|
22
|
+
five labelled lines to the run's event stream as a heartbeat and to the ambient log, prints nothing to
|
|
23
|
+
standard output and keeps running — so a scheduled report never wakes the parent, and the parent
|
|
24
|
+
relays none. **It exits only on one of three, and the command computes which:**
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
| Exit | What the parent does |
|
|
27
|
+
| ------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
28
|
+
| Newly runnable backlog work (the `ready #N` line) | Read the ready line, act on it, and restart the watcher in that turn |
|
|
29
|
+
| `pnpm josh followup` removed the run's life record | Nothing — the run has ended |
|
|
30
|
+
| `--hours` elapsed (8 by default for `--wait`) | Restart the watcher in that turn |
|
|
29
31
|
|
|
30
32
|
**`pnpm josh run:watcher:guard` detects a missed restart** (joshuafolkken/kit#2113): it refuses when
|
|
31
33
|
lane children are in-flight but the watcher's life record has gone stale. **It is wired into
|
|
@@ -33,18 +35,18 @@ lane children are in-flight but the watcher's life record has gone stale. **It i
|
|
|
33
35
|
until the watcher is restarted — once per run, so the `pnpm josh run:progress --wait` that fixes it is
|
|
34
36
|
not blocked.
|
|
35
37
|
|
|
36
|
-
**`run:progress`
|
|
38
|
+
**`run:progress` writes the five labelled lines itself (joshuafolkken/kit#2026).** It emits the observation instant (`at`, local first and UTC beside it), the elapsed figures
|
|
37
39
|
(`quiet` and `unchanged`), the children in flight, the run state (`lanes`, `load`, `record`), and the
|
|
38
|
-
scheduled `next`, each behind its own label and on its own line — so
|
|
39
|
-
|
|
40
|
+
scheduled `next`, each behind its own label and on its own line — so where a session does present them
|
|
41
|
+
(`--once`), it relays the output verbatim and rounds, rephrases or re-labels nothing. How each field reads when it has nothing to report (`record
|
|
40
42
|
unread`, `no in-progress child yet`, `lanes none`, an absent `next`) is fixed by the command's own unit
|
|
41
43
|
tests. **A value said that way is still an observation, never a state**: `record unread` means no
|
|
42
44
|
`--output` path was given, not *not stalled*; `lanes none` is *no lane is open*, not *nothing is
|
|
43
45
|
running*; and the `next` line is a schedule — the time *if the silence continues*, superseded when a
|
|
44
46
|
real report resets the clock through `--mark`.
|
|
45
47
|
|
|
46
|
-
**
|
|
47
|
-
|
|
48
|
+
**A report is not an exit, and neither is a decline** — with no run recorded it keeps waiting, and the
|
|
49
|
+
`--hours` exit says so on standard error.
|
|
48
50
|
|
|
49
51
|
**`--mark` at every real report.** Whenever this loop reports something of its own — a child merged,
|
|
50
52
|
parked, a stop — run `pnpm josh run:progress --mark` in the same turn to restart the silence clock. The clock is silence, never a timer
|
|
@@ -130,21 +132,13 @@ in the same turn as each: **the Step 0 work summary, the pull request opening, e
|
|
|
130
132
|
verdict, and any `confirmation` / `failure` / `completion` notification or stop.** **A tool result only
|
|
131
133
|
you read is not one** — a gate run, a `gh` read, an edit.
|
|
132
134
|
|
|
133
|
-
**On a quiet tick the turn is the relayed line plus at most two lines of the run's own prose**, saying
|
|
134
|
-
only what changed stage and what is being waited on. **A tick is quiet when none of the real reports
|
|
135
|
-
happened since the last one**; a gate that went green, a review round, a file edited, a poll answering
|
|
136
|
-
`wait` are the run working, not a report. **No table, no re-listing of children, no restating of the
|
|
137
|
-
plan** — `epic:next`, the epic body and the progress comment hold all three. **A real report is not
|
|
138
|
-
bounded by that**: `--mark` restarts the clock, so a merge, a park or a stop is where the run may be
|
|
139
|
-
long.
|
|
140
|
-
|
|
141
135
|
**`--output` is omitted in a single-issue run, and `record` reads `unread`.** Rationale for the
|
|
142
136
|
watcher's scope and placement: `docs/maintainers/backlogrun-progress-rationale.md` → "Why the watcher
|
|
143
137
|
runs where it does".
|
|
144
138
|
|
|
145
139
|
**A run that merges needs no teardown; a run that stops has to end the reporting itself.** **A stop
|
|
146
140
|
keeps the `in-progress` label on purpose** — so **no further `--wait` is started** after the stop
|
|
147
|
-
notification, and
|
|
141
|
+
notification, and the running `--wait` is stopped in the same turn, since no report ends it. That
|
|
148
142
|
covers `halfrun`'s stop before commit, a `needs-human-review` stop, a split or prerequisite stop, and
|
|
149
143
|
a `backlogrun` named issue's failure stop.
|
|
150
144
|
|
|
@@ -275,11 +269,12 @@ run in lanes".
|
|
|
275
269
|
a session that cannot measure is read as `over`. **Never read the condition off `pnpm josh delegate
|
|
276
270
|
epic-child`** ("The check is asked at every merge" below).
|
|
277
271
|
3. **`wait`** — go back to step 1. **With something of this run's own in flight, that happens on the
|
|
278
|
-
wake the progress watcher's exit delivers** and the parent starts no sleep
|
|
279
|
-
figure bounds how soon the ask may be repeated. **
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
something is in flight" below decides
|
|
272
|
+
wake `lane:await` or the progress watcher's arrival exit delivers** and the parent starts no sleep
|
|
273
|
+
of its own; the 60 s figure bounds how soon the ask may be repeated. **A scheduled report is not one
|
|
274
|
+
of those wakes** (joshuafolkken/kit#3102). **With nothing in flight neither wake comes, so the parent
|
|
275
|
+
keeps the interval** — the case for "another repository has work but this one does not", and for a
|
|
276
|
+
cross-repository publish wait. "The wake exists only while something is in flight" below decides
|
|
277
|
+
which.
|
|
283
278
|
4. **`stop`** — report the parked children and finish.
|
|
284
279
|
5. **`complete`** — post the epic summary and finish.
|
|
285
280
|
6. **Exit code 1** — `epic:next` refused a cyclic or contradictory graph, or could not read a child.
|
|
@@ -421,8 +416,8 @@ in the background, in the same turn as that first `lane:list`. The wired `run:wa
|
|
|
421
416
|
|
|
422
417
|
**A carried-over child finishes in its own detached unit, and the resumed parent does not stand in front
|
|
423
418
|
of its merge.** A lane handed over at the cut is still running its own `fullrun` — the foreground
|
|
424
|
-
`pnpm josh followup` and the CI wait included — in a process of its own (background-commands.md →
|
|
425
|
-
"
|
|
419
|
+
`pnpm josh followup` and the CI wait included — in a process of its own (`background-commands.md` →
|
|
420
|
+
"Background the gate and push": foreground is *within the unit*, the background from the parent).
|
|
426
421
|
**So the parent never runs a carried-over child's `followup` itself**: it polls the handed-over lane and
|
|
427
422
|
opens new work beside it. **The reads and the dispatches go out together, in one turn** — `pnpm josh lane:list`,
|
|
428
423
|
`pnpm josh run:liveness`, `epic:next --lanes`, and opening a lane for a child it offers take none of each
|
|
@@ -472,7 +467,7 @@ clock". A stale child's label is
|
|
|
472
467
|
removed first, so the next poll can offer it. **A graph that has deadlocked on a cycle is not this loop's
|
|
473
468
|
to untangle**: `epic:next` detects it and exits with an error.
|
|
474
469
|
|
|
475
|
-
### The parent keeps no clock of its own —
|
|
470
|
+
### The parent keeps no clock of its own — a child's completion or an arrival is the wake
|
|
476
471
|
|
|
477
472
|
**After hand-off, the supervisor's driver owns the mechanical clock.** `backlog:drive` polls lane
|
|
478
473
|
completion and the backlog inside the detached process, without waking an AI parent; the parent-turn
|
|
@@ -483,12 +478,14 @@ source and `run:report` the final report.
|
|
|
483
478
|
`docs/maintainers/backlogrun-progress-rationale.md` → "Why the parent waits on classification, not a
|
|
484
479
|
clock".
|
|
485
480
|
|
|
486
|
-
The watcher reports on its own interval
|
|
481
|
+
The watcher reports on its own interval to the event stream and exits only on an arrival, so a judgment
|
|
482
|
+
session takes that exit — or a `lane:await` completion — as its prompt to act, never a report.
|
|
487
483
|
|
|
488
484
|
#### The wake exists only while something is in flight
|
|
489
485
|
|
|
490
|
-
`
|
|
491
|
-
decline; the driver still polls for new work and enforces the
|
|
486
|
+
`lane:await` wakes on a child's completion and `run:progress --wait` on an arrival; its reports wake
|
|
487
|
+
nobody. With no child in flight it may decline; the driver still polls for new work and enforces the
|
|
488
|
+
idle and whole-run bounds. A GitHub
|
|
492
489
|
listing failure stays a retry or unreadable answer from the offer command, never an empty backlog.
|
|
493
490
|
|
|
494
491
|
`epic:next` does not report when a label was applied, so read that from the issue's timeline:
|
|
@@ -365,7 +365,7 @@ subsection.
|
|
|
365
365
|
| Answer | What to do | Budget answer |
|
|
366
366
|
| --- | --- | --- |
|
|
367
367
|
| One or more issue numbers | Start each one as a child, up to the free lanes — `backlogrun-lanes.md` → "Lanes" and "Each child runs in a delegated unit", unchanged. Then **ask the command again**, with the merged numbers added to `--exclude` | `candidates` |
|
|
368
|
-
| `wait`, with something of this run's own still in flight | Everything opted in is blocked or already running, so waiting can still change the answer. **Ask the command again on the wake the progress watcher's exit
|
|
368
|
+
| `wait`, with something of this run's own still in flight | Everything opted in is blocked or already running, so waiting can still change the answer. **Ask the command again on the in-flight wake — `pnpm josh lane:await` or the progress watcher's arrival exit, never a report** — the parent starts no sleep of its own, and the interval is a floor on the re-ask rather than a clock (`backlogrun-progress.md` → "Waiting, and never waiting forever" and "The parent keeps no clock of its own") | `blocked` |
|
|
369
369
|
| `wait` this checkout can never resolve — the only candidates the command reported on standard error are in other repositories, and this run has nothing of its own in flight | Report those candidates with their checkouts. **Waiting cannot resolve them, but a person opting a new issue in here still can**, so the ending is the idle watch's rather than this row's | `exhausted` |
|
|
370
370
|
| `stop` | Nothing can proceed without a person. Report the parked issues and finish | `parked` |
|
|
371
371
|
| `triage` | A candidate lacks `run:solo` / `run:lane` (joshuafolkken/kit#2779). Judge each one stderr names as the pre-start pass does, then **ask again**; running children continue | `untriaged` |
|
|
@@ -451,7 +451,7 @@ tracks.
|
|
|
451
451
|
| Verdict | What the loop does |
|
|
452
452
|
| --- | --- |
|
|
453
453
|
| `run` | Start what `backlog:next` offered, up to the free lanes. The reason names how many more the maximum still allows; start no more than that |
|
|
454
|
-
| `watch` | Ask both commands again — at the 5-minute idle poll while the backlog is empty **and** nothing of this run's is in flight, and at the 60-second polling interval in every other case (a blocked backlog, a drain, or a watch that opened while children were still merging). *Whether the parent keeps that interval as a clock of its own* is the in-flight test: with nothing in flight the watcher declines for the whole watch and never exits, so the parent sleeps the interval itself; with something in flight the wake is the watcher's exit and the interval is only a floor on the re-ask (`backlogrun-progress.md` → "The wake exists only while something is in flight"). **Nothing is held while watching** — the working tree's hold and each drained lane were released at the last child's merge, so a watching run blocks no other run |
|
|
454
|
+
| `watch` | Ask both commands again — at the 5-minute idle poll while the backlog is empty **and** nothing of this run's is in flight, and at the 60-second polling interval in every other case (a blocked backlog, a drain, or a watch that opened while children were still merging). *Whether the parent keeps that interval as a clock of its own* is the in-flight test: with nothing in flight the watcher declines for the whole watch and never exits, so the parent sleeps the interval itself; with something in flight the wake is `pnpm josh lane:await` or the watcher's arrival exit — never a report — and the interval is only a floor on the re-ask (`backlogrun-progress.md` → "The wake exists only while something is in flight"). **Nothing is held while watching** — the working tree's hold and each drained lane were released at the last child's merge, so a watching run blocks no other run |
|
|
455
455
|
| `stop` | Report and finish. The reason it printed **is** the termination reason the completion report carries |
|
|
456
456
|
|
|
457
457
|
**At the drain the retrospective fires before this watch, not after it** (joshuafolkken/kit#2335):
|
|
@@ -32,8 +32,8 @@ call reports `hold`.
|
|
|
32
32
|
`pnpm josh run:release`: `gh api -X DELETE repos/{owner}/{repo}/issues/<N>/labels/in-progress
|
|
33
33
|
2>/dev/null || true`. A `needs-human-review` stop keeps both hold and label.
|
|
34
34
|
3. **Ask the session boundary in the same turn as the hold** — `pnpm josh cost --cut`. `under`
|
|
35
|
-
continues; `over` (or unanswerable) stops before the title
|
|
36
|
-
|
|
35
|
+
continues; `over` (or unanswerable) stops before the title — `run:entry` sends this and step 1's
|
|
36
|
+
`confirmation` Telegram and runs `run:release` (`stop notified: …`); by hand only for `new`.
|
|
37
37
|
**Skip it when dispatched by `backlogrun`** (that batch owns the question). `backlogrun-progress.md`
|
|
38
38
|
→ "The hand-off" is the single source of the check and the shared 135,000 threshold.
|
|
39
39
|
4. **Gather the mechanical reads — `pnpm josh run:prep <N>`**: `issue:read`'s body/comments
|
|
@@ -51,7 +51,7 @@ call reports `hold`.
|
|
|
51
51
|
## The progress step and the lane-child seam
|
|
52
52
|
|
|
53
53
|
- **Start the progress watcher once the hold is claimed** — `pnpm josh run:progress --wait` in the
|
|
54
|
-
background,
|
|
54
|
+
background, started once and relayed never, and `pnpm josh run:progress --mark` in the same turn as
|
|
55
55
|
every real report (`backlogrun-progress.md` → "Progress while the run is quiet"). A `fullrun`
|
|
56
56
|
dispatched as a lane child starts none and never reads that document (`pnpm josh read:set
|
|
57
57
|
lane-child`). **The watcher is a per-session heartbeat; the run's report surface is not it** — the
|
|
@@ -62,7 +62,8 @@ call reports `hold`.
|
|
|
62
62
|
before the hold, joshuafolkken/kit#2760); on `resume` it skips the title, plan, hold and implementation and goes to the gate. At the pre-gate
|
|
63
63
|
boundary — immediately after `pnpm josh main:merge`, before the gate — it takes the cut with
|
|
64
64
|
`pnpm josh run:cut <N>` (the ordered step in `chain-rule.md`), and it records any park on the Issue before the stop notify.
|
|
65
|
-
`pre-gate-cut.md`
|
|
65
|
+
`pre-gate-cut.md` → "Resuming — the fresh process's entry check" and `pre-gate-cut.md` → "Taking
|
|
66
|
+
the cut" are the single sources of the two.
|
|
66
67
|
- **`resume: halfrun`** adopted a stopped `halfrun` (#2796): gate in full; `resume: prrun-*` a stopped
|
|
67
68
|
`prrun` (#3023); `working-tree-hold.md`.
|
|
68
69
|
|
|
@@ -13,18 +13,19 @@ that holds its detail.
|
|
|
13
13
|
|
|
14
14
|
1. **Claim the working tree first** — `pnpm josh run:entry <N> --to halfrun` (bare `pnpm josh
|
|
15
15
|
run:hold` for `new`), ahead of the title and a `new` filing; it folds steps 3 and 5 and starts
|
|
16
|
-
at its stage line's `start:` (`SKILL.md` → §2k). `busy` / `unknown` stop with a `confirmation` Telegram. **The stop
|
|
16
|
+
at its stage line's `start:` (`SKILL.md` → §2k). `busy` / `unknown` stop with a `confirmation` Telegram (`run:entry` sends it). **The stop
|
|
17
17
|
before commit keeps the hold** (a second run would trample the uncommitted work); a stop on a
|
|
18
18
|
split, prerequisite or third-party target releases it. `working-tree-hold.md` is the single source; a
|
|
19
19
|
cross-repository target resolves its checkout from `pnpm josh doctor` first (`target-repository.md`).
|
|
20
20
|
2. **Apply `in-progress` the moment `run:hold` answered `hold`** — the stop before commit keeps it on;
|
|
21
21
|
a stop that leaves the tree clean removes it in the same turn as `pnpm josh run:release` (`gh api -X
|
|
22
22
|
DELETE repos/{owner}/{repo}/issues/<N>/labels/in-progress 2>/dev/null || true`).
|
|
23
|
-
3. **Ask the session boundary** — `pnpm josh cost --cut` (folded into `run:entry`); `over` stops
|
|
24
|
-
`halfrun new
|
|
23
|
+
3. **Ask the session boundary** — `pnpm josh cost --cut` (folded into `run:entry`); `over` stops — `run:entry` notifies and releases
|
|
24
|
+
(`halfrun new`: by hand). **Skip it when dispatched by a batch.** `backlogrun-progress.md` → "The hand-off" is
|
|
25
25
|
the single source of the check and the shared 135,000 threshold.
|
|
26
26
|
4. **Start the progress watcher once the hold is claimed** — `pnpm josh run:progress --wait` in the
|
|
27
|
-
background,
|
|
27
|
+
background, started once — it reports to the event stream itself and nothing is relayed — and
|
|
28
|
+
`--mark` in the same turn as every real report; the stop before commit ends the watcher
|
|
28
29
|
itself (`backlogrun-progress.md` → "Progress while the run is quiet").
|
|
29
30
|
5. **The mechanical reads** — `run:entry` folds `run:prep` (body/comments — `SKILL.md` → §2g;
|
|
30
31
|
`human_review`; `latest:scope`); a `new` entry runs `pnpm josh run:prep <N>` once filed.
|
|
@@ -64,21 +64,13 @@ merge is CI**: the `Security Audit` job runs on every pull request and is one of
|
|
|
64
64
|
whatever this gate answered locally. The local reading is a head start on a failure CI would catch
|
|
65
65
|
anyway; it was never the only net.
|
|
66
66
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
The
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
so no entry needs a rule of its own — and the batch hoists survive it unchanged, because a batch's
|
|
75
|
-
second child asks the same command and is told `skip`.
|
|
76
|
-
|
|
77
|
-
**The lock file the update rewrites still lands with whichever issue ran it.** `josh latest` leaves
|
|
78
|
-
`pnpm-lock.yaml` modified and that issue's `pnpm josh git -y` commits it, exactly as before. What the
|
|
79
|
-
window removes is the other runs carrying the same bumps; it does not make that one diff clean.
|
|
80
|
-
Should the issue then fail CI on a bump rather than on its own change, that is a dependency problem
|
|
81
|
-
found once — fix it forward before parking the issue for it.
|
|
67
|
+
## The lock file lands with the issue that ran the update
|
|
68
|
+
|
|
69
|
+
**The lock file the update rewrites lands with whichever issue ran it.** `josh latest` leaves
|
|
70
|
+
`pnpm-lock.yaml` modified and that issue's `pnpm josh git -y` commits it. Should the issue then fail
|
|
71
|
+
CI on a bump rather than on its own change, fix it forward before parking the issue for it. Rationale
|
|
72
|
+
for the elapsed-time window: `docs/maintainers/latest-gate-rationale.md` → "Why an elapsed-time
|
|
73
|
+
window rather than once per batch".
|
|
82
74
|
|
|
83
75
|
This file is the single source of the rule. `fullrun.md`, `halfrun.md`, `backlogrun.md` and `backlogrun.md`
|
|
84
76
|
each name `pnpm josh latest:scope` at the point their procedure reaches it and route here for
|
|
@@ -69,9 +69,8 @@ pnpm josh run:cut <N>
|
|
|
69
69
|
**`cut` is the only verdict that ends the turn.** Every other one — `under-threshold` included — leaves
|
|
70
70
|
the current process to carry the run on itself.
|
|
71
71
|
|
|
72
|
-
### The gate refuses until the cut has been taken
|
|
72
|
+
### The gate refuses until the cut has been taken
|
|
73
73
|
|
|
74
|
-
**This step was carried as prose and fired exactly never.** In measured lane children the cut was taken **0 times**, so
|
|
75
74
|
`pnpm josh rule:guard` **refuses `pnpm josh gate`** while this checkout is a lane and no cut record is
|
|
76
75
|
carried, handing back the command above. Rationale:
|
|
77
76
|
`docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
|
|
@@ -165,13 +164,10 @@ hand-off". The parent's seam and the child's `run_cut.IMPLEMENTATION_CONTEXT_THR
|
|
|
165
164
|
**135_000** `CONTEXT_CUT_THRESHOLD` (aliased so the tests cannot drift). No separate measurement is
|
|
166
165
|
built for the lane child.
|
|
167
166
|
|
|
168
|
-
### It is a guard, fired at the edit that crosses the threshold
|
|
167
|
+
### It is a guard, fired at the edit that crosses the threshold
|
|
169
168
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
|
|
173
|
-
|
|
174
|
-
So `pnpm josh rule:guard` **refuses an `Edit` / `Write`** while this checkout is a dispatched lane child
|
|
169
|
+
Rationale: `docs/maintainers/pre-gate-cut-rationale.md` → "Why the rules are guards, not prose".
|
|
170
|
+
`pnpm josh rule:guard` **refuses an `Edit` / `Write`** while this checkout is a dispatched lane child
|
|
175
171
|
whose recent-context cost is over threshold, handing back `pnpm josh run:cut --impl <N> --handoff <path>` — the
|
|
176
172
|
refusal lands _before_ the edit. `cut` ends the turn, the rest leave this process implementing; a fresh
|
|
177
173
|
process's `pnpm josh run:cut --resume <N>` then answers **`resume-impl`**, so it **skips the title, plan,
|
|
@@ -33,27 +33,13 @@ does. **There is no second criterion.** §2i's observation, the review round cap
|
|
|
33
33
|
prerequisite each route a second filing through it, delivered by `pnpm josh rule:guard` at the run's
|
|
34
34
|
second `pnpm josh issue:file` call, never the first.
|
|
35
35
|
|
|
36
|
-
## Why the default is not to split
|
|
37
|
-
|
|
38
|
-
**The rules were manufacturing Issues faster than runs could close them.** Execution was never the
|
|
39
|
-
bottleneck; arrival was, and this assessment was one of the routes producing it: `route:split`
|
|
40
|
-
accounted for **28 of the 119 open Issues (24%)**.
|
|
41
|
-
|
|
42
|
-
**Separability is not scarce, which is why a test made only of it splits nearly everything.** Almost
|
|
43
|
-
any request can be described as several deliverables that could each ship alone, so the old test bit on
|
|
44
|
-
requests worth a handful of lines. The second question is what makes the test bite only where one Issue
|
|
45
|
-
would genuinely be unverifiable in one pass. The review round cap's default and the WIP cap changed
|
|
46
|
-
alongside it, in one commit.
|
|
47
|
-
|
|
48
36
|
## Diff size is not a reason to split, and that is measured
|
|
49
37
|
|
|
50
38
|
**Size is a bar a split has to clear; it is never a reason to split.** Question 2 is a *minimum* — below
|
|
51
|
-
it the work stays whole — and nothing makes a large diff a reason to divide one.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
which splitting to cut it pays). **A proposal to add a size threshold that splits more is required to
|
|
56
|
-
say why that data does not reach it.**
|
|
39
|
+
it the work stays whole — and nothing makes a large diff a reason to divide one. **A proposal to add a
|
|
40
|
+
size threshold that splits more is required to say why the round-1 measurement does not reach it.**
|
|
41
|
+
Rationale: `docs/maintainers/split-assessment-rationale.md` → "Why the default is not to split" and
|
|
42
|
+
`docs/maintainers/split-assessment-rationale.md` → "Why diff size is not a reason to split".
|
|
57
43
|
|
|
58
44
|
**The size half is measured, not eyeballed — `pnpm josh split:assess`.** It counts the branch's
|
|
59
45
|
changed files and changed lines with test files excluded and answers `split` / `single` on size
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Setup Node.js
|
|
2
|
+
description: >
|
|
3
|
+
Set Node.js up at the version every kit workflow runs on, optionally pointed at a package
|
|
4
|
+
registry.
|
|
5
|
+
|
|
6
|
+
# The one place the Node.js version of kit's workflows is written (joshuafolkken/kit#3084). Every
|
|
7
|
+
# job used to call actions/setup-node with its own `node-version` literal, so a version move had to
|
|
8
|
+
# find all of them. A job that needs a different runtime says so explicitly — `node-26-pnpm` in
|
|
9
|
+
# `ci.yml` passes its own runtime to `.github/actions/setup-pnpm` instead of calling this.
|
|
10
|
+
#
|
|
11
|
+
# Distributed: `josh sync` writes this file into a consumer beside the workflows that call it, the
|
|
12
|
+
# same way as `.github/actions/setup-pnpm`. `workflow_pin_logic` reads this file as a source of
|
|
13
|
+
# canonical action pins.
|
|
14
|
+
|
|
15
|
+
inputs:
|
|
16
|
+
registry-url:
|
|
17
|
+
description: Passed to actions/setup-node's `registry-url`; empty writes no `.npmrc`.
|
|
18
|
+
required: false
|
|
19
|
+
default: ''
|
|
20
|
+
scope:
|
|
21
|
+
description: Passed to actions/setup-node's `scope`, for a scoped registry.
|
|
22
|
+
required: false
|
|
23
|
+
default: ''
|
|
24
|
+
|
|
25
|
+
runs:
|
|
26
|
+
using: composite
|
|
27
|
+
steps:
|
|
28
|
+
- name: Setup Node.js
|
|
29
|
+
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
30
|
+
with:
|
|
31
|
+
node-version: '24'
|
|
32
|
+
registry-url: ${{ inputs.registry-url }}
|
|
33
|
+
scope: ${{ inputs.scope }}
|
|
@@ -10,10 +10,10 @@ description: >
|
|
|
10
10
|
# job that calls this action cannot install without the scan.
|
|
11
11
|
#
|
|
12
12
|
# Distributed: `josh sync` writes this file into a consumer beside the workflows that call it
|
|
13
|
-
# (`pr-classification.yml`), stamped as managed like they are (joshuafolkken/kit#3013).
|
|
14
|
-
# `
|
|
15
|
-
#
|
|
16
|
-
#
|
|
13
|
+
# (`ci.yml` and `pr-classification.yml`), stamped as managed like they are (joshuafolkken/kit#3013).
|
|
14
|
+
# The distributed `ci.yml` calls it exactly as kit's own does, so a consumer's CI prepares pnpm on
|
|
15
|
+
# the path kit's CI runs (joshuafolkken/kit#3095). `workflow_pin_logic` reads this file as a source
|
|
16
|
+
# of canonical action pins.
|
|
17
17
|
|
|
18
18
|
inputs:
|
|
19
19
|
install:
|
|
@@ -8,6 +8,7 @@ jobs:
|
|
|
8
8
|
create-tag:
|
|
9
9
|
name: Create Git Tag if Version Changed
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
|
+
timeout-minutes: 10
|
|
11
12
|
permissions:
|
|
12
13
|
actions: write
|
|
13
14
|
contents: write
|
|
@@ -19,9 +20,7 @@ jobs:
|
|
|
19
20
|
fetch-depth: 2
|
|
20
21
|
|
|
21
22
|
- name: Setup Node.js
|
|
22
|
-
uses: actions/setup-node
|
|
23
|
-
with:
|
|
24
|
-
node-version: '24'
|
|
23
|
+
uses: ./.github/actions/setup-node
|
|
25
24
|
|
|
26
25
|
- name: Check if package.json changed
|
|
27
26
|
id: pkg_changed
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -224,9 +224,8 @@ jobs:
|
|
|
224
224
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
225
225
|
|
|
226
226
|
- name: Setup Node.js
|
|
227
|
-
uses: actions/setup-node
|
|
227
|
+
uses: ./.github/actions/setup-node
|
|
228
228
|
with:
|
|
229
|
-
node-version: '24'
|
|
230
229
|
registry-url: 'https://npm.pkg.github.com'
|
|
231
230
|
|
|
232
231
|
- name: Setup ESLint cache
|
|
@@ -327,8 +326,9 @@ jobs:
|
|
|
327
326
|
|
|
328
327
|
# The other half of the gate, on a runner of its own. A GitHub job is its own machine, so this job
|
|
329
328
|
# sets Node up again; the pnpm preamble is the shared `.github/actions/setup-pnpm` action
|
|
330
|
-
# (joshuafolkken/kit#2982),
|
|
331
|
-
#
|
|
329
|
+
# (joshuafolkken/kit#2982), which `templates/workflows/ci.yml` calls the same way, so
|
|
330
|
+
# `scripts/ci/ci-yml-action-parity.test.ts` compares the two files without the action's own pins
|
|
331
|
+
# (joshuafolkken/kit#3095).
|
|
332
332
|
#
|
|
333
333
|
# No ESLint cache here — nothing in this job lints — and no `--maxWorkers`: `gate-plan.ts` leaves
|
|
334
334
|
# any machine below its measured 11 cores uncapped, so vitest sizes its own pool from the runner
|
|
@@ -347,9 +347,8 @@ jobs:
|
|
|
347
347
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
348
348
|
|
|
349
349
|
- name: Setup Node.js
|
|
350
|
-
uses: actions/setup-node
|
|
350
|
+
uses: ./.github/actions/setup-node
|
|
351
351
|
with:
|
|
352
|
-
node-version: '24'
|
|
353
352
|
registry-url: 'https://npm.pkg.github.com'
|
|
354
353
|
|
|
355
354
|
- name: Setup pnpm and install dependencies
|
|
@@ -525,9 +524,8 @@ jobs:
|
|
|
525
524
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
526
525
|
|
|
527
526
|
- name: Setup Node.js
|
|
528
|
-
uses: actions/setup-node
|
|
527
|
+
uses: ./.github/actions/setup-node
|
|
529
528
|
with:
|
|
530
|
-
node-version: '24'
|
|
531
529
|
registry-url: 'https://npm.pkg.github.com'
|
|
532
530
|
|
|
533
531
|
- name: Setup build cache
|
|
@@ -595,6 +593,7 @@ jobs:
|
|
|
595
593
|
needs.e2e-detect.result == 'success' &&
|
|
596
594
|
(needs.e2e.result == 'success' || needs.e2e.result == 'skipped')
|
|
597
595
|
runs-on: ubuntu-latest
|
|
596
|
+
timeout-minutes: 5
|
|
598
597
|
permissions:
|
|
599
598
|
contents: write
|
|
600
599
|
steps:
|