Skip to content

test(apple): wait for the owner lookup's spawns by event, not a turn count - #4244

Closed
thymikee wants to merge 1 commit into
mainfrom
fix/launch-confirmation-spawn-wait
Closed

thymikee wants to merge 1 commit into
mainfrom
fix/launch-confirmation-spawn-wait

Conversation

@thymikee

@thymikee thymikee commented Nov 5, 2026 •

Copy link
Copy Markdown
Member

Summary

Validation

  • Tested SHA: 0ffc0d7c3459b0b3028fdba516902987c3fbd6d2
  • pnpm check:affected --run --head 0ffc0d7c3459b0b3028fdba516902987c3fbd6d2: format, lint, typecheck, layering, fallow, vitest-related and unit passed.
  • The test file passed 15 plain runs and 5 runs under coverage with 12 CPU-burning processes.
  • Not reproduced locally: the old version also passed 5 loaded coverage runs on macOS. The failure is CI-only (Linux); the fix removes the turn bound rather than tuning it.

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

View guided diff Turn on auto-fix

@github-actions

github-actions Bot commented Nov 5, 2026

Copy link
Copy Markdown
Contributor

Size Report

Metric Base Current Diff
Installed (including dependencies) 6.06 MB 6.06 MB 0 B
Package (unpacked) 6.06 MB 6.06 MB 0 B
Package (download) 1.83 MB 1.83 MB -8 B

Startup median (7 runs, lower is better):

Scenario Base Current Diff
CLI --version 28.0 ms 27.8 ms -0.1 ms
CLI --help 66.0 ms 65.1 ms -0.9 ms

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/platform-apple/src/launch-confirmation.test.ts">

<violation number="1" location="packages/platform-apple/src/launch-confirmation.test.ts:304">
P2: This race has no bounded fallback when the lookup stalls before its second spawn. Because the lookup timeout is not armed until that spawn, a delayed filesystem operation can hold the test until Vitest’s global timeout instead of failing fast; retain a bounded pre-spawn fallback.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

);

