@wildorder/nightshift 0.11.1 → 0.13.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.
Files changed (48) hide show
  1. package/dist/author.d.ts.map +1 -1
  2. package/dist/author.js +43 -0
  3. package/dist/author.js.map +1 -1
  4. package/dist/cli.js +86 -3
  5. package/dist/cli.js.map +1 -1
  6. package/dist/commit-plan.d.ts +40 -0
  7. package/dist/commit-plan.d.ts.map +1 -0
  8. package/dist/commit-plan.js +154 -0
  9. package/dist/commit-plan.js.map +1 -0
  10. package/dist/decision-ledger.d.ts +10 -0
  11. package/dist/decision-ledger.d.ts.map +1 -1
  12. package/dist/decision-ledger.js +7 -0
  13. package/dist/decision-ledger.js.map +1 -1
  14. package/dist/exit-codes.d.ts +16 -2
  15. package/dist/exit-codes.d.ts.map +1 -1
  16. package/dist/exit-codes.js +17 -2
  17. package/dist/exit-codes.js.map +1 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/install-skills.d.ts +1 -1
  23. package/dist/install-skills.d.ts.map +1 -1
  24. package/dist/install-skills.js +5 -1
  25. package/dist/install-skills.js.map +1 -1
  26. package/dist/manifest.d.ts +47 -13
  27. package/dist/manifest.d.ts.map +1 -1
  28. package/dist/manifest.js +80 -11
  29. package/dist/manifest.js.map +1 -1
  30. package/dist/preflight.d.ts +73 -0
  31. package/dist/preflight.d.ts.map +1 -0
  32. package/dist/preflight.js +225 -0
  33. package/dist/preflight.js.map +1 -0
  34. package/dist/publish.d.ts +36 -0
  35. package/dist/publish.d.ts.map +1 -1
  36. package/dist/publish.js +185 -0
  37. package/dist/publish.js.map +1 -1
  38. package/dist/run-program.d.ts +35 -1
  39. package/dist/run-program.d.ts.map +1 -1
  40. package/dist/run-program.js +224 -10
  41. package/dist/run-program.js.map +1 -1
  42. package/dist/skill-roots.d.ts +11 -3
  43. package/dist/skill-roots.d.ts.map +1 -1
  44. package/dist/skill-roots.js +59 -12
  45. package/dist/skill-roots.js.map +1 -1
  46. package/package.json +2 -2
  47. package/skills/backlog-capture/SKILL.md +182 -0
  48. package/skills/plan-program/SKILL.md +221 -5
