Repository navigation
🤖 tests: mutation survivors on lines that phase 4 PRs did not change (moved from #7326) #7475
Description
Moved from #7326. These mutation survivors are on lines that no phase 4 PR changed, and none of them is lock code. Phase 4 PR 17 (the test-gap PR for the lock files) does not close them, because they are outside its scope and do not fit in a 500-line PR. The issue also tracks T14, the one lock-code test gap that PR 17 leaves out (see its section).
- Owner: the author of the next PR that changes one of the functions below.
- Trigger: the repo's mutation gate.
make mutate-checkand theQuality / Mutationcheck report the survivors of each function that a PR changes. That PR kills the survivors on the lines it changes, and marks them done here. - Close: when every item below is killed, or has a reasoned close.
Single survivors (#7326 items M33 to M53)
Line numbers are on the PR 4 head (#7345, 907f6b0).
Status (2026-10-25): #7492 killed M33 to M47. M48 to M53 stay open until #7485 merges. See this comment.
| #7326 item | File and line | Function | Mutant |
|---|---|---|---|
| M33 | src/node/services/artifactVersionStore.ts:152 |
recordArtifactVersion |
?? -> || |
| M34 | src/node/services/artifactVersionStore.ts:166 |
recordArtifactVersion |
0 -> 1 |
| M35 | src/node/services/artifactVersionStore.ts:166 |
recordArtifactVersion |
1 -> 0 |
| M36 | src/node/services/artifactVersionStore.ts:185 |
recordArtifactVersion |
!= -> == |
| M37 | src/node/services/artifactVersionStore.ts:198 |
recordArtifactVersion |
true -> false |
| M38 | src/node/services/artifactVersionStore.ts:224 |
acquireIndexFileLock |
?. -> . |
| M39 | src/node/services/workflows/WorkflowRunStore.ts:228 |
constructor |
0 -> 1 |
| M40 | src/node/services/workflows/WorkflowRunStore.ts:228 |
constructor |
> -> >= |
| M41 | src/node/services/workflows/WorkflowRunStore.ts:230 |
constructor |
?? -> || |
| M42 | src/node/services/workflows/WorkflowRunStore.ts:232 |
constructor |
0 -> 1 |
| M43 | src/node/services/workflows/WorkflowRunStore.ts:232 |
constructor |
> -> >= |
| M44 | src/node/services/workflows/WorkflowRunStore.ts:1110 |
acquireLease |
0 -> 1 |
| M45 | src/node/services/workflows/WorkflowRunStore.ts:1110 |
acquireLease |
> -> >= |
| M46 | src/node/services/workflows/WorkflowRunStore.ts:1119 |
acquireLease |
<= -> < |
| M47 | src/node/services/workflows/WorkflowRunStore.ts:1778 |
withWorkflowFileLock |
0 -> 1 |
| M48 | src/node/utils/journal/journal.ts:92 |
constructor |
0 -> 1 |
| M49 | src/node/utils/journal/journal.ts:92 |
constructor |
> -> >= |
| M50 | src/node/utils/journal/journal.ts:98 |
constructor |
?? -> || |
| M51 | src/node/utils/journal/journal.ts:99 |
constructor |
0 -> 1 |
| M52 | src/node/utils/journal/journal.ts:99 |
constructor |
> -> >= |
| M53 | src/node/utils/journal/journal.ts:152 |
append |
+ -> - |
Survivor counts per function (from the #7326 comments)
Each phase 4 PR below changed only one argument or one property line in these functions, so the mutation gate scored the whole function. Counts are from the latest run of each PR. Line numbers are on that PR's head.
| Function (file) | Survivors | Reported by |
|---|---|---|
TurnRequestBuilder.prepareOrThrow (turnRequestBuilder.ts) |
141 (94 not run), later 27 and 45 | PR 15 #7380, PR 16 #7378 round 3, PR 13 #7423 |
createProposePlanTool (tools/propose_plan.ts) |
lines 35, 47, 60, 69, 91, 115 | PR 15 #7380 |
createReviewPaneUpdateTool (tools/review_pane.ts) |
lines 182, 184, 206 | PR 15 #7380 |
AgentSession.buildAttachmentsFromContext (agentSession.ts) |
9 (lines 13546, 13598 to 13600) | PR 16 #7378 |
InitStateManager (constructor, readUnownedRunningInit, acquireRecordLock, releaseRecordClaim, isRecordLockHeld) |
lines 140, 511, 524, 557, 568, 573 | PR 16 #7378 |
WorkspaceService.importLegacyPlan, markRemotePlanMigratedForRemoval, deletePlanFilesOfMetadata |
lines 6076, 6077; 9002, 9004 (7); 18771 (2) | PR 16 #7378 |
markRemotePlanMigratedForDeletion, migrateRemotePlan, findImportableLegacyPlanPath (planLocation.ts) |
lines 141, 263, 290 | PR 16 #7378 rounds 1 and 2 |
WorkspaceService.rename |
59 (lines 10286 to 10602) | PR 16 #7378 round 2 |
WorkspaceService.getImportableLegacyPlan |
lines 6052, 6053, 6063 | PR 16 #7378 round 2 |
TaskService.handleSuccessfulProposePlanAutoHandoff |
25 | PR 16 #7378 round 3 |
TaskService.handleSuccessfulWorkflowProposePlan |
23 | PR 16 #7378 round 3 |
ensurePlanSnapshot (planReviewService.ts) |
lines 288, 311 | PR 16 #7378 round 3 |
WorkspaceTurnManager.acquireTurnOwnerLock (workspaceTurnManager.ts) |
2 (:746 0 -> 1, :757 ! deleted) |
PR 11 #7403 |
AgentSession.prepareMessage (agentSession.ts) |
177, later 197 (budget of 300 used up) | PR 12 #7404, PR 18 #7427 |
cacheAuditCommand (cli/debug/cache-audit.ts) |
20 | PR 12 #7404 |
removeSingleWorkspaceUnlocked (workspaceService.ts) |
35 | PR 12 #7404 round 5 |
RefineService.applyLocked, RefineService.runLocked |
22, 12 | PR 12 #7404 round 5 |
removeSessionDirUnderMemoryLocks (workspaceRemoval.ts) |
10 | PR 12 #7404 round 5 |
rollbackRefinement, acquireRollbackFileLock (refinementRollback.ts) |
9, 1 | PR 13 #7423 |
createRefinementRollbackTool (tools/refinement_rollback.ts) |
2 | PR 13 #7423 |
GitPatchArtifactService.generate, maybeStartGenerationUnlocked |
29, 20 | PR 14 #7425 |
taskGitPatchEngine.applyProjectPatch, applyPatch |
31, 21 | PR 14 #7425 |
upsertSubagentReportArtifact, updateSubagentReportArtifactsFile |
7, 1 | PR 14 #7425 |
upsertSubagentFailureArtifact |
3 | PR 14 #7425 |
upsertSubagentTranscriptArtifactIndexEntry |
2 | PR 14 #7425 |
upsertSubagentGitPatchArtifact, markSubagentGitPatchArtifactApplied |
1, 1 | PR 14 #7425 |
WorkspaceService.fork |
78 | PR 18 #7427 (scoped run without agentSession.ts) |
awaitPendingBranchSummary, startAbandonedBranchSummaryInBackground (branchSummary.ts) |
2, 1 | PR 18 #7427 |
Several runs stopped at the default budget of 300 mutants, so these functions can have more survivors than the counts show.
T14: the macOS branch of probeProcessBirth (from phase 4 PR 17)
src/node/utils/concurrency/processLiveness.ts:72 has 7 surviving mutants in the ps -o lstart= branch, which runs only where /proc is missing (macOS). A Linux test needs a seam that makes the /proc read fail, and PR 17 adds only tests. A macOS test lane, or a later PR that adds that seam, closes it.
Status (2026-10-25): #7492 killed all 7 mutants without a seam. A readFileSync spy makes the /proc read fail.
Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $179.60
Activity
🤖 tests: kill the lock mutants that the phase 4 whole-file run left a…
ThomasK33 commentedon Oct 25, 2026
This workspace (8dcb4713cb, agent-loop refactor follow-ups) takes M33 to M53 and T14. A PR follows.
ThomasK33 commentedon Oct 25, 2026
Update from #7492 (tests only, merged as a0165b2):
Killed by new tests. Each test fails on its mutant and passes on main. I checked this by hand, and the mutation tool confirms it.
artifactVersionStore.ts): killedWorkflowRunStore.ts): killedprocessLiveness.ts:72: killed. No production seam was needed. AspyOn(fs, "readFileSync")that throws reaches theps -o lstart=branch on Linux, and aspawnSyncstub sets the ps result.Found in the same functions, not in the table:
WorkflowRunStore.ts:1778-->+(withWorkflowFileLock): killedprocessLiveness.ts:62&&->||(probeProcessBirth): killedartifactVersionStore.ts:145??->||: equivalent.readArtifactIndexreturns an object ornull, so??and||agree.processLiveness.ts:71?.->.: equivalent. A nullstdoutmakes the mutant throw inside thetry, and thecatchreturns the samenull.On main, the mutation tool reported 26 survivors in these six functions. After #7492 it reports 2, and both are the equivalent ones above.
Still open: M48 to M53 (
journal.ts, now lines 97, 103, 104 and 159).journal.tsis a #7485 file. This workspace (8dcb4713cb) takes them in a follow-up PR after #7485 merges.Out of scope here: the "Survivor counts per function" table. As this issue says, the mutation gate covers each of those functions on the next PR that changes it.
ThomasK33 commentedon Oct 25, 2026
#7511 (tests only, merged as cf7b78b) killed the last items, so this issue is closed.
journal.ts, now at lines 97, 103, 104 and 171): killed. Each test fails on its mutant and passes on main. I checked this by hand, and the mutation tool confirms it:Journal.constructorandJournal.appendhave 0 survivors after 🤖 tests: kill the #7475 journal.ts mutation survivors M48 to M53 #7511.journal.ts:127and:139, in thecreateParentDircode that 🤖 fix: a late skill-tool journal row no longer recreates a removed session dir #7485 added for 🤖 bug: removing a workspace during a turn with parallel tool calls can recreate its session directory #7474. A new test removes the session folder, appends withcreateParentDir: false, and checks for ENOENT and that the folder is still missing. It also checks that a default append creates the folder again. These 3 were not in this issue's table.Every item in the "Single survivors" table and T14 is now killed: M33 to M47 and T14 in #7492, and M48 to M53 in #7511. The 2 survivors outside the table that #7492 found are equivalent, and its comment gives the reasons.
Reasoned close for the "Survivor counts per function" table: I left it out of scope. As this issue says, the mutation gate (
make mutate-checkandQuality / Mutation) scores each of those functions on the next PR that changes it, and that PR kills the survivors on its lines.🤖 tests: kill the coder#7475 mutation survivors M33 to M47 and T14 (c…
🤖 refactor: callers pass their session locks to the branch-summary ma…
🤖 tests: kill the coder#7475 journal.ts mutation survivors M48 to M53 (…