pi-crew 0.11.47 → 0.11.48
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 +19 -0
- package/dist/index.mjs +331 -331
- package/package.json +1 -1
- package/src/config/env-vars.ts +1 -1
- package/src/prompt/surface-worker.ts +1 -1
- package/src/runtime/broker/crew-broker-child.ts +6 -3
- package/src/runtime/broker/crew-broker-delegate-request.ts +5 -5
- package/src/runtime/child-pi/child-pi-spawn.ts +21 -13
package/package.json
CHANGED
package/src/config/env-vars.ts
CHANGED
|
@@ -668,7 +668,7 @@ export const CREW_ENV_VARS: Record<string, CrewEnvVarSpec> = {
|
|
|
668
668
|
},
|
|
669
669
|
PI_CREW_BROKER_STDIN: {
|
|
670
670
|
name: "PI_CREW_BROKER_STDIN",
|
|
671
|
-
doc: "LOW-1 closure (2026-10-27) broker-credential transport gate
|
|
671
|
+
doc: "LOW-1 closure (2026-10-27) broker-credential transport gate, OPT-IN since v0.11.48 (2026-10-28): '1' sends the per-task compound PI_CREW_BROKER_TOKEN to the headless JSON worker over the spawn STDIN pipe (one buildBrokerStdinLine v2 payload; heap → pipe → heap — child-pi-spawn.ts writer, crew-broker-child.ts startChildBrokerClientAsync reader) so the token never appears in the child env; unset/any-other-value (default) keeps the LEGACY ENV ROUTE (token in built.env, stdin stays 'ignore') on BOTH sides — the stdin reader path was caught by the live battery (real-test-pi-crew T7) killing real headless workers with a silent exit 0 and is disabled-by-default until root-caused. RPC-mode workers and surface TUI panes are unaffected (they keep the env route; the worker-side stdin read skips --mode rpc argv and TTY stdin by design)",
|
|
672
672
|
},
|
|
673
673
|
PI_CREW_GUEST: {
|
|
674
674
|
name: "PI_CREW_GUEST",
|
|
@@ -182,7 +182,7 @@ export function parentAlive(pid: number, expectedStartTime: string | undefined,
|
|
|
182
182
|
// workers at the first 5s tick.
|
|
183
183
|
readerThrew = true;
|
|
184
184
|
}
|
|
185
|
-
if (readerThrew) return expectedStartTime
|
|
185
|
+
if (readerThrew) return !expectedStartTime;
|
|
186
186
|
// Reader returned "no entry" (default /proc reader ENOENT = dead on
|
|
187
187
|
// Linux) — dead-parent detection stays intact.
|
|
188
188
|
if (stat === undefined) return false;
|
|
@@ -139,8 +139,11 @@ export async function startChildBrokerClientAsync(options: StartChildBrokerClien
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/** Worker-side mirror of the parent gate (child-pi-spawn
|
|
142
|
-
* .resolveBrokerStdinHandshakeEnabled)
|
|
143
|
-
*
|
|
142
|
+
* .resolveBrokerStdinHandshakeEnabled). **OPT-IN since v0.11.48** (live
|
|
143
|
+
* battery caught the reader path killing real headless workers — see the
|
|
144
|
+
* parent gate's doc block): the default is now OFF, so a new parent that set
|
|
145
|
+
* the env token travels the legacy env route. PI_CREW_BROKER_STDIN=1 opts
|
|
146
|
+
* BOTH sides into the stdin route. */
|
|
144
147
|
function resolveBrokerStdinFallbackEnabled(): boolean {
|
|
145
|
-
return getCrewEnv("PI_CREW_BROKER_STDIN")
|
|
148
|
+
return getCrewEnv("PI_CREW_BROKER_STDIN") === "1";
|
|
146
149
|
}
|
|
@@ -43,14 +43,14 @@ import { loadRunManifestById, saveRunTasks } from "../../state/stores/state-stor
|
|
|
43
43
|
import type { TeamRunManifest, TeamTaskState } from "../../state/types.ts";
|
|
44
44
|
import { type GrandchildSpawnResult, spawnDelegateGrandchild } from "../delegate-spawn.ts";
|
|
45
45
|
import { resolveCrewMaxDepth } from "../model/pi-args.ts";
|
|
46
|
-
import { NestedSlotBudget } from "../scheduling/nested-slots.ts";
|
|
46
|
+
import type { NestedSlotBudget } from "../scheduling/nested-slots.ts";
|
|
47
47
|
import { evaluateDelegateAdmission } from "../spawn-policy.ts";
|
|
48
|
-
import { DelegateAbortRegistry } from "./delegate/delegate-abort.ts";
|
|
49
|
-
import {
|
|
48
|
+
import type { DelegateAbortRegistry } from "./delegate/delegate-abort.ts";
|
|
49
|
+
import type { DelegateEventTarget, DelegateEventType } from "./delegate/delegate-event.ts";
|
|
50
50
|
import { delegateTerminalEvent, finalizeDelegateResult } from "./delegate/delegate-finalize.ts";
|
|
51
51
|
import { promoteShadowToRunning } from "./delegate/shadow-lifecycle.ts";
|
|
52
|
-
import {
|
|
53
|
-
import {
|
|
52
|
+
import type { CrewBrokerOptions, ServerConnection } from "./protocol/connection-state.ts";
|
|
53
|
+
import type { LockBusyOutcome } from "./protocol/lock-busy.ts";
|
|
54
54
|
import { parseDelegateRequestParams } from "./protocol/request-parsers.ts";
|
|
55
55
|
|
|
56
56
|
/** Options slice the delegate handler reads off the broker's RESOLVED
|
|
@@ -46,17 +46,24 @@ import {
|
|
|
46
46
|
// NOT set this (their sessions persist and benefit from long-lived cache).
|
|
47
47
|
export const PI_CACHE_RETENTION_ENV = "PI_CACHE_RETENTION";
|
|
48
48
|
|
|
49
|
-
/** LOW-1 residual closure (2026-10-27
|
|
50
|
-
* are present, the per-task compound TOKEN
|
|
51
|
-
* (one `buildBrokerStdinLine` payload,
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
49
|
+
/** LOW-1 residual closure (2026-10-27, DISABLED-DEFAULT 2026-10-28 v0.11.48):
|
|
50
|
+
* when the inter-pi broker credentials are present, the per-task compound TOKEN
|
|
51
|
+
* can travel over the spawn stdin pipe (one `buildBrokerStdinLine` payload,
|
|
52
|
+
* heap → pipe → heap — same shape as the F4 background-runner handshake)
|
|
53
|
+
* instead of the child env. **EXPERIMENTAL / OPT-IN since v0.11.48**: the
|
|
54
|
+
* worker-side stdin reader path (startChildBrokerClientAsync →
|
|
55
|
+
* readStdinFirstLine) was caught by the live battery (real-test-pi-crew T7)
|
|
56
|
+
* making REAL headless JSON workers exit 0 silently with zero stdout — only
|
|
57
|
+
* when the reader activates (env broker identity + no env token + gate ON).
|
|
58
|
+
* Unit tests missed it because they inject the `readStdinLine` seam instead of
|
|
59
|
+
* running process.stdin in a real pi process. Until that is root-caused, the
|
|
60
|
+
* default is OFF (legacy env route, bit-for-bit pre-0.11.46 behavior); set
|
|
61
|
+
* PI_CREW_BROKER_STDIN=1 to opt the parent into the stdin route. Only the
|
|
62
|
+
* headless JSON spawn branch consumes the payload: the RPC branch (stdin is
|
|
63
|
+
* the JSONL protocol channel) and the surface TUI panes keep the env route,
|
|
64
|
+
* so their env is untouched either way. */
|
|
58
65
|
export function resolveBrokerStdinHandshakeEnabled(): boolean {
|
|
59
|
-
return getCrewEnv("PI_CREW_BROKER_STDIN")
|
|
66
|
+
return getCrewEnv("PI_CREW_BROKER_STDIN") === "1";
|
|
60
67
|
}
|
|
61
68
|
|
|
62
69
|
// ── Env allowlist (base set always passed to children) ──────────────────
|
|
@@ -452,12 +459,13 @@ export function prepareSpawnContext(
|
|
|
452
459
|
// safe under assertOnlyControlEnvKeys). Only when the parent broker issued
|
|
453
460
|
// credentials for this run — i.e. the broker is enabled AND this run is
|
|
454
461
|
// eligible. NEVER persisted to disk.
|
|
455
|
-
// LOW-1 closure
|
|
462
|
+
// LOW-1 closure (OPT-IN since v0.11.48): when PI_CREW_BROKER_STDIN=1 the
|
|
463
|
+
// TOKEN leaves the env entirely — it rides the
|
|
456
464
|
// spawn stdin pipe as a single buildBrokerStdinLine payload (ctx
|
|
457
465
|
// .brokerStdinPayload; the headless JSON branch pipes stdin and writes it
|
|
458
466
|
// right after spawn). SOCKET/RUN_ID/TASK_ID stay in env (non-secret, needed
|
|
459
|
-
// by the worker bootstrap to bind
|
|
460
|
-
// gate
|
|
467
|
+
// by the worker bootstrap to bind and validate the stdin payload). Default
|
|
468
|
+
// (gate off, or a legacy shape without runId/taskId to
|
|
461
469
|
// bind the payload to) keeps the env route bit-for-bit.
|
|
462
470
|
if (input.brokerSpawn?.socketPath && input.brokerSpawn.token) {
|
|
463
471
|
built.env.PI_CREW_BROKER_SOCKET = input.brokerSpawn.socketPath;
|