pi-crew 0.11.49 → 0.11.51

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.
Files changed (64) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/index.mjs +551 -544
  3. package/package.json +1 -1
  4. package/skills/real-test-pi-crew/SKILL.md +2 -0
  5. package/src/agents/agent-config.ts +58 -1
  6. package/src/config/config-validation.ts +18 -0
  7. package/src/config/env-allowlist-registry.ts +5 -1
  8. package/src/config/env-vars.ts +5 -1
  9. package/src/config/sanitize-project-config.ts +55 -0
  10. package/src/extension/management.ts +9 -0
  11. package/src/extension/registration/lifecycle-handlers.ts +28 -0
  12. package/src/extension/registration/subagent-tools.ts +5 -1
  13. package/src/extension/run-import.ts +40 -6
  14. package/src/extension/team-tool/api/agent-control.ts +49 -0
  15. package/src/extension/team-tool/api/heartbeat.ts +48 -1
  16. package/src/extension/team-tool/api/mailbox.ts +81 -2
  17. package/src/extension/team-tool/api/read.ts +22 -0
  18. package/src/extension/team-tool/api/task-claims.ts +134 -3
  19. package/src/extension/team-tool/destructive-gate.ts +92 -8
  20. package/src/extension/team-tool/inspect.ts +8 -2
  21. package/src/extension/team-tool/lifecycle-actions.ts +9 -2
  22. package/src/extension/team-tool.ts +128 -27
  23. package/src/observability/exporters/otlp-exporter.ts +69 -19
  24. package/src/prompt/message-tool.ts +19 -8
  25. package/src/prompt/prompt-runtime.ts +160 -51
  26. package/src/runtime/broker/crew-broker-child.ts +55 -17
  27. package/src/runtime/broker/crew-broker-tokens.ts +24 -13
  28. package/src/runtime/broker/crew-broker.ts +12 -6
  29. package/src/runtime/broker/protocol/wait-resolve.ts +15 -1
  30. package/src/runtime/child-pi/child-pi-spawn.ts +36 -10
  31. package/src/runtime/child-pi/child-pi-steering.ts +8 -1
  32. package/src/runtime/child-pi/child-pi.ts +2 -1
  33. package/src/runtime/child-pi/inference-broker.ts +41 -7
  34. package/src/runtime/child-pi/pi-version.ts +31 -3
  35. package/src/runtime/child-pi/sandbox.ts +38 -1
  36. package/src/runtime/dwf-state-store.ts +193 -7
  37. package/src/runtime/goal-workflow/dynamic-workflow-context.ts +48 -7
  38. package/src/runtime/goal-workflow/dynamic-workflow-runner.ts +82 -6
  39. package/src/runtime/live-session/live-session-runtime.ts +78 -3
  40. package/src/runtime/mcp-proxy.ts +65 -6
  41. package/src/runtime/model/pi-args.ts +16 -15
  42. package/src/runtime/plan-replan.ts +4 -1
  43. package/src/runtime/task-runner/child-executor.ts +11 -5
  44. package/src/runtime/task-runner/hybrid-tier.ts +17 -0
  45. package/src/runtime/task-runner/pre-execution.ts +13 -6
  46. package/src/runtime/task-runner.ts +14 -0
  47. package/src/runtime/team-runner.ts +26 -0
  48. package/src/runtime/verification/verification-worktree.ts +46 -29
  49. package/src/runtime/verification/verify-gate-memo.ts +211 -32
  50. package/src/runtime/verification/verify-gate.ts +266 -14
  51. package/src/runtime/workspace-lock.ts +95 -21
  52. package/src/schema/config-schema.ts +12 -2
  53. package/src/state/coordination/locks.ts +86 -19
  54. package/src/state/coordination/mailbox.ts +263 -22
  55. package/src/state/stores/manifest-io.ts +206 -7
  56. package/src/state/stores/state-store.ts +44 -15
  57. package/src/state/types.ts +9 -0
  58. package/src/ui/inline-panel/agent-transcript.ts +151 -11
  59. package/src/ui/settings-overlay.ts +8 -3
  60. package/src/ui/theme-discovery.ts +14 -2
  61. package/src/ui/tool-renderers/index.ts +26 -6
  62. package/src/utils/safe-terminal-text.ts +60 -0
  63. package/src/worktree/git-hardening.ts +78 -1
  64. package/src/worktree/worktree-manager.ts +34 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,121 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.11.51] — SEC-2026-11: security audit remediation (30 confirmed findings + 4 leads, 13 waves) (2026-10-30)
4
+
5
+ **Fixed (security).** Full remediation of the 2026-10-29 independent security audit (skill security-audit, full
6
+ profile, whole package @ 6063f377; 30 confirmed / 4 needs_validation / 3 rejected). Story:
7
+ `docs/stories/SEC-2026-11-audit-remediation/`. Evidence: `/home/bom/security-audit-skill/pi-crew/run-1` (report,
8
+ findings, fix-records). Wave-by-wave:
9
+
10
+ **Fixed (CI live-probed, Windows).** Hardened git env (`GIT_CONFIG_NOSYSTEM=1`) dropped the
11
+ Git-for-Windows system gitconfig — where the install-wide `core.autocrlf=true` default lives — so every
12
+ hardened `git status` reported phantom modifications on pristine CRLF worktrees (verify-gate skip refusals,
13
+ memo disabled, snapshot dirty: all fail-closed on clean trees). `buildGitSafeEnv` now re-injects ONLY the two
14
+ eol scalars (`core.autocrlf`/`core.eol`), parsed and value-domain-checked from the canonical system gitconfig
15
+ by trusted code, via git's env-config channel (`GIT_CONFIG_COUNT`, honored independently of NOSYSTEM). No
16
+ include/filter/other system key can travel the channel; attacker-supplied `GIT_CONFIG_*` stays stripped
17
+ (pinned). Diagnosed with a live windows-2025 CI probe (run 41058674711: full-env status clean vs safe-env
18
+ `M run.js`). Test suite hardening: deadline test isolates its bound (no seeded budget racing the terminal
19
+ status), O_NOFOLLOW symlink-swap pin skips documented on win32 (libuv no-op; binding control there is the
20
+ Ed25519 steering signature layer), theme-stem escape plant skips documented where the OS forbids control
21
+ chars in filenames (vector structurally absent).
22
+
23
+ **Fixed (live-caught regression, real-test battery).** Ask/delegate/message were dead in every default-config
24
+ worker session since 0.11.50: LOW-1 moved the broker token from env to the fd3 pipe, but the three tool guards
25
+ still read the env token. Workers now bridge to fd3-resolved child broker credentials (task-identity-bound,
26
+ settled-promise seam in `crew-broker-child.ts`; guards in `prompt-runtime.ts` / `message-tool.ts`). Proven live:
27
+ ask park→respond(signed)→resume, message delivery, signed steer honored; pinned unit suite 5/5
28
+ (`test/unit/prompt/low1-fd3-tool-guard.test.ts`).
29
+
30
+ - **w1a broker (HIGH×2, MEDIUM)** — spawns without a task identity no longer receive the bare per-run token
31
+ (fail closed); bare-runId fallback retired for explicit taskId hello claims; `wait.*` authenticate via
32
+ task-scoped compound tokens only; durable mailbox rows + steering lines are Ed25519-signed by the root session
33
+ (private key heap-only, children get the public verify key via `PI_CREW_MAILBOX_VERIFY_KEY`), consumers drop
34
+ unsigned/invalid rows as noise; steering poll re-validates per tick (TOCTOU); inbox fence neutralization covers
35
+ every attacker-influenced metadata field.
36
+ - **w1b bindings (MEDIUM, LOW)** — gatherReplies binds replies to (mailId → expected addressee) with broker-
37
+ authenticated `from`; api claim/release/transition gated for read_only tier + claim bound to the caller's
38
+ `PI_CREW_TASK_ID`.
39
+ - **w2 verify-gate (HIGH×3)** — gate binds the tracked working tree at dispatch (temp-index treeOid), fails on
40
+ drift, downgrades mid-gate tamper to INCONCLUSIVE; memo key = cwd + full tracked-tree oid (dirty ⇒ memo off);
41
+ dependency-worktree probes refuse skip on uncommitted work even on memoized PASS.
42
+ - **w3 dwf trust (HIGH, MEDIUM)** — user-tier `.dwf.ts`/preStepScript default-deny (`PI_CREW_TRUST_USER_DWF`);
43
+ dispatch-time `dynamicScriptPin` (path+sha256) persisted before load and verified on every resume arm;
44
+ checkpoints bound to runId with schema/clamp/verdict-allowlist hydration validation.
45
+ - **w4a child-pi (HIGH×2)** — inference-broker in-flight cap enforced (increment + exactly-once settle; over-cap
46
+ 429s); sandbox toolchain binds capped below the user trust boundary (no `$HOME`/`~/.pi/agent` overshoot —
47
+ auth.json unreachable).
48
+ - **w4b config (HIGH, MEDIUM)** — `runtime.embeddedWorkers` user-only (sensitive); embedded routing fails closed
49
+ while a sandbox posture is on; S-7 read_only execution-tool floor (bash/edit/write un-expandable by
50
+ frontmatter; D5 write-tier parity preserved); `pi-args` emits tools from the resolved policy.
51
+ - **w5a root-gate (HIGH, MEDIUM)** — dryRun carriers traverse the full R11-S1 matrix; delete/cleanup/init gated
52
+ (resolved-tier backstop in handleDelete; init scope union resolver).
53
+ - **w5b resume (MEDIUM×2, LOW)** — resume inherits budget + deadline (manifest-derived re-arm; deadline timer
54
+ armed); maxTasks admission re-enforced before any side effect; special-kind adopt performs the in-lock
55
+ liveness recheck. Plus: perf-sampler child error listener (pre-existing abort-after-exit host crash).
56
+ - **w6 locks (HIGH, MEDIUM, LOW)** — seed-path destination O_NOFOLLOW ancestor validation (pre+post mkdir);
57
+ workspace-lock refresh CAS on (dev,ino)+bytes (no clobber of a stolen lock); steal removal bound to the
58
+ verified corpse token + post-claim verification in both acquire loops.
59
+ - **w7a render (MEDIUM×2, LOW)** — shared `stripTerminalSequences`; control-char theme names refused/neutralized;
60
+ inline-panel transcript + tool-renderers + inspect sinks sanitize OSC/CSI/control chars.
61
+ - **w7b observability/import (MEDIUM, LOW×2)** — OTLP `redirect:'manual'` + 3xx refusal; userinfo endpoints
62
+ refused + origin-only error/log rendering; imported manifest fields rendered through `sanitizeImportedText`.
63
+ - **w8 ci (MEDIUM, LOW)** — battery changed-path matching decodes git C-quoted paths (quotePath pinned,
64
+ fail-closed decode) so T7 live-smoke can't be blind-triggered; ci.yml tarball smoke binds the exact pack name
65
+ with loud existence/count/version assertions (no decoy glob).
66
+
67
+ **Verification.** Per-wave regression tests (≈160 new) + sequential re-run of all 211 suite files affected by
68
+ mid-run tree churn: green. `npm run typecheck`, `npm run lint`, `biome format`, `check-env-vars`,
69
+ `check-lazy-imports`, `check-slop-rules`, `check-event-types-registry --enforce` all pass. Full-suite fresh run
70
+ on the final tree pending release gate (see story validation.md).
71
+
72
+ ## [0.11.51] — wave 9: needs_validation leads + deferred residuals
73
+
74
+ **Fixed (security hardening).** Follow-up wave closing the audit's 4 needs_validation leads (deterministic/defensive
75
+ halves) and the residuals deferred by w1b/w7a/w7b:
76
+
77
+ - **N1** legacy live-session MCP route: allowlist-shaped post-creation foreign-extension assert (typed
78
+ fail-closed `McpForeignExtensionError` + `live-session.foreign_extension_blocked` event) — a differently-named
79
+ MCP adapter can no longer silently load/connect for a read-only role when the SDK falls back to the
80
+ DefaultResourceLoader path.
81
+ - **N2** version probe: `probePiVersion` failures re-arm after a 60s TTL instead of memoizing null for the
82
+ process lifetime — one transient cold-start miss no longer permanently drops `--no-mcp` from parity spawns on
83
+ hosts that support it (the empty-frontmatter `--tools` half was already closed in the first wave).
84
+ - **N3** persisted run state: loader-level validation — per-task shape + runId binding (foreign-runId entries
85
+ dropped) + 10k DoG cap; manifest runKind allowlist (unknown → team-run + warn); non-object manifests fail
86
+ closed with quarantine. On-disk forensics preserved (in-memory drops only).
87
+ - **N4** verification subsystem git invocations: all 16 sites (verification-worktree ×6, verify-gate-memo ×9,
88
+ verify-gate dirty-probe ×1) routed through the MED-1 composition (`hardenGitArgs` + `buildGitSafeEnv` +
89
+ `assertWorktreePointerTrusted`), closing the config-reachable helper-execution sink the audit reproduced live
90
+ (core.fsmonitor at a hijacked worktree). w2 tree-OID values pinned unchanged.
91
+ - **residuals**: read_only role gates + caller audit fields on the remaining mutating api ops
92
+ (write-heartbeat, live-agent control cluster, mailbox send/ack/repair, foreground-interrupt);
93
+ `parseOtlpConfig` refuses userinfo endpoints at validation time (origin-only errors); `tool_execution_start`
94
+ `event.args` string leaves sanitized before ToolExecutionComponent render.
95
+
96
+ 42 new regression tests. Owner-observed deployment checklists for the leads' impact confirmation remain in the
97
+ audit's NEEDS-VALIDATION.md.
98
+
99
+ ## [Unreleased] — test hardening
100
+
101
+ **Fixed (test-only).** `waitForPreGateEvents` (classifier-pre-gate) now THROWS on timeout with counts + path
102
+ instead of returning silently — the silent return turned a legit wait-timeout into a far-away
103
+ `TypeError: Cannot read properties of undefined (reading 'taskId')` on `preGateEvents(...)[0]!` (the [pg-10]
104
+ CI flake: 2 Node-22 shards, run 40797688830, 2026-10-29; rerun green). A timeout now fails AT the wait site
105
+ with diagnostics (found vs expected `task.verifier_pre_gate` events, eventsPath, budget). Bug-030 RCA backlog item.
106
+
107
+ ## [0.11.50] — LOW-1: PI_CREW_BROKER_STDIN fd3 handshake DEFAULT-ON ('0' opts out) (2026-10-28)
108
+
109
+ **Changed (LOW-1 gate flip).** The broker-credential fd3 handshake route is now **DEFAULT-ON**: both gates
110
+ (`child-pi-spawn.resolveBrokerStdinHandshakeEnabled`, `crew-broker-child.resolveBrokerStdinFallbackEnabled`) flipped
111
+ from `=== "1"` (opt-in, v0.11.48–0.11.49) to `!== "0"` — only the exact value `0` opts out (rollback to the
112
+ bit-for-bit legacy env route, unchanged contract). Safe now because the v0.11.49 fd3 dedicated-pipe transport removed
113
+ the fd0/readPipedStdin race that caused the 0.11.46/47 silent-worker-death incident. The FIX-1 spawner write of
114
+ `"1"` stays (pins the child route deterministically + keeps a default-ON parent compatible with pre-flip workers
115
+ whose mirror gate still reads `=== "1"`); an opted-out parent keeps the token in the child env, which independently
116
+ disarms the worker reader. New live-worker integration pin: DEFAULT (gate unset) + fd3 payload → alive + no leak
117
+ (unit seams are structurally blind to this failure class — run the real-test battery T7 before publishing).
118
+
3
119
  ## [0.11.49] — 0.11.46/47 incident ROOT-CAUSED & CLOSED: fd0 handshake race → fd3 dedicated pipe; T7 nonce binding; review fix wave (2026-10-28)
4
120
 
5
121
  **Root cause (dynamically confirmed 5/5 + on-disk leak proof).** pi's `readPipedStdin` (main.js:52-65) consumes ALL