voidmachine 6.0.0 → 7.0.1

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 (32) hide show
  1. package/core-assets/.claude-plugin/plugin.json +2 -2
  2. package/core-assets/PHILOSOPHY.md +18 -5
  3. package/core-assets/data/catalog.v3.json +29 -109
  4. package/core-assets/data/certification.json +1 -1
  5. package/core-assets/data/model.json +28 -52
  6. package/core-assets/hooks/_syntax-worker.cjs +1 -1
  7. package/core-assets/hooks/_void-hook.mjs +8 -6
  8. package/core-assets/hooks/tdd-guard.md +45 -88
  9. package/core-assets/hooks/viewport-screenshot-gate.sh +3 -3
  10. package/core-assets/packs/pack-monorepo/skills/void-dependency-direction/SKILL.md +27 -146
  11. package/core-assets/packs/pack-monorepo/skills/void-service-package/SKILL.md +5 -8
  12. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/.source +4 -2
  13. package/core-assets/packs/pack-server/skills/void-webhook-handler-pattern/SKILL.md +32 -132
  14. package/core-assets/skills/void-accessibility/SKILL.md +2 -2
  15. package/core-assets/skills/void-async-safety/SKILL.md +37 -24
  16. package/core-assets/skills/void-autopilot/SKILL.md +17 -15
  17. package/core-assets/skills/void-autopilot/references/publication.md +82 -0
  18. package/core-assets/skills/void-code-review/SKILL.md +1 -1
  19. package/core-assets/skills/void-commit-discipline/SKILL.md +5 -11
  20. package/core-assets/skills/void-frontend-design/SKILL.md +2 -2
  21. package/core-assets/skills/void-hexagonal-architecture/SKILL.md +5 -5
  22. package/core-assets/skills/void-implement/SKILL.md +11 -5
  23. package/core-assets/skills/void-observability/SKILL.md +4 -4
  24. package/core-assets/skills/void-orchestrate/SKILL.md +57 -224
  25. package/core-assets/skills/void-testing/SKILL.md +4 -4
  26. package/core-assets/skills/void-verify/SKILL.md +1 -1
  27. package/core-assets/skills/void-verify/references/ci-admission.mjs +1 -1
  28. package/core-assets/skills/void-verify/references/ci-feedback.md +33 -4
  29. package/core-assets/templates/github/void-dependency-audit.yml +18 -2
  30. package/dist/main.js +2941 -2449
  31. package/package.json +2 -2
  32. package/core-assets/hooks/block-protected-push.sh +0 -81
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: void-orchestrate
3
- description: Delegate independent research and substantial implementation through native agents; choose context, isolation and bounded concurrency, collect results and preserve review evidence. Use the supported session host.
3
+ description: Delegate independent research and substantial implementation through native agents; choose context, isolation and bounded concurrency, collect results and preserve review evidence. Publish observed worker lifecycle events.
4
4
  ---
5
5
 
6
6
  # Orchestrate
@@ -17,16 +17,10 @@ context, permissions, completion and resume capabilities. Use the best supported
17
17
  capabilities for the task in the current session; an installed executable or an
18
18
  environment hint alone does not validate a host, identity or permission.
19
19
 
20
- Herdr is optional for consumers, not discretionary inside a validated Herdr session.
21
- When fresh discovery validates the coordinator in Herdr, use its adapter below for
22
- durable terminal workers and mission visibility. Short agents remain native; never
23
- duplicate an agent to give it a pane. Outside Herdr, use the current supported host
24
- (such as tmux) when its required capabilities and ownership can be verified. This
25
- policy adds no tmux transport and never relaunches through the legacy kernel.
26
- Without supported presentation, retain native delegation and report the limitation;
27
- do not claim durability from a pane or unsupported API. Failed or ambiguous host
28
- discovery blocks the affected host action: diagnose it, never silently switch hosts
29
- or act on an unrelated project. Native work independent of that action may continue.
20
+ Use native execution independently of presentation. The harness publishes worker
21
+ observations; external plugins own windows, tabs and panes. Never discover or call
22
+ a multiplexer to delegate, and never duplicate an agent to make it visible.
23
+ An absent display cannot change execution permissions or invalidate real evidence.
30
24
 
