Skip to content

LM-5 slice 1: admit a local Codex child on its effective configuration (#380) - #419

Closed
BunsDev wants to merge 1 commit into
lm3-codexfrom
lm5-policy
Closed

BunsDev wants to merge 1 commit into
lm3-codexfrom
lm5-policy

Conversation

@BunsDev

@BunsDev BunsDev commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

LM-5 slice 1 (#380) under #376, stacked on LM-3 (#417, lm3-codex): the base is lm3-codex, so this PR shows only its own commit until #417 lands. Main-only: no UI, no new IPC, no inference client. Refs #380, #379, #376.

What it answers. The #417 review's remaining finding: naming a provider on thread/start does not verify the effective HTTP destination, and #379 AC6 (inherited config, proxy/redirect and managed policy) was open.

Admission by effective configuration (engine/local-models/run-policy.ts, backends/codex.ts, local-models/execution.ts). Before a local child opens or resumes any thread, CodexBackend reads the child's own config/read (with layers, for the turn's cwd) and configRequirements/read, and admitLocalConfiguration admits it only when: every governed key (model, model_provider(s), openai_base_url, context, web_search, features, mcp_servers, shell_environment_policy, plugins, hooks, instructions, experimental_*, …) originates from Modex's session flags; no project layer is loaded; the private home is empty; no managed layer (MDM, /etc/codex, enterprise bundle, legacy managed_config.toml) touches a governed key even where its value loses; requirements is null; and the effective values are exactly the ones Modex passed (destination <origin>/v1, Responses wire, no OpenAI auth, env_key only with a token, no retries, no headers/query/auth command, the context window, web search disabled, no reasoning summary, view_image off, no MCP servers). Otherwise the turn fails naming the layer and key; nothing is rewritten, bypassed or sent. A Codex without config/read is refused. The admitted provenance (session-flags hash, each layer's source/hash/file; no secrets) is kept with the child (LocalExecution.provenance). A model/rerouted notification on a local turn interrupts it and reports it failed, ending running terminals as on Stop.

Evidence (review). codex-cli 0.164.0 config/read returns the effective configuration, an origins map and the layers with hashes; for an LM-3 child every origin is sessionFlags over an empty user and empty system layer (receipt). A requirements.toml in the private home is not read. Redirects: a 307 from the configured loopback server is followed with the full 29 KB body and without the token; a 302 becomes a bodyless GET; no Codex setting constrains this (receipt). The opt-in native test now asserts the token never follows a redirect and records the body behaviour.

Checks. RED at LM-3's head: the extended execution tests fail to build (provenance missing) and the reroute case never ends. GREEN: local-run-policy (5), local-model-execution (11), codex-backend, runner-local-models: 62/62; pnpm build and pnpm typecheck pass; full desktop unit suite: 2,038 tests, 2,018 passed, 0 failed, 20 skipped (17 usual opt-in plus the three native LM-3/LM-5 checks); core/site/store-desktop/worktree suites pass. MODEX_LM3_WIRE=1: the LM-3 wire test passed with admission in the path (provenance recorded, receipt) and the redirect test passed.

Open. A live managed-policy run on a Mac that has one (the refusal is fixture-proven). Product admission stays closed (main/index.ts still does not construct LocalExecution): this is the refusal boundary the review asked for, and wiring it is Val's decision. AC1's live local turn (LM-3) remains Val's. AC2/AC5/AC6 of #380 and the capacity/outcome slices are later slices. No merge or release is requested.

🤖 Generated with Claude Code

#380)

Before a local child opens or resumes a thread, CodexBackend reads the
child's own config/read (effective configuration, the layer that set each
key, every layer's contents and hash) and configRequirements/read, and
admitLocalConfiguration (engine/local-models/run-policy.ts) admits it only
when every governed key comes from Modex's session flags, no project layer
is loaded, the private home is empty, no managed layer touches a governed
key, no managed requirements apply, and the effective destination, wire,
credential reference, context and tools are exactly what Modex passed.
Otherwise the turn fails naming the layer and key; nothing is rewritten or
sent. The admitted provenance is kept with the child. A model/rerouted
notification on a local turn interrupts it and reports it failed.

Real-CLI evidence (codex-cli 0.164.0): config/read reports origins and
layers as the policy expects; a requirements.toml in the private home is
not read; a 307 from the configured loopback server is followed with the
full body and never with the token, a 302 as a bodyless GET. The opt-in
native test records both. This is the refusal boundary #417's review asked
for; wiring local execution into the product stays a separate decision.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
modex Ready Ready Preview Oct 27, 2026 8:56pm UTC

Request Review

@BunsDev

BunsDev commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Hosted unit + e2e (macOS) on 065447f (run 40582439562) has failed twice, each time on one renderer e2e case while the other 467 passed, and each time a different case:

  1. Attempt 1: e2e/markdown-keyboard.spec.ts "Markdown keyboard traversal and reduced motion in graphite": after ArrowRight then ArrowLeft on an overflow stop, scrollLeft was 40, expected ≤ 0. The poll accepts any rightward movement, so ArrowLeft can land while the scroll is still settling. It passed on attempt 2.
  2. Attempt 2: e2e/transcript-measure.spec.ts "a 200-turn transcript opens within the agreed median budget across five fresh launches": cold first-open samples 1166, 994, 643, 640, 541 ms, median 642.5 against the 500 ms gate. The run took 32 minutes against 28 on LM-3: local execution through an isolated Codex child (#379) #417's green run of the same renderer, so the runner was slower than usual.

This PR changes only the main process (backends/codex.ts, local-models/*) and their unit tests; the renderer and the measured transcript path are byte-identical to #417's head 9159eda, where this job passed. Locally: build, typecheck, the full desktop unit suite (2,038 tests, 0 failures) and the native wire/redirect checks pass. A third attempt of the failed job is running; if it fails on yet another timing case I will leave it to your call rather than keep rerunning.

@github-code-quality

Copy link
Copy Markdown

Code coverage overview

Languages: TypeScript

TypeScript / code-coverage-agent

lm3-codex d717bb0 lm5-policy 065447f +/-
65% 66% +1%
View coverage of the 10 most impacted files.
File lm3-codex d717bb0 lm5-policy 065447f +/-
apps/desktop/sr...ions/intents.ts 100% 99% -1%
apps/desktop/sr...review/patch.ts 98% 100% +2%
apps/desktop/sr...eview/writes.ts 0% 86% +86%
apps/desktop/sr...rite-service.ts 0% 97% +97%
apps/desktop/sr...review-patch.ts 0% 97% +97%
apps/desktop/sr...review-write.ts 0% 100% +100%
apps/desktop/sr...ls/execution.ts 0% 100% +100%
apps/desktop/sr...s/run-policy.ts 0% 100% +100%
apps/desktop/sr...ons/write-gh.ts 0% 100% +100%
apps/desktop/sr...ge-preflight.ts 0% 100% +100%

ℹ️ Calculations represent line coverage. Results may change as calculations are updated.

@BunsDev

BunsDev commented Oct 27, 2026

Copy link
Copy Markdown
Contributor Author

Attempt 3 of unit + e2e (macOS) on 065447f passed (all 468 desktop e2e cases, run 40582439562); every hosted check is now green. The two earlier single-case failures were the Markdown keyboard scroll race and the 500 ms cold-open median on a slow runner, both renderer measurements this main-only change does not touch. Ready for review; no merge requested by me.

This branch was successfully deployed

1 active deployment
Preview — 065447f9 Deployed Oct 27, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants