pi-crew 0.11.13 → 0.11.15
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 +21 -0
- package/dist/index.mjs +106 -106
- package/package.json +1 -1
- package/skills/real-test-pi-crew/SKILL.md +8 -0
- package/src/runtime/async-runner.ts +10 -0
- package/src/runtime/effectiveness.ts +10 -1
- package/src/state/stores/state-store.ts +9 -0
package/package.json
CHANGED
|
@@ -127,6 +127,11 @@ End-to-end verification discipline for pi-crew changes. Distilled from the broke
|
|
|
127
127
|
| `scripts/wc-gate.mjs` | T11b |
|
|
128
128
|
| `scripts/test-runner.mjs` (the runner itself) | T1 (exercises it) + `test/unit/scripts/test-runner-exit.test.ts` (21 tests: exit codes, cancelled-guard red-green, missing-file pre-check, batch shard empirical) + ONE batch-mode run (`PI_CREW_TEST_BATCH_SIZE=2 node scripts/test-runner.mjs --shard=0/1 <3 small files>`). Dev script — NOT bundled, no T3/T4 needed |
|
|
129
129
|
| `scripts/check-lazy-imports.mjs` | Run the gate on a clean tree (`node scripts/check-lazy-imports.mjs` exit 0) + re-probe the pattern battery vs the KNOWN GAPS comment (round-3 lesson: a skip-rule fix can OPEN a new false-skip hole — probe both directions). NOT bundled |
|
|
130
|
+
| `src/runtime/verification/verify-gate.ts` + task-runner gate mount (U13) | T7 smoke ×2 — (a) goal whose checks PASS → run must reach `completed` (NOT `blocked`) + `task.verifier_pre_gate` event with `skipVerifier:true` + verifier result artifact carries gate summary; (b) goal whose checks FAIL (e.g. `false` command) → LLM verifier spawns WITH gate context. **Guards the U13×effectiveness interplay** (live-caught 2026-10-10: green-gated verifier = no usage/transcript by design → effectiveness guard false-blocked the run → sync calls hung forever; fixed by counting `diagnostics.verifyGate` as observable work — `effectiveness-guard.test.ts` pins it) |
|
|
131
|
+
| `PI_CREW_STATE_BACKEND=sqlite` (U8 state backend) | Unit: `sqlite-run-state.test.ts` + `state-store-sqlite-parity.test.ts` (incl. coalesced-mirror pin). LIVE: one fast-fix run with the env set → assert `state.sqlite` exists, **sqlite tasks reach terminal status** (live-caught 2026-10-10: `saveRunTasksCoalesced` hot path skipped the db — manifest+tasks.json completed while sqlite stuck at createRun `queued`), events.jsonl still written (audit spine), JSON mirrors present |
|
|
132
|
+
| `PI_CREW_CHILD_PI_MODE=rpc` / `PI_CREW_CHILD_PI_POOL` (U14 transport) | Unit: `child-pi-rpc-mode.test.ts` (18) + `owned-process-u15.test.ts` (11). LIVE: one async run with env set → workers' status.json carry rpc transport markers, run green, `pgrep -f "mode rpc"` clean after completion (no orphan rpc processes), json default unaffected |
|
|
133
|
+
| `src/runtime/live-session/**` shared-services rework (U4) | Unit: `live-session-u4` suite (10 — init<50ms via `session_created.elapsedMs`, recursion assert, D4 planning-window replay, hung-tool drop). LIVE: T8 md5 + one fast-fix run (live-session path opt-in) — session_created.elapsedMs < 50ms in events |
|
|
134
|
+
| `src/runtime/effectiveness.ts` / guard semantics | `effectiveness-guard.test.ts` + `effectiveness-cov.test.ts` + T7 smoke (sync) — **a completed run must never end non-terminal `blocked` when every task has evidence**; sync T7 hang = guard/gate interplay regression smell |
|
|
130
135
|
| `dist/` (bundle) | T3 → T4 → T8 → T11j |
|
|
131
136
|
| `src/runtime/rpc/**` (worker transport seam — RPC vẫn EXPERIMENTAL) | Pinned suites `test/unit/runtime/rpc/rpc-worker.test.ts` (10) + `test/unit/runtime/run-worker-rpc-seam.test.ts` (8, gồm DR1/DR5 exit-race) + **T7 smoke với `PI_CREW_WORKER_TRANSPORT=rpc`** khi đụng transport wiring; stdio fallback phải giữ structured warn |
|
|
132
137
|
| `src/runtime/classifier/**` + config ceremony (`classifierEnabled` / `classifierModel`) | `classifier-service.test.ts` (14) + `child-executor-retry-triage.test.ts` (6) + `npm run check:env-vars` — unit-only, KHÔNG live tier (seam DORMANT default off; chỉ live khi `PI_CREW_CLASSIFIER_ENABLED=1`) |
|
|
@@ -1104,6 +1109,9 @@ PY
|
|
|
1104
1109
|
|
|
1105
1110
|
---
|
|
1106
1111
|
|
|
1112
|
+
|
|
1113
|
+
> **2026-10-10 update (upgrade-spec Waves 1-3, v0.11.11→0.11.14 + battery)**: 14/15 upgrade-specs landed (U1-U10, U13-U15; U11 gated on U4 stability, U12 track-only). The battery ran against the shipped bundles and **live-caught 2 integration bugs unit tests structurally cannot see**: (1) **U13×effectiveness-guard** — a verifier skipped by the deterministic gate completes with no LLM usage/transcript BY DESIGN, the guard read that as "no observable worker activity" → run stuck non-terminal `blocked` → **sync team calls hung forever** (runs team_20261010161149/76c80253; fixed 0.11.14 by counting `diagnostics.verifyGate` as observable work); (2) **U8 coalesced-mirror gap** — `saveRunTasksCoalesced` (hot path from `persistSingleTaskUpdate`) wrote only the tasks.json mirror; authoritative `state.sqlite` kept its createRun snapshot (probe run team_20261010164746: manifest completed + sqlite tasks `queued`). New decision-table rows above pin live probes for the wave seams (verify_gate ×2, sqlite backend, rpc mode, live-session init cost, guard semantics). **Operational traps learned**: (a) sync `team` runs wait FOREVER on a non-terminal `blocked` run — a T7 smoke that hangs is a guard/gate interplay smell, kill the probe pi and diff manifest vs tasks vs agents; (b) `pi -p` with a hung final model stream (zai) never exits and survives `kill` — probe via async runs + read state files directly; (c) ALL live probes must run through FRESH pi sessions (`pi -p …`) — the interactive session keeps the startup-time bundle in RAM, so in-session team calls prove nothing about new code; (d) full `npm test` from a pi-crew-running session needs ambient `PI_CREW_*/PI_TEAMS_*` scrubbed or env-assertion tests hang/flake.
|
|
1114
|
+
|
|
1107
1115
|
## Anti-patterns (the cost is real, observed in this session)
|
|
1108
1116
|
|
|
1109
1117
|
| Anti-pattern | Cost | Where fixed | Reference |
|
|
@@ -250,6 +250,16 @@ export const BACKGROUND_RUNNER_ENV_ALLOWLIST: string[] = [
|
|
|
250
250
|
// PI_CREW_MODEL_REQUIRE_CREDENTIALS is NOT here — see forwardModelControlEnv.
|
|
251
251
|
"PI_CREW_MODEL",
|
|
252
252
|
"PI_CREW_MODEL_FALLBACK_ORDER",
|
|
253
|
+
// U8/U14 state+transport control (2026-10-10, live-caught P2 probe run
|
|
254
|
+
// team_20261010165359): the detached runner OWNS task-state writes for async
|
|
255
|
+
// runs — stripping PI_CREW_STATE_BACKEND made the host create the run with
|
|
256
|
+
// the sqlite backend while every runner-side task update silently used the
|
|
257
|
+
// JSON default (state.sqlite stuck at its createRun snapshot; tasks.json
|
|
258
|
+
// correct). PI_CREW_CHILD_PI_MODE/POOL ride along for the same parity
|
|
259
|
+
// reason (runner spawns the child-pi workers).
|
|
260
|
+
"PI_CREW_STATE_BACKEND",
|
|
261
|
+
"PI_CREW_CHILD_PI_MODE",
|
|
262
|
+
"PI_CREW_CHILD_PI_POOL",
|
|
253
263
|
];
|
|
254
264
|
|
|
255
265
|
/**
|
|
@@ -22,7 +22,16 @@ export function taskHasObservableWorkerActivity(task: TeamTaskState): boolean {
|
|
|
22
22
|
task.usage ||
|
|
23
23
|
task.transcriptArtifact ||
|
|
24
24
|
task.modelAttempts?.some((attempt) => attempt.success) ||
|
|
25
|
-
task.jsonEvents
|
|
25
|
+
task.jsonEvents ||
|
|
26
|
+
// U13 deterministic verify_gate: a gated verifier does real work
|
|
27
|
+
// (typecheck/test exit codes via ctx.executeTool) WITHOUT spawning an
|
|
28
|
+
// LLM worker — no usage/transcript by design. The gate verdict recorded
|
|
29
|
+
// in task.diagnostics.verifyGate is the observable-work evidence.
|
|
30
|
+
// Live-caught 2026-10-10 (T7 battery, runs team_20261010161149 +
|
|
31
|
+
// team_20261010162310): green-gated verifier tasks were false-blocked
|
|
32
|
+
// here ("no observable worker activity") → run stuck non-terminal
|
|
33
|
+
// "blocked" → sync team calls hung forever.
|
|
34
|
+
task.diagnostics?.verifyGate !== undefined,
|
|
26
35
|
);
|
|
27
36
|
}
|
|
28
37
|
|
|
@@ -795,6 +795,15 @@ export function saveRunTasksCoalesced(
|
|
|
795
795
|
} catch {
|
|
796
796
|
return;
|
|
797
797
|
}
|
|
798
|
+
// U8 FIX (2026-10-10, live P2 probe run team_20261010164746): the coalesced
|
|
799
|
+
// json write below is the READ-SIDE mirror (50ms buffer); the sqlite db is
|
|
800
|
+
// AUTHORITATIVE and must see every task-state change immediately — this is
|
|
801
|
+
// the hot path from persistSingleTaskUpdate. Without this branch the db
|
|
802
|
+
// kept its createRun snapshot ("queued") while tasks.json moved on
|
|
803
|
+
// (manifest completed + tasks.json completed + sqlite tasks stuck queued).
|
|
804
|
+
if (isSqliteStateBackend()) {
|
|
805
|
+
getSqliteRunStateStore(manifest.stateRoot).saveTasks(tasks);
|
|
806
|
+
}
|
|
798
807
|
atomicWriteJsonCoalesced(manifest.tasksPath, tasks, undefined, { compact: true, durability }, skipCoalesce);
|
|
799
808
|
}
|
|
800
809
|
|