31
25
  - Work directly for a tiny targeted change, a single tool call, mechanical processing,
32
26
  or tightly coupled work where delegation adds no useful separation.
@@ -70,22 +64,6 @@ conflict, rather than silently upgrading or claiming the quality requirement is
70
64
  and report the effective model only when the runtime supplies it; otherwise it is unknown.
71
65
  Use existing evidence/reporting, not a new registry. Report cost/time only when observed.
72
66
 
73
- ## First ticket and optional worker tabs
74
-
75
- SessionStart discovers Herdr even before central mission files exist. Its advice
76
- requires a fresh caller pane at the canonical checkout and process ownership;
77
- environment variables alone never authorize a host action. Revalidate before launch.
78
- On a new implementation ticket, reuse the assigned writer if one exists. Otherwise,
79
- in a validated Herdr session, register the mission and planned worker first, then
80
- create one background tab in the resolved coordinator workspace with the assigned
81
- worktree as cwd. Read the installed `herdr tab` schema, preserve focus with
82
- `--no-focus`, and use the returned root pane for the single agent start below.
83
- Reattach a matching existing worker instead of opening another tab. The coordinator
84
- stays in its existing pane. Hooks only discover and advise; they never create tabs,
85
- launch agents or write central files. Without Herdr, use native delegation normally.
86
- An invalid host or explicit mission selection refuses only that host action;
87
- independent native work may continue with the limitation stated.
88
-
89
67
  ## Brief and bound the delegation
90
68
 
91
69
  Use a fresh context by default. Choose a supported fork only when the task needs
@@ -98,7 +76,7 @@ Formal specialist envelopes and evidence follow the independent contract below.
98
76
 
99
77
  Count writer, research and review children together against observed available runtime slots
100
78
  and the coordinator's bounded dispatch; queue work when full. Preserve tighter caller
101
- limits, including Autopilot's ticket cap and the central schema's four-worker limit.
79
+ limits, including Autopilot's ticket cap.
102
80
  This is no machine-wide quota. Do not create recursive child coordinators or redispatch
103
81
  the same complete workflow. Required formal specialists remain dispatched by their
104
82
  designated owner within the shared available capacity. Do not duplicate a child's work
@@ -150,206 +128,59 @@ Preserve the complete result; incomplete results go back to the same agent.
150
128
  With `panel.provider: orchestrator`, only ORCH launches and collects this panel.
151
129
  Missing required native capability is reported with cause and next action.
152
130
 
