Skip to content

Keep an Antigravity automation running while its subagents outlive the parent's turn - #34084

Closed
brennanb2025 wants to merge 7 commits into
mainfrom
brennanb2025/bug-automation-run-still-ends-early-when-an-anti
Closed

brennanb2025 wants to merge 7 commits into
mainfrom
brennanb2025/bug-automation-run-still-ends-early-when-an-anti

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 7 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​303 $\color{#cf222e}{\Huge{\mathbf{−}}}$​14 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​289
Prod 6 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​41 $\color{#cf222e}{\Huge{\mathbf{−}}}$​15 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​26

An Antigravity automation can finish and close its terminal while a subagent is still working. The parent has ended its own turn to wait, so its OSC status says done, while its hooks correctly say background work remains. After two minutes without another parent hook, Orca trusts that narrower status and completes the run with the waiting message instead of the final report. Tracked in #33973.

The fix publishes the parent’s state separately from the combined state. A root-only done report cannot complete a row still held open by child work. The parent’s final idle Stop, a later wake, and real session boundaries still settle it. The existing fallback remains for other agents, explicit child questions, and rows whose parent is still working.

Review also covered delayed observations: a completed transcript rejects stale busy events while allowing idle Stop retries to recover final text. A finished status without a recognized outcome remains unknown and cannot immediately erase an accepted interruption. Explicit outcomes and new turns retain their authority; the existing bounded cancellation policy stays unchanged.

This is the full review path: the change affects event ordering, asynchronous completion and independently updated relay hosts. It reuses the existing optional lead-state field and does not add a saved format or wire operation.

Differences from the common pattern are intended: external terminal hooks can report child work that the program omits, so those hooks remain authoritative for that work. If every final-wake hook and its replay is lost, a child-held row waits for later evidence or session end. Older relays without the optional lead field retain their existing behavior until updated; mixed versions remain supported. Terminal cancellation remains inferred where no owned provider turn is available, using the existing bounded policy.

Validation is being completed on the final head. Baseline agy1.4.7 evidence reproduced premature completion at120,002ms with a real model and120,011ms with a scripted145s child. In the real run, translation files existed but the parent report was absent and a child was still active. The scripted run confirmed all21 hooks reached Orca. No baseline failure screenshot was captured; raw hooks, OSC, accepted rows and automation timelines establish the failure.

…s outlive the parent's turn

agy reports its own turn over OSC 7501 but not the invoke_subagent
children it runs in-process, so when a parent ended its turn to wait,
its program status said done while its Stop hook said fullyIdle=false.
Program status yields to a disagreeing hook row only for two minutes of
hook silence, and subagent hooks never refresh the parent's row, so a
subagent that ran past that window let the program's done settle the
pane: the automation completed and closed the tab mid-work.

Antigravity rows now publish the lead's own verdict through the shared
lead/child fold (fullyIdle=false is agy's word that work outlives the
turn), and a same-agent program done no longer settles a hook row that
is held open by child work. Session boundaries, other apps and rows not
held open keep the silence fallback.

Tracked in #33973.
@brennanb2025
brennanb2025 marked this pull request as ready for review October 26, 2026 23:02
@coderabbitai

coderabbitai Bot commented Oct 26, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c3864aea-8b12-4adb-ae72-c155ec8d2f74
Commits

Reviewing files that changed from the base of the PR and between c785303 and f1f14f5.

Files selected for processing: 1
  • src/renderer/src/store/slices/agent-status/agent-status-main-agent-fact.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Walkthrough

Antigravity event normalization now maintains a main-agent status per pane and includes it in normalized payloads. Listener cache operations and tab cleanup move or remove that status. Server status precedence accounts for child work, and cancellation-latch resolution requires a recognized outcome. Added tests cover server status projections, delayed Antigravity reports, cancellation timing, cache cleanup, and renderer projections.

Priority: Normal

Merge Risk: Low · up to f1f14

A delayed hook may leave an automation shown as working after it finishes. Confirm or fix that edge case before treating the status lifecycle as settled.

Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Description check Warning The description explains the problem, solution, scope, issue reference, compatibility considerations, and validation evidence. However, it omits most required template sections and checklist items, in… Reformat the description using the repository template. Add the missing required headings and complete each applicable section. Include an actual linked issue reference, state Visual Proof as N/A with a reason if applicable, document test e…
Docstring Coverage Warning Docstring coverage is 17.65% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 17 functions across 13 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Title check Passed The title clearly identifies the main change: keeping an Antigravity automation active while subagent work continues after the parent turn ends.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the problem, solution, scope, issue reference, compatibility considerations, and validation evidence. However, it omits most required template sections and checklist items, including ELI5, What Changed, Why, Visual Proof or N/A, Testing checkboxes, AI Disclosure, Review, Agent skill upstream boundary, Notes, and Checklist.

Resolution

Reformat the description using the repository template. Add the missing required headings and complete each applicable section. Include an actual linked issue reference, state Visual Proof as N/A with a reason if applicable, document test execution and platforms, complete the AI Disclosure and Agent skill sections, address the Notes items, and complete the Checklist.

Finishing Touches: 💡 2
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
⚔️ Resolve merge conflicts: 💡
  • Resolve merge conflict in branch brennanb2025/bug-automation-run-still-ends-early-when-an-anti
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai 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.

Actionable comments posted: 1


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 775ce985-da8f-446e-a77e-783c92e3611d
Commits

Reviewing files that changed from the base of the PR and between f06f737 and ab9f3d1.

Files selected for processing: 13
  • src/main/agent-hooks/server-closed-tab-suppression.test.ts
  • src/main/agent-hooks/server-main-agent-turn-verdicts.test.ts
  • src/main/agent-hooks/server-program-status-hook-yield.test.ts
  • src/main/agent-hooks/server-turn-ended-at.test.ts
  • src/main/agent-hooks/server.test-fixtures.ts
  • src/main/agent-hooks/server/program-status/hook-precedence.test.ts
  • src/main/agent-hooks/server/program-status/hook-precedence.ts
  • src/main/agent-hooks/server/server-tab-cleanup.ts
  • src/shared/agent-hook-cancel-verdict-latch.ts
  • src/shared/agent-hook-listener-antigravity.test.ts
  • src/shared/agent-hook-listener-extraction-characterization.test.ts
  • src/shared/agent-hook-listener/listener-state.ts
  • src/shared/agent-hook-listener/providers/antigravity-events.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 1 remain after this review.

eventName !== 'Stop' &&
state.antigravityCompletedTranscriptByPaneKey.get(paneKey) === transcriptPath
state.antigravityCompletedTranscriptByPaneKey.get(paneKey) === transcriptPath &&
(eventName !== 'Stop' || stopStillBusy)

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.

Minor · Stability & Availability · Quick win

🔎 Supported by static analysis

Script executed:

sed -n 1,130p src/shared/agent-hook-listener/providers/antigravity-events.ts
sed -n 1,60p src/main/agent-hooks/server/program-status/hook-precedence.ts

Repository: stablyai/orca

Length of output: 7368


Script executed:

set -u
echo "=== antigravity-event-rules.ts ==="
sed -n 1,200p src/shared/agent-hook-listener/providers/antigravity-event-rules.ts
echo "=== agent-lead-status-fold.ts ==="
sed -n 1,200p src/shared/agent-lead-status-fold.ts
echo "=== server ingest guards (stale/turn/invocation) ==="
rg -n -i 'stale|turnId|turn_id|invocation' src/main/agent-hooks/server.ts src/main/agent-hooks/server || test "$?" -eq 1
echo "=== transcript path references near antigravity ==="
rg -n -i 'antigravity' src/main/agent-hooks src/shared/agent-hook-listener src/cli -l || test "$?" -eq 1
rg -n -i 'transcript_?path' src/main/agent-hooks src/shared/agent-hook-listener src/cli || test "$?" -eq 1

Repository: stablyai/orca

Length of output: 29012


Script executed:

set -u
echo "=== server-foreign-turn-hook.ts ==="
sed -n 1,80p src/main/agent-hooks/server/server-foreign-turn-hook.ts
echo "=== callers of foreign turn guard ==="
rg -n -F -- 'server-foreign-turn-hook' src/main/agent-hooks || test "$?" -eq 1
echo "=== antigravity installer/registry transcript or Stop fields ==="
rg -n -i 'antigravity' src/main/agent-hooks/managed-agent-hook-registry.ts src/main/agent-hooks/remote-managed-hook-installers.ts || test "$?" -eq 1
rg -n -i 'transcript' src/main/agent-hooks/managed-agent-hook-registry.ts || test "$?" -eq 1

Repository: stablyai/orca

Length of output: 2665


Script executed:

set -u
echo "=== server-status-update.ts ==="
sed -n 1,140p src/main/agent-hooks/server/server-status-update.ts
echo "=== server-status-inference.ts 105-135 ==="
sed -n 105,135p src/main/agent-hooks/server/server-status-inference.ts

Repository: stablyai/orca

Length of output: 7640


Key the completed-turn cache by conversation when no transcript path exists.

An idle Stop with conversationId and no transcriptPath records no completion. A delayed busy Stop for the same conversation then skips the completion guard. It folds to a working row, and mainAgent.state becomes done. programStatusHookYieldEndsAt then returns Infinity for a same-agent program done, so the row stays working until a later hook changes it.

Use transcriptPath ?? conversationId as the cache key. The existing PreInvocation reset already clears this per-pane entry.

🐛 Suggested fix
   const stopStillBusy = eventName === 'Stop' && isAntigravityStopStillBusy(hookPayload)
+  const completionKey = transcriptPath ?? conversationId
   if (eventName === 'PreInvocation') {
     state.antigravityCompletedTranscriptByPaneKey.delete(paneKey)
   } else if (
-    transcriptPath &&
-    state.antigravityCompletedTranscriptByPaneKey.get(paneKey) === transcriptPath &&
+    completionKey &&
+    state.antigravityCompletedTranscriptByPaneKey.get(paneKey) === completionKey &&
     (eventName !== 'Stop' || stopStillBusy)
   ) {
   if (eventName === 'Stop' && !stopStillBusy) {
     state.antigravitySubagentParentByPaneKey.delete(paneKey)
-    if (transcriptPath) {
-      state.antigravityCompletedTranscriptByPaneKey.set(paneKey, transcriptPath)
+    if (completionKey) {
+      state.antigravityCompletedTranscriptByPaneKey.set(paneKey, completionKey)
     }
   }

@coderabbitai coderabbitai 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.

🔇 Additional comments: 1
src/shared/agent-hook-listener-antigravity.test.ts-531-532: 1

531-532: Minor · Functional Correctness · Quick win

⚠️ Unverified finding
Verification ran but could not confirm this finding. It is shown for review, not as a verified issue.

Pass the fixed timing values to setAgentStatus.

normalizeAgentStatusEvent drops top-level receivedAt and stateStartedAt. Because no timing argument is passed, setAgentStatus still uses Date.now() for each store. (raw.githubusercontent.com)

Pass these values through the fourth setAgentStatus argument, or use fake timers. Otherwise, this fixture remains wall-clock dependent.


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: ce620f0b-6a13-4554-a8dd-c1c9ecbd5eb9
Commits

Reviewing files that changed from the base of the PR and between ab9f3d1 and c785303.

Files selected for processing: 1
  • src/shared/agent-hook-listener-antigravity.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

@brennanb2025

Copy link
Copy Markdown
Contributor Author

Closing as superseded by #34128, which landed the same fix for #33973 on main (Antigravity rows mark the lead's turn done but held open while invoke_subagent helpers run, and a program's own non-boundary done no longer settles a held-open hook row).

Checked against main 7713098 before closing: the original two-minute repro passes on main, and the regressions this PR's review found in its broader variant (child question suppressed by the new clause, late final text lost, an inferred interruption erased) do not reproduce there. One pre-existing behaviour remains on main, unchanged by either PR: a delayed fullyIdle: false Stop that arrives after the final idle Stop reopens the pane as working until the two-minute fallback settles it.

@brennanb2025
brennanb2025 deleted the brennanb2025/bug-automation-run-still-ends-early-when-an-anti branch October 27, 2026 00:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant