voidmachine 7.0.0 → 7.0.2
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/core-assets/.claude-plugin/plugin.json +2 -2
- package/core-assets/codex/hooks.json +1 -1
- package/core-assets/data/catalog.v3.json +10 -10
- package/core-assets/data/certification.json +1 -1
- package/core-assets/data/model.json +9 -9
- package/core-assets/hooks/_void-hook.mjs +366 -107
- package/core-assets/skills/void-autopilot/SKILL.md +17 -13
- package/core-assets/skills/void-autopilot/references/publication.md +82 -0
- package/core-assets/skills/void-implement/SKILL.md +4 -2
- package/core-assets/skills/void-merge/SKILL.md +22 -15
- package/core-assets/skills/void-orchestrate/SKILL.md +9 -4
- package/core-assets/skills/void-verify/references/ci-admission.mjs +1 -1
- package/core-assets/skills/void-verify/references/ci-feedback.md +74 -6
- package/core-assets/templates/github/void-dependency-audit.yml +18 -2
- package/dist/main.js +2830 -1936
- package/package.json +2 -2
|
@@ -151,7 +151,7 @@ Act on each returned action, then ask again:
|
|
|
151
151
|
|
|
152
152
|
| Action | What you do |
|
|
153
153
|
|---|---|
|
|
154
|
-
| `assign` | claim the ticket (In Progress, assigned), run `autopilot fingerprint --before <ticket>`, create or reuse its worktree,
|
|
154
|
+
| `assign` | claim the ticket (In Progress, assigned), run `autopilot fingerprint --before <ticket>`, create or reuse its worktree, create the controlled mission there with title and full frozen ticket via `void-orchestrate`, hand its ID to the worker |
|
|
155
155
|
| `wait` | nothing; the reason says who is working |
|
|
156
156
|
| `hand-back-to-worker` | give the ticket back to its worker, alive or respawned in the same worktree, with the reason and the pull request; a respawned worker resumes its mission (see Respawning) |
|
|
157
157
|
| `mark-human-wait` | record it in `recent` with its `reason`, which `recent` requires and the recap repeats, put the decision's `humanWaitLabel` on the ticket, comment the reason and detail, free the slot; keep reporting its pull request and footprint, which hold its ground until that pull request merges or closes |
|
|
@@ -159,7 +159,7 @@ Act on each returned action, then ask again:
|
|
|
159
159
|
| `update-branch` | `void-machine autopilot update-branch --pr <n> --head <headSha>`: GitHub merges the base into the branch if its head is still that one; the new head is reviewed before anything merges it |
|
|
160
160
|
| `enable-auto-merge` | `void-machine autopilot arm --ticket <id> --pr <n> --head <headSha>`, on a base with a merge queue: the same guards, then it records the head, arms on exactly that head and reads GitHub back; never `gh pr merge --auto` by hand, never `--admin` |
|
|
161
161
|
| `disable-auto-merge` | `void-machine autopilot disarm --pr <n>`, before the action that follows it for the same ticket; it turns its auto-merge off, then takes it out of the merge queue, and fails while GitHub still shows either; never `gh pr merge --disable-auto` alone, which leaves a queued pull request in the queue |
|
|
162
|
-
| `review` | `void-machine autopilot review --ticket <id> --pr <n> --head <headSha> --round <round> --mission <canonical-id
|
|
162
|
+
| `review` | `void-machine autopilot review --ticket <id> --pr <n> --head <headSha> --round <round> --mission <canonical-id> --worktree <assigned-path>` from the coordinator checkout; on awaiting-native-review use `void-orchestrate` for the actual reviewer, record canonical receipts, then repeat to collect. The same attempt keeps its 30 minute deadline; failures retain the existing budget |
|
|
163
163
|
| `requeue` | the same command, to put an ejected head back in the queue; the kernel bounds how often |
|
|
164
164
|
| `drain` | take nothing new; keep acting on the tickets in flight |
|
|
165
165
|
| `freeze` | stop acting, once the disarms before it succeeded |
|
|
@@ -201,13 +201,13 @@ the local config and the files it includes, the stash, tags, notes, remotes, the
|
|
|
201
201
|
deploy branches, replace refs, `hooks/` and `info/` are one set for every worktree. The upstream
|
|
202
202
|
(`remote`, `merge`) of every branch but the bases and the one that deploys is left out, since units
|
|
203
203
|
in flight set it when they create or push their branch and drop it with a merged one; the bases'
|
|
204
|
-
own settings still count.
|
|
204
|
+
own settings still count; only regular root `info/refs`, Git’s generated transport cache, is exempt. Start each worktree from
|
|
205
205
|
`origin/<base>` and never move a local base branch while units are in flight. The baseline
|
|
206
206
|
recorded at `assign` is written once: a second `--before` for the same ticket is refused, so a unit
|
|
207
|
-
cannot re-record the state it left as the state it found.
|
|
208
|
-
publishes
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
cannot re-record the state it left as the state it found. `autopilot fingerprint --after <ticket>`
|
|
208
|
+
checks it; the coordinator publishes only through `autopilot publish --ticket <ticket> --head <sha>
|
|
209
|
+
--remote <remote> --branch <branch>`, which couples that guard to the literal SHA push. Never follow
|
|
210
|
+
refusal with direct Git. Human renewal retains evidence; see [publication and recovery](references/publication.md).
|
|
211
211
|
|
|
212
212
|
**Disarming.** Armed means GitHub merges without anyone acting again: an auto-merge request, or,
|
|
213
213
|
once the checks pass on a base with a merge queue, an entry in that queue and no request at all.
|
|
@@ -266,18 +266,19 @@ neither, so a restart loses nothing.
|
|
|
266
266
|
|
|
267
267
|
## Workers
|
|
268
268
|
|
|
269
|
-
Given: one ticket id, its worktree, its branch, the programme's plan and spec. The worker re-fetches
|
|
269
|
+
Given: one ticket id, its worktree, its branch, its canonical mission ID, the programme's plan and spec. The worker re-fetches
|
|
270
270
|
the complete ticket itself; it never works from a summary.
|
|
271
271
|
|
|
272
|
-
It runs `void-implement` whole in that worktree,
|
|
273
|
-
|
|
272
|
+
It runs `void-implement` whole and `mission dispatch` in that worktree, reusing the mission
|
|
273
|
+
the coordinator created once with `--title <ticket-id> --ticket <full-frozen-ticket>`.
|
|
274
|
+
A respawn retains that identity and its budgets. Before any context compaction it writes to the
|
|
274
275
|
mission what it has done: each specialist result through `mission specialist-event`, each proof
|
|
275
276
|
through `mission verify`, a committed candidate through `mission writer-event`. The journal accepts
|
|
276
277
|
only these typed events, no free note; what is not yet one of them does not survive a respawn, and
|
|
277
278
|
uncommitted edits survive only in the worktree. During development, the coordinator may create or reuse a draft pull request
|
|
278
279
|
for the branch; drafts are permitted for development, never for merge admission. After the worker
|
|
279
|
-
returns its commit and green proofs, the coordinator runs `autopilot
|
|
280
|
-
|
|
280
|
+
returns its commit and green proofs, the coordinator runs the guarded `autopilot publish` command
|
|
281
|
+
and must mark the same pull request ready (create one only if absent), then move the ticket
|
|
281
282
|
to In Review. The independent reviewer examines ready pull requests only; an unfinished draft waits.
|
|
282
283
|
Blocking findings come back as a hand-back and are corrected as a batch, per `void-implement`.
|
|
283
284
|
|
|
@@ -338,7 +339,10 @@ its proofs and returns its commit for coordinator publication; `semantic` -- two
|
|
|
338
339
|
sends the ticket to a human. A worker never picks a side of a semantic conflict to keep the loop
|
|
339
340
|
moving.
|
|
340
341
|
|
|
341
|
-
**Serial fallback.**
|
|
342
|
+
**Serial fallback.** This path requires no queue service or paid plan.
|
|
343
|
+
For CI optimization, use [void-verify CI feedback](../void-verify/references/ci-feedback.md);
|
|
344
|
+
add neither a second scheduler nor a mandatory duration gate.
|
|
345
|
+
Without a merge queue, merges run one at a time: the oldest ready pull request
|
|
342
346
|
(or the one already merging) holds the turn. The kernel reads whether the base moved past its head
|
|
343
347
|
itself, since GitHub reports it only under a protection that requires it: a head behind gets
|
|
344
348
|
`update-branch`, its new head is reviewed again, then merged, then the next. `merge` reads it once
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Guarded publication and human recovery
|
|
2
|
+
|
|
3
|
+
The coordinator runs from the checkout containing the ticket's original baseline.
|
|
4
|
+
The local candidate branch can belong to another worktree; no checkout movement
|
|
5
|
+
or evidence copy is needed. Workers remain commit-only.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
void-machine autopilot publish --ticket DEV-42 --head <full-sha> --remote origin --branch fix/dev-42 --json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This checks the explicit local branch against the full SHA and the shared Git
|
|
12
|
+
guard, then pushes that literal SHA to the named remote branch in the same
|
|
13
|
+
command. A base or deploy branch is refused. It does not force push, disable
|
|
14
|
+
hooks, set an upstream, grant review or merge permission, or remove a merge hold.
|
|
15
|
+
Missing, invalid, unreadable and changed fingerprints launch zero pushes. A
|
|
16
|
+
transport error can follow a remote success: inspect the named remote branch
|
|
17
|
+
before a deliberate retry. Never automatically follow a refusal with direct Git.
|
|
18
|
+
|
|
19
|
+
## Coverage
|
|
20
|
+
|
|
21
|
+
Policy v4 excludes only a regular file exactly at common-Git-directory `info/refs`.
|
|
22
|
+
Git documents it as generated transport information, rebuilt by
|
|
23
|
+
[`git update-server-info`](https://git-scm.com/docs/git-update-server-info).
|
|
24
|
+
Its creation, update and removal are harmless to this guard. This does not identify
|
|
25
|
+
who created an incident file from its timestamp. `objects/info/packs` is Git's
|
|
26
|
+
other generated output; it is outside the existing fingerprint. `info/packs` is
|
|
27
|
+
not that output and stays guarded. Symlinks, nested `refs`, `info/exclude`,
|
|
28
|
+
`info/attributes`, hooks and their checksums, config/includes, bases, stash, tags,
|
|
29
|
+
notes, remotes and replace refs retain their previous coverage.
|
|
30
|
+
|
|
31
|
+
Version 3 aggregates the whole info directory, including regular root `info/refs`.
|
|
32
|
+
A retained v3 record is compared against a current reading using that same complete
|
|
33
|
+
v3 policy at both publication checks and in `autopilot next` merge decisions. All nine digests and retained protected branches
|
|
34
|
+
stay authoritative; any drift refuses. No conversion, renewal or baseline write is
|
|
35
|
+
needed for an unchanged v3 state. Versions 1 and 2 remain unsupported.
|
|
36
|
+
|
|
37
|
+
A v3 aggregate cannot be converted to v4 without historical file contents. Relaxing
|
|
38
|
+
its policy or accepting actual drift still requires the explicit human renewal below.
|
|
39
|
+
`fingerprint --record` reports the current v4 reading for that renewal inspection;
|
|
40
|
+
`fingerprint --after` and publication use the retained policy for comparison.
|
|
41
|
+
|
|
42
|
+
## Explicit human renewal
|
|
43
|
+
|
|
44
|
+
Stop publication. Inspect the failure and the actual shared-state changes. A
|
|
45
|
+
person must authorize the exact repair or policy transition and affected candidate;
|
|
46
|
+
the ticket's implementation mandate alone is not that authorization.
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
void-machine autopilot fingerprint --record DEV-42 --json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Retain the output, including `recordDigest`, `currentDigest`, old fingerprint and
|
|
53
|
+
current fingerprint. After the human decision, use those exact digest values:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
void-machine autopilot fingerprint --renew DEV-42 --head <full-sha> --branch fix/dev-42 \
|
|
57
|
+
--previous <recordDigest> --expected <currentDigest> \
|
|
58
|
+
--cause 'Reviewed authorized repair or v3 policy transition' \
|
|
59
|
+
--decision '<reference to the explicit human decision>' --json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The original `fingerprints/DEV-42.json` remains byte-for-byte intact. The complete
|
|
63
|
+
renewal under `fingerprints/DEV-42.renewals/` retains both fingerprints, predecessor
|
|
64
|
+
digest, branch/SHA, cause and decision. Its atomic creation is the transition;
|
|
65
|
+
there is no separate baseline replacement. Identical replay returns the retained
|
|
66
|
+
record. Conflicting or stale replay and changed observations refuse. Preserve
|
|
67
|
+
all those files: deleting history is not recovery. Renewal changes no review,
|
|
68
|
+
merge hold, merge authorization or deployment permission.
|
|
69
|
+
|
|
70
|
+
Publication and renewal share `fingerprints/DEV-42.lock`. A competing operation
|
|
71
|
+
refuses immediately. A crashed process may leave that directory: a person must
|
|
72
|
+
establish the owning process ended and inspect retained evidence before removing
|
|
73
|
+
only that abandoned lock. An incomplete canonical record remains blocked and
|
|
74
|
+
must be recovered from retained evidence, never ignored. Unlinked unique temporary
|
|
75
|
+
files are not committed records; retain them for diagnosis after an interrupted write.
|
|
76
|
+
|
|
77
|
+
The lock coordinates these supported commands in this state directory. It cannot
|
|
78
|
+
serialize direct Git, hooks or other processes, nor prevent malicious edits to
|
|
79
|
+
local evidence. The command rechecks immediately before its side effect and uses
|
|
80
|
+
an immutable commit refspec, but does not claim an atomic snapshot of all Git state
|
|
81
|
+
through network completion. See [Git push](https://git-scm.com/docs/git-push) for
|
|
82
|
+
refspec and hook semantics. Direct Git is outside this guarantee.
|
|
@@ -55,8 +55,10 @@ materializes its runtime-neutral specialist envelopes from the current plan.
|
|
|
55
55
|
|
|
56
56
|
1. Keep one `leadWriterId` for implementation and every correction. The implementer owns
|
|
57
57
|
the worktree and code; specialists and the independent reviewer never edit.
|
|
58
|
-
2.
|
|
59
|
-
|
|
58
|
+
2. Reuse the mission ID the coordinator supplied. The coordinator creates it once from the
|
|
59
|
+
assigned worktree with `mission start --title <unit> --ticket <full-frozen-ticket> --json`.
|
|
60
|
+
Run `mission dispatch --id <mission> --json` from that worktree. Never start another mission
|
|
61
|
+
to repair a refusal. The frozen task and controller own routing, state and correction budget. Normal
|
|
60
62
|
dispatch starts the writer without a compulsory preparation panel. The writer still obtains
|
|
61
63
|
the primary domain specialist advice required by pass 5 before production edits.
|
|
62
64
|
For canonical `invoke-specialists` actions, pass each envelope unchanged through
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: void-merge
|
|
3
|
-
description: Vider la file des PR ouvertes sans casser le dépôt.
|
|
3
|
+
description: Vider la file des PR ouvertes sans casser le dépôt. Fusions séquentielles, ordre stable et dépendances explicites, CI verte ET à jour, artefacts générés régénérés, conflits de contenu rendus à leur auteur. Use when merging pull requests.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# merge — voidcorp craftsman edition
|
|
7
7
|
|
|
8
8
|
`void-implement` s'arrête à la PR ouverte. `void-autopilot` laisse à une personne les PR qu'il ne peut
|
|
9
|
-
pas
|
|
9
|
+
pas fusionner dans son mandat. Personne ne dit comment vider la file. Ce geste a l'air trivial jusqu'au moment où il ne l'est pas.
|
|
10
10
|
|
|
11
11
|
**Attribution**: see `.source`.
|
|
12
12
|
|
|
@@ -36,19 +36,26 @@ Sortent de la file, sans discussion :
|
|
|
36
36
|
|
|
37
37
|
Une file vide est un résultat, pas un échec : le dire et s'arrêter.
|
|
38
38
|
|
|
39
|
-
## Étape 2 —
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
2.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
39
|
+
## Étape 2 — Garder un ordre stable, identifier les dépendances
|
|
40
|
+
|
|
41
|
+
Une seule fusion à la fois suffit, sans service de file ni abonnement particulier.
|
|
42
|
+
Une file native déjà configurée reste compatible ; ses protections restent applicables.
|
|
43
|
+
|
|
44
|
+
1. **Conserver le tour engagé.** Dans `void-autopilot`, le noyau choisit : une PR dont la
|
|
45
|
+
fusion est déjà armée garde son tour ; sinon, la plus ancienne PR ouverte non brouillon
|
|
46
|
+
parmi les tickets suivis passe d'abord. Utiliser ses actions, pas un script de fusion parallèle.
|
|
47
|
+
2. **Hors autopilot, garder l'ordre des PR admissibles.** À défaut d'ordre explicite, partir
|
|
48
|
+
de la plus ancienne. Une PR dont la revue est acquise et dont seule la CI attendue tourne
|
|
49
|
+
conserve son tour ; une PR plus récente ne la dépasse pas simplement parce qu'elle est verte.
|
|
50
|
+
3. **Un déblocage réel se traite explicitement.** Nommer la dépendance, le conflit ou le
|
|
51
|
+
blocage durable et son propriétaire. Hors autopilot, une PR préalable peut passer d'abord
|
|
52
|
+
avec cette raison. Sous autopilot, rendre ce blocage au coordinateur : ne pas contourner
|
|
53
|
+
le tour choisi par le noyau. Une PR rouge ou en conflit ne justifie pas une attente indéfinie.
|
|
54
|
+
|
|
55
|
+
Remettre à jour seulement la PR dont le tour arrive, puis attendre ses preuves avant de
|
|
56
|
+
fusionner. Ne pas remettre toutes les branches à jour après chaque fusion : la suivante
|
|
57
|
+
ferait immédiatement vieillir ce travail. Le temps déjà dépensé ne rend jamais valide
|
|
58
|
+
une preuve liée à un ancien commit ou à une ancienne base.
|
|
52
59
|
|
|
53
60
|
## Étape 3 — Trois conditions pour merger, toutes nécessaires
|
|
54
61
|
|
|
@@ -131,8 +131,11 @@ Missing required native capability is reported with cause and next action.
|
|
|
131
131
|
## Publish worker observations
|
|
132
132
|
|
|
133
133
|
For each mission worker or reviewer, keep one `run_<opaque-id>` for its assignment.
|
|
134
|
-
|
|
135
|
-
`void-machine mission start --title <unit>
|
|
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.
|
|
136
139
|
Do not recreate a mission to evade a refusal. This publication never substitutes
|
|
137
140
|
for the mission's implementation, verification or independent review receipts.
|
|
138
141
|
|
|
@@ -189,8 +192,10 @@ stays within the existing project boundary and must match its digest and invocat
|
|
|
189
192
|
A central report marked done is never a review receipt. Preserve limitations honestly.
|
|
190
193
|
|
|
191
194
|
For autopilot, `autopilot review --ticket <id> --pr <n> --head <sha> --round <1|2>
|
|
192
|
-
--mission <canonical-id
|
|
193
|
-
and
|
|
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
|
|
194
199
|
pending, returns awaiting-native-review. ORCH performs the native invocation and
|
|
195
200
|
records its real receipts, then repeats the same command to collect. Do not start a
|
|
196
201
|
new mission to repair a pending attempt. Budgets, protected paths, HEAD drift checks,
|
|
@@ -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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
@@ -35,17 +40,80 @@ concurrency keys: `cancel-in-progress: false` alone still replaces pending runs
|
|
|
35
40
|
shared group. Keep integration checks before entry to the protected branch; checking
|
|
36
41
|
only after merge permits broken integration.
|
|
37
42
|
|
|
38
|
-
|
|
39
|
-
|
|
43
|
+
Where a repository already uses a merge queue, preserve both its required PR and
|
|
44
|
+
merge-group checks. A queue is optional; sequential merging needs no queue setup.
|
|
45
|
+
Remove a redundant post-merge run only after checking that no release, promotion or artifact consumer
|
|
40
46
|
needs it, and that the protected integration path proves the merged result. The
|
|
41
47
|
example has no push trigger; add one where it provides distinct release evidence.
|
|
42
48
|
|
|
49
|
+
For reusable enforcement, the caller must also declare `ready_for_review` and
|
|
50
|
+
`converted_to_draft`, keeping its existing check names. Preserve
|
|
51
|
+
`merge_group: checks_requested` where a queue is configured. Put concurrency only
|
|
52
|
+
in that caller; the called workflow inherits `github.workflow` and must not cancel the same group. Its admission guard runs
|
|
53
|
+
from the immutable harness checkout before Node setup and floor execution.
|
|
54
|
+
GitHub-hosted runner usage belongs to the caller, even when the reusable workflow
|
|
55
|
+
is public and the caller private. Compare latency and job-minutes before making
|
|
56
|
+
any billing claim.
|
|
57
|
+
|
|
58
|
+
Dependency audit is a separate project-owned job, without a `needs` edge that
|
|
59
|
+
prevents lint/tests/build from running during an advisory-service outage. Preserve
|
|
60
|
+
its actual package-manager/lockfile contract and severity policy: installing Bun
|
|
61
|
+
is not an audit solution for npm or pnpm consumers. `npm ci` advisory output alone
|
|
62
|
+
is not a complete audit gate. Bun consumers can adopt the packaged
|
|
63
|
+
`core-assets/templates/github/void-dependency-audit.yml` and `dependency-audit.mjs`,
|
|
64
|
+
plus this sibling `ci-admission.mjs`; the audit guide is `docs/DEPENDENCY-AUDIT.md`
|
|
65
|
+
in a matching source checkout. Its ready-PR and merge-group runs judge their own
|
|
66
|
+
revision; a weekly scheduled run catches new advisories without a lockfile change
|
|
67
|
+
and is surveillance, not a substitute for a required candidate check. Unavailable
|
|
68
|
+
or malformed evidence stays non-green. No workflow path filter may hide required
|
|
69
|
+
checks or prevent scheduled registry refresh.
|
|
70
|
+
|
|
43
71
|
Rollback: restore the prior workflow triggers and admission step together. Restoring
|
|
44
72
|
full draft CI costs runner time but does not weaken the floor. Leave protection and
|
|
45
73
|
review evidence unchanged. Existing missions and receipts are not migrated.
|
|
46
74
|
|
|
75
|
+
## Measure feedback before changing CI
|
|
76
|
+
|
|
77
|
+
On a CI optimization request, use existing run history to agree a project-specific
|
|
78
|
+
feedback target, separately for ordinary changes and documentation changes. Around ten
|
|
79
|
+
minutes for a complete PR and a few minutes for documentation can start the discussion;
|
|
80
|
+
they are advisory targets, not timeouts, required checks or permission to omit tests.
|
|
81
|
+
Report the sample size, median and p95 when the sample supports it. A missed target
|
|
82
|
+
calls for diagnosis of the critical path, not a retry or another reporting service.
|
|
83
|
+
|
|
84
|
+
Record separately: time waiting for execution, elapsed time until all required results
|
|
85
|
+
are available, and summed job execution minutes across parallel jobs and all attempts.
|
|
86
|
+
Include cancelled work and runs invalidated by branch updates. A later PR overtaking an
|
|
87
|
+
older one only wastes CI when that change actually invalidates work; do not assume a
|
|
88
|
+
saving from ordering alone. Use provider billing data for money: job-minutes are not
|
|
89
|
+
billed minutes. Missing runner-wait timestamps mean unknown, not zero; dependency waits
|
|
90
|
+
are not automatically runner waits. A run update timestamp is not its completion time.
|
|
91
|
+
|
|
92
|
+
For GitHub, inspect a concrete run and repeat for earlier attempts when present:
|
|
93
|
+
|
|
94
|
+
```sh
|
|
95
|
+
gh run view RUN_ID --repo OWNER/REPO --attempt ATTEMPT --json attempt,event,headSha,createdAt,startedAt,jobs
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Job start/completion times describe execution intervals; inspect the workflow dependencies
|
|
99
|
+
and every required workflow before deriving the feedback delay. Another CI provider's
|
|
100
|
+
native run/job view supplies the same evidence; this is no GitHub prerequisite.
|
|
101
|
+
|
|
102
|
+
Investigate a full build/test cache miss on a documentation-only diff by tracing actual
|
|
103
|
+
inputs and cache keys. Markdown may feed generated assets, executable skills or contract
|
|
104
|
+
tests; the extension alone proves nothing. Optimize unaffected work only when dependencies
|
|
105
|
+
are proven; otherwise keep the complete suite above. Preserve exact-candidate checks,
|
|
106
|
+
release artifacts and integration evidence. Reuse local evidence with unchanged inputs
|
|
107
|
+
instead of asking every agent to repeat the same full suite. Adopt workflow changes in
|
|
108
|
+
the consumer's existing configuration; updating these references does not rewrite it.
|
|
109
|
+
|
|
47
110
|
Sources read for GitHub Actions (hosted service):
|
|
48
111
|
- https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#pull_request
|
|
49
112
|
- https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-workflow-concurrency
|
|
50
113
|
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue
|
|
51
114
|
- https://docs.github.com/en/actions/how-tos/write-workflows/choose-when-workflows-run/control-jobs-with-conditions
|
|
115
|
+
|
|
116
|
+
- https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations
|
|
117
|
+
|
|
118
|
+
- https://cli.github.com/manual/gh_run_view
|
|
119
|
+
- https://docs.github.com/en/rest/actions/workflow-jobs
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
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
|