Repository navigation
Read the hosted-agent environment through one type - #838
Conversation
The daemon writes these three variables and every hook reads them back, so their names are a contract between two executables that share only Core, and they live with the reader. A blank value is not a value: read as one, an empty bridge address made every Codex permission request fail closed instead of falling back to Codex's own prompt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR Summary by QodoCentralize hosted-agent environment handling
AI Description
Diagram
High-Level Assessment
Files changed (55)
|
Code Review by Qodo
1.
|
A value made of blanks was set by someone, so reading it as unnamed drops the line that tells them why their bridge is ignored, and lets a hook that fails closed on a bad address fall back silently instead. Only an unset or empty variable names nothing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nothing asserted the marker is that exact value, on either side of the contract. The name is pinned by the scrub tests, and both sides share the constant, so a rename stays self-consistent — only a changed value could pass unnoticed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Closes #836 — AI-2620
What & why
The daemon exports
KCAP_AGENT_ID,KCAP_RENDERED_AGENTandKCAP_DAEMON_URLinto every agent it hosts, and the hook side reads them back to learn whether it is hosted and where its bridge is. Both sides reached for the raw strings, each site inventing its own presence test.HostedAgentin Core now owns the three names — a contract between two executables belongs with its reader — and both rules: a blank variable names nothing, and a bridge must be http loopback. Commands take it from the composition root.DaemonBridgekeeps three cases rather than collapsing tostring?, because callers answer a refused address differently: the Codex hook fails closed, Claude's falls back to the server route, the input-wait relay gives up silently.Where to look
Two presence bugs the raw reads hid.
is { }andis not nullaccept an empty string, so a blank id was forwarded asagent_host_id; andCodexHookCommandbranched ondaemonUrl is null, so a blank bridge took the bridge path, failed validation inside it, and denied — every permission request for the whole session, rather than falling back to Codex's own prompt.The daemon's five writers are deliberately not one helper: the ACP factories stamp the id with no bridge, and
LocalIpcgates the set on--private.Verification
Mutating
DaemonBridge.Parseto read a blank value as an address failsPermissionRequest_with_a_blank_daemon_url_yields_to_codex_rather_than_denyingand nothing else. Three further mutations — the refused-bridge report, the relay's POST, the blank-id rule — each fail only their own tests.The daemon failure is
Installed_codex_schema_matches_the_vendored_pin, comparing the installed codex 0.153.4 against the 0.147.0 pin; it fails identically onmain.dotnet publish -c Releaseis IL2026/IL3050-clean forkcapandkcap-daemon.