# test219 — Grok co-presence TUI runtime
date: 2026-08-01T11:32:30+00:00
source_commit=026937d0e2e124292e10b96c6806abb35c8a3eaf
[L0] isolated environment
/usr/bin/flock
v22.23.2
1.3.14
node-pty ok
PASS: environment + native PTY dependency
[L1] pure reducers and attach protocol
bun test v1.3.14 (0d9b296a)

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

src/runtime/grok-build-cli.test.ts:
(pass) buildGrokCliArgs > rejects an older Grok CLI before it can ignore required safety flags [0.74ms]
(pass) buildGrokCliArgs > uses streaming headless mode and resumes an existing session [0.23ms]
(pass) buildGrokCliArgs > fails closed instead of auto-approving when permission bypass is disabled [0.12ms]
(pass) buildGrokCliArgs > maps an explicit node tool allowlist and keeps MCP unavailable [0.14ms]
(pass) buildGrokCliArgs > intersects explicit tools with the read-only set when auto-approval is off [0.07ms]
(pass) buildGrokCliArgs > rejects unknown node tool names instead of silently widening access [0.05ms]
(pass) buildGrokCliArgs > rejects an explicit empty tool allowlist instead of widening to all tools [0.05ms]
(pass) buildGrokCliArgs > denies model reads of runtime credential and node-state paths [0.05ms]
(pass) runGrokCliTurn > reduces streaming JSON text and persists the end-event session [46.93ms]
(pass) runGrokCliTurn > spawns with exactly the projected environment and no ambient credentials [44.81ms]
(pass) runGrokCliTurn > keeps the production-shaped setpriv/sh launcher on the exact PWD-bound env [47.33ms]
(pass) runGrokCliTurn > refuses a shell launcher when PWD is missing from the reviewed env [0.83ms]
(pass) runGrokCliTurn > removes the prompt when spawn rejects a malformed allowed env value [1.13ms]
(pass) runGrokCliTurn > surfaces non-zero exits and stderr [41.36ms]
(pass) runGrokCliTurn > fails fast when headless Grok asks for an interactive login [39.95ms]
(pass) runGrokCliTurn > rejects cancelled turns [40.93ms]
(pass) runGrokCliTurn > rejects a formal error event even if the process exits zero [48.33ms]
(pass) runGrokCliTurn > rejects max-turn truncation instead of reporting a partial reply as success [66.32ms]
(pass) runGrokCliTurn > terminates the process group when the caller aborts [35.20ms]
(pass) runGrokCliTurn > kills a silent child after the idle timeout [38.15ms]