@@ -0,0 +1,182 @@
1
+ ---
2
+ name: backlog-capture
3
+ description: Capture a discovered-but-deferred feature or larger piece of work as a durable backlog item, written now from the current session's context, so a future planning session starts warm. Use the moment you hit something bigger than the task at hand and want to remember why — in an interactive session with a human present. Do not use during an unattended or automated agent run.
4
+ argument-hint: "[what you discovered]"
5
+ ---
6
+
7
+ # Capture a backlog item
8
+
9
+ A coding session routinely stumbles on something that is really a larger
10
+ feature: too big to absorb into the task at hand, valuable enough to become
11
+ future work. The expensive part of that moment is the context — which files
12
+ constrain the design, which approach was already tried and rejected and why,
13
+ what the naive version breaks. That context is gone by tomorrow. This skill
14
+ gives it a durable, repo-tracked home, written while you still hold it.
15
+
16
+ ## When this fires
17
+
18
+ Fire this yourself, the moment you recognize the discovery, without waiting
19
+ for a human to ask for it. If capture waits until someone notices and
20
+ requests it, the context has already started to fade — the entire point is
21
+ to record it while it is still live.
22
+
23
+ Use this only in an interactive session with a human present to see what
24
+ gets written. Decline to use it during an unattended or automated agent
25
+ run — there is nobody there to review the capture, and this skill is not a
26
+ substitute for whatever that run already does with its own findings. If you
27
+ cannot tell whether a human is present for this session, do not use this
28
+ skill.
29
+
30
+ ## The item format
31
+
32
+ This is the one canonical definition of a backlog item. Nowhere else in this
33
+ project restates it — if you find another description of the item format
34
+ elsewhere, this one wins.
35
+
36
+ An item is one file at `docs/backlog/{slug}.md`. One item per file, never
37
+ several discoveries folded into one file. The slug is the item's title,
38
+ lowercased and converted to kebab-case; do not invent a separate slug that
39
+ diverges from the title.
40
+
41
+ ### Frontmatter
42
+
43
+ Frontmatter carries only the facts a later reader needs to act on
44
+ mechanically. Everything else belongs in the body as prose.
45
+
46
+ ```yaml
47
+ ---
48
+ status: captured
49
+ captured: 2026-09-03
50
+ ---
51
+ ```
52
+
53
+ - `status` — one of `captured | planned | done | declined`. A fresh capture
54
+ is always `captured`.
55
+ - `captured` — the date of capture, as `YYYY-MM-DD`.
56
+ - `planned-into` — the id of the program (the future piece of work) that
57
+ absorbed this item. **Absent until planned.** Do not write this field when
58
+ you capture an item; it is added later, by whatever later reads this
59
+ backlog as planning input, only at the moment this item's status becomes
60
+ `planned`.
61
+
62
+ Do not add a `title` or `slug` field. The title lives in the H1 heading and
63
+ the slug in the filename; duplicating either into frontmatter would give the
64
+ same fact two homes that can drift apart.
65
+
66
+ ### Body — narrative sections
67
+
68
+ Write the body as prose, for a human reading it cold, months from now, with
69
+ none of this session's context. Use these named sections. Each one earns its
70
+ keep for a specific reason — fill it from what you actually know right now,
71
+ not from what you imagine you might discover later:
72
+
73
+ - **What the session hit and where** — the concrete trigger: file paths, the
74
+ task the session was actually doing, the symptom or realization that
75
+ surfaced this.
76
+ - **Why it is bigger than this session** — what makes this a future piece of
77
+ work rather than something to fold into the current task.
78
+ - **Constraints discovered** — the expensive knowledge: what a design here
79
+ must respect, what the existing code already forces, anything that would
80
+ otherwise have to be rediscovered the hard way.
81
+ - **Approaches considered or rejected, and why** — so whoever picks this up
82
+ does not re-walk a dead end you already ruled out.
83
+ - **Pointers** — branches, commits, related items (link them by slug or
84
+ path), anything else that helps someone orient.
85
+
86
+ This is prose in, prose out. Nothing grades or validates what you write here
87
+ — a thin capture with only one or two sections filled in is still worth far
88
+ more than no capture at all. Write what you actually know; do not pad
89
+ sections with speculation to look complete.
90
+
91
+ ## Capture behavior
92
+
93
+ - **Write it now, in full, from this session's live context.** Do not leave
94
+ a one-line stub or a TODO to flesh out later — by the time anyone returns
95
+ to flesh it out, the context this skill exists to preserve is already
96
+ gone. This is the central instruction; everything else here supports it.
97
+ - **Check `docs/backlog/` first for an item that already covers this
98
+ ground.** If one exists, enrich it with what this session adds instead of
99
+ creating a near-duplicate file.
100
+ - **Create `docs/backlog/` if it does not exist yet.** Nothing scaffolds
101
+ this directory in advance; the first real capture creates it.
102
+ - **Never modify anything outside `docs/backlog/`.** This skill is strictly
103
+ additive and scoped to that one directory.
104
+ - **Never overwrite an unrelated file already in `docs/backlog/`.** If a
105
+ file there was not written by this skill and does not cover the same
106
+ discovery, leave it alone and create a new item instead.
107
+ - **Say nothing about how any particular tool or program consumes this
108
+ backlog later.** This skill only describes the item and how to write it;
109
+ it does not depend on, and must not reference, any specific downstream
110
+ tooling or process. It works the same way in any repository that has it
111
+ installed.
112
+ - **Capture `HEAD` before committing.** Before staging anything, record the
113
+ pre-commit baseline with `git rev-parse HEAD`. In a brand-new repository
114
+ with no commits yet, `HEAD` is unborn and this fails — that failure is
115
+ itself the baseline (it means "no commit exists yet"); treat it as a
116
+ sentinel rather than an error, and do not let it block the commit attempt
117
+ below. This captured value (or the unborn sentinel) is what the
118
+ post-commit confirmation below compares against — without it, "confirm
119
+ `HEAD` moved" has nothing to move *from*.
120
+ - **Commit the item the moment it is written, in a repository that uses
121
+ git.** Immediately after writing `docs/backlog/{slug}.md`, make one commit
122
+ that contains only that file — stage exactly it and commit only it, so
123
+ nothing else already sitting in the tree rides along. Use the kebab-case
124
+ `{slug}` in the commit message, not the human title: the slug is
125
+ constrained to `[a-z0-9-]`, so it is safe to interpolate into the command,
126
+ while a title can carry a quote, backtick, `$(...)`, or other shell
127
+ metacharacter that could truncate, alter, or execute the command on common
128
+ shells.
129
+
130
+ ```sh
131
+ git add -- docs/backlog/{slug}.md
132
+ git commit -m "backlog: capture {slug}" -- docs/backlog/{slug}.md
133
+ ```
134
+
135
+ - **Confirm the commit actually landed before reporting anything about
136
+ it, by comparing against the `HEAD` you captured before committing.** A
137
+ commit can fail for reasons beyond "no git repository" — unset git
138
+ identity, a failing pre-commit hook, a signing failure, no write
139
+ permission, or nothing new to commit. After committing, run
140
+ `git rev-parse HEAD` again and confirm it differs from the pre-commit
141
+ value you captured above (or, if the pre-commit capture was the unborn
142
+ sentinel, confirm `HEAD` now resolves at all — either case is "a new
143
+ commit now exists that did not before"), and that this new commit's one
144
+ changed file is `docs/backlog/{slug}.md`, before reading any branch or SHA
145
+ from it. Checking only "the current commit's diff is exactly this file"
146
+ without that prior-`HEAD` comparison is not sufficient: a bare
147
+ `git rev-parse HEAD` run after a *failed* commit still resolves and names
148
+ an older, unrelated commit, and reporting that as the landing SHA hands
149
+ the human a false rescue command; the captured pre-commit value is what
150
+ lets you tell that older commit apart from a genuinely new one. If the
151
+ commit did not land, do the opposite of reporting: say plainly that the
152
+ item could not be committed and why (surface git's message), note that
153
+ the item file is written to disk regardless — the durable capture is the
154
+ point and stands whether or not the commit succeeded — and leave
155
+ committing to the human. **Do not name a branch, a SHA, or a
156
+ cherry-pick/rescue command on this path** — there is no confirmed commit
157
+ for any of those to describe, and offering one anyway (even one built
158
+ from the pre-commit `HEAD`) hands the human a rescue command for a commit
159
+ that does not exist.
160
+ - **Report which branch the confirmed commit landed on.** Read the current
161
+ branch with plain git (for example `git branch --show-current`) and tell
162
+ the human; do not switch branches to check.
163
+ - **Flag a branch unlikely to reach the trunk, and hand over the exact
164
+ rescue command.** If the confirmed landing branch looks like a scratch or
165
+ experiment branch — a throwaway unlikely ever to be merged into the
166
+ repository's default branch — say so plainly, so the human can decide
167
+ whether to re-home the item. When you raise that flag, include the exact
168
+ rescue command with the real, confirmed commit SHA — `git cherry-pick
169
+ <sha>` (read via `git rev-parse HEAD` only after confirming the commit
170
+ landed above), run from the default branch — so re-homing is one paste,
171
+ not a later investigation. The only-the-item-file staging boundary above
172
+ **isolates** that cherry-pick from unrelated files, because the commit
173
+ touches only the one new item file — it does **not** guarantee a clean
174
+ apply in every case (the default branch may already carry the same path
175
+ or a divergent version of it), so present cherry-pick as the convenience
176
+ and tell the human to fall back to merging the branch if it conflicts.
177
+ Never switch branches, cherry-pick, or move the item yourself; commit
178
+ where the session already stands, name the branch, flag the risk, hand
179
+ over the command, and leave relocation to the human.
180
+ - **When there is no git repository, the commit simply cannot happen.**
181
+ Write the item and say so; the durable file on disk is still the point,
182
+ whether or not this repository uses git.
@@ -26,12 +26,80 @@ Read:
26
26
  present.
27
27
  - When re-planning after a run, the program's run report and decision ledger
28
28
  under `docs/programs/` — a prior run's parked workstreams, risk-accepted
29
- findings, and recorded decisions are planning input, not noise. Plan from
29
+ findings, recorded decisions, and **unmet human prerequisites** are
30
+ planning input, not noise. A prior run's workstreams left `awaiting_human`,
31
+ and the `prerequisites` entries still `pending` that they reference, name
32
+ work a human has not yet done. Preserve every prerequisite record that any
33
+ incomplete workstream still references — verbatim, with its stored
34
+ `status` unchanged, including a `satisfied` record a live workstream still
35
+ points at; do not drop it merely because it is satisfied, or the workstream
36
+ would reference an id the manifest no longer defines. Only a record whose
37
+ stored status is already `satisfied` may be treated as settled
38
+ infrastructure, and only because a prior run's preflight flipped it — never
39
+ because the planner judged the human's work done. A record still marked
40
+ `pending` stays `pending` even when the human reports having done the
41
+ action: the planner never flips a prerequisite's status; only the
42
+ deterministic preflight satisfies one, on the next run. Plan from
30
43
  the repository state that exists now, not from the original pre-program
31
44
  design; treat work a prior run verified and committed as current
32
45
  architecture rather than scheduling it again, and give replacement work new
33
46
  workstream IDs and task-file paths so nothing overwrites the historical
34
47
  record.
48
+ - `docs/backlog/`, when it exists. Treat its `captured` items as planning
49
+ input on equal footing with the vision and as-built, and surface the ones
50
+ relevant to the phase being planned before decomposing work in the next
51
+ step — a backlog item is prior context someone already paid for, not a
52
+ file to skim past. If `docs/backlog/` does not exist, proceed without
53
+ comment; an absent or empty backlog changes nothing about how this skill
54
+ runs.
55
+
56
+ Also look past the working tree: because captures commit where the
57
+ session stands, an item can sit on an unmerged branch and be entirely
58
+ invisible to this listing. In a git repository, enumerate ref tips,
59
+ read-only: list the candidate refs (`git for-each-ref --format='%(refname)'
60
+ refs/heads refs/remotes`), and for each one list the `docs/backlog/*.md`
61
+ paths present **at that ref's tip tree**
62
+ (`git ls-tree -r --name-only <ref> -- docs/backlog/`) — not a history
63
+ scan; a bare `git log --diff-filter=A -- docs/backlog/` or
64
+ `git branch --contains` proves only that a commit was once added or is an
65
+ ancestor somewhere, not that the file still exists at any ref's tip today,
66
+ and would misreport an item deleted from every branch as awaiting-merge.
67
+ Union the tip-tree paths across refs and subtract this working tree's own
68
+ `docs/backlog/` listing; what remains are candidates.
69
+
70
+ A candidate is not automatically "not yet merged": a branch can have been
71
+ fully merged and kept around while the item was later deleted here on
72
+ purpose, and tip-tree subtraction alone cannot tell the two apart. So for
73
+ each candidate, resolve the commit that most recently added it on its ref
74
+ (`git log -1 --diff-filter=A --format=%H <ref> -- <path>`) and check
75
+ whether that commit is already reachable from `HEAD`
76
+ (`git merge-base --is-ancestor <commit> HEAD`). A reachable add-commit
77
+ means this content already made it into the current branch's history at
78
+ some point and its absence now is a deliberate removal, not unmerged
79
+ work — drop that candidate rather than resurrecting it as planning input.
80
+ Only an unreachable add-commit is genuinely **awaiting-merge** input; name
81
+ it to the human as living on that branch, not yet merged. When no single
82
+ add-commit can be resolved at all (for example, the path arrived on that
83
+ ref by a rename), do not assert unmerged with confidence — still name the
84
+ item, but say its provenance could not be confirmed and ask the human to
85
+ check it is not already-handled content before treating it as new work.
86
+
87
+ Before naming the cherry-pick option, inspect the resolved add-commit's
88
+ complete changed-path set. Offer `git cherry-pick` of that commit only
89
+ when the set is exactly the one backlog item path — that is what makes
90
+ the only-the-item-file boundary actually isolate the cherry-pick from
91
+ unrelated files; a multi-file add-commit (a legacy, manually captured, or
92
+ renamed item) breaks that isolation despite looking like a single-item
93
+ capture. In every other case — a multi-file add-commit, an unresolved
94
+ add-commit, or an item later modified on its ref (which makes the
95
+ add-commit alone stale) — recommend merging the branch instead, the safer
96
+ default regardless. Either way, the item can only be **absorbed** — its
97
+ frontmatter flipped in §4.5 — once its file is actually present on the
98
+ planning branch, so this step only surfaces the candidate and explains how
99
+ to bring it over; it never merges, cherry-picks, or edits an off-tree item
100
+ itself. Outside a git repository, or when no other ref carries an item
101
+ this working tree lacks, say nothing — the same proceed-without-comment
102
+ tolerance as an absent backlog.
35
103
 
36
104
  If no vision document exists at the resolved path, stop. Explain that it
37
105
  should contain the product description, architecture, target users, API
@@ -88,6 +156,88 @@ npx --yes @wildorder/nightshift branch "{program-id}"
88
156
  This skill composes no git of its own — the command above owns branch
89
157
  selection, and the packaged runner owns every commit that follows.
90
158
 
159
+ ## 2.7. Run the actor audit
160
+
161
+ Before drafting either artifact, walk the phase's work and ask one question of
162
+ each unit: *what credential or access does this step consume, and does the
163
+ crew hold it?* This audit **discovers** human-only steps; it never blocks the
164
+ plan. A phase with no human-only actions produces an empty audit, and the
165
+ skill proceeds exactly as it does today — no `prerequisites` entries, no Human
166
+ Prerequisites section, no friction. There is no rule that a plan must declare
167
+ a prerequisite; there is only a question worth asking before the work is
168
+ scheduled.
169
+
170
+ The roster does not exist yet at this point — §3 and §4 haven't drafted it —
171
+ so audit a **provisional decomposition**: the candidate units of work the
172
+ phase breaks into, the same decomposition §3 and §4 will formalize into
173
+ workstreams. If drafting the final roster later **adds, removes, splits, or
174
+ moves a workstream**, re-check the hoist-and-batch assignment below against
175
+ the new roster, so every eventual unit of work has been audited and every
176
+ prerequisite lands on the workstream that actually consumes it.
177
+
178
+ **The enumerable tells** — the concrete signals a unit of work needs a human:
179
+
180
+ - cloud or organisation **admin credentials** the crew is not given;
181
+ - **console-only actions** with no API the agent can call;
182
+ - **trust anchors** — OIDC providers, state backends, signing keys — that a
183
+ human must establish before anything can authenticate against them;
184
+ - **secrets the agent may not set** (a repository or environment secret the
185
+ crew must never hold);
186
+ - **third-party account creation**;
187
+ - **DNS** records and delegations.
188
+
189
+ **A prerequisite is an action the crew *cannot* perform — never one that is
190
+ merely hard, slow, or annoying.** The audit's test is "does the crew hold
191
+ this?", never "is this unpleasant?" Work an agent can do, even tediously, is
192
+ not a prerequisite; declaring it as one manufactures an intermission and hands
193
+ the human work the run could have done itself.
194
+
195
+ **Convert each hit into a prerequisite** with:
196
+
197
+ - a stable **id**, conventionally `HP-01`, `HP-02`, …;
198
+ - a human-facing **description** of the action only a human can perform;
199
+ - a **remediation** written as the exact commands or console steps the human
200
+ runs — a runbook, not a hint (for example, a repository-settings change like
201
+ configuring branch protection in the hosting provider's settings, described
202
+ as console steps, not as a version-control command);
203
+ - a **verifyCommand**: a shell command that exits zero iff the action is done,
204
+ which the runner executes itself as a deterministic subprocess — never a
205
+ model's judgment. The observable must be one the headless runner can
206
+ actually query: non-interactive, reading no stdin, emitting no prompt, and
207
+ using only credentials the *runner* holds. This is the trap turned back on
208
+ itself — the prerequisite exists because the crew lacks a credential, and
209
+ the obvious way to verify the action often needs that same missing
210
+ privilege. Distinguish permission to **perform** the action (which the crew
211
+ lacks — that is why it is a prerequisite) from permission to **observe**
212
+ its completion (which the runner must have). If the only observable needs
213
+ the human-only privilege, pick a different observable the runner can reach
214
+ — a downstream effect, a read-only or verification-scoped credential
215
+ provisioned for the purpose — rather than shipping a command the runner
216
+ cannot execute. The `verifyCommand` is executed verbatim by the runner, the
217
+ same trust class as the verify commands in `nightshift.config.json` — it is
218
+ reviewed at planning time precisely because it will be run.
219
+
220
+ **Hoist and batch.** Human actions are expensive handoffs. Hoist each human
221
+ action to a workstream boundary rather than burying it mid-workstream, batch
222
+ independent human actions into the fewest handoffs (ideally one), and
223
+ sequence agent-doable work ahead of the first unmet prerequisite so a run
224
+ gets as far as it can before it must wait. A workstream that consumes a
225
+ prerequisite lists it in that workstream's `prerequisites`.
226
+
227
+ An empty audit is the normal outcome for a program that touches no
228
+ infrastructure — write no `prerequisites`, add no Human Prerequisites
229
+ section, and move on. But an infrastructure-touching program that emerges
230
+ from the audit with an empty prerequisites list is worth re-checking during
231
+ review: it usually means a human seam was missed, not that none exists. This
232
+ is guidance for a second look, not a rule the plan must pass.
233
+
234
+ **What this step does not do.** The audit produces manifest entries and
235
+ program-document prose. It never runs a `verifyCommand`, never verifies
236
+ whether a human has acted, and never changes a workstream's or a
237
+ prerequisite's `status` — that is the runner's job, at run time. It never
238
+ makes prerequisite declaration mandatory, never blocks a plan, and never adds
239
+ a step the plan must pass. An empty result is a complete, valid plan.
240
+
91
241
  ## 3. Draft the program document
92
242
 
93
243
  Inspect `docs/programs/` for an existing `*-program.md`. Match its structure
@@ -110,6 +260,13 @@ when one exists. Otherwise use:
110
260
  ## Architecture Changes
111
261
  [Changes from the system in as-built.md. For the first program, describe the full architecture.]
112
262
 
263
+ ## Human Prerequisites
264
+ [Only when the actor audit found human-only actions. One short paragraph or a
265
+ few bullets naming each prerequisite by id (HP-xx) and what it unblocks — which
266
+ workstreams wait on it and why the crew cannot perform it. Reference ids only;
267
+ the remediation, verifyCommand, and status live in the manifest, never here.
268
+ Omit this section entirely when the audit found no prerequisites.]
269
+
113
270
  ## Technology Choices
114
271
  [Only new choices. If none: "No new technology — uses existing stack."]
115
272
 
@@ -133,10 +290,13 @@ and never restates their text.
133
290
  The program document carries only what the manifest cannot: narrative
134
291
  architecture, causal reasoning, anticipated decisions, and risks. Success
135
292
  criteria, the workstream table, the dependency graph, and scope in/out lists
136
- are manifest data — do not reproduce them here. Two copies of the same fact
137
- drift apart; one canonical home per fact is a founding rule of this system.
138
- When this section's rule and an older program document's structure conflict,
139
- this rule wins: delete the duplicated sections rather than matching them.
293
+ are manifest data — do not reproduce them here. Human Prerequisites follows
294
+ the same rule: reference HP ids only, never their description, remediation,
295
+ verifyCommand, or status, all of which are manifest data. Two copies of the
296
+ same fact drift apart; one canonical home per fact is a founding rule of this
297
+ system. When this section's rule and an older program document's structure
298
+ conflict, this rule wins: delete the duplicated sections rather than matching
299
+ them.
140
300
 
141
301
  Write the draft directly to `docs/programs/{program-id}-program.md`. Do not
142
302
  paste the document into the conversation or ask for approval before saving —
@@ -162,6 +322,15 @@ exactly. Otherwise use:
162
322
  "successCriteria": [
163
323
  { "id": "SC-01", "description": "{verifiable outcome}" }
164
324
  ],
325
+ "prerequisites": [
326
+ {
327
+ "id": "HP-01",
328
+ "description": "{the action only a human can perform}",
329
+ "remediation": "{the exact commands or console steps the human runs}",
330
+ "verifyCommand": "{a shell command that exits zero iff the action is done}",
331
+ "status": "pending"
332
+ }
333
+ ],
165
334
  "packages": [
166
335
  {
167
336
  "name": "{package-name}",
@@ -182,6 +351,7 @@ exactly. Otherwise use:
182
351
  "excludes": ["{specific thing it deliberately does not cover}"]
183
352
  },
184
353
  "dependencies": [],
354
+ "prerequisites": [],
185
355
  "packages": []
186
356
  }
187
357
  ],
@@ -189,6 +359,11 @@ exactly. Otherwise use:
189
359
  }
