@tiphys/kernel 0.1.0 → 0.2.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/AGENTS.md +56 -4
- package/assurance-modes.yaml +23 -2
- package/dist/bin/tiphys.js +86 -8
- package/dist/src/adapters/load.d.ts +202 -0
- package/dist/src/adapters/load.js +440 -0
- package/dist/src/brief.js +27 -20
- package/dist/src/checks.d.ts +720 -9
- package/dist/src/checks.js +1874 -163
- package/dist/src/cli.js +11 -0
- package/dist/src/commands/brief.js +27 -4
- package/dist/src/commands/cutover.d.ts +35 -0
- package/dist/src/commands/cutover.js +448 -0
- package/dist/src/commands/doctor.d.ts +229 -0
- package/dist/src/commands/doctor.js +968 -27
- package/dist/src/commands/init.d.ts +3 -3
- package/dist/src/commands/init.js +57 -8
- package/dist/src/commands/lock.d.ts +33 -0
- package/dist/src/commands/lock.js +117 -6
- package/dist/src/commands/next.d.ts +130 -0
- package/dist/src/commands/next.js +597 -0
- package/dist/src/commands/pool.js +12 -1
- package/dist/src/commands/resume.d.ts +1 -0
- package/dist/src/commands/resume.js +88 -0
- package/dist/src/commands/spawn.js +51 -2
- package/dist/src/commands/status.d.ts +6 -4
- package/dist/src/commands/status.js +6 -4
- package/dist/src/commands/sync.d.ts +47 -0
- package/dist/src/commands/sync.js +341 -0
- package/dist/src/commands/teardown.js +10 -2
- package/dist/src/commands/validate.js +70 -0
- package/dist/src/cutover.d.ts +584 -0
- package/dist/src/cutover.js +1444 -0
- package/dist/src/exclusion.d.ts +389 -0
- package/dist/src/exclusion.js +843 -0
- package/dist/src/exec/env.d.ts +152 -2
- package/dist/src/exec/env.js +146 -2
- package/dist/src/fleet.d.ts +172 -0
- package/dist/src/fleet.js +219 -1
- package/dist/src/gates/citations.js +7 -1
- package/dist/src/gates/coverage.d.ts +113 -22
- package/dist/src/gates/coverage.js +166 -31
- package/dist/src/gates/credentials.d.ts +159 -0
- package/dist/src/gates/credentials.js +221 -2
- package/dist/src/gates/gate-classes.d.ts +56 -0
- package/dist/src/gates/gate-classes.js +633 -0
- package/dist/src/gates/merge-preconditions.d.ts +319 -0
- package/dist/src/gates/merge-preconditions.js +932 -0
- package/dist/src/gates/red-witness.js +105 -13
- package/dist/src/gates/run.d.ts +49 -1
- package/dist/src/gates/run.js +83 -5
- package/dist/src/gates/schemas/phase-declaration.schema.json +45 -0
- package/dist/src/gates/suite.js +48 -7
- package/dist/src/hooks.d.ts +55 -3
- package/dist/src/hooks.js +69 -6
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.js +30 -0
- package/dist/src/lock.d.ts +82 -4
- package/dist/src/lock.js +314 -22
- package/dist/src/model-resolution.d.ts +159 -0
- package/dist/src/model-resolution.js +307 -0
- package/dist/src/path-identity.d.ts +32 -0
- package/dist/src/path-identity.js +38 -0
- package/dist/src/pool.d.ts +197 -1
- package/dist/src/pool.js +289 -22
- package/dist/src/roles.d.ts +31 -0
- package/dist/src/roles.js +42 -0
- package/dist/src/spawn.d.ts +307 -2
- package/dist/src/spawn.js +690 -19
- package/dist/src/status.d.ts +27 -2
- package/dist/src/status.js +34 -5
- package/dist/src/task.d.ts +295 -55
- package/dist/src/task.js +125 -123
- package/dist/src/teardown.d.ts +7 -0
- package/dist/src/teardown.js +120 -12
- package/dist/src/validate.d.ts +44 -11
- package/dist/src/validate.js +44 -34
- package/dist/src/watcher.js +1 -11
- package/dist/src/witness/run.d.ts +32 -7
- package/dist/src/witness/run.js +76 -30
- package/dist/src/witness/spec.d.ts +168 -0
- package/dist/src/witness/spec.js +240 -18
- package/dist/tsconfig.src.tsbuildinfo +1 -1
- package/gate-registry.yaml +136 -0
- package/gates.manifest.json +63 -1
- package/package.json +18 -3
- package/roles/implementer.md +3 -0
- package/schemas/README.md +1 -0
- package/schemas/assurance-modes.schema.json +1 -1
- package/schemas/charter.schema.json +19 -0
- package/schemas/cutover-state.schema.json +64 -0
- package/schemas/executor-record.schema.json +36 -0
- package/schemas/model-resolution.schema.json +362 -0
- package/schemas/verdict.schema.json +9 -3
- package/schemas/write-bypass.schema.json +69 -0
package/dist/src/spawn.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { ChildEnvExtension } from "./exec/env.ts";
|
|
1
2
|
import type { Fleet } from "./fleet.ts";
|
|
2
|
-
import type { GuardResult, TaskMeta, TaskShape } from "./task.ts";
|
|
3
|
+
import type { CredentialHandoverRecord, GuardResult, PayloadClass, TaskMeta, TaskShape } from "./task.ts";
|
|
3
4
|
/**
|
|
4
5
|
* tiphys spawn (kernel plan v1, M1-P4 step 4): worktree, brief, turn-end
|
|
5
6
|
* hook, task meta and the executor launch in ONE command.
|
|
@@ -62,7 +63,155 @@ export interface ExecutorRequest {
|
|
|
62
63
|
* declared escape hatch; an adapter must never widen it on its own.
|
|
63
64
|
*/
|
|
64
65
|
env: Record<string, string> | undefined;
|
|
66
|
+
/**
|
|
67
|
+
* THE ASSEMBLED BRIEF, and it is NOT optional (M4-P3 criterion 1).
|
|
68
|
+
*
|
|
69
|
+
* The brief is the agent payload's entire input, and until this phase the
|
|
70
|
+
* request did not carry it at all, although the call site already had it:
|
|
71
|
+
* `assembleBrief` returns the path and `spawnTask` pushes it onto
|
|
72
|
+
* `createdFiles` before the launch. So an optional `briefPath` would be an
|
|
73
|
+
* optionality the kernel never exercises, which is a field that cannot go
|
|
74
|
+
* red: every production path supplies it and no test could construct the
|
|
75
|
+
* absent case without inventing one.
|
|
76
|
+
*
|
|
77
|
+
* The three fields below it are `string | undefined` for the opposite
|
|
78
|
+
* reason: nothing in the kernel produces them, they arrive from the caller,
|
|
79
|
+
* and an adapter that needs one says so through `requires` rather than
|
|
80
|
+
* hoping.
|
|
81
|
+
*/
|
|
82
|
+
briefPath: string;
|
|
83
|
+
/**
|
|
84
|
+
* The role the payload is being asked to play, verbatim as the caller named
|
|
85
|
+
* it. The kernel neither interprets it nor holds a vocabulary for it; the
|
|
86
|
+
* role briefs are a shipped artifact and the mapping from a role to a brief
|
|
87
|
+
* is the plugin's business.
|
|
88
|
+
*/
|
|
89
|
+
role: string | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* THE DECLARED TIER, VERBATIM, AND NEVER A MODEL NAME (M4-P3, the
|
|
92
|
+
* zero-vendor-names requirement). Whatever `role-model-config.yaml`
|
|
93
|
+
* declares, `strongest` or `cheaper` or anything else, crosses this seam
|
|
94
|
+
* unaltered. The tier-to-model mapping lives in the plugin: a mapping in
|
|
95
|
+
* `src/` is what would close off every harness that is not the one it names
|
|
96
|
+
* (delivery/plan/m4-intake.md:377).
|
|
97
|
+
*/
|
|
98
|
+
declaredTier: string | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* The delivery phase this task belongs to, CARRIED and never DERIVED.
|
|
101
|
+
*
|
|
102
|
+
* The scope gate derives a phase id from a branch name, and M4-D-22 leaves
|
|
103
|
+
* open whether that convention is the kernel's or the delivering project's.
|
|
104
|
+
* A kernel that derived the phase id from a branch here would settle
|
|
105
|
+
* M4-D-22 by accident, and a shipped constant is the hardest kind of
|
|
106
|
+
* decision to renumber.
|
|
107
|
+
*/
|
|
108
|
+
phaseId: string | undefined;
|
|
65
109
|
}
|
|
110
|
+
/** The closed set of names an adapter may name in `requires`, in field order. */
|
|
111
|
+
export declare function requirableRequestFields(): readonly string[];
|
|
112
|
+
/**
|
|
113
|
+
* THE ADAPTER CONTRACT CHECK (M4-P3 criterion 3): a requirement naming a
|
|
114
|
+
* field that does not exist is a DEFECT IN THE ADAPTER, refused when the
|
|
115
|
+
* adapter is taken up and before anything is created.
|
|
116
|
+
*
|
|
117
|
+
* IT IS A DIFFERENT QUESTION FROM `checkAdapterRequirements` BELOW, AND THE
|
|
118
|
+
* ORDER IS LOAD-BEARING. The presence test there answers "is this field
|
|
119
|
+
* absent", and an unknown key is absent too, so a single check written that
|
|
120
|
+
* way would answer a defect in the adapter with a message about a missing
|
|
121
|
+
* flag: an operator would go looking for a `--modelName` that the kernel has
|
|
122
|
+
* no field for and could never accept. Running this one FIRST is what keeps
|
|
123
|
+
* the two answers distinct, and `test/spawn.test.ts` asserts that they say
|
|
124
|
+
* structurally different things rather than merely both refusing.
|
|
125
|
+
*/
|
|
126
|
+
export declare function checkAdapterContract(adapter: ExecutorAdapter): {
|
|
127
|
+
ok: true;
|
|
128
|
+
} | {
|
|
129
|
+
ok: false;
|
|
130
|
+
reason: string;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* THE DECLARED-REQUIREMENT CHECK (M4-P3 criterion 2): a field the adapter
|
|
134
|
+
* declared it needs, and the spawn was not given, is a USAGE ERROR, and a
|
|
135
|
+
* usage error creates nothing.
|
|
136
|
+
*
|
|
137
|
+
* THE DANGEROUS STATE THIS EXISTS FOR is not "an adapter gets undefined". It
|
|
138
|
+
* is an adapter DISCOVERING that it got undefined, and raising, after pool
|
|
139
|
+
* create has already made a worktree, a branch and a pool record. That is the
|
|
140
|
+
* measured `--deadline` defect at src/commands/spawn.ts:81 with a new field:
|
|
141
|
+
* a value the kernel could not represent used to raise inside the adapter,
|
|
142
|
+
* after the creation, and the repair was to refuse at parse time. This is the
|
|
143
|
+
* same repair one field along, and it is the reason the check runs at the top
|
|
144
|
+
* of `spawnTask` rather than beside the launch where the request is built.
|
|
145
|
+
*/
|
|
146
|
+
export declare function checkAdapterRequirements(adapter: ExecutorAdapter, options: SpawnOptions): {
|
|
147
|
+
ok: true;
|
|
148
|
+
} | {
|
|
149
|
+
ok: false;
|
|
150
|
+
reason: string;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* THE CREDENTIAL POLICY CHECK (M4-P8 steps 2, 3 and 5), and it runs before
|
|
154
|
+
* ANYTHING is resolved, loaded or created.
|
|
155
|
+
*
|
|
156
|
+
* Three refusals, in this order, and the order is the fail-closed one:
|
|
157
|
+
*
|
|
158
|
+
* 1. an absent or unrecognised `payloadClass`. Checked first so that
|
|
159
|
+
* refusal 2 never has to reason about an unknown value: without this,
|
|
160
|
+
* `payloadClass !== "project"` would read an omission as permission.
|
|
161
|
+
* 2. the declared escape hatch asked for on a PROJECT payload. This is
|
|
162
|
+
* the pairing the phase exists to refuse: `allowPrCredentials` hands
|
|
163
|
+
* the parent environment over UNCHANGED (see ExecutorRequest.env),
|
|
164
|
+
* credentials and all, and M2-P8 criterion 1 wrote it for the
|
|
165
|
+
* orchestrator's own spawns only. Until this phase the option was
|
|
166
|
+
* reachable from the library seam with nothing between it and a
|
|
167
|
+
* project payload.
|
|
168
|
+
* 3. an extension entry the child must not carry, which is the same
|
|
169
|
+
* vocabulary check `buildChildEnv` makes, made EARLIER. The
|
|
170
|
+
* duplication is deliberate and is not two implementations: both call
|
|
171
|
+
* `refuseExtraAllowlist`. Making it here as well is what keeps a
|
|
172
|
+
* rejected widening from costing a worktree, a branch and a pool
|
|
173
|
+
* record, because `buildChildEnv` does not run until after pool
|
|
174
|
+
* create.
|
|
175
|
+
*
|
|
176
|
+
* It returns a reason rather than throwing, because every refusal on this
|
|
177
|
+
* path must be able to say "nothing was created" in the same sentence.
|
|
178
|
+
*/
|
|
179
|
+
export declare function checkCredentialPolicy(options: SpawnOptions): {
|
|
180
|
+
ok: true;
|
|
181
|
+
} | {
|
|
182
|
+
ok: false;
|
|
183
|
+
reason: string;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Pointer evidence: what the five credential-store redirections actually
|
|
187
|
+
* were where the payload ran, and where that observation came from.
|
|
188
|
+
*/
|
|
189
|
+
export interface RedirectionEvidence {
|
|
190
|
+
source: "turn-end-record" | "adapter";
|
|
191
|
+
/** Observed value per name; `null` for a name that was unset. */
|
|
192
|
+
values: Readonly<Record<string, string | null>>;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* COMPARE THE HANDOVER (M4-P8 criterion 6, repaired for CR-B-001).
|
|
196
|
+
*
|
|
197
|
+
* `handed` is what the kernel built and passed, `reported` is the name set
|
|
198
|
+
* the adapter says it launched with, `pointers` is what the five
|
|
199
|
+
* CREDENTIAL_STORE_REDIRECTIONS actually were where the payload ran.
|
|
200
|
+
*
|
|
201
|
+
* TWO PROPERTIES, AND THE STATUS SAYS WHICH WERE CHECKED. The name-set
|
|
202
|
+
* comparison alone used to be written down as `compared`, which an operator
|
|
203
|
+
* reads as "the handover was verified"; an adapter that keeps the name set
|
|
204
|
+
* byte-identical and puts `HOME` and `XDG_CONFIG_HOME` back to their real
|
|
205
|
+
* paths defeats the M2R-004 defense entirely and was recorded as clean. See
|
|
206
|
+
* `CredentialHandoverRecord` for the five status values and for why the
|
|
207
|
+
* VALUES are still never written into the record.
|
|
208
|
+
*
|
|
209
|
+
* The pointer comparison is by value and the values are DISCARDED: only the
|
|
210
|
+
* names that differ survive into `changedRedirections`. A name the kernel
|
|
211
|
+
* never handed over is not compared, because there is no handed value to
|
|
212
|
+
* compare it against, and the name-set arms are what speak to that case.
|
|
213
|
+
*/
|
|
214
|
+
export declare function compareHandover(handed: Record<string, string> | undefined, reported: readonly string[] | undefined, pointers?: RedirectionEvidence): CredentialHandoverRecord;
|
|
66
215
|
/**
|
|
67
216
|
* Launch outcomes. The distinction between a payload that never started
|
|
68
217
|
* and one that did is load-bearing: only the first authorizes rollback.
|
|
@@ -70,12 +219,53 @@ export interface ExecutorRequest {
|
|
|
70
219
|
export type LaunchOutcome = {
|
|
71
220
|
kind: "completed";
|
|
72
221
|
exitCode: number;
|
|
222
|
+
/**
|
|
223
|
+
* THE NAMES THE ADAPTER REPORTS IT ACTUALLY LAUNCHED WITH (M4-P8
|
|
224
|
+
* criterion 6). Optional, and the optionality is honest rather than
|
|
225
|
+
* lenient: an adapter written before this phase reports nothing, and
|
|
226
|
+
* a kernel that refused every silent adapter would be refusing on an
|
|
227
|
+
* absence of evidence. What the kernel DOES refuse is a reported set
|
|
228
|
+
* that DIFFERS from the one it handed over, which is the adapter
|
|
229
|
+
* saying, in its own record, that it widened the environment.
|
|
230
|
+
*
|
|
231
|
+
* It is NOT on `ExecutorRecord`: that document has a shipped schema
|
|
232
|
+
* with `additionalProperties: false`, and this value is a report to
|
|
233
|
+
* the kernel rather than a durable launch fact for an operator.
|
|
234
|
+
*
|
|
235
|
+
* A DISHONEST ADAPTER IS NOT CAUGHT HERE, and nothing in this field
|
|
236
|
+
* pretends otherwise: an adapter that widens `env` and reports the
|
|
237
|
+
* kernel's set is caught by the child-written probe instead, which
|
|
238
|
+
* is why criterion 5 asserts on a file the CHILD wrote.
|
|
239
|
+
*/
|
|
240
|
+
launchedEnvNames?: readonly string[];
|
|
241
|
+
/**
|
|
242
|
+
* THE FIVE CREDENTIAL-STORE POINTERS AS THE ADAPTER LAUNCHED THEM
|
|
243
|
+
* (CR-B-001). Optional for the same honest reason `launchedEnvNames`
|
|
244
|
+
* is, and WEAKER than the kernel's own evidence: it is the adapter's
|
|
245
|
+
* word about its own behaviour. The kernel prefers the turn-end record
|
|
246
|
+
* the generated hook normally writes and falls back to this, and the
|
|
247
|
+
* record says which ARTIFACT it read (`redirectionSource`). That is a
|
|
248
|
+
* weaker claim than which PARTY observed the values, and it used to be
|
|
249
|
+
* spelled as the stronger one; see CredentialHandoverRecord in
|
|
250
|
+
* src/task.ts for the measurement that changed the word.
|
|
251
|
+
*/
|
|
252
|
+
launchedRedirections?: Readonly<Record<string, string | null>>;
|
|
73
253
|
} | {
|
|
74
254
|
kind: "launch-failed";
|
|
75
255
|
reason: string;
|
|
76
256
|
} | {
|
|
77
257
|
kind: "incomplete";
|
|
78
258
|
reason: string;
|
|
259
|
+
/**
|
|
260
|
+
* WHAT AN ADAPTER THAT COULD NOT CONFIRM COMPLETION STILL LAUNCHED
|
|
261
|
+
* WITH (CR-B-003). The payload RAN on this arm, so the handover is a
|
|
262
|
+
* real question here and the kernel now asks it; before this round the
|
|
263
|
+
* comparison sat after the `incomplete` return and `meta.json` carried
|
|
264
|
+
* no `handover` key at all, so a widening on this arm was recorded
|
|
265
|
+
* nowhere. Optional for the same reason as on the `completed` arm.
|
|
266
|
+
*/
|
|
267
|
+
launchedEnvNames?: readonly string[];
|
|
268
|
+
launchedRedirections?: Readonly<Record<string, string | null>>;
|
|
79
269
|
};
|
|
80
270
|
/**
|
|
81
271
|
* The ExecutorAdapter interface (DR-0007, M1-P4 grounding). The ENTIRE
|
|
@@ -90,7 +280,40 @@ export type LaunchOutcome = {
|
|
|
90
280
|
*/
|
|
91
281
|
export interface ExecutorAdapter {
|
|
92
282
|
readonly name: string;
|
|
93
|
-
|
|
283
|
+
/**
|
|
284
|
+
* WHAT THIS ADAPTER CANNOT LAUNCH WITHOUT (M4-P3 criteria 2 and 3).
|
|
285
|
+
*
|
|
286
|
+
* Every name is a field of `ExecutorRequest`. The kernel cannot know what
|
|
287
|
+
* a given adapter needs, so the adapter DECLARES it and the kernel refuses
|
|
288
|
+
* BEFORE it creates anything, rather than handing over an `undefined` that
|
|
289
|
+
* the adapter discovers once a worktree, a branch and a pool record exist.
|
|
290
|
+
*
|
|
291
|
+
* REQUIRED, never optional: an optional declaration would let an adapter
|
|
292
|
+
* omit it and get the old behaviour back silently, which is the thing this
|
|
293
|
+
* field exists to stop. An adapter that needs nothing declares `[]`, and
|
|
294
|
+
* that is a statement rather than a default.
|
|
295
|
+
*/
|
|
296
|
+
readonly requires: readonly string[];
|
|
297
|
+
/**
|
|
298
|
+
* ASYNCHRONOUS since M4-P2. An agent turn is long and a subprocess is
|
|
299
|
+
* short: a window adapter or a cloud-session adapter cannot express
|
|
300
|
+
* "the turn ended" in a synchronous return, so the signature that only
|
|
301
|
+
* ever fitted the local subprocess case is the one that changes.
|
|
302
|
+
*
|
|
303
|
+
* This is NOT permission to background (constraint C-3). The kernel
|
|
304
|
+
* AWAITS this promise inside `spawnTask`, so the command still ends
|
|
305
|
+
* after the payload does; awaiting a call is not outliving it, and
|
|
306
|
+
* delivery/plan/kernel-plan-v1.md:311 already puts process ownership in
|
|
307
|
+
* the harness rather than the kernel.
|
|
308
|
+
*
|
|
309
|
+
* The three-armed outcome is unchanged and is still the whole contract:
|
|
310
|
+
* only `launch-failed` authorises rollback, because only `launch-failed`
|
|
311
|
+
* asserts that the payload never started. An adapter that cannot tell
|
|
312
|
+
* returns `incomplete` and the kernel touches nothing. What DID change
|
|
313
|
+
* is that `completed` is no longer taken on the adapter's word: see the
|
|
314
|
+
* completion precondition in `spawnTask`.
|
|
315
|
+
*/
|
|
316
|
+
launch(request: ExecutorRequest): Promise<LaunchOutcome>;
|
|
94
317
|
}
|
|
95
318
|
/** The launch record (JSON per DR-0006, shape per PR-207). */
|
|
96
319
|
export interface ExecutorRecord {
|
|
@@ -106,6 +329,25 @@ export interface ExecutorRecord {
|
|
|
106
329
|
* choice, recorded rather than assumed.
|
|
107
330
|
*/
|
|
108
331
|
deadline?: string;
|
|
332
|
+
/**
|
|
333
|
+
* WHAT WAS REQUESTED, NOT WHAT WAS RESOLVED (M4-P3 criterion 6).
|
|
334
|
+
*
|
|
335
|
+
* The declared tier the request carried, copied verbatim. Optional in the
|
|
336
|
+
* same sense `deadline` is: present exactly when the request carried one,
|
|
337
|
+
* absent otherwise, never the string "undefined".
|
|
338
|
+
*
|
|
339
|
+
* THERE IS NO RESOLVED MODEL HERE, and the absence is a decision rather
|
|
340
|
+
* than an omission. This record is written BEFORE the payload starts,
|
|
341
|
+
* which is the whole basis of the launch-failed-versus-incomplete
|
|
342
|
+
* distinction, while a harness that requests one model and is served
|
|
343
|
+
* another resolves mid-turn. A resolved model in a launch record would
|
|
344
|
+
* therefore be a value nobody could have observed at the moment it was
|
|
345
|
+
* written. M4-P7 carries the resolved half, at turn end, where it can be
|
|
346
|
+
* true.
|
|
347
|
+
*/
|
|
348
|
+
requestedTier?: string;
|
|
349
|
+
/** The role the request carried, copied verbatim. See `requestedTier`. */
|
|
350
|
+
requestedRole?: string;
|
|
109
351
|
}
|
|
110
352
|
/**
|
|
111
353
|
* The local subprocess adapter, the one M1 ships (and the one the exit
|
|
@@ -115,6 +357,13 @@ export interface ExecutorRecord {
|
|
|
115
357
|
* auto-backgrounds anything (plan constraint C-3, FM-054), so there is
|
|
116
358
|
* no daemonize path here to forget to guard.
|
|
117
359
|
*
|
|
360
|
+
* `async` since M4-P2, and its BODY IS UNCHANGED: every statement below
|
|
361
|
+
* is still synchronous, `spawnSync` is still what runs both children, and
|
|
362
|
+
* the promise this now returns is already settled by the time the first
|
|
363
|
+
* `await` on it runs. The keyword is there because the INTERFACE is async
|
|
364
|
+
* for the adapters that need it, not because this adapter gained a
|
|
365
|
+
* concurrency path to get wrong.
|
|
366
|
+
*
|
|
118
367
|
* It runs without a shell on purpose. Under a shell a missing payload
|
|
119
368
|
* binary arrives as an ordinary exit code 127, indistinguishable from a
|
|
120
369
|
* payload that ran and failed, and spawn's rollback rule turns on
|
|
@@ -150,7 +399,63 @@ export interface SpawnOptions {
|
|
|
150
399
|
* payload; default is false and the scrub is on.
|
|
151
400
|
*/
|
|
152
401
|
allowPrCredentials?: boolean;
|
|
402
|
+
/**
|
|
403
|
+
* WHOSE AUTHORITY THIS PAYLOAD RUNS UNDER (M4-P8 step 2). REQUIRED, and
|
|
404
|
+
* there is NO DEFAULT anywhere on this path, in the type or at runtime.
|
|
405
|
+
*
|
|
406
|
+
* A default would be the whole defect: `allowPrCredentials` is reachable
|
|
407
|
+
* from the library seam, which is where the plugin sits, and the pairing
|
|
408
|
+
* this field exists to refuse is the escape hatch on a project payload.
|
|
409
|
+
* If omission meant "orchestrator", a caller would acquire the
|
|
410
|
+
* orchestrator's authority by leaving a field out, which is the quietest
|
|
411
|
+
* way there is to reach a credential. `spawnTask` therefore refuses an
|
|
412
|
+
* absent or unrecognised value before it creates or loads anything,
|
|
413
|
+
* rather than trusting the type: TypeScript is a compile-time promise and
|
|
414
|
+
* the consumer that matters here is a JavaScript plugin.
|
|
415
|
+
*/
|
|
416
|
+
payloadClass: PayloadClass;
|
|
417
|
+
/**
|
|
418
|
+
* PER-INVOCATION ALLOWLIST EXTENSIONS, EACH WITH THE REASON IT WAS
|
|
419
|
+
* GRANTED (M4-P8 step 3). Absent means none, which is the measured
|
|
420
|
+
* minimum for model authentication in the probed container
|
|
421
|
+
* (delivery/verification/m4-prototype-probes.md:33).
|
|
422
|
+
*
|
|
423
|
+
* The reason is DATA and a blank one is refused, so a widening cannot be
|
|
424
|
+
* granted without leaving behind something a later reader can check; the
|
|
425
|
+
* granted set is copied into meta.json verbatim. The kernel refuses any
|
|
426
|
+
* entry naming a variable in the walked gh-token or dangerous vocabulary,
|
|
427
|
+
* so this field cannot be used to re-admit a credential.
|
|
428
|
+
*/
|
|
429
|
+
extraAllowlist?: readonly ChildEnvExtension[];
|
|
430
|
+
/**
|
|
431
|
+
* The three caller-supplied request fields (M4-P3 criterion 1, M4-D-05).
|
|
432
|
+
* Each is `string | undefined` because nothing in the kernel produces one;
|
|
433
|
+
* `briefPath` is not here because `assembleBrief` does produce it.
|
|
434
|
+
*/
|
|
435
|
+
role: string | undefined;
|
|
436
|
+
declaredTier: string | undefined;
|
|
437
|
+
phaseId: string | undefined;
|
|
438
|
+
/**
|
|
439
|
+
* AN ADAPTER OBJECT SUPPLIED DIRECTLY, which only the kernel's own tests
|
|
440
|
+
* do. It outranks `adapterSpecifier` because it is not a request to
|
|
441
|
+
* resolve anything: there is nothing to root, nothing to load, and no
|
|
442
|
+
* trust boundary to cross.
|
|
443
|
+
*/
|
|
153
444
|
adapter?: ExecutorAdapter;
|
|
445
|
+
/**
|
|
446
|
+
* THE `--adapter` SPECIFIER, verbatim as the operator typed it (M4-P4
|
|
447
|
+
* criterion 1). `undefined` means the flag was absent, which is NOT the
|
|
448
|
+
* same as an empty one: an absent flag falls through to the fleet home's
|
|
449
|
+
* declared default and then to the built-in adapter, and each of those
|
|
450
|
+
* three outcomes is named in the launch record rather than being silent
|
|
451
|
+
* (criterion 6).
|
|
452
|
+
*
|
|
453
|
+
* The specifier is not resolved here. It is handed to `selectAdapter`,
|
|
454
|
+
* which roots Node module resolution at the FLEET HOME and never at the
|
|
455
|
+
* project clone; see src/adapters/load.ts for why that root is the whole
|
|
456
|
+
* security property of this phase.
|
|
457
|
+
*/
|
|
458
|
+
adapterSpecifier?: string;
|
|
154
459
|
}
|
|
155
460
|
export interface SpawnSuccess {
|
|
156
461
|
meta: TaskMeta;
|