@sentropic/h2a-runtime 0.97.11 → 0.98.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/dist/cli-help-groups.js +1 -1
- package/dist/cli-help-groups.js.map +1 -1
- package/dist/file-lock.d.ts +12 -0
- package/dist/file-lock.d.ts.map +1 -1
- package/dist/file-lock.js +37 -17
- package/dist/file-lock.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +79 -7
- package/dist/index.js.map +1 -1
- package/dist/launch-guard.d.ts +31 -0
- package/dist/launch-guard.d.ts.map +1 -0
- package/dist/launch-guard.js +135 -0
- package/dist/launch-guard.js.map +1 -0
- package/dist/native-host.d.ts +11 -4
- package/dist/native-host.d.ts.map +1 -1
- package/dist/native-host.js +19 -6
- package/dist/native-host.js.map +1 -1
- package/dist/native-terminal/client.d.ts.map +1 -1
- package/dist/native-terminal/client.js +7 -0
- package/dist/native-terminal/client.js.map +1 -1
- package/dist/native-terminal/host.d.ts +258 -17
- package/dist/native-terminal/host.d.ts.map +1 -1
- package/dist/native-terminal/host.js +814 -68
- package/dist/native-terminal/host.js.map +1 -1
- package/dist/native-terminal/op.d.ts.map +1 -1
- package/dist/native-terminal/op.js +8 -2
- package/dist/native-terminal/op.js.map +1 -1
- package/dist/native-terminal/process.d.ts.map +1 -1
- package/dist/native-terminal/process.js +1 -0
- package/dist/native-terminal/process.js.map +1 -1
- package/dist/native-terminal/protocol.d.ts +1 -0
- package/dist/native-terminal/protocol.d.ts.map +1 -1
- package/dist/native-terminal/protocol.js.map +1 -1
- package/dist/native-terminal/screen.d.ts +3 -0
- package/dist/native-terminal/screen.d.ts.map +1 -0
- package/dist/native-terminal/screen.js +18 -0
- package/dist/native-terminal/screen.js.map +1 -0
- package/dist/native-terminal/server.d.ts.map +1 -1
- package/dist/native-terminal/server.js +5 -0
- package/dist/native-terminal/server.js.map +1 -1
- package/dist/native-terminal/supervisor.d.ts +34 -2
- package/dist/native-terminal/supervisor.d.ts.map +1 -1
- package/dist/native-terminal/supervisor.js +420 -42
- package/dist/native-terminal/supervisor.js.map +1 -1
- package/dist/proc-identity.d.ts +67 -0
- package/dist/proc-identity.d.ts.map +1 -0
- package/dist/proc-identity.js +106 -0
- package/dist/proc-identity.js.map +1 -0
- package/dist/prompt-delivery.d.ts +11 -1
- package/dist/prompt-delivery.d.ts.map +1 -1
- package/dist/prompt-delivery.js +62 -6
- package/dist/prompt-delivery.js.map +1 -1
- package/dist/registry.d.ts +111 -4
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +86 -11
- package/dist/registry.js.map +1 -1
- package/package.json +4 -3
|
@@ -84,6 +84,44 @@ export declare const H2A_SESSION_TOKEN_ENV_VAR = "H2A_SESSION_TOKEN";
|
|
|
84
84
|
* above it covers the common case.
|
|
85
85
|
*/
|
|
86
86
|
export declare function groupCarriesSessionToken(pgid: number, expectedToken: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* True iff two CONSECUTIVE censuses of `pgid` both positively show the SAME,
|
|
89
|
+
* non-empty set of members and every one of them is a ZOMBIE down to its last
|
|
90
|
+
* thread — a group that is DEAD for containment: a zombie is an exit status
|
|
91
|
+
* waiting to be collected by its parent, it executes nothing, and no terminal
|
|
92
|
+
* work can ever resume in it.
|
|
93
|
+
*
|
|
94
|
+
* Why this needs its own probe: `kill(-pgid, 0)` answers ALIVE for such a
|
|
95
|
+
* group (a zombie is still attached to its pgid), and a zombie's
|
|
96
|
+
* `/proc/<pid>/environ` is empty, so it can carry no session token either.
|
|
97
|
+
* Without this re-check, the leader-absent branch of
|
|
98
|
+
* `#verifyGroupLeaderIdentity` classifies the group as
|
|
99
|
+
* `membership-unprovable` — an unidentifiable SURVIVOR — and a socket is then
|
|
100
|
+
* contained on account of processes that are already dead. Emitting
|
|
101
|
+
* `kill(-pgid, SIGKILL)` there would not help either: a zombie cannot be
|
|
102
|
+
* killed again, so the confirmation poll would run to its timeout.
|
|
103
|
+
*
|
|
104
|
+
* What this DOES fail closed on (answer `false`, i.e. "not proven dead"):
|
|
105
|
+
* non-Linux; a proc mount that hides processes or whose mount table could not
|
|
106
|
+
* be read; any member `stat` unreadable for a reason other than "it exited";
|
|
107
|
+
* any zombie member whose thread list could not be fully read; a group with no
|
|
108
|
+
* member at all (which contradicts the liveness probe that led here and is
|
|
109
|
+
* therefore not evidence of anything); and two censuses that disagree.
|
|
110
|
+
*
|
|
111
|
+
* DECLARED LIMIT, not closed by this: a census is not atomic. A live member can
|
|
112
|
+
* fork a child that inherits the pgid and exit before its own `stat` is read;
|
|
113
|
+
* the second census is what makes that shape answer `false` (the child is
|
|
114
|
+
* listed, or the member set changed), which NARROWS the race rather than
|
|
115
|
+
* eliminating it. The residual requires a member to fork and exit inside both
|
|
116
|
+
* censuses while leaving an identical, all-zombie pid set behind — and the
|
|
117
|
+
* consequence of the residual is bounded by what a caller does with a `true`:
|
|
118
|
+
* nothing is ever signalled on this path.
|
|
119
|
+
*
|
|
120
|
+
* `procRoot` is injected ONLY by tests (a `/proc`-shaped fixture tree, and a
|
|
121
|
+
* function form so a test can make the two censuses see different trees);
|
|
122
|
+
* production always reads the real `/proc`.
|
|
123
|
+
*/
|
|
124
|
+
export declare function groupIsOnlyZombies(pgid: number, procRoot?: string | (() => string)): boolean;
|
|
87
125
|
/** Liveness verdict for a native-terminal PTY session's OWNING HOST. */
|
|
88
126
|
export type NativeTerminalOwnerHostStatus = "alive" | "dead" | "unresolvable";
|
|
89
127
|
/**
|
|
@@ -120,6 +158,10 @@ export type NativeTerminalOwnerHostProbe = (owner: NativeTerminalPgidOwner) => N
|
|
|
120
158
|
* status quo, not a regression.
|
|
121
159
|
*/
|
|
122
160
|
export declare const defaultOwnerHostProbe: NativeTerminalOwnerHostProbe;
|
|
161
|
+
/** How long a group kill waits for the OS to report the group empty before
|
|
162
|
+
* reporting it timed out. Exported so a caller that budgets a wait around a
|
|
163
|
+
* reap (the functional suite) derives it from this value instead of copying it. */
|
|
164
|
+
export declare const NATIVE_TERMINAL_FORCE_KILL_TIMEOUT_MS = 30000;
|
|
123
165
|
export type NativeTerminalExit = Readonly<{
|
|
124
166
|
exitCode: number;
|
|
125
167
|
signal?: number;
|
|
@@ -180,6 +222,11 @@ export type NativeTerminalControllerState = Readonly<{
|
|
|
180
222
|
controllerEpoch: number;
|
|
181
223
|
}>;
|
|
182
224
|
export type NativeTerminalCreateOptions = Readonly<{
|
|
225
|
+
/** Preallocated launch ownership, fenced to this host before PTY creation. */
|
|
226
|
+
launchFence?: Readonly<{
|
|
227
|
+
generation: string;
|
|
228
|
+
incarnation: string;
|
|
229
|
+
}>;
|
|
183
230
|
id: string;
|
|
184
231
|
command: string;
|
|
185
232
|
args: ReadonlyArray<string>;
|
|
@@ -213,11 +260,38 @@ export type NativeTerminalCreateOptions = Readonly<{
|
|
|
213
260
|
* identity check ran at all (e.g. `forceStopAll`, or the group was already
|
|
214
261
|
* confirmed empty before any check).
|
|
215
262
|
*/
|
|
263
|
+
export type NativeTerminalReapRefusalCause = "pgid-mismatch" | "unsupported-process-groups" | "recycled"
|
|
264
|
+
/**
|
|
265
|
+
* The row records a boot id different from this reader's, in this reader's
|
|
266
|
+
* OWN pid namespace ON THIS SAME MACHINE: every process it describes ended
|
|
267
|
+
* when that boot did. A refusal like `recycled` — nothing was signalled —
|
|
268
|
+
* but a POSITIVE proof that the original group is gone, never evidence of a
|
|
269
|
+
* survivor.
|
|
270
|
+
*/
|
|
271
|
+
| "stale-boot"
|
|
272
|
+
/**
|
|
273
|
+
* The row was written in a frame this reader cannot prove is its own:
|
|
274
|
+
* another or an unknown pid namespace, or another boot of a machine not
|
|
275
|
+
* proven to be this one (see proc-identity.ts). Every pid and start-time on
|
|
276
|
+
* it names something else here, so nothing about its group can be decided
|
|
277
|
+
* from this reader — not that it survived, not that it is gone. Nothing was
|
|
278
|
+
* signalled. Kept apart from `membership-unprovable` because a local
|
|
279
|
+
* inspection of the pgid proves nothing either: it describes this reader's
|
|
280
|
+
* process space, not the one that wrote the row.
|
|
281
|
+
*/
|
|
282
|
+
| "foreign-frame" | "membership-unprovable";
|
|
283
|
+
/** The frame a durable row's pids and start-times are valid in (see
|
|
284
|
+
* proc-identity.ts), recorded by the writer and re-read by the reader. */
|
|
285
|
+
export type NativeTerminalProcFrame = Readonly<{
|
|
286
|
+
pidNamespace?: string;
|
|
287
|
+
bootId?: string;
|
|
288
|
+
machineId?: string;
|
|
289
|
+
}>;
|
|
216
290
|
export type NativeTerminalReapOutcome = Readonly<{
|
|
217
291
|
sessionId: string;
|
|
218
292
|
status: "refused";
|
|
219
293
|
reason: string;
|
|
220
|
-
cause?:
|
|
294
|
+
cause?: NativeTerminalReapRefusalCause;
|
|
221
295
|
} | {
|
|
222
296
|
sessionId: string;
|
|
223
297
|
status: "reaped";
|
|
@@ -239,6 +313,13 @@ export declare class NativeTerminalHost {
|
|
|
239
313
|
spawner: PtySpawner;
|
|
240
314
|
/** Durable store for pgid persistence; defaults to the real registry path. */
|
|
241
315
|
registryPath?: string;
|
|
316
|
+
/**
|
|
317
|
+
* The socket this host serves, recorded on every durable row it writes
|
|
318
|
+
* (see `RegistryEntry.ownerHostSocketPath`). Optional: a host constructed
|
|
319
|
+
* without it (the reconcile-only throwaway below, and unit tests that
|
|
320
|
+
* never publish a socket) simply writes rows with no socket attribution.
|
|
321
|
+
*/
|
|
322
|
+
socketPath?: string;
|
|
242
323
|
/** Injectable so tests never send real signals at fabricated pgids. */
|
|
243
324
|
reaper?: NativeTerminalProcessGroupReaper;
|
|
244
325
|
/** Diagnostic sink for the force-kill chain; defaults to prefixed stderr. */
|
|
@@ -254,10 +335,21 @@ export declare class NativeTerminalHost {
|
|
|
254
335
|
* defaults to the real `groupCarriesSessionToken`. Consulted ONLY when
|
|
255
336
|
* the leader is absent — see `#verifyGroupLeaderIdentity`. */
|
|
256
337
|
findGroupMemberToken?: (pgid: number, expectedToken: string) => boolean;
|
|
338
|
+
/** Injectable so tests never touch a real /proc for fabricated pgids;
|
|
339
|
+
* defaults to the real `groupIsOnlyZombies`. Consulted ONLY when the
|
|
340
|
+
* leader is absent AND no member carries the token, as the last re-check
|
|
341
|
+
* before refusing — see `#verifyGroupLeaderIdentity`. */
|
|
342
|
+
groupIsOnlyZombies?: (pgid: number) => boolean;
|
|
343
|
+
/** Injectable so tests can stand in for another machine, boot or pid
|
|
344
|
+
* namespace without root; defaults to the real proc-identity readers.
|
|
345
|
+
* The READER's frame, compared with the one a durable row records before
|
|
346
|
+
* any pid-based proof is derived from that row — see
|
|
347
|
+
* `#verifyGroupLeaderIdentity`. */
|
|
348
|
+
readFrame?: () => NativeTerminalProcFrame;
|
|
257
349
|
});
|
|
258
350
|
get generation(): string;
|
|
259
351
|
/**
|
|
260
|
-
* COUNTABLE per arch condition 1/2: the
|
|
352
|
+
* COUNTABLE per arch condition 1/2: the five DISCERNIBLE outcomes of the
|
|
261
353
|
* group-leader-identity guard, so "has this guard ever refused (and why),
|
|
262
354
|
* or ever proceeded WITHOUT the fast leader-start-time proof" is
|
|
263
355
|
* answerable later without re-deriving it from raw logs.
|
|
@@ -268,16 +360,30 @@ export declare class NativeTerminalHost {
|
|
|
268
360
|
* counted at all (it is the expected common case). `unverifiedLegacy` is
|
|
269
361
|
* an UNPROVEN proceed (the kill WAS emitted) on a row with no baseline —
|
|
270
362
|
* neither a leader-start-time nor a group-token — to check against at
|
|
271
|
-
* all, the fail-open branch of `#verifyGroupLeaderIdentity`.
|
|
272
|
-
*
|
|
273
|
-
*
|
|
363
|
+
* all, the fail-open branch of `#verifyGroupLeaderIdentity`.
|
|
364
|
+
* `zombieGroup` is neither a refusal nor a kill: the group was found
|
|
365
|
+
* reduced to zombies, i.e. already dead, so NOTHING was emitted and the
|
|
366
|
+
* reap is reported confirmed. `groupDrained` is its sibling: the group was
|
|
367
|
+
* still there when the checks began and the OS positively reported it EMPTY
|
|
368
|
+
* when they ended. `staleBoot` is a refusal that PROVES the group gone (the
|
|
369
|
+
* row predates this boot), counted apart from `recycled` because the two
|
|
370
|
+
* rest on different facts. `foreignFrame` is a refusal that proves NOTHING
|
|
371
|
+
* because the row was written in a frame this reader cannot prove is its
|
|
372
|
+
* own, counted apart from `membershipUnprovable`, which judged a group in
|
|
373
|
+
* this reader's own process space. Never collapsed: a proven kill, an
|
|
374
|
+
* unproven one, a refusal that proves death, a refusal that proves nothing,
|
|
375
|
+
* and an already-dead group must never look alike here — see
|
|
274
376
|
* `NativeTerminalReapOutcome`'s `cause`/`verified`.
|
|
275
377
|
*/
|
|
276
378
|
get pgidGuardCounters(): Readonly<{
|
|
277
379
|
recycled: number;
|
|
380
|
+
staleBoot: number;
|
|
381
|
+
foreignFrame: number;
|
|
278
382
|
membershipUnprovable: number;
|
|
279
383
|
unverifiedLegacy: number;
|
|
280
384
|
tokenVerified: number;
|
|
385
|
+
zombieGroup: number;
|
|
386
|
+
groupDrained: number;
|
|
281
387
|
}>;
|
|
282
388
|
create(options: NativeTerminalCreateOptions): NativeTerminalSessionState;
|
|
283
389
|
list(): ReadonlyArray<NativeTerminalSessionState>;
|
|
@@ -326,26 +432,149 @@ export declare class NativeTerminalHost {
|
|
|
326
432
|
* this signals NOTHING and returns `"refused"` after logging a LOUD
|
|
327
433
|
* diagnostic — a silent no-op here would recreate the exact
|
|
328
434
|
* invisible-orphan bug this mechanism exists to close.
|
|
435
|
+
*
|
|
436
|
+
* `expectedPgid` and `expected.groupToken` are the caller's IMMUTABLE
|
|
437
|
+
* snapshot of the row, and BOTH are re-compared against the row as it reads
|
|
438
|
+
* NOW — the same compare-and-delete identity `pruneNativeTerminalPgidEntry`
|
|
439
|
+
* uses, applied to the kill side. Comparing the pgid NUMBER alone is not
|
|
440
|
+
* enough: session ids are caller-chosen, so a live host can recreate the
|
|
441
|
+
* same id within one reconcile pass, and its new PTY leader can be handed
|
|
442
|
+
* back the pid number the snapshotted group just freed. The re-read then
|
|
443
|
+
* matches, every identity check below verifies against the NEW row's own
|
|
444
|
+
* baselines, and a LIVE group is killed. The token is a per-session
|
|
445
|
+
* `randomUUID`, so a successor never matches it. A caller that omits the
|
|
446
|
+
* token (a legacy row carries none) does not constrain it.
|
|
329
447
|
*/
|
|
330
|
-
reapOrphan(sessionId: string, signal?: NativeTerminalStopSignal, expectedPgid?: number
|
|
448
|
+
reapOrphan(sessionId: string, signal?: NativeTerminalStopSignal, expectedPgid?: number, expected?: {
|
|
449
|
+
groupToken?: string;
|
|
450
|
+
}): Promise<NativeTerminalReapOutcome>;
|
|
331
451
|
}
|
|
332
|
-
/**
|
|
452
|
+
/**
|
|
453
|
+
* Per-entry outcome of a `reconcileDeadHostOrphans` pass.
|
|
454
|
+
*
|
|
455
|
+
* `ownerSocketPath`, carried on the three PROVEN-DEAD outcomes, is the durable
|
|
456
|
+
* socket attribution of the row (see `RegistryEntry.ownerHostSocketPath`). It
|
|
457
|
+
* exists so a caller can answer "is this unconfirmed orphan MY socket's
|
|
458
|
+
* containment problem" without guessing; it is absent on a legacy row that was
|
|
459
|
+
* written before the attribution existed.
|
|
460
|
+
*
|
|
461
|
+
* `cause` forwards `reapOrphan`'s own refusal cause, and its ABSENCE is
|
|
462
|
+
* meaningful. A cause-less refusal means only that the pgid could not be
|
|
463
|
+
* resolved — the row was pruned by a concurrent reconcile that DID confirm the
|
|
464
|
+
* reap, or the registry turned unreadable between the snapshot and the lookup.
|
|
465
|
+
* That is an absence of information, not a surviving group, and a caller must
|
|
466
|
+
* not treat the two alike.
|
|
467
|
+
*
|
|
468
|
+
* The causes that DO reach a caller are the two taken with the group observed
|
|
469
|
+
* ALIVE and its identity unprovable — `membership-unprovable` and
|
|
470
|
+
* `unsupported-process-groups` — `foreign-frame`, taken when the pgid number
|
|
471
|
+
* answers ALIVE here but the row was written in a frame (pid namespace, boot,
|
|
472
|
+
* machine) this reader cannot prove is its own, so nothing about the row's
|
|
473
|
+
* own group is decidable — plus `pgid-mismatch`, which is taken BEFORE
|
|
474
|
+
* any liveness probe and only after this pass has re-read the row once (see
|
|
475
|
+
* the revalidation in `reconcileDeadHostOrphans`): it survives that re-read
|
|
476
|
+
* only while the row keeps being rewritten under a proven-dead owner.
|
|
477
|
+
* `recycled` and `stale-boot` never reach a caller as refusals at all — each is
|
|
478
|
+
* positive proof that the original group is GONE, reported as
|
|
479
|
+
* `"pruned-recycled-pgid"` and `"pruned-stale-boot-row"`, never as survivors.
|
|
480
|
+
*/
|
|
333
481
|
export type NativeTerminalReconcileOutcome = Readonly<{
|
|
334
482
|
sessionId: string;
|
|
335
483
|
status: "reaped";
|
|
336
484
|
ownerPid: number;
|
|
485
|
+
ownerSocketPath?: string;
|
|
337
486
|
pgid: number;
|
|
338
487
|
} | {
|
|
339
488
|
sessionId: string;
|
|
340
489
|
status: "reap-timed-out";
|
|
341
490
|
ownerPid: number;
|
|
491
|
+
ownerSocketPath?: string;
|
|
342
492
|
pgid: number;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* This entry's evaluation FAILED — the owner probe threw, the reap threw, or
|
|
496
|
+
* the durable store could not be re-read — so nothing was signalled and
|
|
497
|
+
* NOTHING was proven about the group: neither that it survived nor that it is
|
|
498
|
+
* gone. Reported per entry (the rest of the pass continues) and WITH the
|
|
499
|
+
* row's attribution, because a caller whose socket owns this row must fail
|
|
500
|
+
* closed on it: an absence of proof over a row whose owner is not known to be
|
|
501
|
+
* alive is exactly the state in which starting a host would resume terminal
|
|
502
|
+
* work over a group that may still be alive. The row is kept for a later
|
|
503
|
+
* pass, which may then confirm it.
|
|
504
|
+
*
|
|
505
|
+
* `ownerDeathUnproven` marks the subset where the failure happened BEFORE the
|
|
506
|
+
* owner's liveness was established (the owner probe itself threw). The
|
|
507
|
+
* containment is identical — nothing is known about the group either way —
|
|
508
|
+
* but no diagnostic may then call the owner a proven-dead host, because
|
|
509
|
+
* nobody proved that. Absent means the owner WAS proven dead first.
|
|
510
|
+
*/
|
|
511
|
+
| {
|
|
512
|
+
sessionId: string;
|
|
513
|
+
status: "reap-failed";
|
|
514
|
+
ownerPid: number;
|
|
515
|
+
ownerSocketPath?: string;
|
|
516
|
+
pgid: number;
|
|
517
|
+
reason: string;
|
|
518
|
+
ownerDeathUnproven?: true;
|
|
343
519
|
} | {
|
|
344
520
|
sessionId: string;
|
|
345
521
|
status: "reap-refused";
|
|
346
522
|
ownerPid: number;
|
|
523
|
+
ownerSocketPath?: string;
|
|
524
|
+
pgid: number;
|
|
525
|
+
reason: string;
|
|
526
|
+
cause?: NativeTerminalReapRefusalCause;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* The reap refused with cause `recycled`: the pgid NUMBER this row carries
|
|
530
|
+
* is now held by an unrelated live group leader of a different start-time.
|
|
531
|
+
* A pid number stays allocated while ANY task still references it as pid,
|
|
532
|
+
* tgid, PGID or sid, and a process group id is not reused before that
|
|
533
|
+
* group's lifetime ends — so this PROVES every member of the original group
|
|
534
|
+
* is gone. The stale row is pruned and reported here, distinctly from every
|
|
535
|
+
* outcome that carries evidence of a SURVIVING group; nothing was signalled,
|
|
536
|
+
* and the pgid must not be signalled by anyone acting on this outcome.
|
|
537
|
+
*/
|
|
538
|
+
| {
|
|
539
|
+
sessionId: string;
|
|
540
|
+
status: "pruned-recycled-pgid";
|
|
541
|
+
ownerPid: number;
|
|
542
|
+
ownerSocketPath?: string;
|
|
347
543
|
pgid: number;
|
|
348
544
|
reason: string;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* The reap refused with cause `stale-boot`: the row records a boot id
|
|
548
|
+
* different from this reader's, in this reader's OWN pid namespace, and the
|
|
549
|
+
* same machine id as this reader's. A reboot ends every process of the boot
|
|
550
|
+
* before it, so this PROVES every member of the original group is gone — the
|
|
551
|
+
* strongest form of the `recycled` proof, not an absence of one. The stale row is pruned and reported here,
|
|
552
|
+
* distinctly from every outcome that carries evidence of a SURVIVING group.
|
|
553
|
+
* Nothing was signalled, and the pgid NUMBER must not be signalled by anyone
|
|
554
|
+
* acting on this outcome: an unrelated live group may hold it now. The
|
|
555
|
+
* declared exceptions, out of model, are a process checkpointed before the
|
|
556
|
+
* reboot and restored after it (CRIU), and machines that share one registry
|
|
557
|
+
* AND one duplicated machine id — see `#verifyGroupLeaderIdentity`.
|
|
558
|
+
*/
|
|
559
|
+
| {
|
|
560
|
+
sessionId: string;
|
|
561
|
+
status: "pruned-stale-boot-row";
|
|
562
|
+
ownerPid: number;
|
|
563
|
+
ownerSocketPath?: string;
|
|
564
|
+
pgid: number;
|
|
565
|
+
reason: string;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* The row was REWRITTEN between this pass's snapshot and the reap's own
|
|
569
|
+
* lookup, and the re-read row no longer describes a proven-dead owner's
|
|
570
|
+
* orphan (it is gone, has lost its owner attribution, or its owner is now
|
|
571
|
+
* alive under a different pgid). Nothing was signalled and nothing is owed:
|
|
572
|
+
* a verdict about a row that no longer exists is not containment.
|
|
573
|
+
*/
|
|
574
|
+
| {
|
|
575
|
+
sessionId: string;
|
|
576
|
+
status: "skipped-row-changed";
|
|
577
|
+
reason: string;
|
|
349
578
|
} | {
|
|
350
579
|
sessionId: string;
|
|
351
580
|
status: "skipped-alive";
|
|
@@ -392,13 +621,22 @@ export type NativeTerminalReconcileSummary = Readonly<{
|
|
|
392
621
|
* (unresolvable is treated exactly like alive: never guess).
|
|
393
622
|
* - `ownerProbe` reports "dead" (pid gone, or recycled — a live pid whose
|
|
394
623
|
* start-time no longer matches) -> reap that entry's orphan process group
|
|
395
|
-
* via `reap`, then prune the entry once the reap is CONFIRMED (`"reaped"`
|
|
396
|
-
*
|
|
397
|
-
*
|
|
624
|
+
* via `reap`, then prune the entry once the reap is CONFIRMED (`"reaped"`)
|
|
625
|
+
* or once the refusal itself PROVED the original group gone
|
|
626
|
+
* (`cause: "recycled"` -> `"pruned-recycled-pgid"`; `cause: "stale-boot"`
|
|
627
|
+
* -> `"pruned-stale-boot-row"`). A `"reap-timed-out"`, or a refusal that
|
|
628
|
+
* leaves the group's fate unknown, keeps the row for a future pass instead
|
|
629
|
+
* of losing the only durable record of an unconfirmed pgid.
|
|
398
630
|
*
|
|
399
|
-
* Best-effort per entry
|
|
400
|
-
*
|
|
401
|
-
*
|
|
631
|
+
* Best-effort per entry, and this is a SAFETY property, not politeness: every
|
|
632
|
+
* entry's evaluation (owner probe, reap, row re-read, prune) is wrapped, so one
|
|
633
|
+
* entry's failure never stops the pass over the rest. Each entry is an
|
|
634
|
+
* independent host/session, and the socket-scoped containment decision a caller
|
|
635
|
+
* derives from this pass can only be right if the pass actually reached the row
|
|
636
|
+
* that concerns it — an abort half-way through leaves every later row
|
|
637
|
+
* unevaluated while the caller reads one failure as a cleanup hiccup. A failure
|
|
638
|
+
* is reported as `"reap-failed"` for that entry, WITH its attribution, and its
|
|
639
|
+
* row is kept.
|
|
402
640
|
*/
|
|
403
641
|
export declare function reconcileDeadHostOrphans(options?: {
|
|
404
642
|
registryPath?: string;
|
|
@@ -407,10 +645,13 @@ export declare function reconcileDeadHostOrphans(options?: {
|
|
|
407
645
|
ownerProbe?: NativeTerminalOwnerHostProbe;
|
|
408
646
|
/** Injectable so tests never send real signals; defaults to a throwaway
|
|
409
647
|
* `NativeTerminalHost` (never spawns a pty) calling the real `reapOrphan`.
|
|
410
|
-
* The persisted pgid
|
|
411
|
-
* only to verify
|
|
412
|
-
* mismatch.
|
|
413
|
-
|
|
648
|
+
* The persisted pgid AND group token form an immutable snapshot: the real
|
|
649
|
+
* reap re-resolves only to verify the row still says both, and refuses
|
|
650
|
+
* without signalling on any mismatch. `expected` is passed only for a row
|
|
651
|
+
* that carries a token, so a legacy row's call shape is unchanged. */
|
|
652
|
+
reap?: (sessionId: string, pgid: number, signal: NativeTerminalStopSignal, expected?: {
|
|
653
|
+
groupToken?: string;
|
|
654
|
+
}) => Promise<NativeTerminalReapOutcome>;
|
|
414
655
|
log?: (line: string) => void;
|
|
415
656
|
}): Promise<NativeTerminalReconcileSummary>;
|
|
416
657
|
//# sourceMappingURL=host.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/native-terminal/host.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/native-terminal/host.ts"],"names":[],"mappings":"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"}
|