src/runtime/grok-build-cli-home.test.ts:
(pass) prepareGrokCliHome > derives an opaque path segment and rejects dot identities [0.67ms]
(pass) prepareGrokCliHome > accepts only the pinned Grok regular-file copy of source agent_id [7.40ms]
(pass) prepareGrokCliHome > isolates config/trust, preserves a shared auth path, and creates stable sandbox profiles [3.10ms]
(pass) prepareGrokCliHome > refuses broad-mode or symlinked source auth without repairing it [1.54ms]
(pass) prepareGrokCliHome > repairs an existing Grok session store to owner-only modes [2.57ms]
(pass) prepareGrokCliHome > does not follow a symlink while repairing an existing session store [1.48ms]
(pass) prepareGrokCliHome > keeps the post-stop cleanup policy exact and reviewable [0.20ms]
(pass) prepareGrokCliHome > removes exact empty read-only project placeholders before resume without admitting executable sources [7.19ms]
(pass) prepareGrokCliHome > validates every exact project placeholder before unlinking any sibling [1.91ms]
(pass) prepareGrokCliHome > does not let a fatal project counterexample starve independent state containment [3.20ms]
(pass) prepareGrokCliHome > preserves nonempty, linked, wrong-mode, and wrong-type project counterexamples [5.59ms]
(pass) prepareGrokCliHome > preserves real project extension directories and still rejects executable contents on resume [2.20ms]
(pass) prepareGrokCliHome > removes only exact transient state and hardens retained post-stop state [6.71ms]
(pass) prepareGrokCliHome > hardens only the native lock derived from the exact leader socket [1.45ms]
(pass) prepareGrokCliHome > retains a non-empty leader log and rejects post-stop link attacks [2.77ms]
(pass) prepareGrokCliHome > refuses a non-empty exact sandbox placeholder [1.28ms]
(pass) prepareGrokCliHome > reclaims an empty mode-000 sandbox marker under a foreign pid without aborting [1.17ms]
(pass) prepareGrokCliHome > keeps a non-empty foreign sandbox marker unreadable so it fails closed [1.39ms]
(pass) prepareGrokCliHome > validates exact TUI process ids before mutation and refuses a placeholder symlink [1.86ms]
(pass) prepareGrokCliHome > enables the single TUI leader only for explicit copresence mode [16.67ms]
(pass) prepareGrokCliHome > admits only canonical owner-held commhub MCP artifacts [4.87ms]
(pass) prepareGrokCliHome > rejects a shared auth path covered by a required sandbox deny before state mutation [0.88ms]
(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.86ms]
(pass) prepareGrokCliHome > removes runtime-owned native hooks before every turn [2.64ms]
(pass) prepareGrokCliHome > unlinks a runtime-owned hook symlink without touching its external target [1.66ms]
(pass) prepareGrokCliHome > fails closed when a project native hook path exists [1.24ms]
(pass) prepareGrokCliHome > trusts only the exact canonical nested cwd and atomically replaces stale grants [5.43ms]
(pass) prepareGrokCliHome > rejects broad or symlinked folder-trust targets before writing trust state [3.45ms]
(pass) prepareGrokCliHome > refuses a planted trust-store symlink and leaves its target untouched [1.97ms]
(pass) prepareGrokCliHome > rejects every project executable source before granting folder trust [17.51ms]
(pass) prepareGrokCliHome > does not impose the shared-folder strict policy on legacy headless mode [2.63ms]
(pass) prepareGrokCliHome > rejects repo-root hooks from a nested cwd and dangling hook links [3.57ms]
(pass) prepareGrokCliHome > rejects a symlinked project .grok directory [1.10ms]
(pass) prepareGrokCliHome > rejects symlinked isolated homes and generated state without changing targets [2.54ms]
(pass) prepareGrokCliHome > rejects a state-home path escape before chmod, removal, or writes [0.94ms]
(pass) prepareGrokCliHome > requires a valid zero-hook inspect response [0.83ms]
(pass) prepareGrokCliHome > flocks the canonical project inode across symlink aliases and releases cleanly [122.02ms]
(pass) prepareGrokCliHome > gives the real flock holder only the exact helper environment [61.77ms]

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

src/private-log.test.ts:
(pass) Grok preview private ordinary logs > scrubs and repairs legacy logs before appending through a 0600 file [3.89ms]
(pass) Grok preview private ordinary logs > rejects a symlinked directory or final log file [1.18ms]
(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.53ms]

src/reply-reliability.test.ts:
(pass) classifyCommHubResponse > returns ok with parsed application payload (the happy path) [0.22ms]
(pass) classifyCommHubResponse > JSON-RPC error envelope → retryable CommHubError [0.14ms]
(pass) classifyCommHubResponse > MCP result.isError → retryable CommHubError [0.06ms]
(pass) classifyCommHubResponse > application-level ok:false → appLevel CommHubError (NON-retryable) [0.11ms]
(pass) classifyCommHubResponse > non-JSON tool text is passed through verbatim [0.12ms]
(pass) classifyCommHubResponse > data with neither error nor result returns ok with the raw data [0.04ms]
(pass) CommHubError > instances are distinguishable from generic Error via instanceof [0.04ms]
(pass) CommHubError > appLevel flag survives the throw/catch round trip [0.08ms]
(pass) PendingReplyQueue > load() returns empty array when file does not exist [0.42ms]
(pass) PendingReplyQueue > persist + load round-trips an entry with attempts=0 [2.87ms]
(pass) PendingReplyQueue > final persistence boundary scrubs known, shaped, assignment and error credentials [2.69ms]
(pass) PendingReplyQueue > direct save cannot bypass scrub and leaves no sibling temp artifact [2.23ms]
(pass) PendingReplyQueue > load migrates an old broad-mode queue without leaving raw credential bytes [2.29ms]
(pass) PendingReplyQueue > load repairs a broad mode even when content needs no rewrite [0.37ms]
(pass) PendingReplyQueue > accepts the same process-wide redactor used by ordinary log call sites [2.08ms]
(pass) PendingReplyQueue > invalid legacy content is securely replaced with an empty 0600 queue [2.22ms]
(pass) PendingReplyQueue > persist is idempotent on (to, taskId) — attempts counter preserved [6.60ms]
(pass) PendingReplyQueue > clear removes only the matching (to, taskId) [8.17ms]
(pass) PendingReplyQueue.drain > delivers every entry on success and persists an empty queue [6.66ms]
(pass) PendingReplyQueue.drain > transient failure requeues with attempts++ and lastError [5.39ms]
(pass) PendingReplyQueue.drain > transient error text is scrubbed before it reaches disk [4.43ms]
(pass) PendingReplyQueue.drain > app-level CommHubError is dropped loud — not retried, not requeued [7.32ms]
(pass) PendingReplyQueue.drain > drain on empty queue is a no-op and does not write the file [0.57ms]
(pass) PendingReplyQueue.drain > file format is stable JSON — readable by an operator after a crash [2.40ms]
(pass) quickHash > is deterministic [0.18ms]
(pass) quickHash > differs across inputs [0.03ms]
(pass) quickHash > returns 32-char hex [0.09ms]

