Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions apps/desktop/test/local-codex-native.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ for (const mode of ["overflow-http", "overflow-stream", "oom-500", "unavailable-

interface CompactionHop { n: number; method: string; path: string; model: unknown; authorization: "bearer" | "none" | "other"; inputItems: number; hasToolOutput: boolean; summaryRequest: boolean; hasSummary: boolean; hasPrompt: boolean; lastInputHead: string }

test("AC1 compaction: a local child that passes its auto-compact limit compacts through the configured loopback server, and nowhere else", { skip: !process.env.MODEX_LM3_WIRE && "set MODEX_LM3_WIRE=1 to start the installed codex CLI", timeout: 120_000 }, async () => {
test("AC1 compaction: the configured loopback server observes inline compaction after the local child passes its auto-compact limit", { skip: !process.env.MODEX_LM3_WIRE && "set MODEX_LM3_WIRE=1 to start the installed codex CLI", timeout: 120_000 }, async () => {
const PROMPT = "LM5-AC1-COMPACTION-PROMPT-31e2", SUMMARY = "LM5-AC1-SUMMARY-77b0";
const hops: CompactionHop[] = [];
const usage = (total: number) => ({ input_tokens: total - 10, input_tokens_details: { cached_tokens: 0 }, output_tokens: 10, output_tokens_details: { reasoning_tokens: 0 }, total_tokens: total });
Expand Down Expand Up @@ -371,7 +371,7 @@ test("AC1 compaction: a local child that passes its auto-compact limit compacts
}
});

test("AC3: a turn queued behind another profile of the same server and then stopped sends that server nothing", { skip: !process.env.MODEX_LM3_WIRE && "set MODEX_LM3_WIRE=1 to start the installed codex CLI", timeout: 120_000 }, async () => {
test("AC3: a turn queued behind another profile of the same server and then stopped sends that server nothing", { skip: !process.env.MODEX_LM3_WIRE && "set MODEX_LM3_WIRE=1 to start the installed codex CLI", timeout: 120_000 }, async t => {
const FIRST = "LM5-AC3-FIRST-1a9e", QUEUED = "LM5-AC3-QUEUED-5c0d";
const requests: { path: string; first: boolean; queued: boolean }[] = [];
let release!: () => void;
Expand Down Expand Up @@ -405,8 +405,13 @@ test("AC3: a turn queued behind another profile of the same server and then stop
const target = (id: string) => ({ schema: 1 as const, harness: "codex" as const, model: { schema: 1 as const, connection: { id, revision: 1 }, id: model } });
const a = { id: "ac3-a", cwd: workspace(), localTarget: target(one.id), localContextTokens: 32768 };
const b = { id: "ac3-b", cwd: workspace(), localTarget: target(two.id), localContextTokens: 32768 };
const first = execution.backend(a).runTurn(`${FIRST}: reply with one word.`, { cwd: a.cwd, mode: "chat", plan: false, model }, sinkFor([], []), AbortSignal.timeout(90_000));
await holding;
const first = execution.backend(a).runTurn(`${FIRST}: reply with one word.`, { cwd: a.cwd, mode: "chat", plan: false, model }, sinkFor([], []), AbortSignal.any([t.signal, AbortSignal.timeout(90_000)]));
// A failed admission or child startup can finish without ever reaching the server.
// Surface that result and enter cleanup instead of waiting for an impossible request.
await Promise.race([
holding,
first.then(result => { throw new Error(`first turn ended before reaching the fixture: ${JSON.stringify(result)}`); }),
]);
const stop = new AbortController();
const queued = execution.backend(b).runTurn(`${QUEUED}: reply with one word.`, { cwd: b.cwd, mode: "chat", plan: false, model }, sinkFor([], []), stop.signal);
await new Promise(r => setTimeout(r, 500));
Expand Down
24 changes: 23 additions & 1 deletion docs/reviews/2026-10-29-cf7-closeout/checkpoint.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,36 @@ replace `hello` with `hello, live`, run `npm test` again, and say in one sentenc
Unlike the CF-8 probe, this one **keeps** the seeded home and repository, so the saved Note can be
opened in the app:

| Backend | Launch for review (from `.worktrees/cf7-closeout/apps/desktop`) |
| Backend | Launch for review (from `.worktrees/cf7-review-kit/apps/desktop`, after `pnpm build` there) |
| --- | --- |
| Claude | `MODEX_HOME=$PWD/.probes/cf7-human/claude/home npx electron .` |
| Codex | `MODEX_HOME=$PWD/.probes/cf7-human/codex/home npx electron .` |

In each, open **Space → Personal → cf7-review-repo → Task: If you have a task-list…**, then **Task view**.
The thread is in the sidebar. `~/.modex` is never touched.

**Review kit moved, 2026-11-01.** The original `.worktrees/cf7-closeout` was removed by
`scripts/worktree.sh prune` on 2026-10-31 after #443 merged, so the launch commands first written here
pointed at nothing. The git-ignored homes, repositories and probe had been saved beforehand to
`~/.claude/task-evidence/worktree-prune-2026-10-29/cf7-closeout/apps/desktop/.probes/`. That copy stays
untouched. A second copy now sits in the `cf7-review-kit` worktree (cut from `main` at `0a8c513`), and
the table above points there. That worktree stays checked out until Val has reviewed.

Checked on a build of `0a8c513`, which includes #450, #453 and #463. A probe copied each home to a
temporary directory and opened it through **Space**. Both saved Task Notes opened as a read-only Task view:
"Read-only: nothing here runs again", no editable control, no edited or moved warning, and the thread's
items unchanged afterwards. The Claude view lists `greeting.txt read`. The Codex view lists no files. Both
read "Verified: `npm test` passed after the last change". The kit's files hashed the same before and after.
The probe and its screenshots are outside the tree, under `~/.claude/task-evidence/lane-b-2026-11-01/`.

Two things a reviewer will notice:

- The notes reopen as they were saved on 2026-10-29, before #450. They show the old files list and the
title cut mid-word, not the "maybe more" footer or the word-break title. Seeing those needs a new live turn.
- Each home records its project at the old `.worktrees/cf7-closeout/…/repo` path. The thread and the note
open, but the side panel's Review tab reads "Not a git repository". The repositories are copied beside the
homes. The Note and Task view do not depend on them.

### Claude Code 2.1.312 (`claude -p`, Haiku, Chat mode): passed, 2026-10-29 22:54 UTC

Report `live-claude-report.json`, note `live-claude-note.md`, record `live-claude-task-record.json`,
Expand Down
15 changes: 8 additions & 7 deletions docs/reviews/2026-11-01-lm5-fixtures.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,7 @@ Kinds of evidence are kept apart:
| 2 | `POST /v1/responses`, bearer, `scripted-fixture-model` | **compaction**: the history including the tool output, then Codex's "You are performing a CONTEXT CHECKPOINT COMPACTION. Create a handoff summary…" as the last user input |
| 3 | `POST /v1/responses`, bearer, `scripted-fixture-model` | the turn continues on the compacted history ("Another language model started to solve…" plus the server's summary) and completes |

Compaction on 0.166.0 for a custom Responses provider runs inline. It goes to the configured server, on the same
path, for the selected model, with the connection's token. No `/responses/compact` or other endpoint was asked
for. The test fails if any request, compaction included, reaches any other path or model, or if no compaction
happens.
The recording loopback server observed inline compaction on 0.166.0 for a custom Responses provider, on the same path and selected model with the connection's token. It saw no `/responses/compact` request or other path. The test fails if a request observed by this server uses another path or model, or if it observes no compaction. It does not monitor other destinations and does not establish the absence of cloud traffic.

Codex clamps the auto-compact limit to the window. With `model_auto_compact_token_limit` set to 8× the window,
it still compacted at the same point. So a too-high limit can't defer compaction past the window.
Expand Down Expand Up @@ -94,9 +91,7 @@ The test waits 1.5 s after the turn ends to catch a late retry. Receipts are in
| child-exit | stream held; the test SIGKILLs the codex child | failed | "codex app-server exited (null)" |
| stop | stream held; the person stops | interrupted | none |

No mode produced a cloud request or a second model: the only server the child knows is the loopback fixture. The
runner tests already cover the runner side: a failed local turn gets no credit fallback and no cloud retry
("a failed local turn stays failed…").
For every mode, the recording loopback server observed only the selected model and no retry during the observation window. These fixtures do not monitor other destinations and cannot establish that the child made no cloud requests. Separate runner tests cover the runner's refusal to apply credit fallback or cloud retry to a failed local turn ("a failed local turn stays failed…").

## AC5: entry points

Expand Down Expand Up @@ -166,3 +161,9 @@ All logs are in `~/.claude/task-evidence/lane-d-2026-11-01/`.
- **AC1 live:** a real local server.
- **AC6 managed-policy precedence:** no managed Mac has run it.
- **Product admission** of `LocalExecution` in `main/index.ts`: Val's decision. Its brief is on #380.

## Review repair: early AC3 termination

The AC3 server-arrival wait races the first turn result, and the first turn receives the test cancellation signal as well as its 90-second deadline. An early admission, startup or cancellation result therefore fails the fixture with that result and enters cleanup. Before the repair, replacing the first turn signal with an already-aborted signal left the fixture pending until an external 12-second deadline terminated it. After the repair, the same negative control failed promptly with `status: interrupted` (about 15 ms) and the process exited normally with test failure. The unmodified installed-Codex wire fixture passed in about 2 seconds. These checks establish fixture termination and its normal queued-cancel path, not live-model or offline acceptance.

Repair validation: `pnpm build && pnpm test` exited 0, with 2,281 passes and 35 skips across the full unit suite. Independent review found no blocking findings; its minor overbroad AC1 test title was corrected. No UI code changed and no additional E2E suite was run for this fixture/documentation repair. The integration also retains main’s CF-7 checkpoint restoration and corrected October 31 UTC landing dates. Main merge, product admission and native runtime acceptance remain separate gates.
8 changes: 4 additions & 4 deletions docs/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The published application source is `6a97d23aaea315b29008890f25dde2d7ea07f1d0` (
## v0.4.1 publication and remaining acceptance

- **v0.4.1 published (2026-10-31).** Signed tag `v0.4.1` names protected merge `6a97d23`. Release run `41163487821` passed signed packaged E2E (479 desktop passed, 4 skipped; 7 site passed), three native updater scenarios, Windows/Linux checks and artifact attachment. All five downloaded installers match the release manifest; macOS signature, Gatekeeper and stapler checks passed. The initial download-failure job stopped before updater execution because its fixture manifest was missing; one retry passed on the unchanged candidate. Original failures and acceptance limits remain in the [publication review](reviews/2026-10-30-v0.4.1-release-review.md#published--2026-10-31-utc).
- **CF-7 close-out follow-ups (#280, #450, #453).** The file-evidence and title fixes shipped in v0.4.1. Val's human review of the saved Notes remains open on #280; publication does not complete that acceptance. See the [close-out receipt](reviews/2026-10-29-cf7-closeout/checkpoint.md).
- **CF-7 close-out follow-ups (#280, #450, #453).** The file-evidence and title fixes shipped in v0.4.1. Val's human review of the saved Notes remains open on #280; publication does not complete that acceptance. The review homes moved to the `cf7-review-kit` worktree on 2026-11-01, after the original worktree was pruned. Both saved Notes still reopen read-only on a build of `0a8c513`. See the [close-out receipt](reviews/2026-10-29-cf7-closeout/checkpoint.md#the-real-task-and-its-saved-note-human-review-candidate) for the launch commands.

## v0.4.0 source delivery and remaining acceptance

Expand Down Expand Up @@ -233,7 +233,7 @@ The published application source is `6a97d23aaea315b29008890f25dde2d7ea07f1d0` (

## In flight

- **Deferred Markdown for long threads (hosted cold-open budget).** Hosted CI's approved 500 ms cold-open gate failed on runner variance alone: 33 hosted runs on 2026-10-30 had a 377.7 ms median and a 781.9 ms failure on application code identical to a 436.1 ms pass. Val chose on 2026-10-30 to defer offscreen answers. Turns before the newest eight show their Markdown as written until it nears the view, then parse once; scroll anchoring keeps the reader's place. Locally the five-launch median fell from about 190 to 88 ms, and 3× CPU throttling cut it from 806–870 to 312–340 ms. The gate is unchanged. The first hosted run had a 129.9 ms median (481 desktop E2E passes). It landed through #463 (`32f1cb4`) on 2026-11-01 and is unreleased. [Evidence](reviews/2026-10-30-deferred-markdown.md).
- **Deferred Markdown for long threads (hosted cold-open budget).** Hosted CI's approved 500 ms cold-open gate failed on runner variance alone: 33 hosted runs on 2026-10-30 had a 377.7 ms median and a 781.9 ms failure on application code identical to a 436.1 ms pass. Val chose on 2026-10-30 to defer offscreen answers. Turns before the newest eight show their Markdown as written until it nears the view, then parse once; scroll anchoring keeps the reader's place. Locally the five-launch median fell from about 190 to 88 ms, and 3× CPU throttling cut it from 806–870 to 312–340 ms. The gate is unchanged. The first hosted run had a 129.9 ms median (481 desktop E2E passes). It landed through #463 (`32f1cb4`) on 2026-10-31 UTC and is unreleased. [Evidence](reviews/2026-10-30-deferred-markdown.md).

Desktop CI memory diagnostics landed through #458 after #456’s cold transcript budget failure. The workflow reuses the existing resource sampler and retains its log as a separate CI artifact; it does not establish the cause of the earlier failure or change the 500 ms gate. The #458 queue passed desktop and site E2E and retained its memory log. See [the diagnostic review](reviews/2026-10-30-desktop-ci-memory.md).

Expand All @@ -242,7 +242,7 @@ Desktop CI memory diagnostics landed through #458 after #456’s cold transcript
- **LM-5 auxiliary dispatch regressions.** Candidate tests exercise deterministic local approvals, human approval fallback and four local failure outcomes with a recording Jev transport and cloud positive control. Thirteen focused cases passed; removing the local approval guard made both local approval cases fail on unexpected dispatch. Build and full unit validation passed (2,251 passes, 26 skips); independent review found no actionable findings. Protected delivery landed through #447; native offline acceptance and the remaining #380 criteria stay open. [Evidence](reviews/2026-10-30-lm5-auxiliary-dispatch.md).
- **LM-5 context-window evidence (#380 AC6).** A local child's context window keeps its sources apart: the person's explicit setting, the effective value Codex reports, the runtime's last advertised maximum (or "not checked") and an unknown loaded size. A window above the advertised maximum is refused before any process starts. Disabling each of the four new guards made its regression fail. Product admission, the native offline canary and real-runtime overflow handling stay open. [Evidence](reviews/2026-10-30-lm5-context-evidence.md).
- **LM-5 known cloud-routed models refused by main (#380).** `LocalExecution.validate` refuses a model the connection's last listing marked cloud-routed, embedding-only or not generative. On an Ollama connection it also refuses a `…:cloud`/`…-cloud` name without any listing. Nothing is spawned. Unmarked models stay unverified rather than local. Disabling each of the four guards made its regression fail. [Evidence](reviews/2026-10-30-lm5-cloud-routed-models.md).
- **LM-5 fixture-level AC1 compaction, AC3, AC4 and AC5 (#380, in review).** On codex-cli 0.166.0 against a scripted loopback server, a local child's native compaction goes inline to the configured server for the selected model, and nowhere else. Two profiles for one service share a slot, and a stopped queued turn sends that server nothing. A context overflow, an OOM 500, a 503, a dropped stream, a killed child and Stop each end failed or interrupted, with no retry, model switch or second tool run. Four repairs: a local 500 no longer shows Codex's cloud "high demand" text; admission requires `stream_max_retries=0`; the compaction prompt and threshold keys are governed; only this Mac's window (`by: "desktop"`) may set or clear a local target. Each new regression failed before its fix or under a negative control. Product admission, AC2 offline and real-runtime AC4 stay with Val. [Evidence](reviews/2026-11-01-lm5-fixtures.md).
- **LM-5 fixture-level AC1 compaction, AC3, AC4 and AC5 (#380, in review).** On codex-cli 0.166.0 against a scripted loopback server, the recording server observed a local child's inline compaction for the selected model. Other destinations were not monitored. Two profiles for one service share a slot, and a stopped queued turn sends that server nothing. A context overflow, an OOM 500, a 503, a dropped stream, a killed child and Stop each end failed or interrupted, with no retry or model switch observed by the fixture and no second tool run. Four repairs: a local 500 no longer shows Codex's cloud "high demand" text; admission requires `stream_max_retries=0`; the compaction prompt and threshold keys are governed; only this Mac's window (`by: "desktop"`) may set or clear a local target. Each new regression failed before its fix or under a negative control. The AC3 fixture now surfaces early turn termination instead of waiting indefinitely for server arrival; an aborted-turn negative control and the normal wire fixture verified this repair. Product admission, AC2 offline and real-runtime AC4 stay with Val. [Evidence](reviews/2026-11-01-lm5-fixtures.md).

- **Canvas Escape harness readiness.** Repeated hosted failures showed the main pane still hidden after guest Escape. A controlled delayed-IPC diagnostic proved that renderer full-view state can precede native readiness. The test-only candidate waits for the native guest to become visible at the expanded preview bounds before sending one Escape, retaining all security and lifecycle assertions. Five candidate repetitions and full local validation passed; the implementation also passed hosted macOS validation. The Windows first failure, passing retry and original CodeQL upload failure remain recorded. It landed through #446 (`2ce777c`) on 2026-10-30, after v0.4.0. [Evidence](reviews/2026-10-30-canvas-native-readiness.md).

Expand Down Expand Up @@ -305,7 +305,7 @@ Desktop CI memory diagnostics landed through #458 after #456’s cold transcript
overview and remote diff now in the panes, that the list, overview, diff and file tree scroll alone
and keep focus at 1440×900 and 900×600 ([acceptance record](reviews/2026-10-28-cr3-acceptance.md)).
On 2026-10-30 the automated half was re-run on `main` at `f51ef7e` and the read-only authenticated
navigation probe passed six of six there again ([resume record](reviews/2026-10-30-cr3-acceptance-resume.md), landed through #464, `3d72c6e`, on 2026-11-01);
navigation probe passed six of six there again ([resume record](reviews/2026-10-30-cr3-acceptance-resume.md), landed through #464, `3d72c6e`, on 2026-10-31 UTC);
the journey spec's R1 and R4 captures, which had shown an empty Changes pane and no checks, now carry
populated content for the comparison.
Original reference comparison waits for Val to name the references (deferred on 2026-10-28); human
Expand Down
Loading