Repository navigation
Conversation
Size Report
Startup median (7 runs, lower is better):
|
There was a problem hiding this comment.
1 issue found across 25 files
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="src/cli/commands/exec.ts">
<violation number="1" location="src/cli/commands/exec.ts:139">
P2: Relative Windows executables such as ` .\gradlew.bat` are not resolved because this check recognizes only `/`; the spawn helper then rejects the backslash path. Recognize both path separators before calling `path.resolve`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
There was a problem hiding this comment.
All reported issues were addressed across 6 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
|
The exec wrapper can die on terminal hangup while the build it wraps keeps running, so the device claim does not last as long as the command (reviewed at 06e8600). The child is spawned with The rule to satisfy: while the child group is alive, every terminating signal the wrapper can catch is forwarded to the group, and the wrapper releases the claim only after the child exits. Could I did not run the SIGHUP behavior. It follows from Node's The live simulator run was at 55beffd. The later changes in The failing checks (Lint/Typecheck, Repo Guards, Integration, both Smoke lanes) all fail while loading |
`agent-device exec --platform ios --udid <UDID> -- <cmd> [args...]` takes the host-global device claim on the wrapper process's own identity, runs the child with stdio inherit, forwards SIGINT/SIGTERM to the child's process group, exits with the child's code (128+signum for signal exits, 127 for a missing command), and releases the claim on every exit path. A killed wrapper's claim carries an explicit owner kind so the supersession proof never steals a live wrapper claim and every later acquirer reconciles a dead one as stale. - device-claims: acquireWrapperDeviceClaim records ownerKind 'wrapper' under a dedicated <stateDir>/exec claim dir; the session label exec:<command> is sanitized like session names. - device-claim-inspection: the daemon-supersession proof applies only to daemon-served claims (ownerKind absent); wrapper liveness stands. - device-claim-conflict moves to daemon-contracts so the wrapper throws the same typed refusal the daemon admission seam returns. - registry: new honest 'wrapper-exclusive' claim policy for the exec descriptor. - docs: commands.md and sessions.md claim sections, README claim paragraph.
The wrapper-claim label sanitizing reached host-kit/session-paths statically, growing three budgeted eager closures by one module each. Take the same safeSessionName through a function-scoped dynamic import, as the closure guard prescribes.
… docs - Forward every received signal to the child group; the first one still owns the exit code, so a child that traps or ignores SIGINT stays stoppable by a later SIGTERM (r4297377444). - Refuse to start on win32 with UNSUPPORTED_PLATFORM and reason unsupported-host-platform instead of half-supporting process-group signalling and backslash relative paths there (r4297377356, r4297377386); help and docs now say macOS and Linux hosts. - Help synopsis lists every accepted selector: --target and --ios-simulator-device-set were declared but missing (r4297377464). - Docs: README shows matching selectors fencing the same device the build targets (r4297377397); sessions.md names the local-only boundary (r4297377423), the attempted-release guarantee (r4297377435), the exact auto-reconcile condition with uncertain claims staying blocked (r4297377455); commands.md documents the reboot-takeover exception (r4297377408).
- README: the hosted-device sentence no longer covers `exec`; it holds claims for local devices only (r4297509439). - exec tests: the second-signal case pins listener restoration for both SIGINT and SIGTERM, so a leaked onSigint fails the run (r4297509474).
… build too The child leads its own session, so terminal hangup reached only the wrapper and its default action killed it before the release: the claim named a dead pid while the build kept mutating the device. attachSignalForwarding now owns one list of forwarded signals (SIGINT, SIGTERM, SIGHUP, SIGQUIT), registers and disposes every handler from it, and replays all signals received before the child existed. The claim is released only after the child exits. - exec tests: real-process SIGHUP case (fails on the previous code: wrapper killed, claim stranded, child alive) asserting release-before-exit, the child group stopping, and exit 129. - help and docs name the full forwarded set. - delete the dead outcome assignment in releaseExecDeviceClaim. - fix the stale device-claim-conflict.ts path in the help-conformance sample.
06e8600 to
2665364
Compare
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
You’re at about 90% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Reply with feedback, questions, or to request a fix.
View guided diff | Turn on auto-fix | Re-trigger cubic
Signal disposition, process-group kill, and a real SIGHUP's default action are POSIX semantics, and exec refuses before claiming on a Windows host, so the signal cases would only time out waiting for the claim there. Gate all three from one IS_WINDOWS condition (r4298409165).
|
Addressed in 2665364 (+ 5509d9a for the Windows test skip), rebased onto main ( Blocking (terminal hangup). Small items. The dead Live run at the final head (through Unverified side effects — recorded under "Not verified" in the PR body: the child has no controlling terminal, so The CI-red checks you listed are the #3717/#3720 builder gap on main; this head rebases over #3740, so they should clear. |
Summary
agent-device exec --platform ios --udid <UDID> -- expo run:ios --device <UDID>holds the host-global device claim for the whole lifetime of an external command, so builds that install through the platform tools directly are fenced against agent-device sessions on the same device. Fixes #3263.wrapper-exclusiveclaim policy; the registry never claims the wrapper goes through daemon admission.ownerKind: 'wrapper'; the daemon-supersession proof (which reads adaemon.jsonthat can only ever describe daemons) no longer steals live wrapper claims, and claims under a dedicated<stateDir>/execdir reconcile asowner-process-deadwhen the wrapper is killed.daemon-contractssoexecthrows exactly the refusal the daemon admission seam returns.execrefuses to start on win32 (UNSUPPORTED_PLATFORM,reason: unsupported-host-platform).commands.md,sessions.md, README (matching selectors fence the very device the build targets). No scope expansion beyond the claim-store owner-kind fix the wrapper needs.Validation
Tested at 5509d9a (review rounds 1–3, rebased onto
4c1c78696which includes #3740 and #3741).pnpm check:affected --run --head 5509d9a7dat the exact commit: all runnable checks passed (receipt.tmp/validation/run-X3P6fp/receipt.json). Two earlier runs at this head each hit one unrelated timing-sensitive test (snapshot-source/lifecycletimeout, thendaemon-registration-ownerfixture timeout) that pass in isolation and on the clean re-run.acquiredinstead ofconflict); with the forwarded-signal list narrowed back to SIGINT/SIGTERM, the real-SIGHUP case fails (claim stranded at a dead pid, child alive). Mutations (no release, no signal code, no forward, drop-second-signal) each fail their test for the named reason.pnpm typecheck,pnpm lint,check:layering,check:doc-prose, help-conformance, command-doc-coverage, fullpackages/daemon(2770 tests), daemon-contracts, command-registry, exec suites — green. The three POSIX signal cases share onetest.skipIf(IS_WINDOWS)condition.ExecIssue3263R3, iOS 27.0, created and deleted for the check; 5509d9a only adds a Windows test skip): duringexec … -- sleep 120,device statusshowedlive session=exec:sleepand a secondexecrefused withDEVICE_IN_USEnamingsession "exec:sleep"; SIGTERM → rc 143 and claims store empty; SIGHUP → rc 129, the childsleepin the wrapper's group was gone, and the claims store was empty once the wrapper exited; after exit a freshexecsucceeded (rc 0)./dev/tty(sudo, credential prompts) may fail — untested; Ctrl-Z stops the wrapper but not the child (job control for a session leader's detached child would need a terminal the child doesn't share).🤖 Generated with Claude Code