await untilSpawned(coreSimulator, 2);
await Promise.race([

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This race has no bounded fallback when the lookup stalls before its second spawn. Because the lookup timeout is not armed until that spawn, a delayed filesystem operation can hold the test until Vitest’s global timeout instead of failing fast; retain a bounded pre-spawn fallback.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/platform-apple/src/launch-confirmation.test.ts, line 304:

<comment>This race has no bounded fallback when the lookup stalls before its second spawn. Because the lookup timeout is not armed until that spawn, a delayed filesystem operation can hold the test until Vitest’s global timeout instead of failing fast; retain a bounded pre-spawn fallback.</comment>

<file context>
@@ -300,7 +301,13 @@ test.each([
       );
 
-      await untilSpawned(coreSimulator, 2);
+      await Promise.race([
+        lookupStarted,
+        answer.then(() => {
</file context>

@apex-sentinel-staging

Copy link
Copy Markdown

Apex Sentinel

Verdict: approve

1 finding(s): 1 minor.

🟡 Minor (1)

Where Finding
packages/platform-apple/src/launch-confirmation.test.ts:301 Lookup that never spawns the second command now hangs to the test timeout

Reviewed with this repository's own Sentinel configuration (e6ac165961de).

Reply under an inline comment with @apex-sentinel-staging note ... or @apex-sentinel-staging pivot ... to re-check that finding.
Comment @apex-sentinel-staging review on this conversation to run a full review.

@apex-sentinel-staging apex-sentinel-staging Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apex Sentinel: 1 new finding on 0ffc0d7. The verdict and the full list are in the summary comment.

Comment on lines 301 to +309
).then((value) => (answered = value)),
);

await untilSpawned(coreSimulator, 2);
await Promise.race([
lookupStarted,
answer.then(() => {
throw new Error('Owner lookup completed before the second command started');
}),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Minor · Lookup that never spawns the second command now hangs to the test timeout

When the owner lookup never spawns the second command (expected +0 to be 2), both race branches stay pending and the test dies on the Vitest timeout with a generic message instead of naming the spawn count. The new fast-fail covers only the opposite case; the bounded turn loop that was removed existed to fail this one, as its doc comment stated.

Suggested change

Keep a bounded wait so the never-spawned case reports the spawn count: race lookupStarted against answer and a timeout that asserts coreSimulator.spawns(), so a CI flake fails with "expected 0 to be 2" rather than the harness timeout.

Details

Also raised here

Also raised at this location by persona javascript: Race has no bound: a lookup that stalls without a second spawn hangs the worker — If the owner lookup spawns the app list and then stalls on something that is neither a spawn nor a completion (a pending fs stat, a lost await), neither arm of the race settles: lookupStarted never resolves and answer never settles, so the test hangs instead of failing. The worker runs with vi.useFakeTimers({ toFake: ['setTimeout', 'clearTimeout', 'Date'] }) in effect (line 282), so Vitest's own test-timeout timer is faked too and never fires — the file's remaining assertions never execute and the run dies on the worker/pool timeout, the same unattributed-failure shape this file's Coverage-lane history is about. The removed untilSpawned stated this as its purpose: "bounded so a lookup that stops early fails here, not at the test timeout", and its final expect(spawns()).toBe(count) still ran on exhaustion. The new code only detects the early stop that completes (the answer.then(throw) arm); the arm for a stalled lookup is gone. …

Also raised at this location by persona senior-developer: Removal of untilSpawned leaves an unbounded wait: a lookup that never spawns fails as a bare test timeout — If the owner lookup stalls before its second spawn — the first command never starts, or it starts and its hang() promise settles only on a timer the fake clock never advances — Promise.race never settles and the test dies on Vitest's generic test timeout instead of the named assertion the removed helper produced. The race's fast-fail arm covers only answer settling; it cannot cover a lookup that neither spawns twice nor completes, and with toFake: ['setTimeout','clearTimeout','Date'] nothing can advance it. The removed docstring stated this invariant explicitly: "bounded so a lookup that stops early fails here, not at the test timeout" (old launch-confirmation.test.ts:260-266). Keep the bound by racing the event against a wall-clock deadline, or assert a named failure when neither arm wins.

persona: maintainability, javascript, senior-developer

Reply @apex-sentinel-staging note ... to add context, or @apex-sentinel-staging pivot ... if this is wrong — I will re-check the cited code.

Useful? Reply @apex-sentinel-staging like, or @apex-sentinel-staging dislike <why> if it is not.

@thymikee

thymikee commented Nov 5, 2026

Copy link
Copy Markdown
Member Author

At 0ffc0d7, the code looks good. Waiting for the owner lookup's spawns by event removes the turn-count race behind the Coverage flake, and the test still proves two spawns within the bounded lookup. All 17 checks pass and there are no conflicts. I read the change and did not run it under coverage load.

Not blocking, take or leave: if the second spawn never comes, the failure now shows as a generic test timeout instead of the old explicit expect(spawns).toBe(2) message, since the fake clock keeps the lookup deadline from firing (launch-confirmation.test.ts:304); racing lookupStarted against a real-timer rejection would keep the clear message.

The two open inline threads can be resolved: the test fakes only setTimeout, clearTimeout and Date, so the per-test timeout still bounds a stalled lookup, and the clearer failure message is the note above.

@thymikee thymikee added the ready-for-human Valid work that needs human implementation, judgment, or maintainer merge label Nov 5, 2026
@thymikee

thymikee commented Nov 6, 2026

Copy link
Copy Markdown
Member Author

Superseded by #4225, which merged the same event-driven wait into main, plus a real-time 1 s bound and an abort for the lookup. Resolving the conflict against main leaves this PR with no changes, so I'm closing it.

@thymikee thymikee closed this Nov 6, 2026
@thymikee
thymikee deleted the fix/launch-confirmation-spawn-wait branch November 6, 2026 04:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-human Valid work that needs human implementation, judgment, or maintainer merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant