# test725/test745 扩到 tests/ 目录
source_commit=1e9e75dab635dc03d12636232ebc2ac117c2dee6
base(current main)=034f00647d42d38d5086d7fc057eb7824a441791
本文件是该源码提交的 report-only 子提交。

## 本轮:tests/ 分派加绝对下限(同 #798 那个洞)
双向验过:19 个 → RESULT: PASS;删到 4 个 → rc=1 FAIL: only 4 file(s) under agent-network/tests, floor is 15

## test725
```
# test725 — complete agent-node unit domain
source_commit=1e9e75dab635dc03d12636232ebc2ac117c2dee6
bun=1.3.14 node=v22.23.2 uid=1000
[L0] full agent-node/src unit suite as non-root
bun test v1.3.14 (0d9b296a)

src/inbox-message-policy.test.ts:
(pass) atomic peer reply inbox policy > ordinary work still expects a response [1.21ms]
(pass) atomic peer reply inbox policy > a peer reply is actionable but cannot start reply ping-pong [0.09ms]
(pass) atomic peer reply inbox policy > plain informational messages retain ack-only behavior [0.05ms]

src/external-schedules.test.ts:
(pass) external schedule manifest > reports an exact bounded shape and strips host paths to basename [1.27ms]
(pass) external schedule manifest > missing manifest is an explicit empty observation; config-less legacy stays omitted [2.14ms]
(pass) external schedule manifest > unknown keys, duplicate ids, invalid timestamps, and oversized lists fail closed [1.14ms]
(pass) external schedule manifest > symlink manifest never follows the target [0.65ms]
(pass) external schedule manifest > editable/revision are derived only from a verified managed crontab under the process gate [3.25ms]

src/inbox-skip-log.test.ts:
(pass) formatInboxSkipLog > self-message diagnostics identify the routing layer and full task [0.09ms]
(pass) formatInboxSkipLog > all inbound filter reasons produce an actionable INFO-safe line [0.16ms]
(pass) formatInboxSkipLog > the formatter has no message-content input [0.06ms]

src/owner-schedule-consumer.test.ts:
(pass) process-gated owner schedule consumer > disabled process registers no poll and makes zero network/host calls [1.69ms]
(pass) process-gated owner schedule consumer > exact node intent applies once, ACKs, and deletes journal only after ACK [10.94ms]
(pass) process-gated owner schedule consumer > foreign-node intent and invalid authority shape never reach crontab [1.03ms]
(pass) process-gated owner schedule consumer > lost ACK keeps journal; same delivered intent recovers without a second install [9.97ms]

src/codex-model-default.test.ts:
(pass) agent-node Codex model resolution > missing model uses the verified supported default [0.09ms]
(pass) agent-node Codex model resolution > explicit model remains authoritative [0.03ms]

src/claude-tool-aliases.test.ts:
(pass) Claude CommHub tool aliases > pins the exact registered in-process CommHub tool set [0.06ms]
(pass) Claude CommHub tool aliases > does not advertise aliases when the in-process server failed [0.09ms]

src/reply-reliability.test.ts:
(pass) classifyCommHubResponse > returns ok with parsed application payload (the happy path) [0.43ms]
(pass) classifyCommHubResponse > JSON-RPC error envelope → retryable CommHubError [0.25ms]
(pass) classifyCommHubResponse > MCP result.isError → retryable CommHubError [0.20ms]
(pass) classifyCommHubResponse > real legacy Hub unknown-tool result preserves the MCP code [0.10ms]
(pass) classifyCommHubResponse > application-level ok:false → appLevel CommHubError (NON-retryable) [0.13ms]
(pass) classifyCommHubResponse > non-JSON tool text is passed through verbatim [0.34ms]
(pass) classifyCommHubResponse > data with neither error nor result returns ok with the raw data [0.07ms]
(pass) CommHubError > instances are distinguishable from generic Error via instanceof [0.15ms]
(pass) CommHubError > appLevel flag survives the throw/catch round trip [0.13ms]
(pass) PendingReplyQueue > load() returns empty array when file does not exist [1.04ms]
(pass) PendingReplyQueue > persist + load round-trips an entry with attempts=0 [4.55ms]
(pass) PendingReplyQueue > final persistence boundary scrubs known, shaped, assignment and error credentials [4.86ms]
(pass) PendingReplyQueue > direct save cannot bypass scrub and leaves no sibling temp artifact [3.03ms]
(pass) PendingReplyQueue > load migrates an old broad-mode queue without leaving raw credential bytes [2.80ms]
(pass) PendingReplyQueue > load repairs a broad mode even when content needs no rewrite [1.32ms]
(pass) PendingReplyQueue > accepts the same process-wide redactor used by ordinary log call sites [3.15ms]
(pass) PendingReplyQueue > invalid legacy content is securely replaced with an empty 0600 queue [3.56ms]
(pass) PendingReplyQueue > persist is idempotent on (to, taskId) — attempts counter preserved [6.94ms]
(pass) PendingReplyQueue > clear removes only the matching (to, taskId) [11.80ms]
(pass) PendingReplyQueue.drain > delivers every entry on success and persists an empty queue [9.85ms]
(pass) PendingReplyQueue.drain > transient failure requeues with attempts++ and lastError [7.19ms]
(pass) PendingReplyQueue.drain > transient error text is scrubbed before it reaches disk [5.25ms]
(pass) PendingReplyQueue.drain > app-level CommHubError is dropped loud — not retried, not requeued [9.46ms]
(pass) PendingReplyQueue.drain > drain on empty queue is a no-op and does not write the file [0.47ms]
(pass) PendingReplyQueue.drain > file format is stable JSON — readable by an operator after a crash [4.46ms]
(pass) quickHash > is deterministic [0.26ms]
(pass) quickHash > differs across inputs [0.06ms]
(pass) quickHash > returns 32-char hex [0.10ms]

src/controlled-upload.test.ts:
(pass) normalizeUploadName > strips directories and control chars [1.34ms]
(pass) resolveControlledUploadPath — NUL live guard > rejects embedded NUL before any fs access [0.92ms]
(pass) resolveControlledUploadPath — NUL live guard > rejects NUL-only / leading NUL [0.61ms]
(pass) resolveControlledUploadPath > accepts regular file under root [0.96ms]
(pass) resolveControlledUploadPath > rejects path outside roots [0.64ms]
(pass) resolveControlledUploadPath > rejects absolute foreign path /etc/passwd [0.42ms]
(pass) resolveControlledUploadPath > rejects traversal that escapes root [0.44ms]
(pass) resolveControlledUploadPath > rejects missing path [0.69ms]
(pass) openFstatBoundedReadControlledFile — same fd + bound > reads small PNG via same-fd path [1.65ms]
(pass) openFstatBoundedReadControlledFile — same fd + bound > rejects oversize without allocating full max+1 into a single slurp beyond cap [20.88ms]
(pass) openFstatBoundedReadControlledFile — same fd + bound > rejects symlink leaf at open (O_NOFOLLOW) [1.32ms]
(pass) openFstatBoundedReadControlledFile — same fd + bound > fstat is on the same opened fd (structural pin) [0.53ms]
(pass) uploadControlledLocalFile > uploads PNG fixture via mock fetch and returns file_id [2.48ms]
(pass) uploadControlledLocalFile > refuses oversize before network [18.23ms]
(pass) uploadControlledLocalFile > never falls back to path when file_id missing [1.88ms]
(pass) uploadControlledLocalFile > rejects untrusted path without calling hub [0.94ms]
(pass) uploadControlledLocalFile > rejects NUL path without calling hub [0.65ms]
(pass) defaultControlledUploadRoots > includes grok sessions and attachment cache [0.96ms]
(pass) source contracts (adversarial pins) > same-fd pin: fstatSync(fd) + openSync; no path re-stat/readFileSync in reader [0.51ms]
(pass) source contracts (adversarial pins) > NUL guard pin: rawPath.includes NUL marker present [0.51ms]
(pass) source contracts (adversarial pins) > bounded-read pin: extra-byte probe after maxBytes [0.33ms]

src/commhub-mcp.test.ts:
(pass) injectAgentFromSession > adds current alias to outbound task calls [0.13ms]
(pass) injectAgentFromSession > adds current alias to outbound message calls [0.07ms]
(pass) injectAgentFromSession > overrides stale or model-supplied from_session on ntok outbound calls [0.07ms]
(pass) injectAgentFromSession > does not add from_session to read-only calls [0.03ms]

src/inbox-dispatch.test.ts:
(pass) isInteractiveDashboardTask > accepts a Hub-authenticated dashboard chat task [0.55ms]
(pass) isInteractiveDashboardTask > pre-stamp admin rows stay FIFO because aliases are not auth facts [0.15ms]
(pass) isInteractiveDashboardTask > rejects node-authenticated spoofing, malformed ids, and plain messages [0.09ms]
(pass) dispatchInboxBatch > awaited batches preserve legacy runtime serialization [1.92ms]
(pass) dispatchInboxBatch > a later SSE snapshot enters while the first detached turn is still running [1.95ms]
(pass) dispatchInboxBatch > the real serialized drain lane can fetch a later SSE snapshot before the active turn ends [1.29ms]
(pass) dispatchInboxBatch > detached completion failures remain observable [1.46ms]
(pass) dispatchInboxBatch > settling detached work emits a wake for the next Hub inbox window [1.47ms]
(pass) dispatchInboxBatch > a throwing settle callback cannot strand queued N+1 work [1.58ms]
(pass) dispatchInboxBatch > same-tick duplicate kicks claim one row exactly once [0.48ms]
(pass) dispatchInboxBatch > bounded admission waits N+1 and starts it after a slot settles [6.29ms]
(pass) dispatchInboxBatch > durable reply drain waits until detached Codex rows finish [0.22ms]
(pass) dispatchInboxBatch > active Codex direct delivery and durable drain send one reply, not two [5.34ms]

src/reply-routing-source.test.ts:
(pass) #698 peer reply runtime wiring > peer replies negotiate the atomic tool and retain only a terminal legacy fallback [1.30ms]
(pass) #698 peer reply runtime wiring > every actionable inbox turn crosses the behavior-tested reply-policy seam [0.65ms]
(pass) #698 peer reply runtime wiring > new_reply SSE events wake the actionable work inbox [0.31ms]

src/task-runtime-evidence.test.ts:
(pass) logicalTaskIdFromInbox > retry/reassign task rows use stable task_id, not fresh inbox.id [0.13ms]
(pass) logicalTaskIdFromInbox > legacy task rows and non-task rows retain transport identity [0.07ms]
(pass) createTaskRuntimeEvidenceReporter > construction and process admission report no evidence [0.27ms]
(pass) createTaskRuntimeEvidenceReporter > submission and many runtime events produce one exact report per level [0.37ms]
(pass) createTaskRuntimeEvidenceReporter > a consumed-only runtime remains honest and lets the Hub imply submission [0.20ms]
(pass) createTaskRuntimeEvidenceReporter > missing logical task identity is a fail-closed no-op [0.14ms]
(pass) createTaskRuntimeEvidenceReporter > an old-Hub failure is visible but never breaks the model turn [0.44ms]
(pass) agent-node inbox wiring > keeps transport ACK separate from stable task evidence and replies [4.25ms]
(pass) agent-node inbox wiring > all runtime dispatch families receive the same task-lifetime reporter [1.20ms]
(pass) agent-node inbox wiring > SDK and direct-stdio boundaries preserve their distinct evidence semantics [1.75ms]

src/grok-isolated-cwd.test.ts:
(pass) prepareGrokIsolatedCwd (#204 preview.7) > creates per-node grok-cwd directory under home/.anet/nodes/<nodeKey>/grok-cwd [2.33ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > falls back to alias when nodeId is absent [2.06ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > sanitises nodeKey to avoid path traversal / weird chars [2.06ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > skips .mcp.json (does NOT symlink it into isolated cwd) [1.42ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > symlinks top-level files (README.md) and directories (docs/, src/) [1.51ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > is idempotent — second run sees existing symlinks and counts 0 new [1.38ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > picks up new entries on re-run (snapshot freshness) [1.60ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > falls back to userCwd (isolated=false) when mkdir fails [1.54ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > falls back to userCwd when userCwd does not exist (readdir fails) [1.35ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > does NOT throw on per-entry symlink failure — warns and continues [1.87ms]
(pass) prepareGrokIsolatedCwd (#204 preview.7) > two different nodes get fully isolated dirs (concurrency safe by construction) [2.62ms]

src/inbox-dispatch-wiring.test.ts:
(pass) Codex app-server live inbox kick wiring > a Codex snapshot releases the serialized fetch lane after submission [0.27ms]
(pass) Codex app-server live inbox kick wiring > Codex detached admission is explicitly bounded and completion wakes the Hub window [0.56ms]
(pass) Codex app-server live inbox kick wiring > pending reply drain is fenced while detached Codex rows are active [0.21ms]

src/owner-schedule-control.test.ts:
(pass) owner schedule managed-cron control > parses only exact managed markers and publishes bounded inventory [1.20ms]
(pass) owner schedule managed-cron control > changes timing/enabled while preserving command and unmanaged bytes [7.71ms]
(pass) owner schedule managed-cron control > command replacement, wrong node, wrong revision, and unknown patch fail before install [3.21ms]
(pass) owner schedule managed-cron control > install/readback failure restores and verifies the exact old crontab [3.10ms]
(pass) owner schedule managed-cron control > unsafe node directory and symlink journal fail closed with zero host write [1.10ms]
(pass) owner schedule managed-cron control > local audit is minimal, private and idempotent [2.70ms]

src/owner-schedule-wiring.test.ts:
(pass) owner schedule process wiring > capability is pinned from config once and never exposed as a model tool [1.23ms]
(pass) owner schedule process wiring > SSE is only a doorbell and snapshots are editable only under the same gate [0.93ms]
(pass) owner schedule process wiring > new token mint paths bind the immutable node id and opt-in is explicit [3.18ms]

src/runtime-effective-label.test.ts:
(pass) #491 startup banner reports the EFFECTIVE runtime > alias input 'codex-tui' → banner names the effective runtime (codex-app-server), not just the raw input [7260.16ms]
(pass) #491 startup banner reports the EFFECTIVE runtime > canonical input stays readable (no regression for the common case) [7190.17ms]
(pass) #491 regression lock — unknown runtime fails closed > unknown runtime → non-zero exit, error names the value AND the supported list [135.14ms]
(pass) #553 Grok startup banner reports model ownership truthfully > unset model on Grok ACP names the Grok CLI as owner, not the runtime alias as a model id [7140.92ms]
(pass) #553 Grok startup banner reports model ownership truthfully > unset model on Grok CLI uses the same non-versioned ownership statement [7160.36ms]
(pass) #553 Grok startup banner reports model ownership truthfully > an explicit Grok model is still reported exactly [7164.00ms]

src/peer-reply-send.test.ts:
(pass) peer reply capability fallback > capable Hub uses only the atomic terminal route [0.49ms]
(pass) peer reply capability fallback > old Hub wire error terminalizes through send_reply, never send_task [0.62ms]
(pass) peer reply capability fallback > every explicit capability downgrade preserves terminal reply semantics [0.61ms]
(pass) peer reply capability fallback > transport ambiguity and unrelated hard errors never choose a second route [0.42ms]
(pass) peer reply capability fallback > negative capability is rechecked instead of cached [0.48ms]
(pass) peer reply capability fallback > legacy terminalization failure stays visible to the pending queue [0.31ms]
(pass) peer reply capability fallback > classifier accepts only explicit capability signals [0.14ms]

src/private-log.test.ts:
(pass) Grok preview private ordinary logs > scrubs and repairs legacy logs before appending through a 0600 file [4.39ms]
(pass) Grok preview private ordinary logs > rejects a symlinked directory or final log file [1.39ms]
(pass) Grok preview private ordinary logs > rejects a multiply-linked log instead of rewriting another pathname [0.62ms]
(pass) Grok preview private ordinary logs > does not follow a log-directory symlink introduced after preparation [0.73ms]

src/owner-schedule-system-crontab.test.ts:
(pass) owner schedule real crontab adapter > round-trips an exact managed marker through the container crontab [26.10ms]

src/credential-redaction.test.ts:
(pass) credential persistence redactor > removes exact caller-known values regardless of punctuation or context [0.27ms]
(pass) credential persistence redactor > redacts network, GitHub, AWS and provider token shapes in free text [0.22ms]
(pass) credential persistence redactor > redacts credential assignments while preserving keys and valid JSON [0.31ms]
(pass) credential persistence redactor > redacts shell/error assignment forms including quoted values [0.11ms]
(pass) credential persistence redactor > redacts an unlabelled connection URI with embedded userinfo [0.04ms]
(pass) credential persistence redactor > does not over-delete normal prose and non-credential settings [0.06ms]
(pass) credential persistence redactor > deep-redacts JSON-like values without mutating the input [0.36ms]
(pass) credential value collection > collects exact sensitive values and shaped values under unknown keys [1.25ms]
(pass) credential value collection > key classifier is exact enough not to treat ordinary AWS settings as credentials [0.13ms]

src/inbox-skip-log-wiring.test.ts:
(pass) processInbox logs skipped messages at INFO before acknowledging [1.61ms]

src/peer-reply-inbox.test.ts:
(pass) inbox turn reply-policy enforcement > delivers once, ACKs once, and exposes no outbound reply dependency [0.55ms]
(pass) inbox turn reply-policy enforcement > ordinary request returns its outcome without ACKing in this seam [0.38ms]
(pass) inbox turn reply-policy enforcement > runtime failure does not ACK a result that was never consumed [0.33ms]
(pass) peer reply SSE routing > new_reply schedules exactly one drain [0.13ms]
(pass) peer reply SSE routing > unrelated events do not schedule a drain [0.06ms]

src/grok-artifact-extractor.test.ts:
(pass) listGrokVideoArtifacts (#205 Step 2 simplified) > returns empty when grokSessionDir is undefined [0.81ms]
(pass) listGrokVideoArtifacts (#205 Step 2 simplified) > returns empty when videos/ subdir is missing [0.31ms]
(pass) listGrokVideoArtifacts (#205 Step 2 simplified) > enumerates .mp4 files in videos/ as absolute paths [1.00ms]
(pass) listGrokVideoArtifacts (#205 Step 2 simplified) > matches mp4 case-insensitively [0.83ms]
(pass) listGrokVideoArtifacts (#205 Step 2 simplified) > does not throw on permission errors — returns [] [0.58ms]
(pass) formatVideoTrailer (#205 Step 2 simplified) > returns empty string for empty list [0.19ms]
(pass) formatVideoTrailer (#205 Step 2 simplified) > formats one path [0.13ms]
(pass) formatVideoTrailer (#205 Step 2 simplified) > formats multiple paths [0.07ms]
(pass) formatVideoTrailer (#205 Step 2 simplified) > skips paths already mentioned in existingReply (no duplication) [0.04ms]
(pass) formatVideoTrailer (#205 Step 2 simplified) > only appends paths NOT already mentioned, even when some are [0.05ms]

src/explicit-task-lifecycle.test.ts:
(pass) explicit delegation lifecycle trace > keeps the production delegation loop wired through the tested state machine [1.27ms]
(pass) explicit delegation lifecycle trace > emits ack, start, and reply from the production polling state machine [1.29ms]
(pass) explicit delegation lifecycle trace > emits both bounded stale warnings and expiry when delivery never advances [0.39ms]
(pass) explicit delegation lifecycle trace > pins the production poll, stale-warning, and timeout defaults [0.67ms]
(pass) explicit delegation lifecycle trace > maps failed and cancelled terminal states to a failed trace without retrying [0.41ms]

src/task-trace.test.ts:
(pass) task trace contract > renders missing parent and lifecycle scope honestly [0.39ms]
(pass) task trace contract > redacts credentials from errors [0.15ms]
(pass) task trace contract > emits parseable JSON and neutralizes human log injection [0.14ms]
(pass) task trace contract > recognizes the real MCP content envelope before cli parsing [0.80ms]
(pass) task trace contract > uses stable event names for send and observed lifecycle phases [0.14ms]

src/sse-recovery-guidance.test.ts:
(pass) sseAbandonGuidance > states that abandon leaves the current process alive [0.13ms]
(pass) sseAbandonGuidance > requires stop-and-replace instead of starting a duplicate [0.05ms]
(pass) sseAbandonGuidance > preserves the co-presence launch shape in recovery guidance [0.06ms]
(pass) sseAbandonGuidance > the production SSE abandon hook uses the honest guidance [0.92ms]

src/cli-explicit-delegation.test.ts:
(pass) extractExplicitDelegation > matches send_task alias/task call [0.93ms]
(pass) extractExplicitDelegation > matches mcp send_task positional call [0.14ms]
(pass) extractExplicitDelegation > matches 给 X 发任务 [0.15ms]
(pass) extractExplicitDelegation > matches 和 X 沟通一下 [0.23ms]
(pass) extractExplicitDelegation > matches bare 和 X 沟通一下 [0.12ms]
(pass) extractExplicitDelegation > matches 和 X send_task 一下 [0.08ms]
(pass) extractExplicitDelegation > matches 和 X send_task 一下 with no punctuation before body [0.07ms]
(pass) extractExplicitDelegation > matches bare 和 X send_task 一下 [0.06ms]
(pass) extractExplicitDelegation > matches 让 X 做 [0.09ms]
(pass) extractExplicitDelegation > matches 交给 X [0.03ms]
(pass) extractExplicitDelegation > does not match no alias [0.02ms]
(pass) extractExplicitDelegation > does not match normal Q&A [0.04ms]
(pass) extractExplicitDelegation > matches bare send_task <alias> <task> (MCP-like) [0.04ms]
(pass) extractExplicitDelegation > matches bare send_task with multi-word task body [0.04ms]
(pass) extractExplicitDelegation > matches 你去给 X 打个招呼 [0.04ms]
(pass) extractExplicitDelegation > matches 你去给 X with longer body [0.09ms]
(pass) extractExplicitDelegation > matches 给 X 发个消息 BODY (verb-suffix stripped) [0.07ms]
(pass) extractExplicitDelegation > matches 给 X 发 BODY (bare verb) [0.05ms]
(pass) extractExplicitDelegation > matches 给 X 沟通一下 BODY [0.04ms]
(pass) extractExplicitDelegation > matches 给 X 说 BODY [0.04ms]
(pass) extractExplicitDelegation > matches 给 X 发任务 (regression — specific pattern still wins) [0.04ms]

src/util/timeout.test.ts:
(pass) withTimeout — happy path (factory wins) > resolves with factory value when fn settles before deadline [0.56ms]
(pass) withTimeout — happy path (factory wins) > passes a non-aborted signal when fn finishes promptly [0.13ms]
(pass) withTimeout — happy path (factory wins) > returns objects, not just strings [0.15ms]
(pass) withTimeout — happy path (factory wins) > propagates fn's rejection unchanged (not wrapped) [0.25ms]
(pass) withTimeout — timeout path (timer wins) > rejects with TimeoutError when fn outlasts deadline [32.21ms]
(pass) withTimeout — timeout path (timer wins) > TimeoutError message includes label + ms [0.11ms]
(pass) withTimeout — timeout path (timer wins) > TimeoutError without label still works [0.07ms]
(pass) withTimeout — timeout path (timer wins) > fires AbortSignal on timeout so factory can cancel in-flight work [43.50ms]
(pass) withTimeout — zero / negative deadline sentinel > timeoutMs=0 disables the timer (CLAUDE_TIMEOUT_MS=0 sentinel) [52.02ms]
(pass) withTimeout — zero / negative deadline sentinel > timeoutMs<0 also disables (defensive) [0.51ms]
(pass) withTimeout — zero / negative deadline sentinel > untimed call still receives a non-aborted signal [0.17ms]
(pass) withTimeout — externalSignal propagation > forwards external abort into factory signal [212.11ms]
(pass) withTimeout — externalSignal propagation > already-aborted external signal aborts immediately [0.53ms]
(pass) withTimeout — cleanup > clears timer on successful return (no dangling handles) [22.67ms]
(pass) resolveTimeoutMs — precedence > env wins over flag and default [0.31ms]
(pass) resolveTimeoutMs — precedence > flag wins when env is missing [0.05ms]
(pass) resolveTimeoutMs — precedence > default wins when env and flag both missing [0.05ms]
(pass) resolveTimeoutMs — precedence > flag wins when env is empty string (treated as unset) [0.05ms]
(pass) resolveTimeoutMs — precedence > flag wins when env is non-numeric garbage [0.12ms]
(pass) resolveTimeoutMs — precedence > flag wins when env is negative [0.04ms]
(pass) resolveTimeoutMs — precedence > default wins when flag is NaN [0.04ms]
(pass) resolveTimeoutMs — precedence > zero is honoured (not treated as unset) — env=0 disables timeout [0.09ms]
(pass) resolveTimeoutMs — precedence > zero is honoured at flag level too [0.05ms]
(pass) resolveTimeoutMs — clamping > clamps below minMs and reports clamped=true [0.07ms]
(pass) resolveTimeoutMs — clamping > clamps above maxMs and reports clamped=true [0.06ms]
(pass) resolveTimeoutMs — clamping > in-bounds value is not clamped [0.05ms]
(pass) resolveTimeoutMs — clamping > default value also gets clamped (configuration sanity) [0.06ms]
(pass) resolveTimeoutMs — defensive null handling > null envValue is treated as unset [0.04ms]
(pass) resolveTimeoutMs — defensive null handling > null flagValue is treated as unset [0.04ms]

src/util/single-flight.test.ts:
(pass) single-flight resource initialization > concurrent callers share exactly one initializer [0.59ms]
(pass) single-flight resource initialization > a rejected initializer is cleared and can be retried [0.51ms]

src/util/supervise-child.test.ts:
(pass) superviseChild — shutdown gate stops the loop > shutdownGate=true from the start → runOnce never called [0.49ms]
(pass) superviseChild — shutdown gate stops the loop > shutdownGate flips true after first iteration → exactly one runOnce [0.27ms]
(pass) superviseChild — backoff growth + cap > waits double the delay each iteration, capping at maxDelayMs [2.57ms]
(pass) superviseChild — runOnce that returns WITHOUT markStable is treated as failed (regression pin) > runOnce that returns cleanly without markStable → backoff doubles [0.58ms]
(pass) superviseChild — markStable resets backoff > after iteration that calls markStable, next wait is baseDelayMs again [0.64ms]
(pass) superviseChild — markStable resets backoff > markStable called multiple times in one iteration is idempotent [0.50ms]
(pass) superviseChild — abandonAfterMs > calls onAbandon and returns after cumulative downtime exceeds threshold [0.60ms]
(pass) superviseChild — abandonAfterMs > markStable in any iteration resets downtime — abandon never fires [0.52ms]
(pass) superviseChild — runOnce error handling > runOnce throws → onError fires, loop continues [0.77ms]
(pass) superviseChild — runOnce error handling > runOnce throws AND shutdownGate goes true → loop exits, no further iteration [0.30ms]
(pass) superviseChild — jitter range > jitterRatio=0.25 + random=0 → -25% of delay (lower bound) [0.59ms]
(pass) superviseChild — jitter range > jitterRatio=0.25 + random=1 → +25% of delay (upper bound) [0.33ms]
(pass) superviseChild — jitter range > jitterRatio=0 → deterministic waits at exact delay [0.42ms]
(pass) superviseChild — jitter range > waitMs floor 100 enforces minimum wait even with tiny base + negative jitter [0.45ms]
(pass) superviseChild — defensive contract > returns (does not throw) when runOnce never resolves and shutdown flips [1.46ms]

src/util/access-resolve.test.ts:
(pass) normalizeAllowFrom — input shapes > real string[] passes through deduped (filter empty strings) [0.21ms]
(pass) normalizeAllowFrom — input shapes > undefined → empty + not malformed [0.05ms]
(pass) normalizeAllowFrom — input shapes > null → empty + not malformed [0.05ms]
(pass) normalizeAllowFrom — input shapes > non-array object → empty + malformed (corrupted access.json shape) [0.04ms]
(pass) normalizeAllowFrom — input shapes > string instead of array → malformed [0.03ms]
(pass) normalizeAllowFrom — input shapes > array with non-string elements drops them [0.06ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > empty array → deny with empty-fail-closed kind [0.23ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > undefined → deny [0.06ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > malformed → deny + reason mentions malformed [0.13ms]
(pass) resolveTelegramAccess — wildcard '*' opens the channel > ['*'] alone allows any sender [0.07ms]
(pass) resolveTelegramAccess — wildcard '*' opens the channel > ['*', 'specific_id'] still wildcard-allows (wins precedence) [0.05ms]
(pass) resolveTelegramAccess — explicit id / username matching > senderId in list → allow [0.08ms]
(pass) resolveTelegramAccess — explicit id / username matching > senderUsername match (no id match) → allow [0.05ms]
(pass) resolveTelegramAccess — explicit id / username matching > neither id nor username in list → deny [0.07ms]
(pass) resolveTelegramAccess — explicit id / username matching > empty senderUsername doesn't accidentally match empty list entry [0.05ms]
(pass) resolveTelegramAccess — explicit id / username matching > blank-string id with username match still allows [0.04ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > empty allowFrom → deny [0.35ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > wildcard allows [0.08ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > specific id allows [0.08ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > sender not in list → deny [0.06ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > empty allowChats → fail-closed [0.12ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat in allowChats + groupPolicy=all → allow [0.08ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat in allowChats + groupPolicy=observe → deny [0.08ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat NOT in allowChats → deny (even with policy=all) [0.10ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > wildcard chats opens any chat (with groupPolicy=all) [0.04ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > groupPolicy=mention allows (caller decides at message inspect time) [0.04ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns warn string for empty allowFrom [0.14ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns warn string for malformed allowFrom + mentions malformed [0.22ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns null when allowFrom has at least one entry [0.09ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns null for wildcard-allow (channel intentionally open) [0.04ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader stores raw allowFrom verbatim — no normalization at load time [0.10ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader emits boot-warn when allowFrom is missing [0.04ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader emits boot-warn when allowFrom is malformed (non-array) [0.06ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader is silent when allowFrom has at least one entry (even if numeric) [0.12ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [123] alone (numeric sender id from a misformatted access.json) → loader+resolver fail-closed [0.08ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [null] (corrupted access.json) → loader+resolver fail-closed [0.10ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [{}] (object instead of id string) → loader+resolver fail-closed [0.07ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [123, '@vansin'] (mixed) → '@vansin' still allowed, numeric '123' rejected [0.21ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [null, '*'] (mixed wildcard) → wildcard wins despite garbage entries [0.13ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > missing access.json entirely (loader gets null) → fail-closed [0.07ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > empty array NEVER allows [0.05ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > undefined NEVER allows [0.03ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > null NEVER allows [0.03ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > object-shape (corrupted) NEVER allows [0.03ms]

src/runtime/fetch-attachment.test.ts:
(pass) FILE_ID_REGEX matches server contract > accepts the same shapes the hub accepts [0.17ms]
(pass) FILE_ID_REGEX matches server contract > rejects path-traversal + length-out-of-range [0.09ms]
(pass) resolveAttachmentToLocalPath — file_id path > hub 200 OK → bytes written to cache + chmod 600 + Bearer auth attached [8.72ms]
(pass) resolveAttachmentToLocalPath — file_id path > file_id_invalid before any HTTP call (path traversal attempt) [0.53ms]
(pass) resolveAttachmentToLocalPath — file_id path > hub 404 → not_found code [0.48ms]
(pass) resolveAttachmentToLocalPath — file_id path > hub 401 → auth_failed code [0.45ms]
(pass) resolveAttachmentToLocalPath — size cap (🔴 通信龙 nit: BYTE unit + mid-stream abort) > Content-Length > cap → size_exceeded with declared-and-cap surfaced + no cache file written [0.70ms]
(pass) resolveAttachmentToLocalPath — size cap (🔴 通信龙 nit: BYTE unit + mid-stream abort) > Content-Length lies (says small, sends big) → size_exceeded MID-STREAM with cleanup [1.42ms]
(pass) resolveAttachmentToLocalPath — size cap (🔴 通信龙 nit: BYTE unit + mid-stream abort) > DEFAULT_MAX_BYTES is 50 MiB unless COMMHUB_ATTACHMENT_MAX_BYTES is set (current process is unset → 50 MiB) [0.08ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > no file_id + path inside cache root → returns canonical path, no HTTP call [0.80ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > configured Feishu root remains a compatible trusted drop-zone [0.65ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > existing file outside trusted roots is rejected [0.59ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > symlink inside a trusted root cannot escape to another host file [0.55ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > no file_id + path does NOT exist → not_found error [0.52ms]
(pass) resolveAttachmentToLocalPath — trusted local path fallback (single-host / feishu compat) > no file_id AND no path → no_file_id_no_path error [0.31ms]
(pass) resolveAttachmentToLocalPath — cache hit > same file_id + same size → no HTTP call, returns cached:true [0.49ms]
(pass) resolveAttachmentToLocalPath — cache hit > same file_id + different size → cache miss, re-fetches [4.90ms]
(pass) sweepAttachmentCacheOnce > purges files older than TTL, keeps fresh [0.99ms]
(pass) sweepAttachmentCacheOnce > no-op when cache dir doesn't exist [0.29ms]

src/runtime/readable-attachment-prompt.test.ts:
(pass) readable attachment prompt > pins the exact runtime set without changing structured-image SDK lanes [0.13ms]
(pass) readable attachment prompt > pins the readable extension allowlist as an exact value set [0.34ms]
(pass) readable attachment prompt > injects absolute deduplicated paths and escapes control characters [0.37ms]
(pass) readable attachment prompt > leaves text byte-identical when no attachment resolved [0.03ms]
(pass) readable attachment prompt > path-prompt runtimes reject sender-local paths while structured lanes retain legacy behavior [0.23ms]
(pass) readable attachment prompt > the inbox choke point feeds the augmented text into processTask [1.60ms]

src/runtime/create-node-daemon.test.ts:
(pass) #633 daemon private state > global config repair and replacement converge to private state [3.55ms]
(pass) #633 daemon private state > global config read refuses a symlink without touching its target [0.96ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > permissionMode enum [0.35ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > dangerouslySkipPermissions boolean (string 'true' must be rejected) [0.11ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > maxTurns integer range — 'DROP TABLE' / float / out-of-range rejected [0.21ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > budget number with decimals allowed; out-of-range rejected [0.27ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > timeout integer range [0.19ms]
(pass) §4.2.2 daemon-side flag VALUE validator (BLOCKER #2 — defense in depth) > unknown key rejected [0.10ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > happy path with mixed flags [0.45ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > smuggled string maxTurns rejected by daemon even if hub missed [0.23ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > smuggled string dangerouslySkipPermissions rejected [0.13ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > name shell-metachar still rejected (existing validateName, F2) [0.10ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > runtime enum still enforced [0.08ms]
(pass) buildAnetArgsDaemon now reaches flag value validation > channels non-empty rejected (P1 fail-closed) [0.09ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > happy path with hash witness [0.96ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: no ANET_BIN_ABS at all [0.14ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: relative path [0.12ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: symlink (contains symlink component) [0.57ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: world-writable (mode 0o777) [0.41ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: group-writable (mode 0o775) [0.37ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: not executable (mode 0o644) [0.42ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: owner not root (no opt-out) [0.43ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > ACCEPT: owner not root WHEN ANET_DAEMON_ALLOW_NON_ROOT_BIN=1 (explicit opt-out) [0.37ms]
(pass) §4.2.6 B2 loadAndVerifyAnetBin — install-time pin 5-check (BLOCKER #3 hardened) > REJECT: sha256 mismatch with install witness [0.48ms]
(pass) minimalEnv defensive compose (BLOCKER #1+#2 lineage — kept stable) > happy path: no extra → PATH includes daemon's own node bin dir + SAFE_PATH (issue #301 nvm fix) [0.39ms]
(pass) minimalEnv defensive compose (BLOCKER #1+#2 lineage — kept stable) > legitimate extra key passes + fixed PATH keeps execPath prepend (issue #301) [0.17ms]
(pass) minimalEnv defensive compose (BLOCKER #1+#2 lineage — kept stable) > THROWS on reserved key in extra (LD_PRELOAD smuggled by attacker) [0.19ms]
(pass) minimalEnv defensive compose (BLOCKER #1+#2 lineage — kept stable) > THROWS on fixed key in extra (PATH smuggled — caller cannot override the trust-root execPath prepend) [0.09ms]
(pass) minimalEnv defensive compose (BLOCKER #1+#2 lineage — kept stable) > C1 invariant — issue #301 fix does NOT widen attacker surface: PATH source is process.execPath (daemon's already-resolved node), NOT env.PATH (attacker C1 surface) [0.31ms]
(pass) FAIL_FAST_MS primitive — real subprocess kill-0 lifecycle > child that exits within window → process.kill(pid, 0) raises ESRCH after wait [501.78ms]
(pass) FAIL_FAST_MS primitive — real subprocess kill-0 lifecycle > child that survives window → process.kill(pid, 0) succeeds [202.99ms]
(pass) RFC-027 BLOCKER-1 — childrenMap key shape matches hub canonical node_id > derive key from request_id, not alias [0.20ms]
(pass) RFC-027 BLOCKER-1 — childrenMap key shape matches hub canonical node_id > recordSpawnedChild end-to-end with the canonical key — stop-daemon can find it [8.35ms]

src/runtime/claude-native-binary.test.ts:
(pass) Claude native binary version pin > uses a directly exported package manifest when available [0.55ms]
(pass) Claude native binary version pin > walks from the resolved entrypoint when package exports hide package.json [0.38ms]
(pass) Claude native binary version pin > fails closed instead of installing latest when the SDK cannot be attested [0.17ms]
(pass) Claude native binary version pin > missing-binary fallback invokes npm with the installed SDK exact version [0.27ms]

src/runtime/stop-daemon.test.ts:
(pass) recordSpawnedChild + map shape > records + snapshot returns entry [0.45ms]
(pass) recordSpawnedChild + map shape > re-record overwrites pid [0.17ms]
(pass) handleStopDoorbell — noop_not_my_child > unknown child_node_id → degraded ack (not error) [1.44ms]
/bin/sh: 1: pgrep: not found
(pass) handleStopDoorbell — happy stop (SIGTERM-reaped quickly) > child reaped after SIGTERM → ack stopped + SIGTERM signal recorded [4.99ms]
/bin/sh: 1: pgrep: not found
(pass) handleStopDoorbell — SIGKILL escalation > child ignores SIGTERM → grace exceeded → SIGKILL → ack stopped w/ SIGKILL [35.29ms]
/bin/sh: 1: pgrep: not found
(pass) handleStopDoorbell — delete action with delete_config > mv child workdir to ~/.anet/deleted/<ts>-<alias>/ + chmod 700 + ack backup_path [3.02ms]
/bin/sh: 1: pgrep: not found
(pass) handleStopDoorbell — delete action with delete_config > delete_config=false → no backup dir, no source move [2.28ms]
(pass) handleStopDoorbell — real subprocess primitive (no mocks) > real subprocess: SIGTERM kills + kill-0 ESRCH after [304.82ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > happy: hub returns 2 children + each has unique matching pid → both recovered [1.94ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > alias substring collision: pgrep finds 'bot2' for alias 'bot' but cmdline argv exact-match rejects [0.74ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > zombie pid skipped (state=Z) [0.55ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > ambiguous: multiple verified pids → skipped (operator intervention) [0.60ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > hub-active but pgrep finds nothing → missing (warn, don't auto-nudge) [0.49ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > daemon's own pid is excluded from candidates [0.45ms]
(pass) rebuildChildrenMapOnBoot (RFC-027 PR1.1) > list_my_children failure → safe empty result (no throw, no map mutation) [0.42ms]
(pass) rebuildChildrenMapOnBoot — real subprocess primitive (no pgrep mocks, no proc mocks) > matcher accepts a real subprocess whose argv contains --alias <token> [203.09ms]

src/runtime/claude-error-classify.test.ts:
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > HTTP 429 standalone [0.31ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > HTTP 529 overloaded (Anthropic spec) [0.04ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > rate_limit_exceeded (Anthropic / OpenAI shape) [0.02ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > rate-limit hyphen variant [0.02ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > rate limit space variant [0.02ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > quota exceeded phrase [0.02ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > quota exhausted phrase [0.02ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > Anthropic spec overloaded_error [0.04ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > plain overloaded mention [0.04ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > too_many_requests OpenAI-compat [0.03ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > too many requests space form [0.04ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > insufficient_quota OpenAI shape [0.03ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > usage_limit hit [0.03ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > MiniMax Chinese Token Plan 上限 [0.15ms]
(pass) isRateLimitOrQuotaError — POSITIVE (must classify as quota/rate-limit) > capacity exceeded vendor message [0.03ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > 401 unauthorized (auth, not quota) [0.03ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > 403 forbidden (auth, not quota) [0.02ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > plain timeout (not quota) [0.02ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > 400 bad request (not quota) [0.02ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > 499 client closed (not quota) [0.04ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > ETIMEDOUT network error (not quota) [0.04ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > HTTP 4290 not a real status (avoid false positive on substring) [0.03ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > empty string [0.03ms]
(pass) isRateLimitOrQuotaError — NEGATIVE (regression gate, must NOT match) > null / undefined [0.04ms]
(pass) isEmptyResultSoftFailure — POSITIVE (must flag as empty-vendor-reply) > result null + output_tokens 0 [0.10ms]
(pass) isEmptyResultSoftFailure — POSITIVE (must flag as empty-vendor-reply) > result undefined (M3 incident shape) [0.04ms]
(pass) isEmptyResultSoftFailure — POSITIVE (must flag as empty-vendor-reply) > result empty string but usage non-zero [0.04ms]
(pass) isEmptyResultSoftFailure — POSITIVE (must flag as empty-vendor-reply) > result has text but output_tokens 0 (suspicious) [0.04ms]
(pass) isEmptyResultSoftFailure — POSITIVE (must flag as empty-vendor-reply) > usage missing entirely (defaulting to 1 = non-zero) but result empty [0.04ms]
(pass) isEmptyResultSoftFailure — NEGATIVE (regression gate, normal success) > normal success — result + non-zero tokens [0.10ms]
(pass) isEmptyResultSoftFailure — NEGATIVE (regression gate, normal success) > short single-char reply still counts as success [0.04ms]
(pass) isEmptyResultSoftFailure — NEGATIVE (regression gate, normal success) > usage entirely missing but result non-empty [0.04ms]
(pass) quotaRemediationHint — vendor URL routing > intern-ai routing [0.16ms]
(pass) quotaRemediationHint — vendor URL routing > minimax routing [0.05ms]
(pass) quotaRemediationHint — vendor URL routing > deepseek routing [0.06ms]
(pass) quotaRemediationHint — vendor URL routing > anthropic-native routing [0.05ms]
(pass) quotaRemediationHint — vendor URL routing > unknown vendor falls back to generic hint [0.06ms]
(pass) quotaRemediationHint — vendor URL routing > empty / undefined → generic [0.04ms]

src/runtime/grok-build-cli.test.ts:
(pass) buildGrokCliArgs > rejects an older Grok CLI before it can ignore required safety flags [0.47ms]
(pass) buildGrokCliArgs > uses streaming headless mode and resumes an existing session [0.31ms]
(pass) buildGrokCliArgs > fails closed instead of auto-approving when permission bypass is disabled [0.15ms]
(pass) buildGrokCliArgs > maps an explicit node tool allowlist and keeps MCP unavailable [0.20ms]
(pass) buildGrokCliArgs > intersects explicit tools with the read-only set when auto-approval is off [0.12ms]
(pass) buildGrokCliArgs > rejects unknown node tool names instead of silently widening access [0.10ms]
(pass) buildGrokCliArgs > rejects an explicit empty tool allowlist instead of widening to all tools [0.10ms]
(pass) buildGrokCliArgs > denies model reads of runtime credential and node-state paths [0.08ms]
(pass) runGrokCliTurn > reports spawn submission before first exact JSONL event consumption [73.29ms]
(pass) runGrokCliTurn > reduces streaming JSON text and persists the end-event session [46.29ms]
(pass) runGrokCliTurn > spawns with exactly the projected environment and no ambient credentials [49.68ms]
(pass) runGrokCliTurn > keeps the production-shaped setpriv/sh launcher on the exact PWD-bound env [58.22ms]
(pass) runGrokCliTurn > refuses a shell launcher when PWD is missing from the reviewed env [1.00ms]
(pass) runGrokCliTurn > removes the prompt when spawn rejects a malformed allowed env value [1.68ms]
(pass) runGrokCliTurn > surfaces non-zero exits and stderr [45.38ms]
(pass) runGrokCliTurn > fails fast when headless Grok asks for an interactive login [44.83ms]
(pass) runGrokCliTurn > rejects cancelled turns [45.24ms]
(pass) runGrokCliTurn > rejects a formal error event even if the process exits zero [49.91ms]
(pass) runGrokCliTurn > rejects max-turn truncation instead of reporting a partial reply as success [47.61ms]
(pass) runGrokCliTurn > terminates the process group when the caller aborts [37.46ms]
(pass) runGrokCliTurn > kills a silent child after the idle timeout [38.18ms]
(pass) assertUnprivilegedUserNsUsable (#grok userns preflight) > passes when the probe succeeds [0.38ms]
(pass) assertUnprivilegedUserNsUsable (#grok userns preflight) > throws with the real stderr and an actionable next step when uid_map is refused [0.17ms]
(pass) assertUnprivilegedUserNsUsable (#grok userns preflight) > still throws when the probe fails with no stderr at all [0.29ms]
(pass) assertUnprivilegedUserNsUsable (#grok userns preflight) > honours a custom unshare binary path [0.10ms]

src/runtime/grok-child-env.test.ts:
(pass) Grok child environment boundary > builds the exact reviewed key set and drops every unreviewed credential [1.76ms]
(pass) Grok child environment boundary > re-projects a beforeSpawn result instead of trusting arbitrary keys [0.18ms]
(pass) Grok child environment boundary > rejects a beforeSpawn callback that changes a controlled value [1.41ms]
(pass) Grok child environment boundary > keeps the inherited list exact and reviewable [0.07ms]
(pass) Grok child environment boundary > keeps PTY PWD equal and adds only reviewed terminal/sandbox controls [0.61ms]
(pass) Grok child environment boundary > builds the narrower helper environment from an empty object [0.24ms]

src/runtime/node-id-source.test.ts:
(pass) resolveNodeIdSource > configured identity wins over a polluted supervisor env [0.45ms]
(pass) resolveNodeIdSource > matching launcher env is accepted without a warning [0.11ms]
(pass) resolveNodeIdSource > legacy config without node_id keeps the env fallback [0.05ms]
(pass) resolveNodeIdSource > missing identity remains empty [0.04ms]
(pass) resolveNodeIdSource > warning escapes control characters from inherited env [0.11ms]

src/runtime/inbox-drain-lane.test.ts:
(pass) inbox drain lanes > an informational lane drains while the work lane is busy [0.45ms]
(pass) inbox drain lanes > each lane remains serial [0.32ms]
(pass) inbox drain lanes > repeated wakeups for the same drain coalesce into one dirty rerun [0.39ms]
(pass) inbox drain lanes > a failed drain is reported and does not poison later retries [0.39ms]
(pass) inbox drain lanes > retry mode backs off and eventually completes the same drain [3.42ms]
(pass) inbox drain lanes > one failed inbox item does not starve later items in the same snapshot [3.03ms]
(pass) inbox drain lanes > ack-only retry does not duplicate the first notification or delay the second [1.51ms]

src/runtime/codex-app-server-client.test.ts:
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > reverse request (method + id) routes to `reverse_request`, NOT orphan_response [16.69ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > reverse request also fires `reverse:<method>` targeted event [10.62ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > notification (method + no id) routes to method-keyed event [8.60ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > response (id + result) resolves the matching pending request [11.02ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > response (id + error) rejects with codex-formatted Error [9.19ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > orphan response (id present, no matching pending) fires `orphan_response` [10.62ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > malformed messages fire `malformed` [8.57ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > parse errors on non-JSON payload fire `parse_error` [10.29ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > request timeout rejects the pending promise and cleans up the entry [45.06ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > close rejects any in-flight request cleanly (no unhandled rejection) [3.73ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > respondToReverseRequest emits a well-formed response envelope [12.65ms]
(pass) CodexAppServerClient — dispatch correctness (RFC-030 §7 + bug fix) > errorReverseRequest emits a JSON-RPC error envelope [10.43ms]
(pass) CodexAppServerClient — dead shared endpoint diagnostics (#455) > wraps an empty TypeError with endpoint and remediation [0.70ms]
(pass) CodexAppServerClient — dead shared endpoint diagnostics (#455) > scrubs nested causes and bearer credentials independently of runtime shape [0.26ms]
(pass) CodexAppServerClient — dead shared endpoint diagnostics (#455) > synchronous WebSocket constructor failure uses the same safe boundary [0.45ms]
(pass) CodexAppServerClient — dead shared endpoint diagnostics (#455) > real dead loopback with query credential rejects/emits without leaking it [1.10ms]

src/runtime/delegation-precheck.test.ts:
(pass) delegationTargetExists > imperative happy path — real other session is found [0.22ms]
(pass) delegationTargetExists > #230 — descriptive-text false positive no longer self-reflects [0.10ms]
(pass) delegationTargetExists > self-only match — only the calling node has this alias [0.07ms]
(pass) delegationTargetExists > typo alias — caller meant a real agent but mistyped [0.07ms]
(pass) delegationTargetExists > empty sessions array → empty_sessions [0.05ms]
(pass) delegationTargetExists > missing sessions field (caller did not destructure correctly) → no_sessions_field [0.06ms]
(pass) delegationTargetExists > empty target alias is defensively reported as not_in_sessions [0.04ms]
(pass) delegationTargetExists > whitespace padding is trimmed before comparison [0.05ms]
(pass) delegationTargetExists > sessions with missing / non-string alias fields are skipped without throwing [0.05ms]

src/runtime/classify-result.test.ts:
(pass) classifyRuntimeResult — error precedence > quota error msg → soft-fail-quota (highest precedence) [1.36ms]
(pass) classifyRuntimeResult — error precedence > non-quota error → hard error [0.06ms]
(pass) classifyRuntimeResult — error precedence > auth error msg (401) → hard error (NOT quota — auth has its own path) [0.04ms]
(pass) classifyRuntimeResult — error precedence > error msg outranks empty result (don't double-classify) [0.04ms]
(pass) classifyRuntimeResult — in=0 & out=0 & cost=0 silent reject > all three zero → soft-fail-empty (even when result text present) [0.06ms]
(pass) classifyRuntimeResult — in=0 & out=0 & cost=0 silent reject > in=0 & out=0 but cost field MISSING + non-empty result → success (codex usage unreliable) [0.05ms]
(pass) classifyRuntimeResult — in=0 & out=0 & cost=0 silent reject > in=0 & cost=0 but out>0 → NOT silent reject (vendor returned something) [0.06ms]
(pass) classifyRuntimeResult — in=0 & out=0 & cost=0 silent reject > normal turn (all signals positive) → success [0.04ms]
(pass) classifyRuntimeResult — in=0 & out=0 & cost=0 silent reject > non-empty result + output_tokens=0 + cost missing → success (codex false-positive guard) [0.05ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > empty string result + non-zero tokens → soft-fail-empty [0.04ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > null result + non-zero tokens → soft-fail-empty [0.04ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > undefined result, missing usage → soft-fail-empty (empty result alone is enough) [0.03ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > single-char '0' result + tokens → success (not empty) [0.03ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > result text present + missing usage → success (don't penalise unreported usage) [0.03ms]
(pass) classifyRuntimeResult — empty-result rule (strict) > empty string result + cost present + tokens → soft-fail-empty (text emptiness is the signal) [0.05ms]
(pass) classifyRuntimeResult — vendor hint routing via baseUrl > quota error with deepseek baseUrl → deepseek dashboard hint [0.05ms]
(pass) classifyRuntimeResult — vendor hint routing via baseUrl > quota error with intern baseUrl → intern hint [0.07ms]
(pass) classifyRuntimeResult — vendor hint routing via baseUrl > empty result with anthropic baseUrl → anthropic hint [0.08ms]
(pass) classifyRuntimeResult — vendor hint routing via baseUrl > missing baseUrl → generic hint [0.05ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > soft-fail-quota → 执行出错: [额度用尽][<code>] <runtime>: <body> — <hint> [0.52ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > soft-fail-empty → 执行出错: <runtime> 返回空响应 with in/out [0.10ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > error kind → 执行出错: <runtime> — <reason> [0.05ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > success kind → empty string (caller should not call this; defensive) [0.04ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > missing usage in context → in=0 out=0 fallback [0.04ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > missing hint on quota → no trailing dash artifact [0.11ms]
(pass) formatClassificationError — message shape (parsed by IM bridge) > reason longer than 80 chars is truncated on quota path [0.08ms]

src/runtime/codex-app-server-bridge.test.ts:
(pass) CodexAppServerBridge — bootstrap + task mapping > bootstrap sends initialize + initialized + thread/resume in order [6.06ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > empty threadId → bootstrap creates a thread (thread/start) and adopts its id [6.92ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > stale threadId with no rollout → resume fails, bootstrap falls back to thread/start [7.70ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > startTaskTurn returns the server-assigned turnId and marks bridge working [3.44ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > turn/completed for OUR turn fires task_reply mapped back to the task_id [15.83ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > only exact owned-turn item events emit task_activity [15.95ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > authenticated Dashboard native /goal text reaches the shared thread unchanged and replies [16.98ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > clientUserMessageId rebinds a task when a goal successor replaces the turn/start response id [53.67ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > client-id ownership observed before the RPC response wins without reversing task event order [28.71ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > real bridge + runtime bounds a deferred terminal when exact client identity never arrives [37.60ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > real bridge + runtime bounds an unresolved turn/start through the left-FIFO fallback [64.08ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > agentMessage/delta accumulates when server omits finalText [14.62ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > turn/completed for a HUMAN-TUI-initiated turn is dropped (§7.5) [17.50ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > events for a DIFFERENT thread are dropped (defense in depth) [16.45ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > startTaskTurn refuses a second task while one is active [4.58ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > turn/completed with an error field fires task_error, NOT task_reply [14.10ms]
(pass) CodexAppServerBridge — bootstrap + task mapping > turn/completed with interrupted status cannot become a successful reply [16.59ms]
(pass) CodexAppServerBridge — approvals (waiting_human) §7.6 > reverse-request approval records waiting_human and sends NO response [16.85ms]
(pass) CodexAppServerBridge — approvals (waiting_human) §7.6 > serverRequest/resolved clears waiting_human and status recovers [28.50ms]
(pass) CodexAppServerBridge — approvals (waiting_human) §7.6 > multiple concurrent approvals: bridge stays waiting_human until all resolve [38.39ms]
(pass) CodexAppServerBridge — two-client race for idle > only one bridge wins turn/start; the other observes and does not reply [23.35ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > reconnect recovers an active human turn and keeps it steerable [5.25ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > reconnect provenance keeps an orphaned network turn FIFO-only [25.24ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > reconnect provenance ignores leading whitespace before the network prefix [7.33ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > reconnect stays FIFO-only when real-wire active history omits userMessage [3.33ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > uses exact turn/steer contract and maps the human turn final answer [28.49ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > multiple Dashboard rows steer one human turn while ordinary agent work stays queued [39.04ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > steer mismatch fails closed and preserves the task in the normal FIFO [38.88ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > turn completion cannot attribute a task before turn/steer acceptance [40.30ms]
(pass) CodexAppServerBridge — authenticated Dashboard steering > reconciliation recovers a missed human turn completion and exact steered reply [17.98ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > concurrent startTaskTurn: exactly ONE turn/start reaches the server even with a slow response [57.99ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > submitTask queues the second task and drains it after turn/completed (order preserved) [118.09ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > cancelQueuedTask removes only the named FIFO row before it can execute [59.53ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > thread/read recovers a completed owned turn while a successor keeps the thread active [107.94ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > thread/read uses clientUserMessageId to recover a replacement turn when all live item events were lost [5.63ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > slow full-history fallback recovers when both terminal and successor notifications are lost [4.47ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > full history never attributes a different completed turn to the owned task [4.79ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > thread/read never recovers an interrupted turn as success [4.90ms]
(pass) CodexAppServerBridge — sync claim + FIFO queue (通信龙) > drain losing the idle race requeues at the FRONT and retries on next idle [168.64ms]

src/runtime/probe-daemon.test.ts:
(pass) createPinnedLookup — Node/Bun lookup callback contract > single-address callback honors requested family [0.72ms]
(pass) createPinnedLookup — Node/Bun lookup callback contract > all-address callback returns only pinned copies [0.21ms]
(pass) createPinnedLookup — Node/Bun lookup callback contract > wrong hostname and unavailable family fail closed without fallback [0.44ms]
(pass) assertSecureTlsEnv (boot guard) > clean env passes [0.11ms]
(pass) assertSecureTlsEnv (boot guard) > NODE_TLS_REJECT_UNAUTHORIZED=0 throws [0.14ms]
(pass) classifyProbeResponse — status enum mapping > 200 → ok [0.14ms]
(pass) classifyProbeResponse — status enum mapping > 401 → auth_fail [0.04ms]
(pass) classifyProbeResponse — status enum mapping > 403 → auth_fail [0.03ms]
(pass) classifyProbeResponse — status enum mapping > 429 → quota [0.02ms]
(pass) classifyProbeResponse — status enum mapping > 500 → vendor_5xx [0.03ms]
(pass) classifyProbeResponse — status enum mapping > 404 → other_4xx [0.03ms]
(pass) classifyProbeResponse — status enum mapping > errorKind=redirect_forbidden surfaces directly [0.03ms]
(pass) classifyProbeResponse — status enum mapping > errorKind=timeout surfaces [0.03ms]
(pass) classifyProbeResponse — status enum mapping > errorKind=probe_resolve_unsafe_ip → returned status string passes through [0.03ms]
(pass) classifyProbeResponse — status enum mapping > ack has NO error_message / response_body / url fields (zod whitelist on hub side will reject; we just don't include) [0.07ms]
(pass) safelyFetchProbe — SSRF guards (per 通信龙 spot-check c) > base_url with private IP literal (169.254.169.254) → probe_resolve_unsafe_ip [1.88ms]
(pass) safelyFetchProbe — SSRF guards (per 通信龙 spot-check c) > base_url with private IP literal (10.0.0.1) → probe_resolve_unsafe_ip [0.20ms]
(pass) safelyFetchProbe — SSRF guards (per 通信龙 spot-check c) > base_url with localhost without ALLOW_LOOPBACK env → probe_resolve_unsafe_ip [0.18ms]
(pass) safelyFetchProbe — SSRF guards (per 通信龙 spot-check c) > base_url with localhost WITH ALLOW_LOOPBACK env → permitted to proceed (will fail on real network but not on IP guard) [5.22ms]
(pass) safelyFetchProbe — SSRF guards (per 通信龙 spot-check c) > NODE_TLS_REJECT_UNAUTHORIZED=0 → tls_error before any fetch [0.13ms]
(pass) handleProbeDoorbell — daemon validateBaseUrl re-check (compromised-hub defense) > non-allowlist host for anthropic → daemon-level reject + ack probe_target_forbidden, no fetch [1.11ms]
(pass) handleProbeDoorbell — daemon validateBaseUrl re-check (compromised-hub defense) > unknown vendor → daemon rejects, ack probe_target_forbidden [0.23ms]
(pass) handleProbeDoorbell — daemon validateBaseUrl re-check (compromised-hub defense) > bad URL (not parseable) → daemon rejects, ack probe_target_forbidden [0.25ms]
(pass) handleProbeDoorbell — daemon validateBaseUrl re-check (compromised-hub defense) > plain HTTP scheme on non-loopback host → daemon rejects, ack probe_target_forbidden [0.18ms]
(pass) handleProbeDoorbell — daemon validateBaseUrl re-check (compromised-hub defense) > get_probe_request returns ok:false → no ack pushed (hub sweeper handles) [0.23ms]

src/runtime/current-alias.test.ts:
(pass) CurrentAliasResolver — startup snapshot > current() returns the initial alias before any refresh() [0.19ms]
(pass) CurrentAliasResolver — startup snapshot > ageMs() reports Infinity before first fetch (cache is cold) [0.17ms]
(pass) CurrentAliasResolver — refresh() cache behaviour > warm cache short-circuits — no fetch fired within TTL [0.60ms]
(pass) CurrentAliasResolver — refresh() cache behaviour > expired cache hits the server and updates the alias + fires onDrift [0.37ms]
(pass) CurrentAliasResolver — refresh() cache behaviour > concurrent refresh() calls dedupe onto one fetch [10.52ms]
(pass) CurrentAliasResolver — graceful fetch failure > fetch throwing keeps the cached value and emits a warn [0.51ms]
(pass) CurrentAliasResolver — graceful fetch failure > fetch returning null is treated as 'server does not know yet' [0.18ms]
(pass) CurrentAliasResolver — graceful fetch failure > fetch returning empty string is also treated as 'server does not know' [0.25ms]
(pass) CurrentAliasResolver — graceful fetch failure > after a failed fetch the cache timestamp still bumps — no hammering [0.28ms]
(pass) CurrentAliasResolver — set() force install > set() updates the alias and fires onDrift with source 'snapshot' [0.24ms]
(pass) CurrentAliasResolver — set() force install > set() with the same value is a no-op (no drift event, but cache timestamp bumps) [0.07ms]
(pass) CurrentAliasResolver — set() force install > set('') is ignored (defends against caller forgetting to validate) [0.05ms]
(pass) CurrentAliasResolver — edge cases > nodeId = null short-circuits refresh() and never calls the fetch hook [0.18ms]
(pass) CurrentAliasResolver — edge cases > cacheTtlMs = 0 disables caching — every refresh() fetches [0.20ms]
(pass) CurrentAliasResolver — edge cases > ageMs() reflects elapsed time after a refresh [0.19ms]

src/runtime/feishu-outbound-dir.test.ts:
(pass) Feishu legacy outbound directory > prefers the canonical worker value verbatim [0.17ms]
(pass) Feishu legacy outbound directory > reconstructs a legacy envelope from the explicit channel binding [0.12ms]
(pass) Feishu legacy outbound directory > does not consult a stale ambient node alias [0.14ms]
(pass) Feishu legacy outbound directory > passes the same explicit binding name to the worker [0.11ms]

src/runtime/deleted-sweeper.test.ts:
(pass) RFC-027 §5.2 K — sweeper purges 30d+ backups (physical delete, no soft state) > backup older than RETENTION_MS → physically removed [1.80ms]
(pass) RFC-027 §5.2 K — sweeper purges 30d+ backups (physical delete, no soft state) > backup younger than 30d → KEPT [0.65ms]
(pass) RFC-027 §5.2 K — sweeper purges 30d+ backups (physical delete, no soft state) > mixed: 2 old + 1 recent → only the 2 olds purged [1.14ms]
(pass) sweeper safety invariants (D7 nit) > skips dir names that don't match <ts>-<alias> pattern (no accidental purge) [0.61ms]
(pass) sweeper safety invariants (D7 nit) > log function receives ONLY the dir name — never any inner file path [0.63ms]
(pass) sweeper safety invariants (D7 nit) > dir-listing error (deletedRoot missing) → returns clean empty result, no throw [0.52ms]
[deleted-sweeper] failed to purge 1783998481024-bad: simulated EACCES
(pass) sweeper safety invariants (D7 nit) > rmDir throw → counted as error, sweep continues for siblings [0.91ms]

src/runtime/config-apply.test.ts:
(pass) RESTART_SENTINEL — exact value pin > equals 75 (BSD EX_TEMPFAIL semantics, parent supervisor checks this exact code) [0.32ms]
(pass) #633 private text writer > replaces a leaf symlink without following it [2.48ms]
(pass) validateLocalPatch — defense-in-depth > undefined model + empty flags passes (no-op patch) [0.43ms]
(pass) validateLocalPatch — defense-in-depth > valid full patch passes [0.20ms]
(pass) validateLocalPatch — defense-in-depth > unknown flag rejected (even if hub validator drifts loose) [0.15ms]
(pass) validateLocalPatch — defense-in-depth > permissionMode invalid enum rejected [0.14ms]
(pass) validateLocalPatch — defense-in-depth > dangerouslySkipPermissions non-boolean rejected [0.16ms]
(pass) validateLocalPatch — defense-in-depth > maxTurns out of range rejected [0.19ms]
(pass) validateLocalPatch — defense-in-depth > timeout invalid rejected [0.14ms]
(pass) validateLocalPatch — defense-in-depth > empty-string model rejected [0.16ms]
(pass) computeApplyMode — tier classifier > empty patch → restart_only (restart_node) [0.21ms]
(pass) computeApplyMode — tier classifier > model only → restart [0.13ms]
(pass) computeApplyMode — tier classifier > permissionMode → restart [0.12ms]
(pass) computeApplyMode — tier classifier > dangerouslySkipPermissions → restart [0.15ms]
(pass) computeApplyMode — tier classifier > teammateMode no longer in allowlist → ignored by classifier (returns hot since no restart-required flag matches) [0.18ms]
(pass) computeApplyMode — tier classifier > timeout → restart [0.21ms]
(pass) computeApplyMode — tier classifier > maxTurns only → hot [0.18ms]
(pass) computeApplyMode — tier classifier > budget only → hot [0.18ms]
(pass) computeApplyMode — tier classifier > mixed (model + maxTurns) → restart (strictest wins) [0.17ms]
(pass) atomicWriteJson — temp + rename > creates file with JSON content + trailing newline [2.37ms]
(pass) atomicWriteJson — temp + rename > overwrites existing file atomically (no .tmp left behind) [2.25ms]
(pass) #472 private config permissions > atomic write is 0600 under umask 0 [3.40ms]
(pass) #472 private config permissions > atomic write is 0600 under umask 2 [2.27ms]
(pass) #472 private config permissions > atomic write is 0600 under umask 22 [2.20ms]
(pass) #472 private config permissions > atomic write is 0600 under umask 77 [2.30ms]
(pass) #472 private config permissions > repairs existing primary, backup, and parent before token read [0.95ms]
(pass) #472 private config permissions > custom --config parent is never chmodded [0.54ms]
(pass) #472 private config permissions > atomic custom --config write preserves parent mode [2.09ms]
(pass) #472 private config permissions > backup atomically replaces a legacy broad .prev [2.20ms]
(pass) backupConfigPrev — pre-write snapshot > copies existing config to .prev [2.24ms]
(pass) backupConfigPrev — pre-write snapshot > returns backedUp=false when no config exists yet (first-write case) [0.30ms]
(pass) backupConfigPrev — pre-write snapshot > overwrites previous .prev (single-generation rotation) [4.01ms]
(pass) loadConfigWithSelfHeal — boot recovery > primary parses → returns primary [0.53ms]
(pass) loadConfigWithSelfHeal — boot recovery > primary corrupted + .prev valid → restores .prev + reports source=prev [2.31ms]
(pass) loadConfigWithSelfHeal — boot recovery > primary corrupted + no .prev → throws (truly bricked, caller surfaces) [0.64ms]
(pass) loadConfigWithSelfHeal — boot recovery > primary AND .prev corrupted → throws with both errors [0.49ms]
(pass) loadConfigWithSelfHeal — boot recovery > primary missing entirely → throws (caller will skip / first-boot path) [0.27ms]
(pass) mergePatch — patch + existing → new config (no mutation) > model replace [0.41ms]
(pass) mergePatch — patch + existing → new config (no mutation) > flags merge (does not replace whole flags obj) [0.23ms]
(pass) mergePatch — patch + existing → new config (no mutation) > empty existing + patch → patch only [0.21ms]
(pass) mergePatch — patch + existing → new config (no mutation) > empty patch → existing unchanged (deep clone) [0.23ms]
(pass) buildConfigSnapshot — pure helper contract (#290 final, drain-omit guard) > buildConfigSnapshot returns a valid snapshot regardless of caller drain state (pure) [0.53ms]
(pass) validateLocalPatch — teammateMode dropped (#290 review) > teammateMode rejected (was: allowed boolean; now: not-in-allowlist) [0.25ms]
(pass) computeApplyMode — teammateMode is no longer restart-required (#290 review) > teammateMode-only patch → hot (no longer in RESTART_REQUIRED_FLAGS) [0.18ms]
(pass) buildConfigSnapshot — masked report (no secrets) > includes model + ALLOWED_FLAGS only [0.32ms]
(pass) buildConfigSnapshot — masked report (no secrets) > missing model → null (not undefined, dashboard renders explicitly) [0.20ms]
(pass) buildConfigSnapshot — masked report (no secrets) > config_update_capable=false signals bare node (no supervisor wrapper) [0.18ms]
(pass) buildConfigSnapshot — role (PR1 #338) > role: host_supervisor passes through (string) [0.16ms]
(pass) buildConfigSnapshot — role (PR1 #338) > role: member passes through [0.16ms]
(pass) buildConfigSnapshot — role (PR1 #338) > role: missing → null (not undefined; dashboard distinguishes) [0.14ms]
(pass) buildConfigSnapshot — role (PR1 #338) > role: non-string narrowed to null (typeof guard) [0.20ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > nests runtimes_supported + allowed_secret_keys + max_concurrent_children [0.26ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > matches hub canonical path snap.daemon_capabilities.* — NOT at top level [0.24ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > partial declare: only runtimes_supported emits, others omitted [0.18ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > missing → daemon_capabilities undefined (regular non-daemon node) [0.16ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > typeof narrow: non-array runtimes_supported dropped silently [0.22ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > typeof narrow: array with non-string element dropped silently [0.19ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > typeof narrow: max_concurrent_children non-finite or non-positive dropped [0.27ms]
(pass) buildConfigSnapshot — daemon_capabilities (PR3 #338 nit ①) > partial valid + partial invalid: only valid fields included [0.23ms]
(pass) channels — validateLocalPatch > valid keys pass [0.30ms]
(pass) channels — validateLocalPatch > commhub rejected — not a fork target (cli.ts:673 UNSUPPORTED_CHANNEL guard) [0.21ms]
(pass) channels — validateLocalPatch > unknown channel key rejected (defense-in-depth vs hub drift) [0.21ms]
(pass) channels — validateLocalPatch > non-array rejected [0.27ms]
(pass) channels — validateLocalPatch > non-string element rejected [0.20ms]
(pass) channels — validateLocalPatch > more than 16 entries rejected [0.26ms]
(pass) channels — computeApplyMode > channels-present patch is restart-tier [0.21ms]
(pass) channels — computeApplyMode > channels: [] still a state change → restart [0.14ms]
(pass) channels — computeApplyMode > channels + hot flag upgrades to restart [0.15ms]
(pass) channels — computeApplyMode > model + channels → restart [0.17ms]
(pass) channels — computeApplyMode > empty patch → restart_only [0.15ms]
(pass) channels — mergePatch replaces, does not merge > channels absent in patch: existing.channels preserved [0.27ms]
(pass) channels — mergePatch replaces, does not merge > channels present: existing.channels REPLACED wholesale [0.33ms]
(pass) channels — mergePatch replaces, does not merge > channels: [] disables all editable channels [0.31ms]
(pass) channels — mergePatch replaces, does not merge > first-write case (existing has no channels key) [0.21ms]
(pass) channels — mergePatch replaces, does not merge > defensive clone — patch mutation does not leak into merged [0.20ms]
(pass) mergePatch — path-qualified specs preserved > bare-type patch preserves existing telegram:/abs/path [0.30ms]
(pass) mergePatch — path-qualified specs preserved > bare-type patch keeps both when both were path-qualified [0.19ms]
(pass) mergePatch — path-qualified specs preserved > bare-type patch adds new bare key when existing had no matching spec [0.18ms]
(pass) mergePatch — path-qualified specs preserved > disable-all still works — empty patch wipes even path-qualified specs [0.19ms]
(pass) mergePatch — path-qualified specs preserved > first-write no existing channels: bare types stay bare [0.16ms]
(pass) buildConfigSnapshot — always emits channels for content-match finalize > empty config emits channels=[] [0.26ms]
(pass) buildConfigSnapshot — always emits channels for content-match finalize > bare-type list emitted verbatim + sorted [0.22ms]
(pass) buildConfigSnapshot — always emits channels for content-match finalize > path-qualified specs collapse to bare type [0.19ms]
(pass) buildConfigSnapshot — always emits channels for content-match finalize > dupes deduped, unparseable dropped [0.17ms]
(pass) buildConfigSnapshot — always emits channels for content-match finalize > non-array channels field yields [] [0.18ms]

src/runtime/codex-dep-loader.test.ts:
(pass) loadCodexSdk > returns the imported module without installing when already present [1.26ms]
(pass) loadCodexSdk > auto-installs and retries when the first import fails [0.66ms]
(pass) loadCodexSdk > throws a friendly multi-line error when install fails — includes pasteable npm command + module path + both root causes [0.86ms]
(pass) loadCodexSdk > install succeeds but post-install import still fails → terminal error names the install-then-resolve mismatch [0.51ms]
(pass) loadCodexSdk > module dir with shell metacharacters is single-quoted in the recovery hint [0.47ms]

src/runtime/create-node-daemon-private-wiring.test.ts:
(pass) #633 daemon secret writers all use the private atomic choke point [0.31ms]

src/runtime/reply-routing.test.ts:
(pass) codex-app-server reply routing > dashboard/user sender that is not a session falls back to send_reply [0.65ms]
(pass) codex-app-server reply routing > agent sender with a real session keeps send_task wake path [0.21ms]
(pass) codex-app-server reply routing > missing task id does not create an unparented reply task [0.15ms]
(pass) codex-app-server reply routing > roster load failure fails closed to send_reply [0.28ms]
(pass) codex-app-server reply routing > short ttl cache avoids repeated roster fetches and refreshes after expiry [0.49ms]
(pass) codex-app-server reply routing > failed send_task replies keep the peer-visible failure marker and high priority [0.11ms]

src/runtime/grok-build-cli-home.test.ts:
(pass) prepareGrokCliHome > derives an opaque path segment and rejects dot identities [0.54ms]
(pass) prepareGrokCliHome > accepts only the pinned Grok regular-file copy of source agent_id [6.34ms]
(pass) prepareGrokCliHome > isolates config/trust, preserves a shared auth path, and creates stable sandbox profiles [2.35ms]
(pass) prepareGrokCliHome > refuses broad-mode or symlinked source auth without repairing it [1.44ms]
(pass) prepareGrokCliHome > repairs an existing Grok session store to owner-only modes [2.11ms]
(pass) prepareGrokCliHome > does not follow a symlink while repairing an existing session store [1.15ms]
(pass) prepareGrokCliHome > keeps the post-stop cleanup policy exact and reviewable [0.16ms]
(pass) prepareGrokCliHome > removes exact empty read-only project placeholders before resume without admitting executable sources [4.36ms]
(pass) prepareGrokCliHome > validates every exact project placeholder before unlinking any sibling [1.93ms]
(pass) prepareGrokCliHome > does not let a fatal project counterexample starve independent state containment [2.06ms]
(pass) prepareGrokCliHome > preserves nonempty, linked, wrong-mode, and wrong-type project counterexamples [4.13ms]
(pass) prepareGrokCliHome > preserves real project extension directories and still rejects executable contents on resume [1.89ms]
(pass) prepareGrokCliHome > removes only exact transient state and hardens retained post-stop state [5.85ms]
(pass) prepareGrokCliHome > hardens only the native lock derived from the exact leader socket [1.22ms]
(pass) prepareGrokCliHome > retains a non-empty leader log and rejects post-stop link attacks [2.28ms]
(pass) prepareGrokCliHome > refuses a non-empty exact sandbox placeholder [1.90ms]
(pass) prepareGrokCliHome > reclaims an empty mode-000 sandbox marker under a foreign pid without aborting [1.28ms]
(pass) prepareGrokCliHome > keeps a non-empty foreign sandbox marker unreadable so it fails closed [1.49ms]
(pass) prepareGrokCliHome > validates exact TUI process ids before mutation and refuses a placeholder symlink [1.51ms]
(pass) prepareGrokCliHome > enables the single TUI leader only for explicit copresence mode [14.69ms]
(pass) prepareGrokCliHome > admits only canonical owner-held commhub MCP artifacts [3.56ms]
(pass) prepareGrokCliHome > rejects a shared auth path covered by a required sandbox deny before state mutation [0.66ms]
(pass) prepareGrokCliHome > refuses to claim sandbox isolation when no deny target exists [0.88ms]
(pass) prepareGrokCliHome > rejects a source GROK_HOME reached through an ancestor symlink before state mutation [0.85ms]
(pass) prepareGrokCliHome > removes runtime-owned native hooks before every turn [1.37ms]
(pass) prepareGrokCliHome > unlinks a runtime-owned hook symlink without touching its external target [1.39ms]
(pass) prepareGrokCliHome > fails closed when a project native hook path exists [0.68ms]
(pass) prepareGrokCliHome > trusts only the exact canonical nested cwd and atomically replaces stale grants [2.86ms]
(pass) prepareGrokCliHome > rejects broad or symlinked folder-trust targets before writing trust state [1.13ms]
(pass) prepareGrokCliHome > refuses a planted trust-store symlink and leaves its target untouched [1.42ms]
(pass) prepareGrokCliHome > rejects every project executable source before granting folder trust [10.52ms]
(pass) prepareGrokCliHome > does not impose the shared-folder strict policy on legacy headless mode [2.45ms]
(pass) prepareGrokCliHome > rejects repo-root hooks from a nested cwd and dangling hook links [1.20ms]
(pass) prepareGrokCliHome > rejects a symlinked project .grok directory [0.70ms]
(pass) prepareGrokCliHome > rejects symlinked isolated homes and generated state without changing targets [1.69ms]
(pass) prepareGrokCliHome > rejects a state-home path escape before chmod, removal, or writes [1.15ms]
(pass) prepareGrokCliHome > requires a valid zero-hook inspect response [0.57ms]
(pass) prepareGrokCliHome > flocks the canonical project inode across symlink aliases and releases cleanly [119.70ms]
(pass) prepareGrokCliHome > gives the real flock holder only the exact helper environment [70.12ms]

src/goals/format.test.ts:
(pass) formatSelfLoopsBlock — empty / omit semantics > no goals + omitWhenEmpty=true (default) → empty string [0.21ms]
(pass) formatSelfLoopsBlock — empty / omit semantics > no goals + omitWhenEmpty=false → explicit '无活跃循环' block [0.13ms]
(pass) formatSelfLoopsBlock — empty / omit semantics > only terminal goals (cancelled/complete/failed) → empty (same as no goals) [0.24ms]
(pass) formatSelfLoopsBlock — content shape > single active goal: header + id8 + cadence + text [0.44ms]
(pass) formatSelfLoopsBlock — content shape > paused goals shown with status='paused' [0.13ms]
(pass) formatSelfLoopsBlock — content shape > mix active + paused + terminal → only active+paused appear [0.16ms]
(pass) formatSelfLoopsBlock — cron-lite cadence rendering > time_of_day cadence: '每天 09:00' [0.10ms]
(pass) formatSelfLoopsBlock — cron-lite cadence rendering > weekday cadence: 'mon/wed/fri 18:30' [0.11ms]
(pass) formatSelfLoopsBlock — cron-lite cadence rendering > new-format interval cadence renders same as legacy interval_ms [0.08ms]
(pass) formatSelfLoopsBlock — cap + truncation > more than maxGoals → truncates with '...' summary [0.35ms]
(pass) formatSelfLoopsBlock — cap + truncation > text is one-line truncated at 100 chars [0.10ms]
(pass) formatSelfLoopsBlock — cap + truncation > multi-line text is rendered as single line [0.34ms]
(pass) formatSelfLoopsBlock — relative time rendering > next_wake_at far in the future → ISO-shortened [0.14ms]
(pass) formatSelfLoopsBlock — relative time rendering > next_wake_at in past → '已到期' [0.13ms]
(pass) formatSelfLoopsBlock — relative time rendering > malformed ISO doesn't crash, falls back to raw [0.12ms]

src/goals/routing.test.ts:
(pass) shouldCreateScheduledGoal — Dashboard native slash pass-through > authenticated Dashboard /goal and /loop pass through for every agent-node runtime [0.21ms]
(pass) shouldCreateScheduledGoal — Dashboard native slash pass-through > authenticated Dashboard /agoal and /aloop always select the ANet scheduler [0.12ms]
(pass) shouldCreateScheduledGoal — Dashboard native slash pass-through > non-Dashboard traffic retains /goal and /loop during the compatibility window [0.11ms]
(pass) shouldCreateScheduledGoal — Dashboard native slash pass-through > near matches and slash text away from the start never select the scheduler [0.14ms]
(pass) appendLegacyScheduledGoalNotice > non-Dashboard /goal and /loop replies carry a deterministic migration notice [0.12ms]
(pass) appendLegacyScheduledGoalNotice > new namespaced commands, Dashboard pass-through, and near matches are not warned [0.05ms]
(pass) appendLegacyScheduledGoalNotice > the migration notice is first so the outer reply cap cannot truncate it [0.10ms]
(pass) Dashboard native slash migration notice > interval-shaped /goal and /loop replies explain that ANet scheduling moved to /aloop [0.85ms]
(pass) Dashboard native slash migration notice > ordinary native commands, namespaced commands, and non-Dashboard paths are untouched [0.11ms]
(pass) Dashboard native slash migration notice > the notice survives low-value filtering and the outer reply cap [0.20ms]
(pass) Dashboard native slash migration notice > failed native replies still surface the migration notice and the failure [0.08ms]
(pass) reply filtering uses authenticated message provenance > a short presence reply to an authenticated Dashboard human task is delivered [0.24ms]
(pass) reply filtering uses authenticated message provenance > the same low-value class remains filtered for agent-to-agent tasks [0.08ms]
(pass) reply filtering uses authenticated message provenance > a provenance flag cannot bypass filtering for a non-task message type [0.05ms]

src/goals/loops-http-server.test.ts:
(pass) localhost binding (通信龙 hard constraint #1+#2) > server bound to 127.0.0.1, not 0.0.0.0 [9.14ms]
(pass) localhost binding (通信龙 hard constraint #1+#2) > port is reachable [10.16ms]
(pass) localhost binding (通信龙 hard constraint #1+#2) > random port (different runs get different ports) [6.04ms]
(pass) bearer auth no-bypass (通信龙 hard constraint #4) > missing Authorization header → 401 [7.16ms]
(pass) bearer auth no-bypass (通信龙 hard constraint #4) > wrong token → 401 [7.32ms]
(pass) bearer auth no-bypass (通信龙 hard constraint #4) > non-Bearer scheme → 401 [5.14ms]
(pass) bearer auth no-bypass (通信龙 hard constraint #4) > correct Bearer → 200 [8.46ms]
(pass) bearer auth no-bypass (通信龙 hard constraint #4) > path other than /mcp → 404 [7.04ms]
(pass) MCP protocol — initialize / tools/list / tools/call > initialize returns serverInfo + tools capability [7.25ms]
(pass) MCP protocol — initialize / tools/list / tools/call > tools/list returns all 6 self-loop tools [7.32ms]
(pass) MCP protocol — initialize / tools/list / tools/call > tools/list each tool has description + inputSchema [7.12ms]
(pass) MCP protocol — initialize / tools/list / tools/call > unknown method → JSON-RPC -32601 [7.27ms]
(pass) MCP protocol — initialize / tools/list / tools/call > malformed JSON → -32700 [5.51ms]
(pass) tools/call — handler dispatch into parent ctx > list_my_loops on empty store [7.26ms]
(pass) tools/call — handler dispatch into parent ctx > create_my_loop with interval string writes to parent goalStore [9.10ms]
(pass) tools/call — handler dispatch into parent ctx > unknown tool name → JSON-RPC -32601 [5.51ms]
(pass) safety防线 cross-HTTP boundary (M2 verification line) > batch-cancel via HTTP triggers confirm-back on 4th call [10.47ms]
(pass) safety防线 cross-HTTP boundary (M2 verification line) > cooldown via HTTP — edit within 30s of upsert rejected [8.05ms]
(pass) safety防线 cross-HTTP boundary (M2 verification line) > max-active-goals cap honored across HTTP [13.04ms]
(pass) safety防线 cross-HTTP boundary (M2 verification line) > preflight invalid timezone rejected via HTTP (M1 #302 round-2 still works) [9.44ms]
(pass) custom token override (for tests) > explicit token honored [14.13ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > /mcp (exact) accepted → 200 [5.28ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > /mcp?foo=bar (with query string) accepted → 200 [10.11ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > /mcpXYZ (suffix) rejected → 404 (not auth-checked) [6.09ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > /mcp/ (trailing slash) rejected → 404 [6.25ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > /mcp-leak (dash suffix) rejected → 404 [5.99ms]
(pass) path routing — exact pathname (通信牛 hardening nit) > / (root) rejected → 404 [5.45ms]

src/goals/failure-counter.test.ts:
(pass) resolveMaxConsecutiveFailures > default 5 when env unset [0.11ms]
(pass) resolveMaxConsecutiveFailures > env override honored [0.04ms]
(pass) resolveMaxConsecutiveFailures > invalid env falls back to default [0.04ms]
(pass) getFailureCount > legacy undefined → 0 [0.15ms]
(pass) getFailureCount > explicit 0 → 0 [0.06ms]
(pass) getFailureCount > explicit N → N [0.04ms]
(pass) bumpFailure > first failure: undefined → 1, shouldPause=false at default threshold [0.11ms]
(pass) bumpFailure > 4 → 5 at default threshold: shouldPause=true [0.06ms]
(pass) bumpFailure > 3 → 4 at threshold 5: shouldPause=false (below threshold) [0.05ms]
(pass) bumpFailure > custom threshold — 2 → 3 at threshold 3: shouldPause=true [0.05ms]
(pass) bumpFailure > beyond threshold: count continues to increment but shouldPause stays true [0.05ms]
(pass) resetFailure > legacy undefined stays undefined (no unnecessary write) [0.16ms]
(pass) resetFailure > 0 stays 0 (no unnecessary write) [0.06ms]
(pass) resetFailure > N > 0 → 0 [0.03ms]
(pass) resetFailure > threshold value → 0 [0.03ms]
(pass) applyAutoPause > status flipped to paused + counter preserved for observability [0.12ms]
(pass) applyAutoPause > progress_log entry recorded with count + reason [0.13ms]
(pass) applyAutoPause > long reason truncated to 300 chars in summary [0.08ms]
(pass) integration: full cycle > 5 bumps → pause → unpause reset → 5 more bumps → pause again [0.15ms]

src/goals/parser.test.ts:
(pass) parseGoalCommand — English intervals > `5 min` form [0.13ms]
(pass) parseGoalCommand — English intervals > `5min` joined form [0.06ms]
(pass) parseGoalCommand — English intervals > `5 minutes` long form (plural wins over `min`) [0.05ms]
(pass) parseGoalCommand — English intervals > `1 hour` [0.08ms]
(pass) parseGoalCommand — English intervals > `hourly` keyword [0.07ms]
(pass) parseGoalCommand — English intervals > `daily` [0.06ms]
(pass) parseGoalCommand — English intervals > `1 day` [0.17ms]
(pass) parseGoalCommand — English intervals > `/goal` prefix is optional [0.07ms]
(pass) parseGoalCommand — English intervals > `/loop` alias [0.07ms]
(pass) parseGoalCommand — English intervals > `/aloop` strips the namespaced canonical prefix [0.09ms]
(pass) parseGoalCommand — English intervals > `/agoal` strips the namespaced compatibility prefix [0.13ms]
(pass) parseGoalCommand — Chinese intervals > `每5分钟` [0.24ms]
(pass) parseGoalCommand — Chinese intervals > `每 5 分钟` with spaces [0.07ms]
(pass) parseGoalCommand — Chinese intervals > `5分钟` bare (no 每) [0.14ms]
(pass) parseGoalCommand — Chinese intervals > `每小时` [0.05ms]
(pass) parseGoalCommand — Chinese intervals > `每天` [0.06ms]
(pass) parseGoalCommand — Chinese intervals > `每2小时` [0.08ms]
(pass) parseGoalCommand — rejection paths > no interval — reject [0.11ms]
(pass) parseGoalCommand — rejection paths > empty input — reject [0.04ms]
(pass) parseGoalCommand — rejection paths > seconds rejected with informative error [0.09ms]
(pass) parseGoalCommand — rejection paths > Chinese 秒 rejected [0.07ms]
(pass) parseGoalCommand — rejection paths > text becomes empty after stripping interval — reject [0.08ms]
(pass) parseGoalCommand — rejection paths > `/goal hourly` alone — reject (no text) [0.06ms]
(pass) parseGoalCommand — rejection paths > MIN_INTERVAL_MS is 60s [0.03ms]
(pass) parseGoalCommand — defence-in-depth > `1 min` exact minimum is accepted [0.03ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `5m` parses to 5 × 60_000 ms (the canonical CLI emission) [0.06ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `30m` / `90m` arbitrary minutes parse correctly [0.08ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `2h` parses to 2 hours [0.09ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `1d` parses to 24 hours [0.08ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > single-letter and word-form yield the same interval (no semantic drift) [0.07ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `5min` still wins over `5m` (longest-prefix declaration order) [0.06ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > single-letter inside a larger word is NOT swallowed (lookahead guard) [0.05ms]
(pass) parseGoalCommand — #144 round-6 single-letter units (CLI parity) > `30s` is rejected with sub-minute error (parser + CLI aligned) [0.08ms]

src/goals/loops-grok-wire.test.ts:
(pass) grok ACP MCP injection — RFC-025 M3 wire > when LOOPS env unset, only commhub server (back-compat) [0.22ms]
(pass) grok ACP MCP injection — RFC-025 M3 wire > when LOOPS env set, commhub + loops servers both present [0.05ms]
(pass) grok ACP MCP injection — RFC-025 M3 wire > loops server entry: ACP http schema (type+url+headers array) [0.09ms]
(pass) grok ACP MCP injection — RFC-025 M3 wire > loops headers: Authorization Bearer <token> + transport tag + alias hint [0.14ms]
(pass) grok ACP MCP injection — RFC-025 M3 wire > loops entry localhost URL only (per security constraint) [0.13ms]
(pass) grok ACP MCP injection — RFC-025 M3 wire > loops + commhub independent: commhub headers don't leak token, loops headers don't leak ntok [0.13ms]
(pass) grok ACP MCP injection — #693 upload stdio > adds stdio commhub_upload when uploadMcpCommand provided [0.16ms]

src/goals/completion-detect.test.ts:
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > Chinese sentinel on its own line [0.10ms]
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > Chinese sentinel at end of text without trailing newline [0.04ms]
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > Chinese sentinel at start of text [0.04ms]
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > English GOAL_COMPLETE underscore on its own line [0.09ms]
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > English GOAL COMPLETE (space) on its own line [0.03ms]
(pass) isGoalCompleteSentinel — POSITIVE (must detect) > sentinel with leading/trailing whitespace on the line [0.03ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > bare 'completed' in progress report [0.03ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > 'X completed' phrase mid-sentence [0.03ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > Chinese '已完成' as section header (not the goal-complete sentinel) [0.02ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > Chinese '已完成 X 项' enumeration in body [0.03ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > 'goal completed' as a phrase inside prose (was caught by old regex) [0.02ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > '目标已完成' substring without standalone line (old regex would match) [0.03ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > lowercased 'goal_complete' (sentinel is case-sensitive on English) [0.04ms]
(pass) isGoalCompleteSentinel — NEGATIVE (regression gate, must NOT detect) > empty / null / undefined input [0.05ms]

src/goals/schedule.test.ts:
(pass) computeNextWakeAt — interval mode > interval 5min from a baseline returns baseline + 5min [0.09ms]
(pass) computeNextWakeAt — interval mode > interval 24h returns +24h [0.07ms]
(pass) computeNextWakeAt — interval mode > interval is timezone-independent (UTC anchor same result regardless of node TZ) [0.07ms]
(pass) computeNextWakeAt — time_of_day mode (per-TZ wall clock) > 09:00 Asia/Shanghai, called at 10:00 Asia/Shanghai → tomorrow 09:00 (already past today) [5.13ms]
(pass) computeNextWakeAt — time_of_day mode (per-TZ wall clock) > 09:00 Asia/Shanghai, called at 08:00 Asia/Shanghai → today 09:00 (still upcoming) [0.46ms]
(pass) computeNextWakeAt — time_of_day mode (per-TZ wall clock) > 09:00 Asia/Shanghai, called AT 09:00 exactly → today (boundary include) [0.77ms]
(pass) computeNextWakeAt — time_of_day mode (per-TZ wall clock) > falls back to node default TZ if schedule has no timezone [0.72ms]
(pass) computeNextWakeAt — weekday mode > Monday 09:00 Asia/Shanghai, called Sun 10:00 → tomorrow (Mon) 09:00 [0.78ms]
(pass) computeNextWakeAt — weekday mode > Mon/Wed/Fri 18:30 Asia/Shanghai, called Sun 10:00 → Monday 18:30 (next eligible) [0.48ms]
(pass) computeNextWakeAt — weekday mode > Mon/Wed/Fri 18:30, called Mon 18:00 → today 18:30 (today eligible AND time still upcoming) [0.39ms]
(pass) computeNextWakeAt — weekday mode > Mon/Wed/Fri 18:30, called Mon 19:00 → today is Mon but past 18:30 → Wed 18:30 [0.78ms]
(pass) computeNextWakeAt — weekday mode > Friday 09:00, called Saturday → next Friday (full week wrap-around) [1.01ms]
(pass) computeNextWakeAt — weekday mode > workdays ['mon','tue','wed','thu','fri'] for daily standup is supported [0.51ms]
(pass) computeNextWakeAt — DST edge cases (US Eastern) > 09:00 America/New_York in summer (EDT) → 13:00 UTC [0.78ms]
(pass) computeNextWakeAt — DST edge cases (US Eastern) > 09:00 America/New_York in winter (EST) → 14:00 UTC [0.65ms]
(pass) computeNextWakeAt — DST edge cases (US Eastern) > daily 02:30 wake DOES NOT skip on DST spring-forward day (just shifts that day) [0.78ms]
(pass) computeNextWakeAt — DST edge cases (US Eastern) > daily 03:30 exists on spring-forward day (post-jump, unambiguous EDT) [0.88ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 01:30, called Sat noon → fires at FIRST 01:30 EDT (before fall-back) [0.78ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 01:30, called AT first 01:30 EDT boundary → NEXT DAY (not second 01:30 EST same day) [0.73ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 01:30, called between the two occurrences (05:45 UTC) → next day [0.54ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 01:30, called AT fall-back moment (06:00 UTC) → next day (skip 2nd occurrence) [0.68ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 01:30, called AFTER second occurrence (06:30 UTC) → next day [0.56ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 02:30 (post-fallback UNAMBIGUOUS) still fires on fall-back day — was buggy before P1.3 [0.60ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > daily 03:00 (fully post-fallback) on fall-back day — regression for iterated offset [0.55ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > weekday Sun 01:30 on fall-back Sunday → first occurrence EDT [0.45ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > weekday Sun 02:30 on fall-back Sunday → same day (was CRASH before P1.3) [0.44ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > weekday Sun 01:30 called AT first fire → NEXT Sunday (not same-day 2nd occurrence) [0.98ms]
(pass) computeNextWakeAt — DST fall-back (autumn) — RFC-025 P1.3 > time_of_day 09:00 on fall-back day (outside ambiguous window) unchanged [0.40ms]
(pass) computeNextWakeAt — legacy interval-only (back-compat regression) > undefined schedule → uses interval_ms from goal context, returns now + interval [0.07ms]
(pass) computeNextWakeAt — legacy interval-only (back-compat regression) > undefined schedule + zero fallback interval → still returns now (no negative offset) [0.08ms]
(pass) computeNextWakeAt — legacy interval-only (back-compat regression) > undefined schedule + missing fallback interval throws (programmer error) [0.12ms]
(pass) computeNextWakeAt — parser-rejected edge cases (defensive) > invalid time format '25:99' throws [0.16ms]
(pass) computeNextWakeAt — parser-rejected edge cases (defensive) > empty weekday list throws (caught by parser too, defense in depth) [0.11ms]
(pass) computeNextWakeAt — parser-rejected edge cases (defensive) > unknown weekday name throws [0.17ms]

src/goals/self-loop-tools.test.ts:
(pass) list_my_loops > empty store → {goals: [], total: 0} [2.23ms]
(pass) list_my_loops > includes goal_id_short + cadence schedule shape [0.85ms]
(pass) create_my_loop > interval string '5m' creates goal [0.63ms]
(pass) create_my_loop > cron-lite time_of_day creates goal with schedule field [1.78ms]
(pass) create_my_loop > missing task → invalid_args [0.32ms]
(pass) create_my_loop > missing both schedule and interval → invalid_schedule [0.32ms]
(pass) create_my_loop > sub-minute interval rejected (parser 60s floor) [0.36ms]
(pass) create_my_loop > max active goals cap (3 cap → 4th rejected) [1.46ms]
(pass) edit_my_loop > change interval + report new value [1.52ms]
(pass) edit_my_loop > paused=true → status=paused [1.12ms]
(pass) edit_my_loop > cooldown — edit within 30s of last update rejected [0.51ms]
(pass) edit_my_loop > unknown goal_id → goal_not_found [0.30ms]
(pass) edit_my_loop > P0.3 unpause resets consecutive_failures (fresh 5-strike window) [1.13ms]
(pass) edit_my_loop > P0.3 paused=false when already active does NOT wipe mid-failure counter [1.14ms]
(pass) edit_my_loop > P0.3 paused=true does NOT reset consecutive_failures [1.15ms]
(pass) reschedule_my_loop (★ ScheduleWakeup 范式) > pushes next_wake_at forward, interval_ms unchanged [1.73ms]
(pass) reschedule_my_loop (★ ScheduleWakeup 范式) > invalid next_wake_in → invalid_interval [0.65ms]
(pass) reschedule_my_loop (★ ScheduleWakeup 范式) > cooldown applies [0.49ms]
(pass) complete_my_loop (★ 达标归档) > status → 'complete' [1.25ms]
(pass) complete_my_loop (★ 达标归档) > unknown goal_id → goal_not_found [0.32ms]
(pass) cancel_my_loop > status → 'cancelled' [1.45ms]
(pass) cancel_my_loop > batch cancel (3 in 30s) triggers confirm-back on 4th [3.52ms]
(pass) #302 round-2 — preflight computeNextWakeAt (self-lock prevention) > create_my_loop: bad timezone in schedule → invalid_schedule, NOT written [0.56ms]
(pass) #302 round-2 — preflight computeNextWakeAt (self-lock prevention) > create_my_loop: bad weekday → invalid_schedule, NOT written [0.46ms]
(pass) #302 round-2 — preflight computeNextWakeAt (self-lock prevention) > create_my_loop: bad time format → invalid_schedule, NOT written [0.37ms]
(pass) #302 round-2 — preflight computeNextWakeAt (self-lock prevention) > edit_my_loop: bad timezone on edit → invalid_schedule, EXISTING goal untouched [0.94ms]
(pass) #302 round-2 — preflight computeNextWakeAt (self-lock prevention) > create_my_loop: VALID structured schedule still works (regression) [1.52ms]
(pass) SELF_LOOP_TOOL_SPECS — registration table > exports 6 tools with stable names [0.27ms]
(pass) SELF_LOOP_TOOL_SPECS — registration table > every spec has non-empty description (LLM-discoverable) [0.22ms]
(pass) SELF_LOOP_TOOL_SPECS — registration table > description guides per RFC-025 §3.2 (intent-parse + report-back + safety) [0.43ms]

src/goals/codex-wake.test.ts:
(pass) runCodexWakeForGoal — first wake (no codex_thread_id) > startThread path → captures threadId, returns text + failed=false [1.60ms]
(pass) runCodexWakeForGoal — first wake (no codex_thread_id) > startThread with thread.id still null → threadId undefined (SDK didn't expose id yet) [0.24ms]
(pass) runCodexWakeForGoal — first wake (no codex_thread_id) > empty agent_message stream → returns '(无回复)' fallback [0.18ms]
(pass) runCodexWakeForGoal — subsequent wake (has codex_thread_id) > resumeThread succeeds → captures (possibly updated) threadId [0.22ms]
(pass) runCodexWakeForGoal — subsequent wake (has codex_thread_id) > resume returns thread whose .id was updated by SDK → reflects new id [0.15ms]
(pass) runCodexWakeForGoal — resume-fail fallback (the critical path) > resumeThread throws → startThread fallback, threadRebuilt=true, rebuildReason populated [0.48ms]
(pass) runCodexWakeForGoal — resume-fail fallback (the critical path) > startThread fallback also throws → failed=true with both errors surfaced [0.23ms]
(pass) runCodexWakeForGoal — resume-fail fallback (the critical path) > first wake + startThread throws → failed=true, threadRebuilt=false [0.14ms]
(pass) runCodexWakeForGoal — run-time error after thread obtained > runStreamed throws on first wake → failed=true, threadId still captured if SDK set it [0.23ms]
(pass) runCodexWakeForGoal — run-time error after thread obtained > runStreamed throws on resume → failed=true, threadRebuilt=false (resume itself worked) [0.22ms]
(pass) runCodexWakeForGoal — DI plumbing > newCodex called per wake (not cached across wakes — fresh client each time) [0.28ms]
(pass) runCodexWakeForGoal — DI plumbing > buildOpts passed verbatim to start/resume Thread [0.42ms]
(pass) runCodexWakeForGoal — DI plumbing > warn callback fires on resume-fail; log callback fires on success [0.35ms]
(pass) runCodexWakeForGoal — DI plumbing > missing log/warn deps → no throw (defaults are noops) [0.17ms]

src/goals/scheduler.test.ts:
(pass) decideTickWork — basic selection > empty list → empty buckets [0.25ms]
(pass) decideTickWork — basic selection > single active goal due now → due [0.27ms]
(pass) decideTickWork — basic selection > single active goal due 1ms ago → due [0.09ms]
(pass) decideTickWork — basic selection > single active goal due 1ms in future → pending, not due [0.12ms]
(pass) decideTickWork — basic selection > multiple active goals: only the overdue ones wake; pending stay [0.16ms]
(pass) decideTickWork — status filtering > each non-active status is skipped (never appears in due) [0.16ms]
(pass) decideTickWork — status filtering > mixed batch: only active+due appear in due bucket [0.21ms]
(pass) decideTickWork — status filtering > wake order preserves input order — deterministic, no shuffling [0.11ms]
(pass) decideTickWork — invalid timestamp recovery > missing next_wake_at → treated as overdue (surface to wake handler) [0.07ms]
(pass) decideTickWork — invalid timestamp recovery > empty string next_wake_at → treated as overdue [0.06ms]
(pass) decideTickWork — invalid timestamp recovery > garbage next_wake_at (Date.parse → NaN) → treated as overdue [0.05ms]
(pass) decideTickWork — invalid timestamp recovery > non-string next_wake_at (number 0 from corrupt JSON) → treated as overdue [0.05ms]
(pass) decideTickWork — invalid timestamp recovery > inactive + invalid timestamp → still skipped (status wins over wake check) [0.06ms]
(pass) decideTickWork — counter sanity > active + skipped sums to total goals; pending + due sums to active [0.12ms]

src/goals/store.test.ts:
(pass) GoalStore — basic lifecycle > fresh store: load with no file → ok, empty list [0.63ms]
(pass) GoalStore — basic lifecycle > upsert → get → list roundtrip [0.69ms]
(pass) GoalStore — basic lifecycle > delete → flushes to disk [1.30ms]
(pass) GoalStore — basic lifecycle > setStatus → in-memory + persisted [1.18ms]
(pass) GoalStore — basic lifecycle > setStatus on unknown id → undefined, no throw [0.33ms]
(pass) GoalStore — basic lifecycle > mutate applies in-place + bumps updated_at [6.45ms]
(pass) GoalStore — basic lifecycle > mutate on unknown id → undefined, mutator NOT invoked [0.35ms]
(pass) GoalStore — restart persistence > two instances see the same goals (= restart simulation) [0.85ms]
(pass) GoalStore — restart persistence > status change survives reload [1.11ms]
(pass) GoalStore — corruption recovery (#2) > invalid JSON → ok=false, .corrupt backup, empty store [1.81ms]
(pass) GoalStore — corruption recovery (#2) > unknown schema version → recovery [0.60ms]
(pass) GoalStore — corruption recovery (#2) > malformed shape (goals not array) → recovery [0.50ms]
(pass) GoalStore — Grok preview persistence boundary > recursively migrates task/progress/error, final writes, and archives at 0600 [3.26ms]
(pass) GoalStore — Grok preview persistence boundary > scrubs a broad-mode corrupt backup and replaces the live file with an empty safe store [1.68ms]
(pass) GoalStore — Grok preview persistence boundary > recursively scrubs a parseable unsupported-schema backup [1.57ms]
(pass) P0 runtime gate — name resolution > isClaudeRuntime accepts every claude alias [0.17ms]
(pass) P0 runtime gate — name resolution > isClaudeRuntime rejects codex / grok / unknown / empty [0.07ms]
(pass) P0 runtime gate — name resolution > runtimeBucket maps to canonical buckets [0.11ms]
(pass) #144 round-6 — claude runtime gate REMOVED, scheduler is universal > newGoal({runtime: 'claude-agent-sdk'}) succeeds (was the load-bearing bug) [0.09ms]
(pass) #144 round-6 — claude runtime gate REMOVED, scheduler is universal > newGoal succeeds for every recognized runtime alias (no per-bucket carve-out) [0.17ms]
(pass) #144 round-6 — claude runtime gate REMOVED, scheduler is universal > GoalStore.upsert accepts a claude-runtime goal end-to-end [0.74ms]
(pass) #144 round-6 — claude runtime gate REMOVED, scheduler is universal > isClaudeRuntime still classifies (kept for cross-bucket detection, not gating) [0.05ms]
(pass) P0 runtime gate — archiveAndClear > with live goals: backup file created, store emptied, reload sees empty [1.91ms]
(pass) P0 runtime gate — archiveAndClear > with no live file: returns undefined, no throw, store still flushes empty [0.45ms]
(pass) P0 runtime gate — archiveAndClear > backup filenames are unique across rapid calls [15.05ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + empty → ok (scheduler runs; was 'skip' pre-#144) [0.27ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + only claude-active goals → ok (scheduler runs) [0.23ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > codex + empty → ok [0.03ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > codex + only codex goals → ok [0.06ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > grok + only grok goals → ok [0.08ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + active codex/grok goals → archive + runScheduler=true (recover after archive) [0.32ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > codex + grok-active leftover → archive (NOT fatal exit anymore) [0.09ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > grok + codex-active leftover → archive [0.05ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > inactive foreign-bucket goals do NOT trigger archive (only `active` counts) [0.09ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude with only inactive foreign leftover → ok (just cleanup pending) [0.05ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > unknown bucket → skip (no scheduler, no auto-archive) [0.06ms]
(pass) GoalStore — mutex serialisation (#1+#3) > 50 concurrent upserts → all 50 persist (no torn writes) [20.63ms]
(pass) GoalStore — mutex serialisation (#1+#3) > interleaved upsert + setStatus + delete stays consistent [13.18ms]

src/runtime/grok-copresence/profile-process.test.ts:
(pass) Grok co-presence profile is pinned for the whole process > same input yields two exact, non-overlapping process capabilities [127.34ms]

src/runtime/grok-copresence/jsonl.test.ts:
(pass) Grok copresence envelope and user parsing > parses only an exact, query-anchored Agent Network envelope [0.50ms]
(pass) Grok copresence envelope and user parsing > extracts the first authoritative user_query from string or Grok text-array content [0.48ms]
(pass) Grok copresence envelope and user parsing > does not trust a syntactically valid prefix unless the bridge registered it [1.50ms]
(pass) Grok copresence envelope and user parsing > nested user_query text cannot turn an owned network task into human delegation [0.37ms]
(pass) Grok copresence turn reducer > waits for completion and replies with the last non-empty assistant record [0.55ms]
(pass) Grok copresence turn reducer > keeps the last no-tool assistant when later tool-bearing chatter exists [0.28ms]
(pass) Grok copresence turn reducer > handles completion/chat-history polling order without returning an empty reply [0.33ms]
(pass) Grok copresence turn reducer > does not finalize an intermediate assistant visible before the completion event [0.24ms]
(pass) Grok copresence turn reducer > retains a completion observed before even the network user line [0.36ms]
(pass) Grok copresence turn reducer > retains an event-first human completion only for a trusted PTY submission [0.26ms]
(pass) Grok copresence turn reducer > never carries an unowned idle completion into a later network task [0.28ms]
(pass) Grok copresence turn reducer > binds an event-first completion to the exact registered network task [0.39ms]
(pass) Grok copresence turn reducer > consumes sanitized sample A block content and turn_number boundary [0.30ms]
(pass) Grok copresence turn reducer > consumes sanitized sample B and selects only the 14th no-tool assistant [0.58ms]
(pass) Grok copresence turn reducer > ignores standalone system-reminder user records without abandoning a network turn [0.17ms]
(pass) Grok copresence turn reducer > fails a terminal record without turn_started and never binds it to the next user [0.27ms]
(pass) Grok copresence turn reducer > never maps a human turn or failed network turn to a network reply [0.69ms]
(pass) Grok copresence turn reducer > abandons an unfinished network turn rather than attaching its answer to a human turn [0.53ms]
(pass) Grok copresence turn reducer > pairs events correctly when chat_history leads by two unnumbered turns [0.68ms]
(pass) Grok copresence turn reducer > does not let a new start overtake an abandoned numbered terminal [0.38ms]
(pass) Grok completion compatibility and defensive parsing > recognizes only top-level turn_ended with an exact successful outcome [0.31ms]
(pass) Grok completion compatibility and defensive parsing > binds turn_started turn_number while permission lifecycle remains inert [0.25ms]
(pass) Grok completion compatibility and defensive parsing > fails a started turn when turn_ended has no outcome [0.25ms]
(pass) Grok completion compatibility and defensive parsing > fails closed on an overlapping turn_started epoch [0.25ms]
(pass) Grok completion compatibility and defensive parsing > retains only a bounded tail of raw completion candidates [0.23ms]
(pass) Grok completion compatibility and defensive parsing > contains malformed and overlong lines instead of parsing or retaining them [1.23ms]
(pass) Grok completion compatibility and defensive parsing > incrementally joins split lines and drops a fragmented oversized line once [1.56ms]
(pass) persistent JSONL tail cursor > starts fresh at end by default, with an explicit start override [0.38ms]
(pass) persistent JSONL tail cursor > continues and fails closed on truncate or inode rotation [0.24ms]
(pass) persistent JSONL tail cursor > treats corrupt persisted state as non-replayable and advances JSON-safely [0.24ms]

src/runtime/grok-copresence/attach.test.ts:
(pass) Grok co-presence local attach server > serves one owner-only client and cleans its socket on close [15.97ms]
(pass) Grok co-presence local attach server > rejects a second client without disturbing the attached human [10.51ms]
(pass) Grok co-presence local attach server > routes input and resize frames only through serialized arbiter callbacks [6.63ms]
(pass) Grok co-presence local attach server > fails closed when an inbound frame exceeds the configured bound [20.40ms]
(pass) Grok co-presence local attach server > refuses symlinks and regular files at the socket path [1.06ms]

src/runtime/grok-copresence/state.test.ts:
(pass) Grok co-presence arbitration > lets the first human byte win a simultaneous human/network race [1.38ms]
(pass) Grok co-presence arbitration > gives a newly active human composer priority over an existing FIFO [0.35ms]
(pass) Grok co-presence arbitration > dequeues network tasks FIFO and never preempts an active turn [0.62ms]
(pass) Grok co-presence arbitration > cancels only queued timeouts and rejects duplicate task ids [0.35ms]
(pass) Grok co-presence arbitration > retains the active network task and FIFO across disconnect/reconnect [1.13ms]
(pass) Grok co-presence arbitration > marks approvals waiting for the human without emitting a response [0.29ms]
(pass) Grok co-presence arbitration > clears an already-waiting preview todo resolution in either active turn without completing it [0.32ms]

src/runtime/grok-copresence/profile-wiring.test.ts:
(pass) Grok co-presence profile wiring > pins validated config before dynamically loading the runtime [3.22ms]
(pass) Grok co-presence profile wiring > cannot mutate the capability according to a logical turn owner [0.15ms]

src/runtime/grok-copresence/leader-lifecycle.test.ts:
(pass) Grok auto-Leader lifecycle identity > rejects a different kernel executable hidden behind a pinned argv0 [0.94ms]
(pass) Grok auto-Leader lifecycle identity > rejects a live native listener whose argv0 forges the pinned executable [363.91ms]
(pass) Grok auto-Leader lifecycle identity > terminates one exact generation and removes only its stale socket [94.35ms]
(pass) Grok auto-Leader lifecycle identity > does not adopt a listener whose generation marker differs [157.07ms]
(pass) Grok auto-Leader lifecycle identity > does not signal or unlink after the socket pathname is replaced [55.12ms]
(pass) Grok auto-Leader lifecycle identity > revalidates the exact identity before escalating a TERM-resistant Leader [585.01ms]
(pass) Grok auto-Leader lifecycle identity > does not escalate when a TERM-resistant Leader replaces its listener [391.50ms]
(pass) Grok auto-Leader lifecycle identity > does not signal after the configured binary inode is replaced [72.03ms]
(pass) Grok auto-Leader lifecycle identity > retains the stale socket when another process from the generation remains [296.91ms]

src/runtime/grok-copresence/allowlist-near-miss.test.ts:
(pass) grok copresence preview tool profile is an exact value set > a profile tool with an otherwise valid tuple is accepted [0.64ms]
(pass) grok copresence preview tool profile is an exact value set > refuses "todo_write2" [0.05ms]
(pass) grok copresence preview tool profile is an exact value set > refuses "search_tool2"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool2"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool_v2"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool-admin"
(pass) grok copresence preview tool profile is an exact value set > refuses "Use_Tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "USE_TOOL"
(pass) grok copresence preview tool profile is an exact value set > refuses "Todo_Write"
(pass) grok copresence preview tool profile is an exact value set > refuses " use_tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool "
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool\n"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_too"
(pass) grok copresence preview tool profile is an exact value set > refuses "tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "not_use_tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "xuse_toolx" [0.02ms]
(pass) grok copresence preview tool profile is an exact value set > refuses "ｕｓｅ＿ｔｏｏｌ"
(pass) grok copresence preview tool profile is an exact value set > refuses "use​tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_to​ol"
(pass) grok copresence preview tool profile is an exact value set > refuses ""
(pass) grok copresence preview tool profile is an exact value set > refuses " "
(pass) grok copresence preview tool profile is an exact value set > refuses "Search_Tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "TODO_WRITE"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool\r"
(pass) grok copresence preview tool profile is an exact value set > refuses "use_tool\u0000"
(pass) grok copresence preview tool profile is an exact value set > refuses "x_todo_write"
(pass) grok copresence preview tool profile is an exact value set > refuses "use-tool"
(pass) grok copresence preview tool profile is an exact value set > refuses "todo-write"
(pass) grok copresence preview tool profile is an exact value set > the profile is exactly the three pinned tools [0.12ms]

src/runtime/grok-copresence/profile-selection.test.ts:
(pass) Grok co-presence process capability profile > accepts only the two exact startup profiles [0.20ms]
(pass) Grok co-presence process capability profile > defaults closed and rejects an invalid process profile [0.13ms]

src/runtime/grok-copresence/runtime.test.ts:
(pass) Grok copresence launch and injection policy > keeps the fixed-tool auto-resolution exception exact and limited to active turns [0.44ms]
(pass) Grok copresence launch and injection policy > admits exact automatic lifecycles only for the fixed preview tool boundary [0.37ms]
(pass) Grok copresence launch and injection policy > exposes only reviewed value-free task failure codes and exact JSONL subcodes [0.52ms]
(pass) Grok copresence launch and injection policy > keeps the JSONL subcode allowlist direct, frozen, and actual-path-only [0.27ms]
(pass) Grok copresence launch and injection policy > locks the probed Grok TUI build exactly [0.21ms]
(pass) Grok copresence launch and injection policy > pins one TUI-effective commhub-only agent profile and hard-denies fallback routes [0.90ms]
(pass) Grok copresence launch and injection policy > rejects terminal escape injection and reserved origin markup [0.57ms]
(pass) Grok copresence launch and injection policy > recognizes the pinned TUI composer footer across ANSI fragments [0.31ms]
(pass) Grok copresence launch and injection policy > rejects external permission sources and noninteractive modes [1.41ms]
(pass) Grok copresence runtime integration > terminates the independently persistent auto-Leader and its unchanged stale socket [559.81ms]
(pass) Grok copresence runtime integration > cleans and hardens the exact pinned footprint only after confirmed close [538.75ms]
(pass) Grok copresence runtime integration > cleans each exact sandbox placeholder at its confirmed recovery boundary [911.85ms]
(pass) Grok copresence runtime integration > removes an old placeholder before a recovery generation reuses its PID [1205.20ms]
(pass) Grok copresence runtime integration > queues network input until the pinned TUI composer is ready [1213.87ms]
(pass) Grok copresence runtime integration > maps keyless fake-writer file mutations to exact value-free tail subcodes [3921.91ms]
(pass) Grok copresence runtime integration > continues exactly once across prefix-preserving atomic chat rewrites [2266.62ms]
(pass) Grok copresence runtime integration > rejects an atomic replacement that preserves only the consumed prefix [667.36ms]
(pass) Grok copresence runtime integration > rejects a same-inode shrink below the highest observed size even when offset remains valid [583.46ms]
(pass) Grok copresence runtime integration > does not expose an intermediate atomic generation before its successor preserves it [1082.15ms]
(pass) Grok copresence runtime integration > does not expose a pinned generation unlinked between path check and read [1107.69ms]
(pass) Grok copresence runtime integration > maps chat and events reset callback failures and stops polling after fatal [1534.92ms]
(pass) Grok copresence runtime integration > maps keyless reducer, lifecycle, and combined flush invariants at their boundaries [2532.40ms]
(pass) Grok copresence runtime integration > close waits for and tears down a Leader spawned by in-flight recovery [937.73ms]
(pass) Grok copresence runtime integration > retains containment and lifetime locks when a closing recovery PTY will not stop [2925.58ms]
(pass) Grok copresence runtime integration > excludes a different runtime from the same canonical project for the full TUI lifetime [1108.26ms]
(pass) Grok copresence runtime integration > contains an exited recovery generation before reusing its PID [1799.07ms]
(pass) Grok copresence runtime integration > retains final-cleanup ownership after every failed recovery PID is consumed [935.21ms]
(pass) Grok copresence runtime integration > reports exact submission and trusted consumption, never queued admission [1795.97ms]
(pass) Grok copresence runtime integration > arbitrates a live PTY, settles final JSONL, attaches once, and resumes [4070.62ms]
(pass) Grok copresence runtime integration > fails closed on automatic permission resolution without a human action [619.65ms]
(pass) Grok copresence runtime integration > accepts only the pinned preview todo_write automatic resolution tuple [1915.08ms]
(pass) Grok copresence runtime integration > keeps the shared TUI alive when the pinned preview auto-resolves todo_write in a human turn [1810.85ms]
(pass) Grok copresence runtime integration > keeps the shared TUI alive across exact search_tool then use_tool in a human turn [1659.41ms]
(pass) Grok copresence runtime integration > rejects every mutated preview todo_write automatic resolution tuple [4236.29ms]
(pass) Grok copresence runtime integration > preserves exact permission lifecycle order across coalesced and split event reads [2342.57ms]
(pass) Grok copresence runtime integration > fails closed on malformed or oversized permission lifecycle JSONL [1198.51ms]
(pass) Grok copresence runtime integration > rejects terminal reordering around automatic permission lifecycles [1802.88ms]
(pass) Grok copresence runtime integration > allows repeated fixed-tool automatic permission lifecycles in one network turn [1103.59ms]
(pass) Grok copresence runtime integration > never replies with a tool-bearing assistant when the final log is delayed past settling [1888.32ms]
(pass) Grok copresence runtime integration > rejects a completed turn that never resolved its approval [595.16ms]
(pass) Grok copresence runtime integration > does not resume a TUI that crashed at an approval prompt [608.79ms]
(pass) Grok copresence runtime integration > rejects a permission record that landed just before the crash poll [891.42ms]
(pass) Grok copresence runtime integration > refuses process-level resume with a persisted unresolved approval [226.93ms]
(pass) Grok copresence runtime integration > permits process-level resume after a persisted approval was resolved [545.57ms]
(pass) Grok copresence runtime integration > arms both resume tails before spawn-time permission records can be skipped [305.07ms]
(pass) Grok copresence runtime integration > discards spawn-time orphan completions before accepting the first new network task [1104.33ms]
(pass) Grok copresence runtime integration > drains more than one tail chunk before attach and fully cleans a startup rejection [901.15ms]
(pass) Grok copresence runtime integration > accepts the pinned startup auto-approval transition [597.71ms]
(pass) Grok copresence runtime integration > reruns the spawn audit and refuses recovery when it fails [824.84ms]
(pass) Grok copresence runtime integration > keeps auto-approval across recovery before scheduling [1726.69ms]
(pass) Grok copresence runtime integration > jointly drains chat and events until both recovery cursors are stable [1884.42ms]
(pass) Grok copresence runtime integration > rejects a beforeSpawn callback that widens a controlled child setting [206.40ms]
(pass) Grok copresence runtime integration > gives every real lifetime-lock holder only the exact helper environment [548.53ms]

src/runtime/opencode-acp/events.test.ts:
(pass) reduceOpencodeAcpNotification — session/update dispatch > agent_message_chunk with text content → replyText += content.text [2.17ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > agent_thought_chunk with text → thoughtText, NOT replyText (grok discipline) [0.17ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > tool_call and tool_call_update both bump toolCalls [0.07ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > usage_update snaps totalTokens into state.usage [0.10ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > available_commands_update consumed silently (session-init only) [0.07ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > agent_message_chunk without text content adds a warning [0.10ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > unknown method returns ignored without mutating state [0.07ms]
(pass) reduceOpencodeAcpNotification — session/update dispatch > unknown sessionUpdate subtype returns ignored (forward-compat) [0.05ms]
(pass) reduceOpencodeAcpResponse — session/prompt terminal response > captures stopReason + usage from result [0.23ms]
(pass) reduceOpencodeAcpResponse — session/prompt terminal response > missing stopReason still marks turn complete [0.04ms]
(pass) reduceOpencodeAcpFrames — replay the Phase 0b captured turn > full one-word turn: 10 thought chunks + 1 message chunk + usage + response [0.38ms]
(pass) reduceOpencodeAcpFrames — replay the Phase 0b captured turn > thinking-only terminal turn (no agent_message_chunk) — replyText stays empty [0.16ms]

src/runtime/opencode-acp/child-env.test.ts:
(pass) buildOpencodeChildEnv — deny-by-default boundary > locks the exact hardened ancestor candidate set [0.12ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > rejects sticky world-writable /tmp instead of silently degrading [4.07ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > passes only runtime/network allowlist and controls all state roots [18.47ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > safe inline policy disables every local tool without replacing provider/model [12.10ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > unsafe opt-in explicitly overrides the wizard's persisted safe policy [9.90ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > detects exact managed config sources across Linux, Windows, and macOS [1.33ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > safe runtime renders ordinary same-uid config through a strict allowlist [17.08ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > copies only blessed API auth fields into fresh data and keeps persistent state outside the child [16.90ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > never exposes planted persistent DB/log/cache/state/tmp descendants in safe or unsafe mode [24.39ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > removes a partially built launch tree when env construction fails [12.67ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > pre-spawn revalidation hard-fails when an ancestor discovery candidate appears [17.11ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > keeps active roots but reclaims a dead-owner crash root without following symlinks [44.43ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > reclaims dead-owner roots after the node workDir is deleted or recreated [53.93ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > a transient cleanup pathname swap is retried after child exit [27.13ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > a dead owner marker is retained while an orphan child still references the root [51.35ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > an exact exited-process identity exemption never hides a live descendant or PID mismatch [50.46ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > rejects symlinks at workDir and every security-sensitive state layer [14.58ms]
(pass) buildOpencodeChildEnv — deny-by-default boundary > rejects permissive modes and foreign ownership without repairing them [1.31ms]

src/runtime/opencode-acp/profile-state.test.ts:
(pass) OpenCode private profile state > loads, atomically updates, backs up, and writes a session [12.43ms]
(pass) OpenCode private profile state > a post-load config symlink cannot redirect session writeback [1.04ms]
(pass) OpenCode private profile state > boot refuses a config symlink before self-heal can write its target [0.99ms]
(pass) OpenCode private profile state > backup refuses a pre-planted .prev symlink [0.72ms]
(pass) OpenCode private profile state > runtime hint rejects suspicious config leaves for every runtime [0.82ms]

src/runtime/opencode-acp/client.test.ts:
(pass) OpencodeAcpClient — request/response correlation > request() resolves with the matching response's result [71.63ms]
(pass) OpencodeAcpClient — request/response correlation > error response rejects the promise with a shaped message [66.81ms]
(pass) OpencodeAcpClient — streaming notifications > emits 'notification' for every session/update frame [70.16ms]
(pass) OpencodeAcpClient — streaming notifications > id-carrying reverse requests get an explicit method-not-found response [69.10ms]
(pass) OpencodeAcpClient — process lifecycle > child exit rejects all pending requests [64.57ms]
(pass) OpencodeAcpClient — process lifecycle > isRunning flips false after stop() [2.51ms]
(pass) OpencodeAcpClient — process lifecycle > explicit child env is not merged with the client's process.env [55.31ms]

src/runtime/opencode-acp/runtime.test.ts:
[opencode-acp] session/new — ses_test...
(pass) openOpencodeRuntime — cwd and tool policy > safe default keeps spawn + ACP session in one external launch workspace [168.23ms]
[opencode-acp] session/new — ses_probe_au...
(pass) openOpencodeRuntime — cwd and tool policy > version probe root is credential-free and gone before runtime auth is materialized [180.57ms]
[opencode-acp] session/load ok — resumed ses_existing...
(pass) openOpencodeRuntime — cwd and tool policy > safe session/load reuses the exact spawn PWD as its ACP cwd [142.37ms]
[opencode-acp] session/new — ses_test...
(pass) openOpencodeRuntime — cwd and tool policy > explicit unsafe flag restores project cwd and emits a trusted-task warning [121.00ms]
[opencode-acp] session/new — ses_evidence...
(pass) openOpencodeRuntime — cwd and tool policy > reports submission before exact prompt-response consumption [141.34ms]
[opencode-acp] session/new — ses_test...
(pass) openOpencodeRuntime — opening lifecycle > normal stop removes the launch root and copied vendor auth [131.47ms]
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
[opencode-acp] session/new — ses_test...
(pass) openOpencodeRuntime — opening lifecycle > repeated open/stop cycles do not accumulate launch roots [3262.64ms]
(pass) openOpencodeRuntime — opening lifecycle > an ancestor candidate planted by the version probe hard-fails before ACP spawn [64.37ms]
(pass) openOpencodeRuntime — opening lifecycle > package replacement after credential-free probe is rejected and runtime auth root is discarded [66.26ms]
(pass) openOpencodeRuntime — opening lifecycle > in-place binary self-modification after probe is rejected before credential spawn [68.04ms]
(pass) openOpencodeRuntime — opening lifecycle > production rejects canonical same-version packages below project cwd or node workDir [29.21ms]
(pass) openOpencodeRuntime — opening lifecycle > initialize failure force-kills the child before rejecting [134.02ms]
(pass) openOpencodeRuntime — opening lifecycle > onClient exposes a stalled-handshake child synchronously for shutdown [53.02ms]
[opencode-acp] session/new — ses_idle...
(pass) opencodeThink — failed-turn lifecycle > prompt idle timeout force-kills the child before rejecting [212.23ms]
[opencode-acp] session/new — ses_rescue_i...
[opencode-acp] #383 thinking-only terminal turn (chunks=0 thoughtChunks=1) — re-prompting for plain-text final
(pass) opencodeThink — failed-turn lifecycle > a failed thinking-only rescue discards the child before returning [163.96ms]

src/runtime/opencode-acp/binary.test.ts:
(pass) resolvePinnedOpencodeBinary > locks the non-root uid=gid umask-0002 compatibility policy [0.16ms]
(pass) resolvePinnedOpencodeBinary > accepts the canonical package entrypoint and probes it from the external cwd [43.50ms]
(pass) resolvePinnedOpencodeBinary > accepts an npm-style PATH shim but returns the canonical package binary [29.04ms]
(pass) resolvePinnedOpencodeBinary > rejects a same-version fake package inside the project before executing it [1.34ms]
(pass) resolvePinnedOpencodeBinary > rejects forged package metadata and noncanonical entrypoints [3.99ms]
(pass) resolvePinnedOpencodeBinary > rejects unsafe file, package-directory, ancestor, and owner modes [3.34ms]
(pass) resolvePinnedOpencodeBinary > still enforces exact --version output after package identity succeeds [24.39ms]
(pass) resolvePinnedOpencodeBinary > refuses a caller-selected version other than the vetted release pin [0.88ms]
(pass) resolvePinnedOpencodeBinary > rejects a same-version package in a monorepo ancestor before probing it [1.76ms]
(pass) resolvePinnedOpencodeBinary > discovers a workspace ancestor when the configured project leaf is absent [0.94ms]
(pass) resolvePinnedOpencodeBinary > launcher absolute path wins over a hostile search PATH [27.12ms]
(pass) resolvePinnedOpencodeBinary > rejects non-absolute overrides [0.23ms]

src/runtime/grok-build-acp/events.test.ts:
(pass) Grok ACP event reducer — fixture replay > T6 prompt fixture accumulates final reply chunks [4.02ms]
(pass) Grok ACP event reducer — fixture replay > T8 session/load skips replay chunks from the previous turn [1.18ms]
(pass) Grok ACP event reducer — fixture replay > T9 abort + resume accumulates only the resumed turn reply [0.93ms]

src/runtime/grok-build-acp/resume-hint.test.ts:
(pass) fetchUnresolvedOutbound > returns empty array when the hub has no outbound rows for this sender [0.51ms]
(pass) fetchUnresolvedOutbound > filters to only delivered/started status [0.32ms]
(pass) fetchUnresolvedOutbound > caps results at topN (preserves server-side recency order) [0.38ms]
(pass) fetchUnresolvedOutbound > forwards the sender alias and a sane limit to the listTasks hook (no node_id fallback path) [0.27ms]
(pass) fetchUnresolvedOutbound > #146 PR-4 二审 — sends from_node_id ONLY when probe confirmed server supports it [0.24ms]
(pass) fetchUnresolvedOutbound > #146 PR-4 二审 — without probe confirmation, never sends from_node_id (old-server safety) [0.18ms]
(pass) fetchUnresolvedOutbound > #146 PR-4 二审 — when probe explicitly returned false, falls back even with node_id available [0.16ms]
(pass) fetchUnresolvedOutbound > #146 PR-4 — empty / null nodeId falls back to from_name path [0.28ms]
(pass) fetchUnresolvedOutbound > graceful fallback when list_tasks throws — returns empty, does not propagate [0.29ms]
(pass) fetchUnresolvedOutbound > graceful fallback for malformed payloads — non-array tasks [0.24ms]
(pass) fetchUnresolvedOutbound > clamps absurd opts: topN > 50 is capped, limit > 100 is capped [0.17ms]
(pass) fetchUnresolvedOutbound > 二审 — drops rows whose from_node_id does not match ours (server bug defence) [0.25ms]
(pass) fetchUnresolvedOutbound > 二审 — when row has no from_node_id, falls back to from_name match [0.30ms]
(pass) fetchUnresolvedOutbound > 二审 — drops rows with NEITHER from_node_id nor from_name (conservative) [0.36ms]
(pass) fetchUnresolvedOutbound > 二审 — prefers from_node_id over from_name when both present (handles rename correctly) [0.27ms]
(pass) fetchUnresolvedOutbound > 二审 — when WE have no nodeId, identity check uses from_name only [0.24ms]
(pass) buildResumeHint > returns null for an empty list — caller skips the prepend with no noise [0.09ms]
(pass) buildResumeHint > single task is listed with target alias + task id (8-char) + content preview [0.36ms]
(pass) buildResumeHint > hint wording: explicit do-NOT-redispatch instruction in both Chinese phrasing and English keyword [0.17ms]
(pass) buildResumeHint > hint promotes send_message as the legitimate alternative for status check-ins [0.09ms]
(pass) buildResumeHint > hint mentions server-side dedup as a safety net but tells the LLM not to rely on it [0.10ms]
(pass) buildResumeHint > hint avoids to-do framing — would push the LLM into reprocessing [0.10ms]
(pass) buildResumeHint > long content is truncated to 120 chars including ellipsis [0.18ms]
(pass) buildResumeHint > content with triple-backticks is defanged (prevents code-fence injection from resumed task body) [0.07ms]
(pass) buildResumeHint > missing fields fall back gracefully without throwing [0.06ms]
(pass) buildResumeHint > multi-task list preserves order from the input (server-side recency) [0.11ms]

src/runtime/grok-build-acp/client.test.ts:
(pass) GrokAcpClient > starts the ACP server as `grok agent stdio` without inventing a model flag [102.18ms]
(pass) GrokAcpClient > handles ACP server-to-client fs and permission requests [71.10ms]
(pass) GrokAcpClient > coerces non-integer fs error codes to numeric JSON-RPC codes [65.89ms]
(pass) GrokAcpClient > requestWithIdleTimeout does not fire while agent is streaming notifications [798.73ms]
(pass) GrokAcpClient > requestWithIdleTimeout fires when agent goes silent past threshold [1209.87ms]
(pass) GrokAcpClient > preserves valid integer error codes [73.74ms]

src/runtime/grok-build-acp/timeout-resolve.test.ts:
(pass) resolveGrokAcpTimeout > env wins over flags and default (mirrors cli.ts precedence) [2.29ms]
(pass) resolveGrokAcpTimeout > flag wins over default when env is unset [0.08ms]
(pass) resolveGrokAcpTimeout > flag string is parsed (config.json values arrive as strings or numbers) [0.06ms]
(pass) resolveGrokAcpTimeout > default fires when neither env nor flag is set [0.10ms]
(pass) resolveGrokAcpTimeout > empty string env is ignored (operator unset the var) [0.06ms]
(pass) resolveGrokAcpTimeout > null and empty flag are ignored — falls through to default [0.10ms]
(pass) resolveGrokAcpTimeout > non-numeric / negative / NaN inputs fall through (the silent-default trap) [0.10ms]

src/runtime/grok-build-acp/runtime.test.ts:
(pass) runGrokAcpTurn runtime evidence > separates prompt submission from exact prompt-response consumption [92.73ms]

src/runtime/opencode-copresence/inbox-wiring.test.ts:
(pass) OpenCode copresence CommHub message wiring > work and informational drains are independent lanes [0.56ms]
(pass) OpenCode copresence CommHub message wiring > new_message SSE uses a non-blocking informational lane [0.18ms]
(pass) OpenCode copresence CommHub message wiring > message is displayed as a non-replying TUI notification in the fast drain [0.19ms]
(pass) OpenCode copresence CommHub message wiring > the task drain does not claim OpenCode copresence messages [0.20ms]
(pass) OpenCode copresence CommHub message wiring > network tasks pass their authenticated sender into the shared TUI turn [0.14ms]
(pass) OpenCode copresence CommHub message wiring > startup and SSE reconnect both recover pending informational messages [0.31ms]
(pass) OpenCode copresence CommHub message wiring > runtime startup is single-flight and shutdown waits for an in-flight open [0.15ms]
(pass) OpenCode copresence CommHub message wiring > tmux SIGHUP enters the same cleanup path as SIGTERM [0.45ms]

src/runtime/opencode-copresence/runtime.test.ts:
(pass) OpenCode native serve+attach copresence > requires an explicit provider/model for production copresence [0.37ms]
(pass) OpenCode native serve+attach copresence > requires an explicit provider/model at the vetted launch seam too [1.60ms]
(pass) OpenCode native serve+attach copresence > wires one token-bound CommHub MCP without reopening local tools [1.93ms]
(pass) OpenCode native serve+attach copresence > uses one authenticated loopback session for FIFO network turns and emits an owner-only attach launcher [250.10ms]
(pass) OpenCode native serve+attach copresence > shows the network sender in both the toast title and message body [174.03ms]
(pass) OpenCode native serve+attach copresence > shows the normalized network-task sender in the shared TUI turn [203.30ms]
(pass) OpenCode native serve+attach copresence > waits for an already-busy human session before injecting a network turn [618.29ms]
(pass) OpenCode native serve+attach copresence > refuses a reply owned by a human turn that won the idle-to-submit race [147.93ms]
(pass) OpenCode native serve+attach copresence > uses OpenCode's ascending message ID shape across sequential network turns [229.37ms]
(pass) OpenCode native serve+attach copresence > does not treat a missing session status and missing session record as idle [481.28ms]
(pass) OpenCode native serve+attach copresence > binds teardown authority to a detached pid, pgrp, and process start ticks [2.14ms]

src/runtime/codex-app-server/session-manager.test.ts:
(pass) createCodexSessionManager > the production Codex inbox path is wired through the shared holder [1.43ms]
(pass) createCodexSessionManager > concurrent Dashboard handlers share one complete open attempt [1.04ms]
(pass) createCodexSessionManager > a rejected open is cleared and the next row can retry [0.42ms]
(pass) createCodexSessionManager > stopped and explicitly invalidated sessions are never reused [0.28ms]
(pass) createCodexSessionManager > a session that dies during bootstrap is not published [0.19ms]

src/runtime/codex-app-server/runtime.test.ts:
(pass) buildOwnedAppServerArgs > no opts → bare app-server (codex defaults apply) [0.12ms]
(pass) buildOwnedAppServerArgs > approval_policy only → single -c override before --listen [0.06ms]
(pass) buildOwnedAppServerArgs > sandbox_mode only → single -c override [0.03ms]
(pass) buildOwnedAppServerArgs > auto-approve posture (never + danger-full-access) → both overrides, policy first [0.04ms]
(pass) buildOwnedAppServerArgs > commhubMcpUrl → adds url + bearer-token-env-var -c overrides [0.08ms]
(pass) buildOwnedAppServerArgs > the CommHub bearer TOKEN never appears in argv (only the env-var NAME) [0.15ms]
(pass) buildOwnedAppServerArgs > full production posture (yolo + commhub MCP) → stable order, --listen last [0.13ms]
(pass) recoverSharedTurnOnAttach > invokes persisted active-turn recovery before shared runtime is returned [0.51ms]
(pass) recoverSharedTurnOnAttach > history read failure is visible and never reported as steerable [0.36ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > FIFO admission reports neither submission nor consumption [22.79ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > exact runtime submission and task_started report each level once [0.76ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > exact task activity resets the response idle deadline for a long-running turn [73.26ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > activity from another task cannot keep a silent owned task alive [57.59ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > a started task whose client identity never confirms has a bounded, distinct response timeout [26.43ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > a never-started FIFO task has its own finite, distinct queue deadline [80.77ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > lost task_started after FIFO removal remains finite [80.83ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > a failed start or steer requeued after the queue deadline cannot leave a ghost row [112.58ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > queued wait does not consume the model-response timeout budget [92.62ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > another task starting cannot arm this task's timeout [114.66ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > resolves from authoritative reconciliation when turn/completed is missed [7.53ms]
(pass) codexAppServerThink — terminal-event reconciliation watchdog > forwards the authenticated Dashboard steering decision to the bridge [5.49ms]
(pass) codexAppServerReplyOrThrow > failed bridge outcomes enter processTask's thrown failure path [0.47ms]
(pass) codexAppServerReplyOrThrow > successful empty replies preserve the existing fallback [0.08ms]

 1281 pass
 0 fail
 4365 expect() calls
Ran 1281 tests across 91 files. [116.25s]
[L0b] every agent-node/tests file, dispatched by kind
tests_dir_executed=6 tests_dir_discovered=6 tests_dir_failed=0
[L1] witnessed-red: disconnect readable attachment content from runtime
MUTATION_RED readable-attachment-runtime-disconnected rc=1
RESULT: PASS
```
## test745
```
# test745 — complete agent-network unit domain
source_commit=1e9e75dab635dc03d12636232ebc2ac117c2dee6
bun=1.3.14 node=v22.23.2 git=git version 2.39.5 uid=1000
test_files=46
[L0] full agent-network/src unit suite as non-root
bun test v1.3.14 (0d9b296a)

src/cli-args.test.ts:
(pass) CLI argument parsing > pins the complete presence-only flag set [0.18ms]
(pass) CLI argument parsing > --accept-dev-channels does not swallow a following positional operand [0.46ms]
(pass) CLI argument parsing > --accept-dev-channels works after a positional operand [0.11ms]
(pass) CLI argument parsing > --dev-open does not swallow a following positional operand [0.02ms]
(pass) CLI argument parsing > --dev-open works after a positional operand [0.02ms]
(pass) CLI argument parsing > --dry-run does not swallow a following positional operand [0.01ms]
(pass) CLI argument parsing > --dry-run works after a positional operand
(pass) CLI argument parsing > --follow does not swallow a following positional operand
(pass) CLI argument parsing > --follow works after a positional operand
(pass) CLI argument parsing > --no-auto-self does not swallow a following positional operand
(pass) CLI argument parsing > --no-auto-self works after a positional operand [0.01ms]
(pass) CLI argument parsing > --no-yolo does not swallow a following positional operand [0.01ms]
(pass) CLI argument parsing > --no-yolo works after a positional operand
(pass) CLI argument parsing > --resume-latest does not swallow a following positional operand
(pass) CLI argument parsing > --resume-latest works after a positional operand
(pass) CLI argument parsing > --self does not swallow a following positional operand [0.02ms]
(pass) CLI argument parsing > --self works after a positional operand
(pass) CLI argument parsing > --f does not swallow a following positional operand [0.02ms]
(pass) CLI argument parsing > --f works after a positional operand
(pass) CLI argument parsing > presence-only flags do not accept an explicit true or false value [0.07ms]
(pass) CLI argument parsing > value flags, repeatable flags, and multiple positionals retain their behavior [0.12ms]
(pass) CLI argument parsing > key=value remains unsupported and is treated as the complete key [0.11ms]

src/normalize-runtime.test.ts:
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > legacy normalization: unknown string → claude-agent-sdk [0.22ms]
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > empty string → claude-agent-sdk [0.04ms]
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > undefined (no arg) → claude-agent-sdk [0.03ms]
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > undefined profile arg → claude-agent-sdk [0.05ms]
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > profile with missing runtime field → claude-agent-sdk [0.05ms]
(pass) normalizeRuntime — fallback default is claude-agent-sdk (Vincent no-Max) > profile with empty-string runtime field → claude-agent-sdk [0.04ms]
(pass) normalizeRuntimeStrict — execution boundaries fail closed > missing and empty runtime still select the documented default [0.14ms]
(pass) normalizeRuntimeStrict — execution boundaries fail closed > canonical names and supported aliases are accepted [0.06ms]
(pass) normalizeRuntimeStrict — execution boundaries fail closed > a non-empty unknown runtime is rejected [0.25ms]
(pass) normalizeRuntime — explicit choices are preserved > explicit 'claude-code-cli' → claude-code-cli (operator opt-in still works) [0.04ms]
(pass) normalizeRuntime — explicit choices are preserved > explicit 'claude-agent-sdk' → claude-agent-sdk [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'claude' → claude-agent-sdk (existing canonicalization) [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'claude-sdk' → claude-agent-sdk [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'agent-sdk' (string form) → claude-agent-sdk [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > 'codex' / 'codex-sdk' → codex-sdk [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > 'grok' / 'grok-build' / 'grok-build-acp' → grok-build-acp [0.05ms]
(pass) normalizeRuntime — explicit choices are preserved > explicit Grok co-presence names → grok-build-cli [0.06ms]
(pass) normalizeRuntime — explicit choices are preserved > explicit 'opencode-cli' → opencode-cli (canonical launcher name) [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'opencode' → opencode-cli (short form) [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > profile with runtime='opencode-cli' → opencode-cli [0.05ms]
(pass) normalizeRuntime — explicit choices are preserved > profile with runtime='opencode' → opencode-cli [0.04ms]
(pass) normalizeRuntime — explicit choices are preserved > explicit 'codex-app-server' → codex-app-server [0.02ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'codex-tui' → codex-app-server [0.25ms]
(pass) normalizeRuntime — explicit choices are preserved > alias 'codex-appserver' → codex-app-server [0.04ms]
(pass) normalizeRuntime — explicit choices are preserved > 'codex-sdk' still → codex-sdk (not shadowed by the app-server branch) [0.05ms]
(pass) normalizeRuntime — explicit choices are preserved > 'codex' still → codex-sdk (legacy short alias unchanged) [0.03ms]
(pass) normalizeRuntime — explicit choices are preserved > profile with runtime='codex-app-server' → codex-app-server [0.04ms]
(pass) normalizeRuntime — profile object paths > profile with runtime='claude-code-cli' → claude-code-cli (explicit, preserved) [0.03ms]
(pass) normalizeRuntime — profile object paths > profile with runtime='agent-sdk' + codexRuntime='codex' → codex-sdk (legacy hybrid) [0.04ms]
(pass) normalizeRuntime — profile object paths > profile with runtime='agent-sdk' + no codexRuntime → claude-agent-sdk [0.03ms]
(pass) normalizeRuntime — profile object paths > legacy profile normalization keeps unknown → default for display/migration [4.15ms]

src/batch-workdir-wiring.test.ts:
(pass) batch workdir wiring > normalizes create workdir before mkdir or chdir [0.86ms]
(pass) batch workdir wiring > normalizes cleanup workdir before filesystem mutation [0.36ms]

src/top-level-help-contract.test.ts:
(pass) top-level help matches the implemented command parsers > advertises only the implemented config and batch shapes [289.50ms]
(pass) top-level help matches the implemented command parsers > includes the provider required by opencode auth-login [219.84ms]

src/opencode-pin.test.ts:
(pass) opencode-pin — built-in fallback > release builtin pin is the revalidated opencode-ai@1.18.1 [0.29ms]
(pass) opencode-pin — built-in fallback > returns the built-in constant when no override file exists [0.57ms]
(pass) opencode-pin — built-in fallback > missing/untrusted package hint preserves detail and exact install command [0.27ms]
(pass) opencode-pin — override file write + read round-trip > a smoke marker for the exact release pin is recognized [1.36ms]
(pass) opencode-pin — override file write + read round-trip > a locally-smoked different version cannot override the release pin [0.43ms]
(pass) opencode-pin — validation refuses malformed / unvalidated overrides > hand-edited file with version but NO smokePassedAt → falls back to built-in [0.36ms]
(pass) opencode-pin — validation refuses malformed / unvalidated overrides > version string doesn't match semver → falls back to built-in [0.34ms]
(pass) opencode-pin — validation refuses malformed / unvalidated overrides > smokePassedAt not an ISO timestamp → falls back to built-in [0.34ms]
(pass) opencode-pin — validation refuses malformed / unvalidated overrides > malformed JSON → falls back to built-in without throwing [0.95ms]

src/tmux-attach.test.ts:
(pass) tmux attach resolution > parses opaque IDs and Unicode names [0.81ms]
(pass) tmux attach resolution > selects the exact TUI instead of prefix siblings [0.21ms]
(pass) tmux attach resolution > does not fall back to a bridge or node session [0.06ms]

src/owner-env-file.test.ts:
(pass) loadOwnerOnlyEnvFile > loads the isolated commhub credential without overriding explicit identity [1.16ms]
(pass) loadOwnerOnlyEnvFile > rejects relative, broad-mode, and symlinked credential files [0.77ms]

src/opencode-owner-mode.test.ts:
(pass) OpenCode owner/mode policy > accepts umask-0002 modes only for a non-root uid=gid layout [0.12ms]
(pass) OpenCode owner/mode policy > always rejects world write and keeps root/foreign ownership strict [0.08ms]

src/channel-attachments.test.ts:
(pass) Claude channel attachments > pins the readable extension allowlist as an exact value set [0.57ms]
(pass) Claude channel attachments > cache roots are alias-isolated even for path-shaped aliases [0.41ms]
(pass) Claude channel attachments > downloads an authenticated Dashboard PNG and surfaces an owner-local Read path [4.77ms]
(pass) Claude channel attachments > downloads an authenticated non-image file for the Read-capable channel [2.53ms]
(pass) Claude channel attachments > does not fetch or inject a non-allowlisted file type [0.26ms]
(pass) Claude channel attachments > download failure preserves the original text and exposes no token [0.72ms]
(pass) Claude channel attachments > rejects traversal-shaped file ids before any fetch [0.33ms]
(pass) Claude channel attachments > does not trust a sender-provided local path [0.66ms]

src/codex-model-default.test.ts:
(pass) Codex model defaults > all Codex creation runtime spellings use the supported default [0.13ms]
(pass) Codex model defaults > shared Codex choice catalog has one supported default [0.12ms]

src/copresence-identity.test.ts:
(pass) Test 1: UUID round-trip > writeMarker persists exactly the provided uuid (single source of truth) [4.48ms]
(pass) Test 1: UUID round-trip > writeMarker refuses empty uuid (guard against silent regeneration) [0.42ms]
(pass) Test 1: UUID round-trip > writeMarker refuses non-string uuid [0.32ms]
(pass) Test 2: enumeration failure is loud (fail-closed) > verifyGroupHomogeneity fails-closed when listAllPids throws [1.10ms]
(pass) Test 2: enumeration failure is loud (fail-closed) > verifyGroupHomogeneity fails-closed when a member's environ read throws [0.65ms]
(pass) Test 2: enumeration failure is loud (fail-closed) > verifyGroupHomogeneity fails-closed when a stat read throws [0.31ms]
(pass) Test 3: foreign member in PGID → SKIP > group with unmarked co-resident refuses homogeneity [0.27ms]
(pass) Test 3: foreign member in PGID → SKIP > group where every member carries the marker is ok [0.24ms]
(pass) Test 4: main-dead-child-alive (environ scan is authority) > scan finds workers even when marker's stored pids are gone [0.80ms]
(pass) Test 5: child setsid → new PGID > detached child grouped under its current pgid, not marker's stored pgid [0.37ms]
(pass) Test 6: PID-reuse defense is the boot_id + environ-scan invariant > environ scan only returns pids whose current environ carries the uuid [0.27ms]
(pass) Test 7: partial-start rollback (marker gate) > MISSING marker after partial start prevents any process action [0.38ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > null body → SCHEMA_INVALID (no TypeError from `in` operator) [0.53ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > bare number → SCHEMA_INVALID [0.42ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > empty array → SCHEMA_INVALID [0.60ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > empty object → SCHEMA_INVALID (missing required fields) [0.60ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > wrong types in schema → SCHEMA_INVALID [0.59ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > syntactically invalid JSON → PARSE_ERROR [0.50ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > wrong mode → WRONG_MODE (even with valid JSON) [0.52ms]
(pass) Test 8: malformed marker → structured refuse (never throws) > symlink → SYMLINK (refuses to follow) [0.57ms]
(pass) Test 8b: filesystem/environment refuse guards (mutation-sensitive) > NOT_REGULAR: directory at marker path with mode 0600 (skips SYMLINK+WRONG_MODE) [0.49ms]
(pass) Test 8b: filesystem/environment refuse guards (mutation-sensitive) > OWNER_MISMATCH: valid marker file whose lstat.uid differs from process.getuid() (SECURITY CRITICAL) [3.00ms]
(pass) Test 8b: filesystem/environment refuse guards (mutation-sensitive) > STALE_BOOT_ID: valid schema but boot_id differs from current /proc boot_id [0.95ms]
(pass) Test 9: self-context refuses stop from within the tree > caller's own environ carrying the marker is detected [0.38ms]
(pass) Test 9: self-context refuses stop from within the tree > ancestor carrying the marker is detected via PPID walk [0.31ms]
(pass) Test 9: self-context refuses stop from within the tree > clean caller (no marker in ancestry) returns self=false [0.26ms]
(pass) Test 10: non-copresence codex-app-server → legacy path (zero diff) > readMarker returns MISSING for an ordinary codex-app-server node dir [0.64ms]
(pass) Test 11: 二次 stop is idempotent (MISSING = already stopped) > 2nd read after successful removeMarker returns MISSING (no side effects) [2.68ms]
(pass) Test 11: 二次 stop is idempotent (MISSING = already stopped) > removeMarker on already-missing marker does not throw [0.36ms]
(pass) reapMarkerGroups: end-to-end (mocked /proc + kill) > verified groups get SIGTERM, still-alive groups then get SIGKILL [6.58ms]
(pass) reapMarkerGroups: end-to-end (mocked /proc + kill) > groups with foreign members are SKIPPED, never signaled [2.38ms]
(pass) reapMarkerGroups: end-to-end (mocked /proc + kill) > no marker-carrying pids anywhere → immediate success (idempotent) [0.47ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > other-user EACCES on environ → skip that pid (expected, not fail) [0.65ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > Defect A defense: own-uid EACCES pid IN SCOPE (anchored) → reap refuses to delete marker [0.97ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > Blocker 1: own-uid EACCES pid OUT OF SCOPE → informational only, teardown still succeeds [1.25ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > Blocker 1: unreadable pid sharing a marker carrier's PGROUP is in scope (no anchors needed) [0.42ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > Blocker 8/invariant 5: an anchor whose starttime no longer matches is REJECTED (pid reuse) [0.39ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > Blocker 7: post-kill RESCAN unreadable half also preserves the marker [0.76ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > zombie process environ EACCES → skip (mm freed, expected) [0.45ms]
(pass) Blocker 1: scanEnvironForMarker EACCES discrimination > EACCES-carrying process that vanishes during discrimination → skip [0.40ms]
(pass) Blocker 2: verifyGroupHomogeneity zombie discrimination + EMPTY_GROUP > group containing a zombie same-uid member still verifies OK for the live marker members [0.41ms]
(pass) Blocker 2: verifyGroupHomogeneity zombie discrimination + EMPTY_GROUP > group containing an other-user EACCES member still verifies OK for our members [0.34ms]
(pass) Blocker 2: verifyGroupHomogeneity zombie discrimination + EMPTY_GROUP > empty group (no live marker members) → EMPTY_GROUP refuse (never ok:true) [0.25ms]
(pass) Blocker 2: verifyGroupHomogeneity zombie discrimination + EMPTY_GROUP > own-uid non-zombie unreadable → ENUM_ERROR (fail-closed) [0.23ms]
(pass) Finding #2: killPgroup pgid<=0 guard > realKiller().killPgroup(0, TERM) throws — kill(-0) would target caller's own pgroup [0.39ms]
(pass) Finding #2: killPgroup pgid<=0 guard > realKiller().pgroupAlive(0) throws [0.34ms]
(pass) Finding #3: reapMarkerGroups uses async sleep (not busy-wait) > grace period is truly asynchronous — event loop ticks during it [103.67ms]
(pass) Finding #3: reapMarkerGroups uses async sleep (not busy-wait) > injected sleep function is used (tests can override with fast/deterministic version) [1.32ms]
(pass) Finding #7: readMarker PLATFORM_UNSUPPORTED on non-Linux > on non-Linux, readMarker refuses cleanly regardless of on-disk state [3.27ms]
(pass) Finding #4: writeMarker accepts partial sessions object > writeMarker with only appsrv session succeeds and readMarker returns ok [3.95ms]
(pass) Finding #4: writeMarker accepts partial sessions object > writeMarker with empty sessions object still succeeds (uuid is what matters) [3.80ms]
(pass) Blocker 3: verifyGroupHomogeneity stat-unreadable pids are bounded by ownership > an unrelated OTHER-uid pid whose stat is unreadable does NOT poison the group [0.47ms]
(pass) Blocker 3: verifyGroupHomogeneity stat-unreadable pids are bounded by ownership > a pid hidden so thoroughly that even its uid is unknown does NOT poison the group [0.43ms]
(pass) Blocker 3: verifyGroupHomogeneity stat-unreadable pids are bounded by ownership > an OWN-uid pid whose stat is unreadable still fails closed (we cannot rule out membership) [0.31ms]
(pass) Blocker 4: readMarker checks MISSING before PLATFORM_UNSUPPORTED > non-Linux + NO marker file → MISSING (silent legacy fall-through, no scary warning) [0.44ms]
(pass) Blocker 4: readMarker checks MISSING before PLATFORM_UNSUPPORTED > non-Linux + marker file present → PLATFORM_UNSUPPORTED (we genuinely cannot act on it) [2.61ms]
(pass) Blockers 5+6: prepareIdentityForStart > no marker on disk → writes the new marker, reaps nothing [1.35ms]
(pass) Blockers 5+6: prepareIdentityForStart > Blocker 6: a PRESERVED marker is reaped by its OWN uuid before the new one is written [0.88ms]
(pass) Blockers 5+6: prepareIdentityForStart > Blocker 6: if the old generation cannot be reaped, start is BLOCKED and nothing is overwritten [0.54ms]
(pass) Blockers 5+6: prepareIdentityForStart > a marker from a previous BOOT is discarded without a reap (its pids cannot exist) [0.51ms]
(pass) Blockers 5+6: prepareIdentityForStart > an unreadable/suspicious marker BLOCKS start rather than overwriting it [0.68ms]
(pass) Blockers 5+6: prepareIdentityForStart > Blocker 5: the marker is written with an EMPTY sessions object (before any session exists) [0.38ms]
(pass) Blockers 5+6: prepareIdentityForStart > refuses an empty uuid (guards against a silently regenerated identity) [0.51ms]

src/claude-vendor-env-wiring.test.ts:
(pass) node create captures vendor shell env before profile construction [0.25ms]
(pass) every dotenv-writing create preflights before any node-state side effect [0.24ms]
(pass) the dotenv writer itself reuses the side-effect-free planner [0.17ms]

src/copresence-cli-wiring.test.ts:
(pass) cli.ts copresence start ordering (structural gate) > the copresence start path really does create tmux sessions with -e (anchor for the tests below) [0.06ms]
(pass) cli.ts copresence start ordering (structural gate) > Blocker 5: prepareIdentityForStart runs BEFORE the first tmux new-session [0.05ms]
(pass) cli.ts copresence start ordering (structural gate) > Blocker 5: no marker write happens before the identity preparation call [0.07ms]
(pass) cli.ts copresence start ordering (structural gate) > Blocker 6: a blocked preparation aborts the start (never falls through to session creation) [0.07ms]
(pass) cli.ts copresence start ordering (structural gate) > Blocker 12: the tmux capability preflight runs BEFORE the first tmux new-session [0.04ms]
(pass) cli.ts copresence stop wiring (structural gate) > Blockers 1+2: the stop-time reap is given the marker's recorded pids as scope anchors [0.21ms]
(pass) cli.ts copresence stop wiring (structural gate) > marker removal happens only on a successful reap [0.24ms]

src/grok-copresence-disclosure.test.ts:
(pass) grok co-presence disclosure > default profile reports the exact three tools and no web [0.18ms]
(pass) grok co-presence disclosure > WebSearch profile reports general web_search without widening other tools [0.10ms]
(pass) grok co-presence disclosure > near-match tools are disclosed as invalid rather than a reviewed profile [0.14ms]
(pass) grok co-presence disclosure > resume warns that a changed config cannot mutate the existing session [0.08ms]

src/opencode-agent-node-pair.test.ts:
(pass) OpenCode agent-node release pairing > pins the exact versions being released together [0.09ms]
(pass) OpenCode agent-node release pairing > rejects latest 2.4.x-style help and accepts the RFC-029 capability [0.08ms]
(pass) OpenCode agent-node release pairing > admits only the exact preview package identity with safe file modes [9.44ms]
(pass) OpenCode agent-node release pairing > skips an exact project-local impersonator and selects the later global package [6.25ms]

src/batch-workdir.test.ts:
(pass) normalizeBatchWorkdir > expands current-user tilde before a batch changes cwd [0.25ms]
(pass) normalizeBatchWorkdir > anchors a relative workdir once to the caller cwd [0.07ms]
(pass) normalizeBatchWorkdir > keeps an absolute workdir absolute [0.04ms]
(pass) normalizeBatchWorkdir > rejects empty and unsupported named-user shorthands [0.24ms]

src/copresence-identity.real.test.ts:
(pass) REAL /proc integration (Linux only) > A: scan on real /proc with a nonce uuid does not throw and finds nothing [1.35ms]
(pass) REAL /proc integration (Linux only) > B: live marker member + REAL zombie sibling in the same pgroup → homogeneity ok:true (escalation stays possible) [118.74ms]
(pass) REAL /proc integration (Linux only) > C: readEnviron(1) EACCESes and readOwnerUid(1) is root (non-root only) [0.28ms]
(pass) REAL /proc integration (Linux only) > D: POSITIVE — spawned marker carrier is found by the scan [28.34ms]
(pass) REAL /proc integration (Linux only) > E: END-TO-END — scan → group → homogeneity all succeed on real /proc [30.82ms]
(pass) REAL /proc integration (Linux only) > F: REAL REAP — reapMarkerGroups(realEnumerator, realKiller) kills a real carrier and returns success [378.32ms]
(pass) REAL /proc integration (Linux only) > G: CLEAN-HOST REAP — nothing carries the uuid → success on THIS host (blocker 1 regression) [1.21ms]
(pass) REAL /proc integration (Linux only) > H: NON-DUMPABLE — marker-carrying non-dumpable child of a carrier is accounted for, not dropped (blocker 2) [97.31ms]
(pass) REAL /proc integration (Linux only) > I: readOwnerUid reports the REAL uid of a non-dumpable process (environ inode owner lies) [52.27ms]
(pass) REAL /proc integration (Linux only) > J: REAL START SEAM — prepareIdentityForStart reclaims a live previous generation and installs the new marker [342.30ms]
(pass) REAL /proc integration (Linux only) > K: REAL START SEAM — a previous generation that cannot be reaped BLOCKS the start and its marker survives [92.22ms]
(pass) REAL /proc integration (Linux only) > L: anchorsFromMarker feeds real recorded pane pids into the scope test [28.44ms]

src/claude-code-cli-tty-preflight.test.ts:
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > body contains the claude-code-cli spawn (anchor for the assertions below) [0.10ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Refuse: non-TTY stdin preflight fires BEFORE the claude spawn [0.11ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Refuse: non-TTY branch exits non-zero [0.23ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Refuse: message names claude-code-cli and recommends --accept-dev-channels first (--tmux listed with its precondition) [0.25ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Success gate: 'session pinned' / 'session saved' only fires on exit code 0 [0.22ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Exit-code propagation: non-zero child exit calls process.exit(code) [0.16ms]
(pass) claude-code-cli spawn preflight (#486 P0 regression gate) > Spawn-error path: child.on('error') exits non-zero (was silent → false success) [0.10ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > body contains the --tmux branch (anchor) [0.06ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > --tmux branch has a headless (no-TTY) codepath (`new-session -d`) [0.11ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > --tmux headless: does NOT inherit stdin on detached spawn (was `stdio:"inherit"`) [0.13ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > --tmux headless: verifies session liveness after detached spawn [0.16ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > --tmux headless: propagates non-zero exit on failure paths [0.10ms]
(pass) --tmux escape-hatch headless (#486 CR regression gate) > --tmux headless: prints attach hint after successful startup [0.08ms]

src/dashboard-managed-process.test.ts:
(pass) managed Dashboard listener decisions > empty port starts; same healthy managed release remains untouched [0.48ms]
(pass) managed Dashboard listener decisions > only an exact managed stale npx listener may be terminated [0.11ms]
(pass) managed Dashboard listener decisions > unmanaged, ambiguous, reused, foreign, and global listeners fail closed [0.25ms]
(pass) record parser and command identity reject malformed state [0.19ms]

src/token-cli.test.ts:
(pass) parseTokenCreateName > keeps the legacy positional form [0.19ms]
(pass) parseTokenCreateName > accepts separated and equals --name forms [0.08ms]
(pass) parseTokenCreateName > fails closed for missing, empty, unknown, mixed, or extra operands [0.17ms]

src/cli-args-wiring.test.ts:
(pass) CLI option and positional parsing share cli-args.ts [3.19ms]

src/private-state.test.ts:
(pass) #472 private state writer > publishes 0600 files and 0700 parent under umask 0 [4.29ms]
(pass) #472 private state writer > publishes 0600 files and 0700 parent under umask 2 [3.41ms]
(pass) #472 private state writer > publishes 0600 files and 0700 parent under umask 22 [3.21ms]
(pass) #472 private state writer > publishes 0600 files and 0700 parent under umask 77 [3.13ms]
(pass) #472 private state writer > atomically replaces a legacy 0664 target with a 0600 inode [4.18ms]
(pass) #472 private state writer > replaces a leaf symlink instead of writing through it [4.29ms]
(pass) #472 private state writer > repairs a legacy file and parent before reading [0.68ms]
(pass) #472 private state writer > read repair refuses a symlink instead of chmod-following it [0.82ms]

src/tmux-capability.test.ts:
(pass) parseTmuxVersion > parses the shapes real tmux builds print [0.49ms]
(pass) parseTmuxVersion > returns null when there is no version to find [0.08ms]
(pass) tmuxSupportsSessionEnv > 3.2 is the floor; the letter suffix is a patch marker and never lifts a version over it [0.14ms]
(pass) tmuxSupportsSessionEnv > major version dominates the minor comparison [0.07ms]
(pass) checkTmuxCapability > too old → actionable verdict naming the required version [0.30ms]
(pass) checkTmuxCapability > tmux absent → missing verdict, not a crash [0.22ms]
(pass) checkTmuxCapability > unparseable version → unknown (permissive: never refuse a tmux that may be fine) [0.13ms]
(pass) checkTmuxCapability > modern tmux → ok [0.08ms]
(pass) assertTmuxSupportsSessionEnv (cli wrapper) > old tmux aborts the start with an explanation [0.40ms]
(pass) assertTmuxSupportsSessionEnv (cli wrapper) > missing tmux aborts the start [0.14ms]
(pass) assertTmuxSupportsSessionEnv (cli wrapper) > modern tmux is silent and does not abort [0.07ms]
(pass) assertTmuxSupportsSessionEnv (cli wrapper) > unknown version warns but does NOT abort [0.12ms]

src/opencode-launch-env.test.ts:
(pass) hardenOpencodeAgentNodeEnv > restores launcher PATH and strips every pre-entrypoint loader hook [0.56ms]
(pass) hardenOpencodeAgentNodeEnv > does not mutate the caller's env object [0.18ms]
(pass) hardenOpencodeAgentNodeEnv > strips case-variant loader and PATH keys for Windows semantics [0.13ms]

src/secret-shell-guidance.test.ts:
(pass) #379 secret shell guidance > keeps the existing POSIX export form [0.23ms]
(pass) #379 secret shell guidance > uses PowerShell syntax and quote escaping on Windows [0.07ms]

src/opencode-auth-login.test.ts:
(pass) OpenCode manual auth-login sandbox > builds deterministic provider-specific API-key login argv [0.52ms]
(pass) OpenCode manual auth-login sandbox > uses a fresh all-XDG tree and strips ambient credentials/config hooks [30.14ms]
(pass) OpenCode manual auth-login sandbox > strictly consumes only the selected provider API record through a private leaf [20.79ms]
(pass) OpenCode manual auth-login sandbox > refuses OAuth, mixed-provider and symlink auth shapes without disclosing secrets [23.01ms]
(pass) OpenCode manual auth-login sandbox > persistent planted DB/log links are never exposed and cleanup never follows descendant links [23.81ms]
(pass) OpenCode manual auth-login sandbox > cleanup unlinks a swapped root symlink but never removes its outside target [18.38ms]
(pass) OpenCode manual auth-login sandbox > cleanup quarantines the tracked inode but leaves a regular root-name replacement untouched [18.67ms]
(pass) OpenCode manual auth-login sandbox > a live tracked root whose literal name ends in deleted is still removed [15.68ms]
(pass) OpenCode manual auth-login sandbox > Linux reports nlink zero for a removed directory retained by fd [9.12ms]
(pass) OpenCode manual auth-login sandbox > cleanup retains inode ownership after bounded failure and succeeds on retry [22.50ms]
(pass) OpenCode manual auth-login sandbox > refuses a concurrent live owner marker [18.22ms]
(pass) OpenCode manual auth-login sandbox > refuses a provider that does not match the node's unique configured preset [12.61ms]
(pass) OpenCode manual auth-login sandbox > prunes a dead owner's stale root without following its planted links [35.52ms]
(pass) OpenCode manual auth-login sandbox > PID reuse does not retain a stale credential root [29.44ms]
(pass) OpenCode manual auth-login sandbox > stale sweep resumes a crash-left quarantine while its owner marker remains [28.32ms]
(pass) OpenCode manual auth-login sandbox > stale sweep removes an empty quarantine left after marker-last deletion [15.26ms]
(pass) OpenCode manual auth-login sandbox > spawn-time revalidation rejects a hostile ancestor discovery candidate [15.70ms]
(pass) OpenCode manual auth-login sandbox > with helper always cleans the fresh root when the action throws [15.04ms]

src/node-start-help.test.ts:
(pass) #518 node start help exposes the recommended headless flag > real `anet node start --help` names --accept-dev-channels and its operating boundary [169.49ms]
(pass) #518 node start help exposes the recommended headless flag > asking for help performs no node-start work [162.59ms]

src/claude-code-cli-dependency-preflight.test.ts:
(pass) #485 claude-code-cli dependency preflight > create remains a warning while start fails closed [0.15ms]
(pass) #485 claude-code-cli dependency preflight > dependency refusal runs before launch side effects [0.07ms]

src/bootstrap-password-db.test.ts:
(pass) bootstrap password database binding > turns the local default into an explicit absolute path [0.64ms]
(pass) bootstrap password database binding > anchors a relative COMMHUB_DB to the hub launch cwd [0.19ms]
(pass) bootstrap password database binding > rejects an unusable default before opening a database [0.26ms]
(pass) bootstrap password database binding > does not invent a SQLite target for a PostgreSQL Hub [0.30ms]
(pass) bootstrap password database binding > updates only the explicitly resolved database, never ambient HOME [70.26ms]
(pass) bootstrap password database binding > child refuses a missing explicit path without falling back to HOME [44.90ms]

src/gitignore-writeback.test.ts:
(pass) ensureGitignoreRule — file does not exist > creates file with the rule + trailing newline [2.81ms]
(pass) ensureGitignoreRule — file does not exist > trims surrounding whitespace from the rule before writing [0.58ms]
(pass) ensureGitignoreRule — file exists, rule absent > appends rule and reports 'appended' [0.77ms]
(pass) ensureGitignoreRule — file exists, rule absent > adds missing trailing newline before appending [0.87ms]
(pass) ensureGitignoreRule — file exists, rule absent > empty file → appended, not created [0.59ms]
(pass) ensureGitignoreRule — rule already present (idempotent) > exact match returns already-present + does not modify file [0.40ms]
(pass) ensureGitignoreRule — rule already present (idempotent) > trimmed match (rule with surrounding whitespace) treats as present [0.35ms]
(pass) ensureGitignoreRule — rule already present (idempotent) > commented-out rule does NOT count as present [0.33ms]
(pass) ensureGitignoreRule — rule already present (idempotent) > multiple invocations are idempotent (call 3 times) [0.40ms]
(pass) ensureGitignoreRule — multiple distinct rules don't collide > two different rules go to two different lines [0.36ms]
(pass) ensureGitignoreRule — multiple distinct rules don't collide > similar-but-different rules don't false-match (`.anet/` vs `.anet/foo`) [0.39ms]
(pass) ensureGitignoreRules — batch > empty rules list is a no-op [0.27ms]
(pass) ensureGitignoreRules — batch > creates file with all rules on first call [0.42ms]
(pass) ensureGitignoreRules — batch > second batch call is fully idempotent [0.40ms]
(pass) ensureGitignoreRules — batch > partial overlap — only new rules appended [0.45ms]
(pass) ensureGitignoreRule — defensive > empty rule throws [0.32ms]
(pass) ensureGitignoreRule — defensive > whitespace-only rule throws [0.22ms]

src/secret-shell-guidance-wiring.test.ts:
(pass) #379 create and migrate both use platform-aware secret guidance [5.30ms]

src/opencode-runtime-binding.test.ts:
(pass) external OpenCode runtime binding > survives regular config runtime downgrade and proves the original exact runtime [11.48ms]
(pass) external OpenCode runtime binding > read returns undefined only for absent state and deterministic keys separate nodes [9.32ms]
(pass) external OpenCode runtime binding > an absent exact leaf does not impose POSIX modes on ordinary runtime state [1.67ms]
(pass) external OpenCode runtime binding > unbound legacy symlink or junction-style node paths remain invisible [7.21ms]
(pass) external OpenCode runtime binding > Windows synthetic permission bits do not disable structural security checks [0.85ms]
(pass) external OpenCode runtime binding > secure removal is idempotent and removes the exact binding [6.77ms]
(pass) external OpenCode runtime binding > secure removal refuses tampered content without unlinking it [5.87ms]
(pass) external OpenCode runtime binding > rejects binding-directory and leaf symlinks [6.03ms]
(pass) external OpenCode runtime binding > rejects dangling binding-root and exact-leaf symlinks [3.54ms]
(pass) external OpenCode runtime binding > rejects permissive modes, hard links, and foreign ownership [6.12ms]
(pass) external OpenCode runtime binding > rejects private but tampered runtime, identity, and extra fields [6.68ms]
(pass) external OpenCode runtime binding > rejects binding roots that overlap the canonical project in either direction [4.03ms]
(pass) external OpenCode runtime binding > a symlinked node workDir cannot remove another project's binding [6.46ms]
(pass) assertOpencodeNodeStateUntracked > allows ordinary non-Git projects [1.42ms]
(pass) assertOpencodeNodeStateUntracked > allows ordinary untracked projects inside a Git worktree checkout [54.44ms]
(pass) assertOpencodeNodeStateUntracked > rejects forged Git worktree file markers [1.42ms]
(pass) assertOpencodeNodeStateUntracked > allows ignored/untracked state but rejects git add -f tracked state [17.46ms]
(pass) assertOpencodeNodeStateUntracked > rejects a force-added dotenv or any tracked file below the node directory [24.25ms]

src/client.test.ts:
(pass) CommHub.reply calls send_reply MCP tool [4.03ms]

src/supervise-child.test.ts:
(pass) superviseChild — shutdown gate stops the loop > shutdownGate=true from the start → runOnce never called [0.81ms]
(pass) superviseChild — shutdown gate stops the loop > shutdownGate flips true after first iteration → exactly one runOnce [0.26ms]
(pass) superviseChild — backoff growth + cap > waits double the delay each iteration, capping at maxDelayMs [13.43ms]
(pass) superviseChild — runOnce that returns WITHOUT markStable is treated as failed (regression pin) > runOnce that returns cleanly without markStable → backoff doubles [16.04ms]
(pass) superviseChild — markStable resets backoff > after iteration that calls markStable, next wait is baseDelayMs again [16.01ms]
(pass) superviseChild — markStable resets backoff > markStable called multiple times in one iteration is idempotent [15.99ms]
(pass) superviseChild — abandonAfterMs > calls onAbandon and returns after cumulative downtime exceeds threshold [16.08ms]
(pass) superviseChild — abandonAfterMs > markStable in any iteration resets downtime — abandon never fires [16.02ms]
(pass) superviseChild — runOnce error handling > runOnce throws → onError fires, loop continues [16.02ms]
(pass) superviseChild — runOnce error handling > runOnce throws AND shutdownGate goes true → loop exits, no further iteration [2.62ms]
(pass) superviseChild — jitter range > jitterRatio=0.25 + random=0 → -25% of delay (lower bound) [13.37ms]
(pass) superviseChild — jitter range > jitterRatio=0.25 + random=1 → +25% of delay (upper bound) [16.02ms]
(pass) superviseChild — jitter range > jitterRatio=0 → deterministic waits at exact delay [16.03ms]
(pass) superviseChild — jitter range > waitMs floor 100 enforces minimum wait even with tiny base + negative jitter [16.01ms]
(pass) superviseChild — defensive contract > returns (does not throw) when runOnce never resolves and shutdown flips [2.82ms]

src/claude-vendor-env.test.ts:
(pass) collectClaudeVendorEnvForCreate > captures known vendor endpoint and credential for claude-agent-sdk [0.43ms]
(pass) collectClaudeVendorEnvForCreate > explicit --env value wins without duplicate capture [0.18ms]
(pass) collectClaudeVendorEnvForCreate > does not capture vendor variables for another runtime [0.05ms]
(pass) collectClaudeVendorEnvForCreate > rejects line-oriented dotenv injection [0.20ms]
(pass) collectClaudeVendorEnvForCreate > rejects line breaks in explicit --env for every runtime [0.16ms]
(pass) planPlainSecretEnvRewrites > plans the exact dotenv assignment without mutating the profile [0.32ms]
(pass) planPlainSecretEnvRewrites > rejects a secret dotenv value with CRLF before any caller mutation [0.20ms]

src/locale-diagnostic-wiring.test.ts:
(pass) #68 doctor reports the pure locale diagnostic as a warning [3.84ms]

src/primary-network.test.ts:
(pass) resolvePrimaryNetwork > uses current_network even when the network list is reversed and renamed [0.64ms]
(pass) resolvePrimaryNetwork > fails explicitly when current_network is missing instead of guessing networks[0] [0.43ms]
(pass) resolvePrimaryNetwork > turns transport and HTTP failures into explicit resolution errors [0.36ms]
(pass) debate, demo-social, and pr-review all use the shared resolver [2.29ms]

src/opencode-preset.test.ts:
(pass) OPENCODE_PRESETS registry > exports the two blessed presets (anthropic + openai) [0.13ms]
(pass) OPENCODE_PRESETS registry > findOpencodePreset('anthropic') returns the record; unknown returns null [0.06ms]
(pass) readPresetKeyFromEnv — env-only, no interactive prompt > returns the trimmed key when the env var is set [0.15ms]
(pass) readPresetKeyFromEnv — env-only, no interactive prompt > returns null when the env var is missing / empty [0.08ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > body shape matches opencode auth.json convention [0.55ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > writes to <workdir>/.local/share/opencode/auth.json with mode 0o600 [6.47ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > writeOpencodeConfigJson lands under .config/opencode with 0o600 [5.70ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > keyless create atomically clears a private pre-planted auth file [7.24ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > default tool policy disables filesystem, shell, task, and skill tools [0.43ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > writes only blessed provider identity and strips all pre-planted routing/executable config [5.80ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > atomically replaces a private but invalid pre-planted config without parsing it [7.78ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > rejects symlink escapes in workDir, config/data ancestors, and final targets [6.92ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > validates the full tree before mutation so a bad auth side cannot partially rewrite config [1.08ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > rejects permissive modes and foreign owners without chmod-follow repair [2.85ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > prepares .anet/nodes/node before profile secrets and provides atomic private leaf I/O [28.92ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > accepts an ordinary 0775 project root for a non-root uid=gid private group [3.24ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > profile preflight rejects .anet/nodes/node and config/.env symlink chains before secret writes [7.16ms]
(pass) buildAuthJsonBody + writeOpencodeAuthJson > profile preflight rejects writable ancestors and non-private node roots [1.78ms]

src/opencode-smoke-env.test.ts:
(pass) buildOpencodeSmokeEnv > locks the exact hardened ancestor candidate set [2.59ms]
(pass) buildOpencodeSmokeEnv > rejects sticky world-writable /tmp instead of silently degrading [0.51ms]
(pass) buildOpencodeSmokeEnv > inherits only transport/locale trust settings and controls all OpenCode roots [0.75ms]
(pass) buildOpencodeSmokeEnv > every writable root can be precreated private, including XDG_RUNTIME_DIR [1.04ms]

src/grok-attach-client.test.ts:
(pass) validateGrokAttachSocket rejects symlinks, non-sockets, and foreign owners [2.76ms]
(pass) connectGrokAttach bridges base64 terminal I/O, status, resize, and detach [8.40ms]
(pass) connectGrokAttach splits large input so every NDJSON frame stays bounded [1.16ms]
(pass) connectGrokAttach fails closed on an invalid handshake and oversized frame [1.22ms]
(pass) a single-client rejection before hello preserves the server error [0.61ms]
(pass) hello followed by a fatal frame in the same chunk cannot return a dead session [0.66ms]
(pass) detach force-closes a peer that never completes its half-close [12.81ms]
(pass) callback failure and invalid limits fail before returning an attached client [1.07ms]
(pass) remote detach is surfaced and closes without echoing a detach frame [0.71ms]

src/grok-copresence-profile.test.ts:
(pass) Grok copresence profile defaults > builds the Grok agent-node parent environment from an exact empty allowlist [1.99ms]
(pass) Grok copresence profile defaults > does not mistake an old headless-only agent-node for co-presence support [0.11ms]
(pass) Grok copresence profile defaults > builds the npm resolver environment from an exact empty allowlist [0.62ms]
(pass) Grok copresence profile defaults > prepares two distinct empty owner-only npm config files without following symlinks [1.59ms]
(pass) Grok copresence profile defaults > enables copresence only for non-headless grok-build-cli [0.46ms]
(pass) Grok copresence profile defaults > uses the owner-bound state home even when XDG is owner-only [0.40ms]
(pass) Grok copresence profile defaults > falls back to a bounded owner tmp path when the state home is too long [0.12ms]

src/opencode-copresence-cli.test.ts:
(pass) OpenCode co-presence CLI wiring > persists copresence mode before launching the bridge [0.04ms]
(pass) OpenCode co-presence CLI wiring > starts only exact alias and alias-bridge tmux sessions [0.07ms]
(pass) OpenCode co-presence CLI wiring > does not depend on a long-lived tmux server's stale launcher environment [0.06ms]
(pass) OpenCode co-presence CLI wiring > waits for the owner-only runtime launcher before starting the official TUI [0.07ms]
(pass) OpenCode co-presence CLI wiring > the generic --copresence dispatcher selects OpenCode by stored runtime [0.16ms]
(pass) OpenCode co-presence CLI wiring > operator help names the create, attach, and stop commands [0.85ms]
(pass) OpenCode co-presence CLI wiring > prints an exact tmux target so an exited TUI cannot prefix-match the bridge [0.07ms]

src/locale-diagnostic.test.ts:
(pass) #68 locale diagnostic > LC_ALL overrides an otherwise UTF-8 LANG [1.50ms]
(pass) #68 locale diagnostic > LC_CTYPE overrides LANG when LC_ALL is empty [0.08ms]
(pass) #68 locale diagnostic > accepts common UTF-8 spellings [0.10ms]
(pass) #68 locale diagnostic > warns for POSIX, C, non-UTF-8, and unset locale [0.10ms]
(pass) #68 locale diagnostic > does not prescribe POSIX locale variables on Windows [0.04ms]
(pass) #68 locale diagnostic > renders locale values without terminal control or unbounded output [0.23ms]

src/opencode-package-binary.test.ts:
(pass) validateOpencodePackageBinary > accepts only the canonical exact npm package entrypoint [1.94ms]
(pass) validateOpencodePackageBinary > rejects a same-version package impersonator inside the project [1.17ms]
(pass) validateOpencodePackageBinary > skips a same-version project shim and selects a later trusted package [2.00ms]
(pass) validateOpencodePackageBinary > rejects a monorepo-root package when invoked from a nested app [2.36ms]
(pass) validateOpencodePackageBinary > ordinary 0664 checkout package.json does not abort boundary discovery [1.75ms]
(pass) validateOpencodePackageBinary > accepts both exact registry spellings of bin.opencode [1.98ms]
(pass) validateOpencodePackageBinary > rejects forged name, version, and bin metadata [2.96ms]
(pass) validateOpencodePackageBinary > rejects world-writable files and package ancestors [2.96ms]
(pass) validateOpencodePackageBinary > rejects a symlinked package.json even when its contents are exact [1.16ms]
(pass) #739 cwd 参与信任判定 > 缺陷现状:cwd 为文件系统根时,禁止根含 / —— 与任何包路径都重叠 [0.21ms]
(pass) #739 cwd 参与信任判定 > 缺陷现状:cwd=/ 时,一个各方面都合法的包也会被拒 [1.37ms]
(pass) #739 cwd 参与信任判定 > 缺陷现状:cwd 是全局安装前缀的祖先时,全局安装的包被判成项目本地 [1.40ms]
(pass) #739 cwd 参与信任判定 > 这条守卫要防的东西必须继续被防住(修 #739 时不许放宽它) [1.02ms]

src/im/access-resolve.test.ts:
(pass) normalizeAllowFrom — input shapes > real string[] passes through deduped (filter empty strings) [1.64ms]
(pass) normalizeAllowFrom — input shapes > undefined → empty + not malformed [0.05ms]
(pass) normalizeAllowFrom — input shapes > null → empty + not malformed [0.05ms]
(pass) normalizeAllowFrom — input shapes > non-array object → empty + malformed (corrupted access.json shape) [0.04ms]
(pass) normalizeAllowFrom — input shapes > string instead of array → malformed [0.02ms]
(pass) normalizeAllowFrom — input shapes > array with non-string elements drops them [0.05ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > empty array → deny with empty-fail-closed kind [0.18ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > undefined → deny [0.06ms]
(pass) resolveTelegramAccess — fail-closed empty allowFrom (v0.11 security change) > malformed → deny + reason mentions malformed [0.10ms]
(pass) resolveTelegramAccess — wildcard '*' opens the channel > ['*'] alone allows any sender [0.05ms]
(pass) resolveTelegramAccess — wildcard '*' opens the channel > ['*', 'specific_id'] still wildcard-allows (wins precedence) [0.07ms]
(pass) resolveTelegramAccess — explicit id / username matching > senderId in list → allow [0.08ms]
(pass) resolveTelegramAccess — explicit id / username matching > senderUsername match (no id match) → allow [0.07ms]
(pass) resolveTelegramAccess — explicit id / username matching > neither id nor username in list → deny [0.06ms]
(pass) resolveTelegramAccess — explicit id / username matching > empty senderUsername doesn't accidentally match empty list entry [0.06ms]
(pass) resolveTelegramAccess — explicit id / username matching > blank-string id with username match still allows [0.04ms]
(pass) resolveTelegramAccess — explicit id / username matching > production-shape: bare username (no @) in allowFrom matches bare msg.from.username [0.04ms]
(pass) resolveTelegramAccess — explicit id / username matching > production-shape mismatch: @vansin in allowFrom does NOT match bare vansin payload [0.05ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > empty allowFrom → deny [0.20ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > wildcard allows [0.05ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > specific id allows [0.04ms]
(pass) resolveFeishuAccess — DM path mirrors telegram fail-closed > sender not in list → deny [0.08ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > empty allowChats → fail-closed [0.11ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat in allowChats + groupPolicy=all → allow [0.08ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat in allowChats + groupPolicy=observe → deny [0.06ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > chat NOT in allowChats → deny (even with policy=all) [0.09ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > wildcard chats opens any chat (with groupPolicy=all) [0.07ms]
(pass) resolveFeishuAccess — group path (allowChats + groupPolicy) > groupPolicy=mention allows (caller decides at message inspect time) [0.06ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns warn string for empty allowFrom [0.16ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns warn string for malformed allowFrom + mentions malformed [0.05ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns null when allowFrom has at least one entry [0.04ms]
(pass) buildEmptyAllowlistWarn — boot-time visibility > returns null for wildcard-allow (channel intentionally open) [0.03ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader stores raw allowFrom verbatim — no normalization at load time [0.13ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader emits boot-warn when allowFrom is missing [0.08ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader emits boot-warn when allowFrom is malformed (non-array) [0.07ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > loader is silent when allowFrom has at least one entry (even if numeric) [0.04ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [123] alone (numeric sender id from a misformatted access.json) → loader+resolver fail-closed [0.10ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [null] (corrupted access.json) → loader+resolver fail-closed [0.05ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [{}] (object instead of id string) → loader+resolver fail-closed [0.04ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [123, '@vansin'] (mixed) → '@vansin' still allowed, numeric '123' rejected [0.06ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > [null, '*'] (mixed wildcard) → wildcard wins despite garbage entries [0.04ms]
(pass) loadTelegramAccess + resolver — wiring regression (CHANGE_REQ on #276) > missing access.json entirely (loader gets null) → fail-closed [0.10ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > empty array NEVER allows [0.06ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > undefined NEVER allows [0.04ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > null NEVER allows [0.05ms]
(pass) regression — pre-v0.11 fail-open MUST NOT come back > object-shape (corrupted) NEVER allows [0.05ms]

src/im/feishu/adapter-lifecycle.test.ts:
(pass) FeishuAdapter WS lifecycle > SDK start resolution is not readiness; missing onReady times out fail-closed [21.73ms]
(pass) FeishuAdapter WS lifecycle > onReady is the only initial online authority [1.53ms]
(pass) FeishuAdapter WS lifecycle > initial onError rejects and scrubs credentials [1.51ms]
(pass) FeishuAdapter WS lifecycle > initial onError scrubs arbitrary Lark access-token shapes [1.59ms]
(pass) FeishuAdapter WS lifecycle > spurious reconnect before first ready cannot mark health connected [17.47ms]
[2026-08-13T03:13:45.223Z] [feishu:audit] error from=? conv=? — inbound [redacted] Bearer [redacted]
(pass) FeishuAdapter WS lifecycle > inbound handler errors use the same token scrub before health [3.79ms]
(pass) FeishuAdapter WS lifecycle > reconnecting lowers health and reconnected restores it [3.09ms]
(pass) FeishuAdapter WS lifecycle > terminal error after ready lowers health and notifies worker owner once [1.58ms]
(pass) FeishuAdapter WS lifecycle > stop closes the public SDK client and invalidates late callbacks [1.61ms]
(pass) worker terminal owner logs safely and exits non-zero [0.15ms]

 438 pass
 0 fail
 1333 expect() calls
Ran 438 tests across 46 files. [4.37s]
executed_files=46 discovered_files=46
[L0b] every agent-network/tests file, dispatched by kind
tests_dir_executed=19 tests_dir_discovered=19 tests_dir_failed=0
[L1] witnessed-red: top-level config help must match the implemented parser
Expected to contain: "anet config [path|json]"
MUTATION_RED stale-config-help rc=1
RESULT: PASS
```
