bareloop 0.20.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +234 -0
- package/README.md +14 -0
- package/bareloop.context.md +331 -10
- package/bin/bareloop.mjs +24 -0
- package/package.json +7 -3
- package/src/authorjob.js +15 -1
- package/src/bundle.js +713 -0
- package/src/cli.js +472 -0
- package/src/close-integrity.js +325 -0
- package/src/closetimeout.js +165 -0
- package/src/index.js +31 -1
- package/src/job.js +48 -4
- package/src/plan.js +5 -1
- package/src/planrun.js +212 -7
- package/src/ralph.js +40 -7
- package/src/reuse.js +4 -2
- package/src/reviewdoor.js +26 -6
- package/src/run.js +24 -3
- package/src/validate.js +59 -0
- package/types/bundle.d.ts +199 -0
- package/types/cli.d.ts +19 -0
- package/types/close-integrity.d.ts +196 -0
- package/types/closetimeout.d.ts +126 -0
- package/types/index.d.ts +4 -1
- package/types/planrun.d.ts +17 -2
- package/types/ralph.d.ts +19 -5
- package/types/reuse.d.ts +16 -0
- package/types/reviewdoor.d.ts +3 -1
- package/types/run.d.ts +25 -2
- package/types/validate.d.ts +48 -0
package/types/planrun.d.ts
CHANGED
|
@@ -221,7 +221,14 @@ export function planPrompt(job: any, scoutBlob: string, reds: any[] | null, maxS
|
|
|
221
221
|
* ladder (src/ladder.js). Arbiter territory exactly as the count it replaced was —
|
|
222
222
|
* the runner sets it, the plan cannot express it, and no step may tighten or raise
|
|
223
223
|
* it.
|
|
224
|
-
* @param {number} [opts.closeTimeoutMs] close/check wall-clock cap (shell territory)
|
|
224
|
+
* @param {number} [opts.closeTimeoutMs] close/check wall-clock cap (shell territory).
|
|
225
|
+
* OPTIONAL as of PRD item 27/M3: absent, this run autosets it from a $0 seed
|
|
226
|
+
* timing pass (or the spec's own signed `closeTimeoutMs` override) — an
|
|
227
|
+
* explicit value here still wins outright (backward compatibility/test
|
|
228
|
+
* control only, F133: `scripts/run-u.mjs`/`src/cli.js` never pass this).
|
|
229
|
+
* @param {string|null} [opts.closeDir] the close's own books directory (PRD
|
|
230
|
+
* item 27/M3 Part B), forwarded to every close invocation as
|
|
231
|
+
* `BARELOOP_CLOSE_DIR`
|
|
225
232
|
* @param {number} [opts.maxStepRounds] the shell's per-step rounds ceiling (validatePlan's bound)
|
|
226
233
|
* @param {boolean} [opts.scout=true] operator-only switch (docs/product/SCOUT-CONTRAST.md):
|
|
227
234
|
* `false` on a FRESH run (no `resumeSeed`) skips the survey entirely — `scoutBlob`
|
|
@@ -392,12 +399,18 @@ export function planPrompt(job: any, scoutBlob: string, reds: any[] | null, maxS
|
|
|
392
399
|
* precisely the state the person rejected), and the words reach the PLANNER as new
|
|
393
400
|
* authoring. It is never a `humanRuling` — that answers a close's human STAGE, and
|
|
394
401
|
* a green-class job has none. Empty words are refused at the same seam every door is.
|
|
402
|
+
* @param {boolean} [opts.resumable=true] PRD item 27(c)/F130 — does THIS runner
|
|
403
|
+
* support `--resume`? Forwarded verbatim from `runJob`; `run-u.mjs` leaves it at
|
|
404
|
+
* the default (byte-identical to before this param existed), the bundle CLI
|
|
405
|
+
* passes `false` so the three `--resume`-naming readouts below (`MONEY_OPTIONS`,
|
|
406
|
+
* the resume-plan-red option, the fix-loop terminal) say "resume is `run-u`-only
|
|
407
|
+
* in v1" instead of naming a flag that would fail if typed.
|
|
395
408
|
* @returns {Promise<string>} 'green' | 'already-green' | 'escalated' | 'plan-red' |
|
|
396
409
|
* 'check-red' | 'close-red' | 'close-unsupported' | 'recipe-stale' | 'pricing-red' |
|
|
397
410
|
* 'branch-red' | 'cap-halt' | 'wall-halt' | 'provider-red' | 'interpreter-red' |
|
|
398
411
|
* 'step-stalled' | 'hitl-pause' | 'hitl-decision-red' | `step-red:<id>`
|
|
399
412
|
*/
|
|
400
|
-
export function runPlan(job: any, { workdir, provider, nativeProvider, providerFor, judgeProvider, emit, remainingUsd, isUnpriced, spendComplete, capRuns, strikeLimit, closeTimeoutMs, maxStepRounds, layerRoot, readShim, scout, scoutRounds, bridge, now, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch, humanRuling, heldRuling, priorSpentUsd, reviewDoor, doorRerun }: {
|
|
413
|
+
export function runPlan(job: any, { workdir, provider, nativeProvider, providerFor, judgeProvider, emit, remainingUsd, isUnpriced, spendComplete, capRuns, strikeLimit, closeTimeoutMs, closeDir, maxStepRounds, layerRoot, readShim, scout, scoutRounds, bridge, now, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch, humanRuling, heldRuling, priorSpentUsd, reviewDoor, doorRerun, resumable }: {
|
|
401
414
|
workdir: string;
|
|
402
415
|
provider: any;
|
|
403
416
|
nativeProvider?: ((o: {
|
|
@@ -414,6 +427,7 @@ export function runPlan(job: any, { workdir, provider, nativeProvider, providerF
|
|
|
414
427
|
capRuns?: number | undefined;
|
|
415
428
|
strikeLimit?: number | undefined;
|
|
416
429
|
closeTimeoutMs?: number | undefined;
|
|
430
|
+
closeDir?: string | null | undefined;
|
|
417
431
|
maxStepRounds?: number | undefined;
|
|
418
432
|
scout?: boolean | undefined;
|
|
419
433
|
scoutRounds?: number | undefined;
|
|
@@ -449,6 +463,7 @@ export function runPlan(job: any, { workdir, provider, nativeProvider, providerF
|
|
|
449
463
|
fromRunid?: string | null;
|
|
450
464
|
receivedAt?: string | null;
|
|
451
465
|
} | null | undefined;
|
|
466
|
+
resumable?: boolean | undefined;
|
|
452
467
|
}): Promise<string>;
|
|
453
468
|
/**
|
|
454
469
|
* The recorded bound-reason's ceiling in the WORKER-facing note. The reason is a
|
package/types/ralph.d.ts
CHANGED
|
@@ -54,17 +54,24 @@
|
|
|
54
54
|
*
|
|
55
55
|
* @param {string[]} close argv, e.g. ['node', '--test', 'close/']
|
|
56
56
|
* @param {(s: string) => string} [redact] source scrubber; identity by default
|
|
57
|
-
* @param {{ timeoutMs?: number, cwd?: string, expect?: number, judged?: {pattern: string, min: number}, gapKeep?: string }} [opts]
|
|
57
|
+
* @param {{ timeoutMs?: number, cwd?: string, expect?: number, judged?: {pattern: string, min: number}, gapKeep?: string, closeDir?: string|null }} [opts]
|
|
58
58
|
* close wall-clock cap (operator-set via the runner, never the config's — the
|
|
59
59
|
* agent must not author its arbiter's clock), the directory the close runs in
|
|
60
60
|
* (the workdir — the tree it is judging), the exit code the SIGNED spec calls
|
|
61
61
|
* success, the judgment-rendered signal, and the kept-failures pattern. All
|
|
62
62
|
* five are arbiter territory: the drafted workflow config cannot express any.
|
|
63
|
+
* `closeDir` (PRD item 27/M3 Part B) is the close's OWN books directory —
|
|
64
|
+
* pristine copies, calibration thresholds, logs — deliberately outside the
|
|
65
|
+
* patient tree (the worker must never read the arbiter's books). Handed to
|
|
66
|
+
* the child as `BARELOOP_CLOSE_DIR` (`CLOSE_DIR_ENV_VAR`,
|
|
67
|
+
* src/close-integrity.js); a close script that needs one and gets none
|
|
68
|
+
* instrument-stops itself, by the script's own contract — this seam only
|
|
69
|
+
* ever THREADS the value, it never invents one.
|
|
63
70
|
* @returns {Promise<{verdict: 'satisfied'|'needs_revision'|'failed'|'timed-out'|'killed'|'crashed',
|
|
64
71
|
* gap?: string, exitCode?: number, signal?: string, detail?: string,
|
|
65
72
|
* judgedCount?: number|null, unaudited?: boolean}>}
|
|
66
73
|
*/
|
|
67
|
-
export function runClose(close: string[], redact?: (s: string) => string, { timeoutMs, cwd, expect, judged, gapKeep }?: {
|
|
74
|
+
export function runClose(close: string[], redact?: (s: string) => string, { timeoutMs, cwd, expect, judged, gapKeep, closeDir }?: {
|
|
68
75
|
timeoutMs?: number;
|
|
69
76
|
cwd?: string;
|
|
70
77
|
expect?: number;
|
|
@@ -73,6 +80,7 @@ export function runClose(close: string[], redact?: (s: string) => string, { time
|
|
|
73
80
|
min: number;
|
|
74
81
|
};
|
|
75
82
|
gapKeep?: string;
|
|
83
|
+
closeDir?: string | null;
|
|
76
84
|
}): Promise<{
|
|
77
85
|
verdict: "satisfied" | "needs_revision" | "failed" | "timed-out" | "killed" | "crashed";
|
|
78
86
|
gap?: string;
|
|
@@ -104,12 +112,13 @@ export function runClose(close: string[], redact?: (s: string) => string, { time
|
|
|
104
112
|
*
|
|
105
113
|
* @param {any[]} stages the stage list (already validated by validateJob)
|
|
106
114
|
* @param {(s: string) => string} [redact] scrub, applied at capture on EVERY stage
|
|
107
|
-
* @param {{timeoutMs?: number, cwd?: string}} [opts]
|
|
115
|
+
* @param {{timeoutMs?: number, cwd?: string, closeDir?: string|null}} [opts]
|
|
108
116
|
* @returns {Promise<any>} runClose's verdict shape, plus `stage` and `stages`
|
|
109
117
|
*/
|
|
110
|
-
export function runStages(stages: any[], redact?: (s: string) => string, { timeoutMs, cwd }?: {
|
|
118
|
+
export function runStages(stages: any[], redact?: (s: string) => string, { timeoutMs, cwd, closeDir }?: {
|
|
111
119
|
timeoutMs?: number;
|
|
112
120
|
cwd?: string;
|
|
121
|
+
closeDir?: string | null;
|
|
113
122
|
}): Promise<any>;
|
|
114
123
|
/**
|
|
115
124
|
* Bound an over-long close stream to a head sample + elided middle + tail. When
|
|
@@ -210,9 +219,13 @@ export function boundGap(s: string, keepPattern?: string): string;
|
|
|
210
219
|
* it to the gate audit's allow-decision writes. Injected like `redact` so the shell
|
|
211
220
|
* stays stdlib-only and dumb; consulted ONLY at a crashed verdict. With no seam, or
|
|
212
221
|
* with zero writes, a crash stays what it always was: an instrument stop.
|
|
222
|
+
* @param {string|null} [opts.closeDir] the close's own books directory
|
|
223
|
+
* (PRD item 27/M3 Part B), forwarded to the raw `close` path's `runClose`
|
|
224
|
+
* call unchanged; a caller supplying `judge` instead already closed over
|
|
225
|
+
* its own `closeDir` and this param does nothing for it.
|
|
213
226
|
* @returns {Promise<'green'|'escalated'>}
|
|
214
227
|
*/
|
|
215
|
-
export function ralph({ middle, close, judge, capRuns, ladder, emit, redact, closeTimeoutMs, cwd, expect, judged, gapKeep, workerWrites }: {
|
|
228
|
+
export function ralph({ middle, close, judge, capRuns, ladder, emit, redact, closeTimeoutMs, cwd, expect, judged, gapKeep, workerWrites, closeDir }: {
|
|
216
229
|
middle: (iteration: number, gap?: string) => void | Promise<void>;
|
|
217
230
|
close?: string[] | undefined;
|
|
218
231
|
judge?: (() => Promise<{
|
|
@@ -237,6 +250,7 @@ export function ralph({ middle, close, judge, capRuns, ladder, emit, redact, clo
|
|
|
237
250
|
} | undefined;
|
|
238
251
|
gapKeep?: string | undefined;
|
|
239
252
|
workerWrites?: (() => string[]) | undefined;
|
|
253
|
+
closeDir?: string | null | undefined;
|
|
240
254
|
}): Promise<"green" | "escalated">;
|
|
241
255
|
/**
|
|
242
256
|
* What the close child must NOT be able to read (operator ruling, 2026-07-31:
|
package/types/reuse.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The name a cold green FORKS to when the entry of the job's own name greened a
|
|
3
|
+
* different close. Derived from the shape itself, so it is deterministic: the same
|
|
4
|
+
* close always lands in the same file, and the next green of that shape appends there
|
|
5
|
+
* instead of minting a third entry.
|
|
6
|
+
*
|
|
7
|
+
* The separator is a HYPHEN, not the `~` first proposed: the registry name IS the
|
|
8
|
+
* filename and `validateBridge` holds it to the same kebab alphabet the job validator
|
|
9
|
+
* uses (`^[a-z0-9][a-z0-9-]*$`), so a `~` name would be refused by the entry's own
|
|
10
|
+
* validator and the green would be lost — which is the exact failure this fork exists
|
|
11
|
+
* to prevent.
|
|
12
|
+
* @param {string} name @param {string[]} stageNames @returns {string}
|
|
13
|
+
*/
|
|
14
|
+
export function shapeForkName(name: string, stageNames: string[]): string;
|
|
1
15
|
/**
|
|
2
16
|
* Validate the reuse envelope — the three numbers the operator signs before the run.
|
|
3
17
|
*
|
|
@@ -363,6 +377,7 @@ export function resumeTreeGate({ head, seed, dirty }: {
|
|
|
363
377
|
* @param {number} [opts.capRuns] forwarded
|
|
364
378
|
* @param {number} [opts.strikeLimit] forwarded (a plan step's strike ceiling)
|
|
365
379
|
* @param {number} [opts.closeTimeoutMs] forwarded
|
|
380
|
+
* @param {string} [opts.closeDir] forwarded (PRD item 27/M3 Part B)
|
|
366
381
|
* @param {boolean} [opts.layerRoot] forwarded
|
|
367
382
|
* @param {boolean|'cap'|'diff'} [opts.readShim] the read shim's ARM (A0/A1/A2/A3), forwarded verbatim
|
|
368
383
|
* @param {any} [opts.resume] RESUME (module C) — a `readResume` reading of the KILLED
|
|
@@ -397,6 +412,7 @@ export function runReuse(opts: {
|
|
|
397
412
|
capRuns?: number | undefined;
|
|
398
413
|
strikeLimit?: number | undefined;
|
|
399
414
|
closeTimeoutMs?: number | undefined;
|
|
415
|
+
closeDir?: string | undefined;
|
|
400
416
|
layerRoot?: boolean | undefined;
|
|
401
417
|
readShim?: boolean | "cap" | "diff" | undefined;
|
|
402
418
|
resume?: any;
|
package/types/reviewdoor.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export function doorAgeGate(door: any, { now, ttlMs }?: {
|
|
|
40
40
|
* @param {string} opts.decision one of the three doors
|
|
41
41
|
* @param {string|null} [opts.text] the rerun's words — the gap, and refused when empty
|
|
42
42
|
* @param {number} [opts.closeTimeoutMs] the per-stage bound for the accept's re-run
|
|
43
|
+
* @param {string|null} [opts.closeDir] the close's own books directory (PRD item 27/M3 Part B), forwarded to the accept's re-run
|
|
43
44
|
* @param {string|null} [opts.registryDir] the workflow registry, when the runner keeps one
|
|
44
45
|
* @param {string|null} [opts.name] the workflow this run wrote its row against
|
|
45
46
|
* @param {string|null} [opts.runid] the RUN's id, exactly as the bridge row records it
|
|
@@ -51,13 +52,14 @@ export function doorAgeGate(door: any, { now, ttlMs }?: {
|
|
|
51
52
|
* doorRecorded: boolean, reds: any[], mechanical: any, door: any, text: string|null,
|
|
52
53
|
* options: string[], ttlMs: number, note: string|null}>}
|
|
53
54
|
*/
|
|
54
|
-
export function answerReviewDoor({ job, workdir, events, decision, text, closeTimeoutMs, registryDir, name, runid, at, now, ttlMs, emit, }: {
|
|
55
|
+
export function answerReviewDoor({ job, workdir, events, decision, text, closeTimeoutMs, closeDir, registryDir, name, runid, at, now, ttlMs, emit, }: {
|
|
55
56
|
job: any;
|
|
56
57
|
workdir: string;
|
|
57
58
|
events: any[];
|
|
58
59
|
decision: string;
|
|
59
60
|
text?: string | null | undefined;
|
|
60
61
|
closeTimeoutMs?: number | undefined;
|
|
62
|
+
closeDir?: string | null | undefined;
|
|
61
63
|
registryDir?: string | null | undefined;
|
|
62
64
|
name?: string | null | undefined;
|
|
63
65
|
runid?: string | null | undefined;
|
package/types/run.d.ts
CHANGED
|
@@ -45,7 +45,22 @@
|
|
|
45
45
|
* CLOSE-FIX loop (a plan STEP runs under the strike ladder instead)
|
|
46
46
|
* @param {number} [opts.strikeLimit] shell-owned strike ceiling for a plan step's ladder
|
|
47
47
|
* @param {number} [opts.shellCapUsd] the shell's hard USD ceiling
|
|
48
|
-
* @param {number} [opts.closeTimeoutMs] close wall-clock cap (shell territory)
|
|
48
|
+
* @param {number} [opts.closeTimeoutMs] close wall-clock cap (shell territory).
|
|
49
|
+
* OPTIONAL as of PRD item 27/M3: absent, the plan flow autosets it from a $0
|
|
50
|
+
* seed timing pass (or reads the spec's own signed `closeTimeoutMs`
|
|
51
|
+
* override) — a caller passing an explicit value here still wins outright
|
|
52
|
+
* (backward compatibility / test control), but production callers
|
|
53
|
+
* (`src/cli.js`, `scripts/run-u.mjs`) pass nothing (F133, run mtqwmb9l: a
|
|
54
|
+
* runner that resolves this itself for its own purposes — e.g. `run-u.mjs`
|
|
55
|
+
* sizing its outside watchdog, F67 — must never feed the number back in
|
|
56
|
+
* here too, or this call's own autoset/override banner prints a SECOND,
|
|
57
|
+
* mislabelled "explicit runner override" line on top of the runner's own
|
|
58
|
+
* correctly-labelled one).
|
|
59
|
+
* @param {string|null} [opts.closeDir] the close's own books directory (PRD item
|
|
60
|
+
* 27/M3 Part B) — pristine copies, calibration thresholds, logs — outside
|
|
61
|
+
* the patient tree. Forwarded to every close invocation as
|
|
62
|
+
* `BARELOOP_CLOSE_DIR`; a close script that needs one and gets none
|
|
63
|
+
* instrument-stops itself (`checkCloseDirRequired`, src/close-integrity.js).
|
|
49
64
|
* @param {unknown} [opts.bridge] Layer 3 — a bridge-v1 entry to reuse as the drafter's
|
|
50
65
|
* STARTING DRAFT (design record 2026-08-01, D4), forwarded to the plan flow. Omitted is
|
|
51
66
|
* the cold path and is byte-identical to a pre-Layer-3 run. WHICH entry (the listing, an
|
|
@@ -141,13 +156,19 @@
|
|
|
141
156
|
* @param {{text: string, fromRunid?: string|null, receivedAt?: string|null}|null} [opts.doorRerun]
|
|
142
157
|
* MODULE 8 — this leg IS the fresh engagement a signer commissioned at a previous
|
|
143
158
|
* run's review door, carrying their words. Forwarded verbatim.
|
|
159
|
+
* @param {boolean} [opts.resumable=true] PRD item 27(c)/F130 — does THIS runner
|
|
160
|
+
* support `--resume` at all? `run-u.mjs` does (the default, `true`, byte-identical
|
|
161
|
+
* to before this param existed); the exported bundle CLI does not (F130) and
|
|
162
|
+
* passes `false` so the escalation tail's option strings say "resume is
|
|
163
|
+
* `run-u`-only in v1" instead of naming a flag that would fail if typed. Forwarded
|
|
164
|
+
* verbatim to the plan flow, which owns the three `--resume`-naming readouts.
|
|
144
165
|
* @returns {Promise<string>} outcome: 'green' | 'already-green' | 'escalated' |
|
|
145
166
|
* 'unapproved-spec' | 'job-red' | 'smoke-red' | 'plan-red' | 'check-red' |
|
|
146
167
|
* 'close-red' | 'close-unsupported' | 'recipe-stale' | 'branch-red' | 'pricing-red' | 'provider-red' |
|
|
147
168
|
* 'interpreter-red' | 'cap-halt' | 'wall-halt' | 'step-stalled' |
|
|
148
169
|
* 'hitl-pause' | 'hitl-decision-red' | `step-red:<id>`
|
|
149
170
|
*/
|
|
150
|
-
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, judgeProvider, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, layerRoot, readShim, scout, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch, humanRuling, heldRuling, reviewDoor, doorRerun }: {
|
|
171
|
+
export function runJob(rawSpec: object | string, { approvals, workdir, provider, nativeProvider, providerFor, judgeProvider, emit, capRuns, strikeLimit, shellCapUsd, closeTimeoutMs, closeDir, layerRoot, readShim, scout, bridge, priorSpentUsd, priorSpendComplete, priorWallMs, resumeSeed, resumeGrades, resumeReplans, resumeBranch, humanRuling, heldRuling, reviewDoor, doorRerun, resumable }: {
|
|
151
172
|
approvals: unknown;
|
|
152
173
|
workdir: string;
|
|
153
174
|
provider: any;
|
|
@@ -164,6 +185,7 @@ export function runJob(rawSpec: object | string, { approvals, workdir, provider,
|
|
|
164
185
|
strikeLimit?: number | undefined;
|
|
165
186
|
shellCapUsd?: number | undefined;
|
|
166
187
|
closeTimeoutMs?: number | undefined;
|
|
188
|
+
closeDir?: string | null | undefined;
|
|
167
189
|
bridge?: unknown;
|
|
168
190
|
priorSpentUsd?: number | undefined;
|
|
169
191
|
priorSpendComplete?: boolean | undefined;
|
|
@@ -196,6 +218,7 @@ export function runJob(rawSpec: object | string, { approvals, workdir, provider,
|
|
|
196
218
|
fromRunid?: string | null;
|
|
197
219
|
receivedAt?: string | null;
|
|
198
220
|
} | null | undefined;
|
|
221
|
+
resumable?: boolean | undefined;
|
|
199
222
|
}): Promise<string>;
|
|
200
223
|
/** @typedef {{code: string, path: string, detail?: string}} Red */
|
|
201
224
|
/**
|
package/types/validate.d.ts
CHANGED
|
@@ -25,6 +25,34 @@ export function scopeContained(s: string): boolean;
|
|
|
25
25
|
export function isObj(v: unknown): boolean;
|
|
26
26
|
/** @param {unknown} v @returns {v is string} */
|
|
27
27
|
export function isNonEmptyString(v: unknown): v is string;
|
|
28
|
+
/**
|
|
29
|
+
* The candidate script path TOKEN a close stage's `cmd` names, by SHAPE
|
|
30
|
+
* alone — no fs, no cwd resolution, so this is safe for `validateJob` (pure)
|
|
31
|
+
* to call directly. Two recognized forms, first match wins:
|
|
32
|
+
* - an INTERPRETER cmd: the token is the first argv[1..] element that is
|
|
33
|
+
* PATH-SHAPED (not a `-`-prefixed flag, and either contains `/` or ends
|
|
34
|
+
* in one of `.mjs .cjs .js .ts .sh .py`) — never just argv[1] outright.
|
|
35
|
+
* `node --enable-source-maps ./close/x.mjs stage` names `./close/x.mjs`,
|
|
36
|
+
* not `--enable-source-maps`; `python -m pytest` and `npx tsc --noEmit`
|
|
37
|
+
* name NOTHING (`-m`/`--noEmit` are flags, `pytest`/`tsc` are bare
|
|
38
|
+
* command names with no path shape) — fixed 2026-09-06 (orchestrator
|
|
39
|
+
* audit) after the earlier bare-argv[1] version demanded a sha256 for a
|
|
40
|
+
* token that named no file, making such a spec unsignable forever (the
|
|
41
|
+
* sign helper reads nothing, the validator reds permanently);
|
|
42
|
+
* - a bare cmd whose argv[0] ITSELF is an absolute path (no interpreter
|
|
43
|
+
* prefix — a `.sh`/other directly-executable close script) → the token
|
|
44
|
+
* is argv[0].
|
|
45
|
+
* Anything else — a relative bare executable (`true`, `pytest`), an
|
|
46
|
+
* interpreter with no path-shaped argument (`python -m pytest`, `npx tsc
|
|
47
|
+
* --noEmit`), a non-string/empty cmd — names no addressable file under this
|
|
48
|
+
* scheme and returns null; those stages carry no sha256 demand and are
|
|
49
|
+
* invisible to the byte/path detectors, exactly as they always were (most
|
|
50
|
+
* test-fixture closes use exactly this shape on purpose, to exercise
|
|
51
|
+
* runtime behaviour with no real script file at all).
|
|
52
|
+
* @param {unknown} cmd
|
|
53
|
+
* @returns {string|null}
|
|
54
|
+
*/
|
|
55
|
+
export function closeScriptCandidateToken(cmd: unknown): string | null;
|
|
28
56
|
/**
|
|
29
57
|
* Scan a RAW text stream (a spine file, a close's output, a transcript) for
|
|
30
58
|
* known secret shapes and return the literal matches. The ONE spelling of the
|
|
@@ -177,4 +205,24 @@ export function hasNestedQuantifier(src: string): boolean;
|
|
|
177
205
|
* @param {(code: string, path: string, detail?: string) => void} red
|
|
178
206
|
*/
|
|
179
207
|
export function sweepNestedQuantifiers(root: any, red: (code: string, path: string, detail?: string) => void): void;
|
|
208
|
+
/**
|
|
209
|
+
* PRD item 27/M2 close-bytes signature, orchestrator-flagged gap
|
|
210
|
+
* (2026-09-06): a close stage's `cmd` can name an addressable script TWO
|
|
211
|
+
* ways — `node <path> …` (M1's original scope) or a BARE directly-executable
|
|
212
|
+
* absolute path (a `.sh` wrapper, e.g. `jobs/aurora-testgen-cold.json`'s
|
|
213
|
+
* close, which `readCloseScripts` used to skip entirely, leaving both
|
|
214
|
+
* `close-absolute-path` and the sha256 signature blind to it — a "blind
|
|
215
|
+
* instrument" the audit named directly). This list is the shared, STATIC
|
|
216
|
+
* (no fs) shape test both `src/job.js` (which only needs to know WHETHER a
|
|
217
|
+
* stage names an addressable script, to decide whether `sha256` is
|
|
218
|
+
* demanded) and `src/close-integrity.js` (which resolves the token against
|
|
219
|
+
* a real cwd and reads it off disk) key off — one spelling, so the demand
|
|
220
|
+
* and the detector can never drift apart about which stages are in scope.
|
|
221
|
+
* A leading-interpreter cmd (`sh`/`bash`/`python`/`python3`/`npx` besides
|
|
222
|
+
* `node`) is included for the same reason `node` is: a close author may use
|
|
223
|
+
* any of them, and a scope that only recognized `node` would just move the
|
|
224
|
+
* blind spot rather than close it.
|
|
225
|
+
* @type {readonly string[]}
|
|
226
|
+
*/
|
|
227
|
+
export const CLOSE_SCRIPT_INTERPRETERS: readonly string[];
|
|
180
228
|
export const SECRET_PATTERNS: RegExp[];
|