153
- ## Herdr adapter: recovery
154
-
155
- The following Herdr sections apply when the session-host policy selects this adapter.
156
- Native delegation without it does not require these central files or pane discovery.
157
-
158
- Read project instructions, the approved task and the current Git status. Preserve
159
- other writers' changes. Resolve the canonical Git common directory, SHA-256 its
160
- absolute real path as UTF-8, and inspect
161
- `~/.local/state/orchestra/<project>/<mission>/`. Never use an inherited workspace
162
- variable or a stale pane ID as authority. Read mission.md, the applicable
163
- workers/<label>/brief.md and report.md. Re-read `herdr pane list` before every
164
- identity decision. Match **label + worktree**, using the canonical worktree path.
165
- Refuse multiple matches, incomplete discovery, symlinks, traversal and invalid data.
166
- After reattachment/restart, ORCH atomically updates pane_id and coordinator.workspace
167
- from that validated fresh inventory. Hooks and workers never write these hints.
168
- A missing unrelated historical worktree does not invalidate a current identity.
169
-
170
- The coordinator is the existing ORCH session, never a second agent opened for display.
171
- Resolve its own label + worktree before selecting its workspace. Keep each writer
172
- in its assigned worktree. Do not affect any other project, workspace or pane.
173
- An uncertain launch or prompt acknowledgement requires reconciliation of that same
174
- worker before retrying. A timeout proves neither launch failure nor prompt loss.
175
-
176
- ## Herdr adapter: explicit coordinator context
177
-
178
- If unique discovery refuses multiple compatible missions, ORCH reads the target
179
- mission and reports, then atomically replaces its local, unversioned
180
- `<canonical worktree>/.void/machine/orchestra-selection.json`. Schema 1 is strict
181
- JSON, at most 4096 UTF-8 bytes: `{ "schema": 1, "project": "<project-sha256>",
182
- "mission": "<existing-id>", "coordinator": { "label": "ORCH", "worktree":
183
- "/absolute/canonical/worktree" } }`. ORCH alone writes it; hooks never repair it.
184
- No unknown or duplicate keys, YAML, traversal, symlinks or partial writes.
185
-
186
- This selects context only, never execution state or permissions. Full bounded
187
- central discovery still runs; malformed unrelated missions or limits refuse.
188
- A stale/invalid binding never falls back. Verify selected coordinator label and
189
- canonical worktree against the current worktree and a fresh `herdr pane list`;
190
- missing or duplicate live matches refuse. Never prefer timestamps, running status
191
- or pane tokens to decide intent. Without a binding, preserve unique discovery.
192
- Clear/compact/resume re-read selection and central state without launching workers.
193
- Separate worker worktrees retain their own mission, attempt and report discovery.
194
- A selected terminal mission retains the guarded cleanup below: never clear tokens
195
- belonging to another mission. No binding belongs in the programme descriptor.
196
-
197
- ## Herdr adapter: central files and ownership
198
-
199
- Use schema: 1 YAML frontmatter, strict string keys and one document, followed by
200
- Markdown. Reject duplicate keys, tags, anchors, aliases and unknown fields. Bound
201
- mission/report to 64 KiB, brief to 256 KiB, discovery to 64 entries and 1 MiB of
202
- mission bytes; exceeding a bound is incomplete, never a unique match.
203
- See the shipped technical contract `docs/ORCHESTRA.md` in the harness source for
204
- schemas; the operational fields are listed here so an installed skill is sufficient.
205
-
206
- - mission.md: schema, mission, project, status, updated_at
207
- (ISO with `Z` or `+HH:MM`/`-HH:MM`; prefer UTC `Z`), repository
208
- (canonical Git common path), coordinator {label, worktree, workspace?}, workers.
209
- - Worker entries: label, agent (codex or claude), worktree, branch, ticket, status,
210
- attempt; optional pane_id and session are hints only. At most four workers.
211
- - Coordinator status and worker status: planned, running, blocked, done, failed.
212
- - report.md: schema, mission, attempt, worker, branch, status (running, blocked,
213
- done, failed), commits (full SHAs), tests (passed, failed, not_run), updated_at.
214
- Body: actual commands/results, proof locations, risks, questions and remaining work.
215
- - brief.md: absolute paths, exact base, footprint, acceptance criteria, ownership,
216
- permissions, forbidden effects and current attempt. No secrets. Explicitly warn
217
- that other writers exist and their changes must be preserved.
218
-
219
- ORCH alone writes mission and briefs; each worker alone writes its report. Use an
220
- atomic replacement: write an exclusive temporary sibling, then rename. Hooks never
221
- write these files. A new work turn gets a new attempt; resume keeps its attempt.
222
- A valid report for the current mission/attempt overrides workers[].status at every
223
- event. An absent report falls back to the manifest. Malformed, foreign, partial or
224
- unrecognized stale reports refuse usage; never turn a parse failure into absence.
225
- The files carry coordination state, not independent review proof.
226
-
227
- ## Herdr adapter: copyable starting files
228
-
229
- Replace the example project hash with SHA-256 of the canonical common Git path.
230
- Replace every path, branch, ticket and timestamp from actual observations. These
231
- three files are authored by their owner, never by the hook.
232
-
233
- mission.md:
234
-
235
- ```yaml
236
- ---
237
- schema: 1
238
- mission: dev-42
239
- project: "<project-sha256>"
240
- status: planned
241
- updated_at: "2026-10-08T10:00:00.000Z"
242
- repository: /absolute/repository/.git
243
- coordinator:
244
- label: ORCH
245
- worktree: /absolute/repository
246
- workspace: wA
247
- workers:
248
- - label: WORK-1
249
- agent: codex
250
- worktree: /absolute/worktrees/dev-42
251
- branch: work/dev-42
252
- ticket: DEV-42
253
- status: planned
254
- attempt: implementation-1
255
- ---
256
- # Mission
257
- Scope, acceptance criteria, canonical mission journal and proof locations.
258
- ```
259
-
260
- workers/WORK-1/brief.md:
261
-
262
- ```yaml
263
- ---
264
- schema: 1
265
- mission: dev-42
266
- attempt: implementation-1
267
- worker: WORK-1
268
- ---
269
- # Work
270
- Worktree: /absolute/worktrees/dev-42. Branch: work/dev-42.
271
- Base: <verified full commit SHA>. Ticket: DEV-42.
272
- Footprint: <exact owned files/directories>; preserve every other writer's edits.
273
- Acceptance: <complete observable criteria and verification commands>.
274
- Limits: <role permissions, forbidden effects, human gates>.
275
- Report: /absolute/mission/workers/WORK-1/report.md, owned only by this worker.
276
- Resume: <actual runtime session and the recipe from the table below>.
277
- ```
278
-
279
- workers/WORK-1/report.md:
280
-
281
- ```yaml
282
- ---
283
- schema: 1
284
- mission: dev-42
285
- attempt: implementation-1
286
- worker: WORK-1
287
- branch: work/dev-42
288
- status: running
289
- commits: []
290
- tests: not_run
291
- updated_at: "2026-10-08T10:00:00.000Z"
292
- ---
293
- # Checkpoint
294
- Completed: <actual changes>. Verification: <commands, results and proof paths>.
295
- Remaining: <work and exact next action>. Risks/questions: <observed limitations>.
296
- ```
297
-
298
- ## Herdr adapter: durable workers
299
-
300
- Read installed `herdr --help`, `herdr agent --help` and the live schema before
301
- issuing commands. Use structured argv, exact acknowledged identities and bounded
302
- waits/output. The launch recipes for the selected worktree are:
131
+ ## Publish worker observations
303
132
 