src/goals/store.test.ts:
(pass) GoalStore — basic lifecycle > fresh store: load with no file → ok, empty list [1.53ms]
(pass) GoalStore — basic lifecycle > upsert → get → list roundtrip [2.29ms]
(pass) GoalStore — basic lifecycle > delete → flushes to disk [1.35ms]
(pass) GoalStore — basic lifecycle > setStatus → in-memory + persisted [1.30ms]
(pass) GoalStore — basic lifecycle > setStatus on unknown id → undefined, no throw [0.34ms]
(pass) GoalStore — basic lifecycle > mutate applies in-place + bumps updated_at [6.61ms]
(pass) GoalStore — basic lifecycle > mutate on unknown id → undefined, mutator NOT invoked [2.21ms]
(pass) GoalStore — restart persistence > two instances see the same goals (= restart simulation) [1.04ms]
(pass) GoalStore — restart persistence > status change survives reload [1.21ms]
(pass) GoalStore — corruption recovery (#2) > invalid JSON → ok=false, .corrupt backup, empty store [2.06ms]
(pass) GoalStore — corruption recovery (#2) > unknown schema version → recovery [0.66ms]
(pass) GoalStore — corruption recovery (#2) > malformed shape (goals not array) → recovery [0.51ms]
(pass) GoalStore — Grok preview persistence boundary > recursively migrates task/progress/error, final writes, and archives at 0600 [3.59ms]
(pass) GoalStore — Grok preview persistence boundary > scrubs a broad-mode corrupt backup and replaces the live file with an empty safe store [1.62ms]
(pass) GoalStore — Grok preview persistence boundary > recursively scrubs a parseable unsupported-schema backup [1.56ms]
(pass) P0 runtime gate — name resolution > isClaudeRuntime accepts every claude alias [0.16ms]
(pass) P0 runtime gate — name resolution > isClaudeRuntime rejects codex / grok / unknown / empty [0.09ms]
(pass) P0 runtime gate — name resolution > runtimeBucket maps to canonical buckets [0.15ms]
(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.67ms]
(pass) #144 round-6 — claude runtime gate REMOVED, scheduler is universal > isClaudeRuntime still classifies (kept for cross-bucket detection, not gating) [0.06ms]
(pass) P0 runtime gate — archiveAndClear > with live goals: backup file created, store emptied, reload sees empty [1.94ms]
(pass) P0 runtime gate — archiveAndClear > with no live file: returns undefined, no throw, store still flushes empty [0.54ms]
(pass) P0 runtime gate — archiveAndClear > backup filenames are unique across rapid calls [14.55ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + empty → ok (scheduler runs; was 'skip' pre-#144) [0.24ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + only claude-active goals → ok (scheduler runs) [0.20ms]
(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.04ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude + active codex/grok goals → archive + runScheduler=true (recover after archive) [0.26ms]
(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.10ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > claude with only inactive foreign leftover → ok (just cleanup pending) [0.09ms]
(pass) #144 round-6 — decideStartupAction (refined-B matrix) > unknown bucket → skip (no scheduler, no auto-archive) [0.05ms]
(pass) GoalStore — mutex serialisation (#1+#3) > 50 concurrent upserts → all 50 persist (no torn writes) [18.69ms]
(pass) GoalStore — mutex serialisation (#1+#3) > interleaved upsert + setStatus + delete stays consistent [12.71ms]

src/runtime/grok-copresence/state.test.ts:
(pass) Grok co-presence arbitration > lets the first human byte win a simultaneous human/network race [1.76ms]
(pass) Grok co-presence arbitration > gives a newly active human composer priority over an existing FIFO [0.40ms]
(pass) Grok co-presence arbitration > dequeues network tasks FIFO and never preempts an active turn [0.83ms]
(pass) Grok co-presence arbitration > cancels only queued timeouts and rejects duplicate task ids [0.41ms]
(pass) Grok co-presence arbitration > retains the active network task and FIFO across disconnect/reconnect [1.11ms]
(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.22ms]

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

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.50ms]
(pass) Grok co-presence local attach server > rejects a second client without disturbing the attached human [4.69ms]
(pass) Grok co-presence local attach server > routes input and resize frames only through serialized arbiter callbacks [5.61ms]
(pass) Grok co-presence local attach server > fails closed when an inbound frame exceeds the configured bound [14.23ms]
(pass) Grok co-presence local attach server > refuses symlinks and regular files at the socket path [0.92ms]

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

../agent-network/src/grok-copresence-profile.test.ts:
(pass) Grok copresence profile defaults > builds the Grok agent-node parent environment from an exact empty allowlist [0.43ms]
(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.56ms]
(pass) Grok copresence profile defaults > prepares two distinct empty owner-only npm config files without following symlinks [1.58ms]
(pass) Grok copresence profile defaults > enables copresence only for non-headless grok-build-cli [0.89ms]
(pass) Grok copresence profile defaults > uses an owner-only, non-symlink XDG runtime directory [0.36ms]
(pass) Grok copresence profile defaults > falls back to a bounded path when XDG is unsafe or too long [0.44ms]

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

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

 234 pass
 0 fail
 1018 expect() calls
Ran 234 tests across 14 files. [1137.00ms]
PASS: state machine + JSONL reducer + local attach protocol
[L2] single-PTY runtime integration
bun test v1.3.14 (0d9b296a)

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

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.68ms]
(pass) Grok copresence launch and injection policy > admits exact automatic lifecycles only for the fixed preview tool boundary [0.20ms]
(pass) Grok copresence launch and injection policy > exposes only reviewed value-free task failure codes and exact JSONL subcodes [0.44ms]
(pass) Grok copresence launch and injection policy > keeps the JSONL subcode allowlist direct, frozen, and actual-path-only [0.21ms]
(pass) Grok copresence launch and injection policy > locks the probed Grok TUI build exactly [0.18ms]
(pass) Grok copresence launch and injection policy > pins one TUI-effective commhub-only agent profile and hard-denies fallback routes [0.96ms]
(pass) Grok copresence launch and injection policy > rejects terminal escape injection and reserved origin markup [0.40ms]
(pass) Grok copresence launch and injection policy > recognizes the pinned TUI composer footer across ANSI fragments [0.24ms]
(pass) Grok copresence launch and injection policy > rejects external permission sources and noninteractive modes [1.35ms]
(pass) Grok copresence runtime integration > terminates the independently persistent auto-Leader and its unchanged stale socket [534.46ms]
(pass) Grok copresence runtime integration > cleans and hardens the exact pinned footprint only after confirmed close [530.28ms]
(pass) Grok copresence runtime integration > cleans each exact sandbox placeholder at its confirmed recovery boundary [860.07ms]
(pass) Grok copresence runtime integration > removes an old placeholder before a recovery generation reuses its PID [1170.38ms]
(pass) Grok copresence runtime integration > queues network input until the pinned TUI composer is ready [1160.98ms]
(pass) Grok copresence runtime integration > maps keyless fake-writer file mutations to exact value-free tail subcodes [3813.63ms]
(pass) Grok copresence runtime integration > continues exactly once across prefix-preserving atomic chat rewrites [2234.51ms]
(pass) Grok copresence runtime integration > rejects an atomic replacement that preserves only the consumed prefix [663.82ms]
(pass) Grok copresence runtime integration > rejects a same-inode shrink below the highest observed size even when offset remains valid [539.59ms]
(pass) Grok copresence runtime integration > does not expose an intermediate atomic generation before its successor preserves it [1077.04ms]
(pass) Grok copresence runtime integration > does not expose a pinned generation unlinked between path check and read [1078.83ms]
(pass) Grok copresence runtime integration > maps chat and events reset callback failures and stops polling after fatal [1494.90ms]
(pass) Grok copresence runtime integration > maps keyless reducer, lifecycle, and combined flush invariants at their boundaries [2496.29ms]
(pass) Grok copresence runtime integration > close waits for and tears down a Leader spawned by in-flight recovery [908.09ms]
(pass) Grok copresence runtime integration > retains containment and lifetime locks when a closing recovery PTY will not stop [2909.81ms]
(pass) Grok copresence runtime integration > excludes a different runtime from the same canonical project for the full TUI lifetime [1058.37ms]
(pass) Grok copresence runtime integration > contains an exited recovery generation before reusing its PID [1750.55ms]
(pass) Grok copresence runtime integration > retains final-cleanup ownership after every failed recovery PID is consumed [884.66ms]
(pass) Grok copresence runtime integration > arbitrates a live PTY, settles final JSONL, attaches once, and resumes [4007.49ms]
(pass) Grok copresence runtime integration > fails closed on automatic permission resolution without a human action [575.26ms]
(pass) Grok copresence runtime integration > accepts only the pinned preview todo_write automatic resolution tuple [1876.37ms]
(pass) Grok copresence runtime integration > keeps the shared TUI alive when the pinned preview auto-resolves todo_write in a human turn [1746.18ms]
(pass) Grok copresence runtime integration > keeps the shared TUI alive across exact search_tool then use_tool in a human turn [1669.73ms]
(pass) Grok copresence runtime integration > rejects every mutated preview todo_write automatic resolution tuple [3991.51ms]
(pass) Grok copresence runtime integration > preserves exact permission lifecycle order across coalesced and split event reads [2341.94ms]
(pass) Grok copresence runtime integration > rejects terminal reordering around automatic permission lifecycles [1753.90ms]
(pass) Grok copresence runtime integration > allows repeated fixed-tool automatic permission lifecycles in one network turn [1060.25ms]
(pass) Grok copresence runtime integration > never replies with a tool-bearing assistant when the final log is delayed past settling [1873.89ms]
(pass) Grok copresence runtime integration > rejects a completed turn that never resolved its approval [593.95ms]
(pass) Grok copresence runtime integration > does not resume a TUI that crashed at an approval prompt [590.56ms]
(pass) Grok copresence runtime integration > rejects a permission record that landed just before the crash poll [888.99ms]
(pass) Grok copresence runtime integration > refuses process-level resume with a persisted unresolved approval [192.78ms]
(pass) Grok copresence runtime integration > permits process-level resume after a persisted approval was resolved [561.13ms]
(pass) Grok copresence runtime integration > arms both resume tails before spawn-time permission records can be skipped [281.02ms]
(pass) Grok copresence runtime integration > discards spawn-time orphan completions before accepting the first new network task [1104.41ms]
(pass) Grok copresence runtime integration > drains more than one tail chunk before attach and fully cleans a startup rejection [866.92ms]
(pass) Grok copresence runtime integration > accepts the pinned startup auto-approval transition [550.07ms]
(pass) Grok copresence runtime integration > reruns the spawn audit and refuses recovery when it fails [779.62ms]
(pass) Grok copresence runtime integration > keeps auto-approval across recovery before scheduling [1696.86ms]
(pass) Grok copresence runtime integration > jointly drains chat and events until both recovery cursors are stable [1818.86ms]
(pass) Grok copresence runtime integration > rejects a beforeSpawn callback that widens a controlled child setting [201.49ms]
(pass) Grok copresence runtime integration > gives every real lifetime-lock holder only the exact helper environment [556.27ms]

 60 pass
 0 fail
 428 expect() calls
Ran 60 tests across 2 files. [58.66s]
PASS: FIFO/human arbitration + final reply + approval + reconnect + single bridge
[L3] package build and CLI integration

> @sleep2agi/agent-node@2.5.0-preview.26 build
> bun build src/cli.ts --outdir dist --entry-naming cli.js --target node --minify --external @anthropic-ai/claude-agent-sdk --external '@anthropic-ai/claude-agent-sdk-*' --external @openai/codex-sdk --external node-pty

Bundled 244 modules in 77ms

  cli.js  1.1 MB  (entry point)


> @sleep2agi/agent-network@2.3.0-preview.34 typecheck
> tsc --noEmit

Bundled 193 modules in 64ms

  anet-cli.js  1.78 MB  (entry point)

PASS: agent-node + anet CLI builds
Summary: PASS (294 tests, 0 failures; all validation ran inside Docker)