190
360
  ```
191
361
 
362
+ The root `prerequisites` array and each workstream's `prerequisites` id list
363
+ come from the actor audit (§2.7). Omit the root array, or leave it empty, when
364
+ the audit found nothing — the schema defaults it to `[]`, so a
365
+ prerequisite-free manifest is byte-for-byte what the skill emits today.
366
+
192
367
  Save it directly to `docs/programs/{program-id}-manifest.json`.
193
368
  Keep the manifest, program document, and every referenced `taskFile`
194
369
  trackable by Git — nightshift tags decisions to commits and replays roll back
@@ -248,6 +423,47 @@ For a shared contract migration, prefer an explicit sequence:
248
423
  The destructive cleanup depends on every migration workstream. Do not place
249
424
  foundational deletion first merely because it is conceptually central.
250
425
 
426
+ ## 4.5. Absorb backlog items
427
+
428
+ When any part of this program's scope came from an item captured under
429
+ `docs/backlog/`, close the loop before handing off:
430
+
431
+ - Flip that item's `status` to `planned` and write this program's id into
432
+ its `planned-into` field. Edit only those two fields — do not restate or
433
+ reshape the rest of the item.
434
+ - Carry that item's captured constraints into both the program document
435
+ narrative and the manifest's `planningInput`, instead of re-deriving
436
+ them — the reason to read the backlog in step 1 is so this plan starts
437
+ from knowledge a prior session already paid for, not to re-research it.
438
+ - Leave every item this program does not draw on untouched at `captured`.
439
+
440
+ This is the planner exercising judgment interactively, in the moment a
441
+ program is being shaped — not an automated transition. Statuses beyond
442
+ `planned` (`done`, `declined`) are closed out separately, by a human editing
443
+ the item file directly; no skill advances them.
444
+
445
+ ## 4.6. Commit the plan
446
+
447
+ The plan is committed now, on this program's branch, so it never sits
448
+ untracked where a different program's run could sweep it up. Run exactly
449
+ this command and nothing else:
450
+
451
+ ```sh
452
+ npx --yes @wildorder/nightshift commit-plan "{program-id}"
453
+ ```
454
+
455
+ This skill composes no git of its own — the command above owns staging and
456
+ committing the plan (the program document, the manifest, and any backlog
457
+ items absorbed in the previous step), and the packaged runner owns every
458
+ commit that follows. If the command exits nonzero — no git repository, or
459
+ HEAD is not this program's branch — surface its message to the human as a
460
+ warning and proceed to the handoff below anyway; do not treat it as a hard
461
+ stop. The artifacts already exist on disk regardless, and every refusal the
462
+ command can raise is a "could not commit here" a human can resolve (init a
463
+ repository, or run the branch step). A clean no-op — the plan is already
464
+ committed and unchanged — ends this step the same way a fresh commit does:
465
+ move on.
466
+
251
467
  ## 5. Hand off for review
252
468
 
253
469
  Both files now exist on disk. Reply with a short summary only — program