304
- | Kind | Launch argv | Resume argv | Short contexts | ctx capability |
305
- | --- | --- | --- | --- | --- |
306
- | codex | `--no-daemon --add-dir <absolute-mission>` | `resume <actual-session> --no-daemon --add-dir <absolute-mission>` | Native fresh context | Unmeasurable without a supported usage source |
307
- | claude | `--add-dir <absolute-mission>` | `--resume <actual-session> --add-dir <absolute-mission>` | Native Agent, no interception | Fresh transcript usage plus required context.windowTokens |
133
+ For each mission worker or reviewer, keep one `run_<opaque-id>` for its assignment.
134
+ The coordinator reuses the unit's open canonical mission. If none exists for controlled
135
+ implementation, it creates one from the assigned worktree with `void-machine mission start --title <unit>
136
+ --ticket <full-frozen-ticket> --json` and hands the returned ID to the writer.
137
+ The writer reuses that ID and runs `mission dispatch` from the assigned worktree.
138
+ Title-only missions remain valid for simple work without controlled dispatch or review.
139
+ Do not recreate a mission to evade a refusal. This publication never substitutes
140
+ for the mission's implementation, verification or independent review receipts.
308
141
 
309
- Use the selected kind's executable and preserve these options on every launch/resume:
142
+ After an actual successful native dispatch acknowledgement, publish:
310
143
 
311
144
  ```sh
312
- herdr agent start <unique-mission-worker-name> --kind <kind> --pane <resolved-pane> -- <argv-from-table>
145
+ void-machine agents record --mission <mis_id> --event-file <observation.json>
313
146
  ```
314
147
 
