Repository navigation
Conversation
… SessionLocks ToolConfiguration gains an optional sessionLocks (absent: the Node layer, for configs that tests build by hand). The turn request builder passes its history service's locks, so todo_write, propose_plan's todo sync and review_pane_update take the workspace FIFO from SessionLocks. setTodosForSessionDir takes locks (Node default), and its two app callers pass one: propose_plan and the mock stream player. todo.ts and review_pane.ts import no lock module now.
…uivalent ?? mutants propose_plan passes config.sessionLocks as is: setTodosForSessionDir's default parameter covers undefined, so the tool gains no branch (the CRAP gate refused CC 15 -> 16). The two remaining config.sessionLocks ?? nodeSessionLocks lines get a mutation-equivalent marker: sessionLocks is an object or undefined, so ?? and || agree.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
🟢 e2e stories (Haiku): 14 passed27 agent steps · 7 replayed from cache · 30 model calls · 207.4k tokens (72% cached) All 14 tests in 9 files
e2e 0.20.0 · 3m 5s · web · run artifacts 🟢 e2e Electron stories (Haiku): 3 passed3 agent steps · 3 model calls · 8.1k tokens (21% cached) All 3 tests in 3 files
e2e 0.20.0 · 20.8s · electron · run artifacts 🟢 e2e agent repros (Haiku): no tests selectedSpend: $0.00 of the $1.00 cap (proxy ledger) e2e 0.20.0 · 5.4s · 2 targets (web, phone) · run artifacts |
|
@codex security review |
|
Codex's security review on this PR started at about 02:06 UTC on head 16124bf and has not finished. One same-head security retry at 03:08:45 UTC also has not finished after 60 minutes. The code review of the same head is clean. So the same branch (phase4/tools) and head move to a new PR for a fresh review, as for #7354. I close this PR and keep the branch. |
…om SessionLocks (coder#7385) Replaces coder#7380 (Codex security review hung there). ## Summary The todo and review pane tools take the workspace FIFO from `SessionLocks`. The turn request builder passes its history service's locks in the tool config. It is PR 15 of phase 4. Lock keys and order do not change: the Node layer gives today's `workspaceFileLocks`. ## Order - Plan order: PR 15 comes after PRs 10 to 14. - Landing order: PR 15 lands on main as its own PR, before PR 5 (coder#7355), PR 8 (coder#7354), PR 7 and PRs 10 to 14 (recorded as a phase 4 plan note). - Why: PR 15 waits for phase 3 PR 8 (coder#7277) and for PR 9's `historyService.locks` (coder#7372). Both have merged. It uses no code from the PRs it jumps. Phase 5's 5a PR 12 waits for it. ## Implementation - `common/utils/tools/tools.ts`: `ToolConfiguration` gains an optional `sessionLocks`. When it is absent, the tools use the Node layer, as for `clock` and `desktopNotifications` in configs that tests build by hand. - `turnRequestBuilder.ts`: the tool config gets `sessionLocks: historyService.locks`. - `tools/todo.ts`: `writeTodos` takes the locks. `todo_write` passes `config.sessionLocks`. `setTodosForSessionDir(ws, dir, todos, locks = nodeSessionLocks)` takes locks, and both app callers pass one: - `propose_plan.ts` passes `config.sessionLocks` as is. The default parameter covers undefined, so `createProposePlanTool` gains no branch. - `mock/mockAiStreamPlayer.ts` passes `deps.historyService.locks`. Tests and the call record scenarios keep the default. - `tools/review_pane.ts`: the read, apply and write of `review_pane_update` run under `locks.workspaceFiles`, from `config.sessionLocks`. - `todo.ts` and `review_pane.ts` import no lock module now. The lint pairs for these two files arrive with coder#7355. coder#7355 drops them when it next merges main. ## Validation - On the head `16124bf4be`: `bun test` of `tools/todo.test.ts`, `tools/review_pane.test.ts`, `tools/propose_plan*.test.ts`, `mock/`, `scripts/noHostImports.test.ts` and `sessionLocks/`: 128 pass, 0 fail. `make static-check`: pass. `make crap-check`: PASS, 0 violations (a warning on the touched hotspot `prepareOrThrow`, CC 308 unchanged). - On `3b158d7e39` (the first commit; the second one drops a `??` in `propose_plan.ts` and adds two comments): `make lint-eslint` passes. `make test` gives 27753 pass, 0 fail in the main run, and every other run passes. The tripwire (`scripts/perf/loopTestBaseline.ts --runs 3 --base origin/main`) reports 0 trips. - In `todo.ts` and `review_pane.ts`, `rg -nP '(?<![.\w])(acquireProcessFileLock\(|acquireCrossProcessLock\(|inspectCrossProcessLock\(|workspaceUseLeasesFor\(|workspaceFileLocks\b)'` prints nothing. ## Mutation check `make mutate-check` on `16124bf4be`: 148 killed, 2 equivalent, 150 survived, 94 not run. - Equivalent (2): the `config.sessionLocks ?? nodeSessionLocks` lines in `todo.ts` and `review_pane.ts`. Each has a `mutation-equivalent:` marker: `sessionLocks` is an object or undefined, so `??` and `||` agree. - Survived (150): every survivor is on a line that this PR does not change. Each is a pre-existing gap for PR 17, listed in coder#7326. - `TurnRequestBuilder.prepareOrThrow` (CC 308): 141. The PR adds one property line, `sessionLocks: this.dependencies.historyService.locks`, with no operator to mutate. - `createProposePlanTool`: 6, on lines 35, 47, 60, 69, 91 and 115. - `createReviewPaneUpdateTool`: 3, on lines 182, 184 and 206. - Not run (94): past the default budget of 300 mutants per run (`mutate_report.py --max-mutants`). The scope is large because `prepareOrThrow` is a CC 308 hotspot. ## Risks - None for behavior. In the app, `historyService.locks` is the Node layer, so every tool uses today's `workspaceFileLocks` FIFO. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$122.03`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=122.03 -->
…h their 1 pair (coder#7355) ## Summary Puts the five session lock modules under `local/no-host-imports` for the agent-loop files, with the 1 (file, module) pair that those files still import. It is PR 5 of phase 4. ## Background Phase 4 moves the loop's lock calls behind `SessionLocks`. With the lock modules in `HOST_MODULES`, a loop file that adds a new direct lock import fails lint. The allow map holds today's imports, and the later move PRs remove them: - `agentSession.ts` -> `workspaceUseLeases` (PR 10) The PR first listed 5 pairs. 4 of them are gone, because the PRs that moved those imports merged first: - `historyService.ts` -> `workspaceFileLocks`, `fileLock`: coder#7372 (PR 9). - `tools/todo.ts` -> `workspaceFileLocks` and `tools/review_pane.ts` -> `workspaceFileLocks`: coder#7385 (PR 15, which replaced coder#7380). ## Implementation - `eslint.config.mjs`: `HOST_MODULES` gains `@/node/utils/concurrency/workspaceFileLocks`, `@/node/utils/concurrency/fileLock`, `@/node/utils/concurrency/processLiveness`, `@/node/utils/main/crossProcessLock` and `@/node/services/workspaceUseLeases`. `mutexMap` stays off the list: `tools/file_edit_operation.ts` keeps a pure in-memory map. `HOST_IMPORT_ALLOW` gains the 1 pair. - `.oxlintrc.json`: the same modules and pair. - `scripts/noHostImports.test.ts`: the frozen pairs gain the same 1. - No config block is added, and no source file changes. coder#7381 (PR 8) merged, so this PR now has base main. The branch has one merge of main, which resolves the 3 lint files. ## Validation - `bun test ./scripts/noHostImports.test.ts`: 6 pass, 0 fail. - `make static-check` and `make lint-eslint`: pass. The rule fails a stale allow entry, so the 1 pair is in use. - `make check-oxlint-config`: `.oxlintrc.json` matches `eslint.config.mjs` for every lint file. - `make test` on 1afc6e2: 27804 pass, 1 fail under host load (load average about 13): `backgroundProcessManager.test.ts` ("gives concurrent same-name spawns from two backends distinct directories on a non-host runtime"). The file passes alone on this head (166 of 166). The PR changes no runtime code. - Tripwire (`--runs 3 --base origin/main`): 0 trips. - `make crap-check`: PASS, CC 0 -> 0. `make mutate-check`: PASS with 0 mutants. The PR changes no production function. ## Risks Lint-only. A loop file that later adds a direct lock import fails lint until its PR lists the pair. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$135.57`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=135.57 -->
Summary
The todo and review pane tools take the workspace FIFO from
SessionLocks. The turn request builder passes its history service's locks in the tool config. It is PR 15 of phase 4. Lock keys and order do not change: the Node layer gives today'sworkspaceFileLocks.Order
historyService.locks(🤖 refactor: HistoryService takes its session locks from SessionLocks #7372). Both have merged. It uses no code from the PRs it jumps. Phase 5's 5a PR 12 waits for it.Implementation
common/utils/tools/tools.ts:ToolConfigurationgains an optionalsessionLocks. When it is absent, the tools use the Node layer, as forclockanddesktopNotificationsin configs that tests build by hand.turnRequestBuilder.ts: the tool config getssessionLocks: historyService.locks.tools/todo.ts:writeTodostakes the locks.todo_writepassesconfig.sessionLocks.setTodosForSessionDir(ws, dir, todos, locks = nodeSessionLocks)takes locks, and both app callers pass one:propose_plan.tspassesconfig.sessionLocksas is. The default parameter covers undefined, socreateProposePlanToolgains no branch.mock/mockAiStreamPlayer.tspassesdeps.historyService.locks.Tests and the call record scenarios keep the default.
tools/review_pane.ts: the read, apply and write ofreview_pane_updaterun underlocks.workspaceFiles, fromconfig.sessionLocks.todo.tsandreview_pane.tsimport no lock module now. The lint pairs for these two files arrive with 🤖 tests: put the session lock modules under local/no-host-imports with their 1 pair #7355. 🤖 tests: put the session lock modules under local/no-host-imports with their 1 pair #7355 drops them when it next merges main.Validation
16124bf4be:bun testoftools/todo.test.ts,tools/review_pane.test.ts,tools/propose_plan*.test.ts,mock/,scripts/noHostImports.test.tsandsessionLocks/: 128 pass, 0 fail.make static-check: pass.make crap-check: PASS, 0 violations (a warning on the touched hotspotprepareOrThrow, CC 308 unchanged).3b158d7e39(the first commit; the second one drops a??inpropose_plan.tsand adds two comments):make lint-eslintpasses.make testgives 27753 pass, 0 fail in the main run, and every other run passes. The tripwire (scripts/perf/loopTestBaseline.ts --runs 3 --base origin/main) reports 0 trips.todo.tsandreview_pane.ts,rg -nP '(?<![.\w])(acquireProcessFileLock\(|acquireCrossProcessLock\(|inspectCrossProcessLock\(|workspaceUseLeasesFor\(|workspaceFileLocks\b)'prints nothing.Mutation check
make mutate-checkon16124bf4be: 148 killed, 2 equivalent, 150 survived, 94 not run.config.sessionLocks ?? nodeSessionLockslines intodo.tsandreview_pane.ts. Each has amutation-equivalent:marker:sessionLocksis an object or undefined, so??and||agree.TurnRequestBuilder.prepareOrThrow(CC 308): 141. The PR adds one property line,sessionLocks: this.dependencies.historyService.locks, with no operator to mutate.createProposePlanTool: 6, on lines 35, 47, 60, 69, 91 and 115.createReviewPaneUpdateTool: 3, on lines 182, 184 and 206.mutate_report.py --max-mutants). The scope is large becauseprepareOrThrowis a CC 308 hotspot.Risks
historyService.locksis the Node layer, so every tool uses today'sworkspaceFileLocksFIFO.Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high• Cost:$122.03