315
- The arguments after `--` belong to the selected runtime. The name is unique within
316
- the mission; it is not an invented native session ID. Resolve the pane first and
317
- keep the session ID actually returned by the runtime.
318
-
319
- Apply the role's existing permission/read-only policy; `--add-dir` only grants the
320
- specified directory, never disables a sandbox or an approval. Unsupported kind or
321
- option: diagnose and stop that launch. Do not update or restart Herdr to make it fit.
322
- Register planned worker before creating its owned surface. Keep the returned pane
323
- ID as a hint, launch once, submit the brief once, then reconcile by label + worktree.
324
- Use `herdr agent wait` in bounded slices and read the report after every turn.
325
- Idle/done is a turn ending, never proof the task passed. Request a missing report
326
- from the same session. Follow up in that session; never create a duplicate worker.
327
- After /clear read the same mission; after a killed process resume its actual session
328
- in the same worktree. Missing session: retain the mission and expose the loss.
329
-
330
- `resume_argv` is absent from Herdr 0.9.0 and 0.9.1, present from 0.9.2. Publish it
331
- only after the installed schema proves support. Otherwise retain the complete resume
332
- recipe in the brief. Never claim restart restoration was tested without doing it.
333
-
334
- ## Herdr adapter: projection and closure
335
-
336
- The hook publishes source void-machine on SessionStart startup/resume/clear/compact
337
- and Stop after re-reading central state and fresh Herdr identities. Pane tokens:
338
- mission, worker, ticket, wstatus; coordinator-only workspace: mission, wstatus, workers.
339
- These are file status, never agent state. ctx requires the selected kind's measured capability from the table; unavailable measurement stays unavailable. Clear
340
- removes ctx before fresh measurement. State TTL is 86400000 ms, ctx TTL 7200000 ms.
341
- Sequences are exact nanosecond decimal BigInts captured before discovery. Old or
342
- equal seq is ignored by Herdr. Tokens are global keys, not source namespaces: another
343
- source may overwrite them; null clears globally. Never reconfigure cockpit to win.
344
-
345
- Terminal mission cleanup explicitly clears keys on all still-resolved owned panes,
346
- only where the currently projected mission still matches. Only the resolved
347
- coordinator clears workspace keys, again after verifying the displayed mission.
348
- A late closure of A must not clear B. A worker SessionEnd never cleans the workspace.
349
- When no mission is active, recover the verified displayed terminal mission; do not
350
- choose arbitrary history. Discovery/transport errors never trigger a purge.
351
- After collection and acceptance ORCH may close its owned surfaces; retain worktrees,
352
- branches and evidence according to their own lifecycle. Do not close the coordinator.
148
+ The file contains `observationId`, `kind` and `payload`. Use a stable observation ID
149
+ and exactly the same content on a retry. The payload always carries `schemaVersion: 1`
150
+ and `runId`. Publish these three kinds at their real boundaries:
151
+
152
+ - `worker.dispatched`: add `missionId`, `ticket` (or `unknown`), `role` (`work` or
153
+ `review`), `runtime` (`claude` or `codex`), the verified absolute `worktree`,
154
+ `branch` (`detached` requires `headSha`), and `attachCommand` (verified argv or
155
+ `unknown`). Never invent an attachment recipe or use presentation hints as identity.
156
+ - `worker.state`: add `state` (`running`, `blocked`, `done`, `failed`) and the UTC
157
+ `observedAt`; optional `reason` explains a wait. Publish the initial running state
158
+ and subsequent observed changes. A turn ending while awaiting the coordinator
159
+ is blocked, not done. No observation means unknown, never inferred failure.
160
+ - `worker.finished`: add `outcome` (`succeeded`, `failed`, `stopped`) after final
161
+ collection or confirmed terminal failure/stop, preceded by done for succeeded,
162
+ failed otherwise. Finish before closing the mission. It does not mean merged.
163
+
164
+ Keep the same assignment through corrections and resume. Repeated running states
165
+ across distinct turns need distinct observation IDs. A finished assignment is closed;
166
+ new work afterwards gets a new run ID. Keep real native identities in the existing
167
+ brief/evidence; the observation ID is not a fabricated native receipt.
168
+
169
+ A publication error is visible and retried with the same identity/content after its
170
+ cause is resolved; it never authorizes another launch. No brief, transcript, secret
171
+ or result content belongs in these metadata. Native calls outside this procedure are
172
+ not automatically captured, including unsupported Codex observation paths.
173
+
174
+ `void-machine agents status --json` reads all project mission journals and reports
175
+ active assignments, their last observed state and coverage issues. It does not poll
176
+ runtimes or control presentation. Partial coverage is explicit and exits nonzero;
177
+ never treat an unreadable history as no workers. External tools consume this public
178
+ contract; the harness does not open or close their surfaces.
179
+
180
+ Existing legacy runs retain their session and journal. Their mutating CLI commands
181
+ publish the same events; `void-machine agents publish <runId>` retries publication
182
+ from saved transitions without re-executing or stopping the runtime. This does not
183
+ make the legacy launcher mandatory for new work.
353
184
 
354
185
  ## Independent review
355
186
 
@@ -361,8 +192,10 @@ stays within the existing project boundary and must match its digest and invocat
361
192
  A central report marked done is never a review receipt. Preserve limitations honestly.
362
193
 
363
194
  For autopilot, `autopilot review --ticket <id> --pr <n> --head <sha> --round <1|2>
364
- --mission <canonical-id>` checks the target ticket against the existing bounded ticket reader (filename identity
365
- and frozen content hash), then prepares the exact review subject/worktree and, when
195
+ --mission <canonical-id> --worktree <assigned-path>` runs from the coordinator checkout,
196
+ retains its programme and local verdicts there, and checks the target ticket against the existing bounded ticket reader (filename identity
197
+ and frozen content hash) in the assigned checkout, reading the journal from its resolved
198
+ installation root. Missing plans and mismatched subjects refuse before spending an attempt. It then prepares the exact review subject/worktree and, when
366
199
  pending, returns awaiting-native-review. ORCH performs the native invocation and
367
200
  records its real receipts, then repeats the same command to collect. Do not start a
368
201
  new mission to repair a pending attempt. Budgets, protected paths, HEAD drift checks,
@@ -128,7 +128,7 @@ Describe the behavior. Imperative. Specific.
128
128
  - `it should retry` (the "should" is fluff)
129
129
  </Bad>
130
130
 
131
- The companion hook `test-name-lint` warns on weak patterns (`test`, `works`, `should` as the entire name).
131
+ The `test-name-lint` write hook blocks detected generic names: exactly `test`, or names starting with `should `, `work` or `works`. The owning rule defines the lexical scope.
132
132
 
133
133
  ---
134
134
 
@@ -231,7 +231,7 @@ Each snapshot has a reason. No `.toMatchSnapshot()` outside the whitelist withou
231
231
 
232
232
  Banned in committed code. They mean "I will not run this." If you mean "this case is intentionally not yet tested," write a `it.todo('description')` — the test runner reports todos.
233
233
 
234
- The companion hook `no-only-no-skip` blocks commits with `.only` / `fdescribe` / `xit` in the staged diff (allowed in `**/__skip-on-purpose__/**` whitelist with justifying comment).
234
+ The `no-only-no-skip` write hook rejects focused and skipped calls in proposed test files, including `fit`, `fdescribe`, `xit`, `xdescribe` and suite `.skip`. There is no path whitelist; use an explicit `todo` for pending coverage.
235
235
 
236
236
  ### Implementation spies as primary assertion
237
237
 
@@ -259,8 +259,8 @@ Use pglite or dev branch. Mocking Drizzle breaks at every schema change while pr
259
259
 
260
260
  ## Companion hooks
261
261
 
262
- - **`no-only-no-skip`** — block on `.only` / `fdescribe` / `xit` / `.skip` in staged diff (whitelist: `**/__skip-on-purpose__/**`)
263
- - **`test-name-lint`** — warn on weak test names matching `/^\s*(test|works|should)\s*$/i`
262
+ - **`no-only-no-skip`** — blocks focused/skipped calls on supported test writes; no path exemption
263
+ - **`test-name-lint`** — blocks the generic test-name patterns described above
264
264
  - **`no-business-mock`** — warn on `vi.mock\('@/(services|domain)/...'\)` patterns
265
265
  - **`no-snapshot-default`** — warn on new `.toMatchSnapshot()` outside `**/__visual__/**` whitelist
266
266
 
@@ -77,7 +77,7 @@ Remove unrelated scope unless the requested behavior requires it.
77
77
  Give the result, relevant commands/results, independent review outcome and material limits.
78
78
  Do not print a twelve-item checklist with irrelevant N/A rows. Keep applicability reasoning in
79
79
  the existing task/review evidence; summarize it when it explains a real omission or decision.
80
- For a plan, update its existing resume point; the tracker owns mutable programme progress.
80
+ For a standalone sequential plan, update its existing resume point. For a programme, the declared tracker alone owns mutable progress; do not add a current/next unit to the plan.
81
81
  The PR evidence and final report reuse the same observed results rather than duplicate work.
82
82
 
83
83
  Once at ticket end, the coordinator closes each explicitly bound source with
@@ -6,7 +6,7 @@ import { readFileSync } from 'node:fs';
6
6
 
7
7
  try {
8
8
  const name = process.env.GITHUB_EVENT_NAME;
9
- if (!['pull_request', 'merge_group', 'push', 'workflow_dispatch'].includes(name)) {
9
+ if (!['pull_request', 'merge_group', 'push', 'workflow_dispatch', 'schedule'].includes(name)) {
10
10
  throw new Error('CI_INVALID_EVENT: unsupported or missing GitHub event.');
11
11
  }
12
12
  const event = JSON.parse(readFileSync(process.env.GITHUB_EVENT_PATH, 'utf8'));
@@ -1,7 +1,8 @@
1
1
  # Fast local feedback, real integration checks
2
2
 
3
3
  The sibling files are shipped with this skill and copied by `init` into the selected
4
- runtime's skill directory. Resolve them relative to the SKILL.md you actually loaded,
4
+ runtime's skill directory. `update` refreshes owned references; adopted workflows
5
+ remain project-owned and are never overwritten by that reference refresh. Resolve them relative to the SKILL.md you actually loaded,
5
6
  not from a developer checkout or a global installation.
6
7
 
7
8
  On an explicit CI configuration request:
@@ -14,7 +15,9 @@ On an explicit CI configuration request:
14
15
  inside an existing **required** quality job, before dependency installation, without
15
16
  `continue-on-error`, `always()` on later quality steps, or a job-level draft skip.
16
17
  3. Set up the project's actual package manager and immutable lockfile installation.
17
- The example uses npm. For pnpm/Bun use their pinned setup and frozen install.
18
+ The example uses npm and an illustrative Node version; preserve the project's
19
+ supported Node version owner (for example `.node-version`). For pnpm/Bun use
20
+ their pinned setup and frozen install. Do not introduce another package manager.
18
21
  Define `ci:verify` in package.json to run the actual complete lint, typecheck, build,
19
22
  and test commands appropriate to the project. Do not equate `testUnit` with the
20
23
  whole integration suite; discover the project's existing CI contract. Missing
@@ -24,9 +27,11 @@ On an explicit CI configuration request:
24
27
  this template alone does not configure GitHub protection. Retain the separate
25
28
  `void-enforce` floor and independent review. This template does not replace either.
26
29
  5. Test draft, ready without another commit, new head, return to draft, merge group,
27
- and manual run. `CI_DEFERRED_DRAFT` is expected non-admission during preparation,
30
+ and manual run. A deliberately added schedule is supported by the guard and
31
+ runs real checks; it does not prove a separate PR candidate. `CI_DEFERRED_DRAFT` is expected non-admission during preparation,
28
32
  not a failed test: tests have not run. Readiness runs the full suite even at the
29
- same SHA. Never treat a skipped required job as successful test evidence.
33
+ same SHA. Continue focused local work during draft non-admission, without
34
+ retrying the remote refusal. Never treat a skipped required job as test evidence.
30
35
 
31
36
  Development runs configured local tests for the changed behavior and affected types.
32
37
  There is no network hook or mandatory remote wait per edit. Only obsolete PR runs are
@@ -40,6 +45,28 @@ post-merge run only after checking that no release, promotion or artifact consum
40
45
  needs it, and that the protected integration path proves the merged result. The
41
46
  example has no push trigger; add one where it provides distinct release evidence.
42
47
 
48
+ For reusable enforcement, the caller must also declare `ready_for_review`,
49
+ `converted_to_draft` and `merge_group: checks_requested`, keeping its existing
50
+ check names. Put concurrency only in that caller; the called workflow inherits
51
+ `github.workflow` and must not cancel the same group. Its admission guard runs
52
+ from the immutable harness checkout before Node setup and floor execution.
53
+ GitHub-hosted runner usage belongs to the caller, even when the reusable workflow
54
+ is public and the caller private. Compare latency and job-minutes before making
55
+ any billing claim.
56
+
57
+ Dependency audit is a separate project-owned job, without a `needs` edge that
58
+ prevents lint/tests/build from running during an advisory-service outage. Preserve
59
+ its actual package-manager/lockfile contract and severity policy: installing Bun
60
+ is not an audit solution for npm or pnpm consumers. `npm ci` advisory output alone
61
+ is not a complete audit gate. Bun consumers can adopt the packaged
62
+ `core-assets/templates/github/void-dependency-audit.yml` and `dependency-audit.mjs`,
63
+ plus this sibling `ci-admission.mjs`; the audit guide is `docs/DEPENDENCY-AUDIT.md`
64
+ in a matching source checkout. Its ready-PR and merge-group runs judge their own
65
+ revision; a weekly scheduled run catches new advisories without a lockfile change
66
+ and is surveillance, not a substitute for a required candidate check. Unavailable
67
+ or malformed evidence stays non-green. No workflow path filter may hide required
68
+ checks or prevent scheduled registry refresh.
69
+
43
70
  Rollback: restore the prior workflow triggers and admission step together. Restoring
44
71
  full draft CI costs runner time but does not weaken the floor. Leave protection and
45
72
  review evidence unchanged. Existing missions and receipts are not migrated.
@@ -49,3 +76,5 @@ Sources read for GitHub Actions (hosted service):
49
76
  - https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
50
77
  - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue
51
78
  - https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-jobs-with-conditions
79
+
80
+ - https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
@@ -1,4 +1,4 @@
1
- # Manual consumer template: copy this workflow and its companion script.
1
+ # Bun consumer template: adopt with dependency-audit.mjs and ci-admission.mjs.
2
2
  # See docs/DEPENDENCY-AUDIT.md before adopting; no consumer CI is overwritten.
3
3
  name: void-dependency-audit
4
4
 
@@ -6,17 +6,33 @@ on:
6
6
  push:
7
7
  branches: [main]
8
8
  pull_request:
9
+ types: [opened, synchronize, reopened, ready_for_review, converted_to_draft]
10
+ merge_group:
11
+ types: [checks_requested]
12
+ # New advisories can affect an unchanged lockfile. Surveillance is not PR proof.
13
+ schedule:
14
+ - cron: '17 4 * * 1'
9
15
  workflow_dispatch:
10
16
 
11
17
  permissions:
12
18
  contents: read
13
19
 
20
+ concurrency:
21
+ group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || github.run_id }}
22
+ cancel-in-progress: ${{ github.event_name == 'pull_request' }}
23
+
14
24
  jobs:
15
25
  dependency-audit:
16
26
  runs-on: ubuntu-latest
17
27
  timeout-minutes: 10
18
28
  steps:
19
29
  - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
30
+ with:
31
+ ref: ${{ github.event.pull_request.head.sha || github.sha }}
32
+ persist-credentials: false
33
+ - name: Admit dependency audit
34
+ id: admission
35
+ run: node .github/scripts/ci-admission.mjs
20
36
  - uses: actions/setup-node@249970729cb0ef3589644e2896645e5dc5ba9c38 # v6
21
37
  with:
22
38
  node-version: 24
@@ -26,7 +42,7 @@ jobs:
26
42
  - name: Classify dependency audit
27
43
  run: node .github/scripts/dependency-audit.mjs "$RUNNER_TEMP/dependency-audit"
28
44
  - name: Preserve audit report
29
- if: always()
45
+ if: ${{ always() && steps.admission.outcome == 'success' }}
30
46
  uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
31
47
  with:
32
48
  name: dependency-audit