Skip to content

feat: add Antigravity runtime provider - #2375

Open
L42y wants to merge 11 commits into
first-tree-ai:mainfrom
L42y:feat/antigravity-runtime-provider
Open

feat: add Antigravity runtime provider#2375
L42y wants to merge 11 commits into
first-tree-ai:mainfrom
L42y:feat/antigravity-runtime-provider

Conversation

@L42y

@L42y L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add the Google Antigravity runtime provider to the shared provider catalog, client composition, capability probing, CLI, and web configuration surfaces.
  • Drive agy with the documented stream-json stdin/stdout protocol, preserve the provider conversation ID, and resume exact conversations with fail-closed protocol and identity checks.
  • Project managed MCP servers and skills safely into the Antigravity workspace, with provider-owned auth guidance, retry classification, tests, and QA coverage.

Validation

  • corepack pnpm typecheck
  • corepack pnpm check (passes; existing repository lint warnings remain)
  • Focused client tests: 8 files, 110 tests
  • Shared catalog tests: 9 tests
  • Web provider/configuration tests: 6 files, 56 tests

Notes

The implementation follows the official headless mode and resume command documentation. The local validation environment does not have agy installed, so Google authentication and live provider execution remain host-level follow-up validation.

@L42y
L42y requested review from bestony and yuezengwu as code owners August 31, 2026 14:30

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

Reviewed exact head 6acfd8009535f25e8bbce10b1b06f1ddb05ed387.

Requesting changes for the following correctness blockers:

  1. [P1] A timed-out turn can replay after a mutating tool already ran. handleEvent records non-read-only tool calls in state.sawUnsafeTool, and settleFailure correctly converts that state to replaySafety: "unsafe". However, the timeout/cancellation branch at packages/client/src/providers/antigravity/index.ts:672-674 bypasses settleFailure and unconditionally calls token.retry(...). If agy executes a mutating tool and then stalls or misses the terminal result, First Tree resends the original delivery. On an initial turn the observed conversation ID is not adopted until the success branch, so the retry can start a fresh conversation and duplicate the external side effect. Route timeout/provider abort through the replay-safety settlement path (while keeping explicit user suspend semantics separate if necessary), preserve the exact conversation identity when it is safe to do so, and add deterministic coverage for timeout after a mutating tool, pre-provider timeout, and resumed identity/no duplicate delivery.

  2. The current head has reproducible PR-attributable test failures. Local exact-head runs reproduce three failures in apps/cli/src/__tests__/capability-refresh.test.ts: the nominally all-healthy snapshots omit antigravity, so the refresher keeps polling. The focused client run also has two failures: capability-probes.test.ts contains duplicate antigravity expectation entries and capability-reprobe.test.ts omits the provider from the healthy snapshot. The same failures appear in Test CLI (1/2) and Test Client & Web. Please update the complete-provider fixtures and restore a green exact-head run.

There is also an unresolved accounting contract that needs evidence before this provider can be accepted: First Tree token_usage events are per-turn deltas (packages/shared/src/schemas/session-event.ts:107-128), while the handler forwards the terminal Antigravity usage snapshot verbatim on every resumed turn (index.ts:707-716). Google documents terminal usage as cumulative for a conversation session. Either compute a delta keyed to the exact conversation, or add live multi-turn evidence proving --conversation returns process-local rather than conversation-cumulative counters and encode that behavior in tests.

Verification performed on this exact head:

  • git diff --check 47094ba6a014555294d446a7324a089f5eb6b709...6acfd8009535f25e8bbce10b1b06f1ddb05ed387 — pass.
  • Focused Antigravity/client suite — 145 passed, 2 failed.
  • CLI capability refresher suite — 19 passed, 3 failed.
  • agy is not installed on the review host, so live auth/start/resume/tool/MCP/Skills/process-lifecycle behavior was not validated.

This review does not authorize merge. Because this introduces an external CLI/install path, host-local Google identity, MCP credentials/headers, Skills projection, and --dangerously-skip-permissions, an exact-head full-isolated live QA run plus human architecture/security/supply-chain acceptance is still required after the code blockers are resolved.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up for the review findings, now on the current PR head:

  • Provider timeout/abort is routed through the Antigravity replay-safety settlement path. Explicit suspend/shutdown generation cancellation remains a lifecycle redelivery, while a timeout after a mutating tool settles as unsafe_replay without resending the delivery.
  • A single exact conversation ID observed before the abort/failure is adopted before settlement, so a later recovery keeps the provider conversation instead of creating a fresh one.
  • Cumulative Antigravity usage is diffed against a baseline keyed by the exact conversation. Fresh starts emit their first snapshot; cold resumes skip the unknown first baseline, and later turns emit per-turn deltas.
  • Complete-provider capability fixtures are corrected, including the duplicate client expectation and the CLI/client healthy snapshots.

Validation on this head: Antigravity tests 25/25, capability fixture tests 100/100, full repository typecheck 9/9 tasks, and repository Biome check pass. The local full client suite still has six unrelated host-sensitive baseline failures (broker HOME/managed-skill permissions and a long authority-boundary timeout); the review host also does not have agy, so live Google auth/start/resume/tool/MCP lifecycle QA remains pending on a host with that CLI installed.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

All requested code and fixture blockers are now addressed on the current PR head, and the complete GitHub CI suite is green. Please re-review the current head when available; the remaining merge block is the earlier review being attached to the superseded commit.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Additional accounting hardening is now on the current head:

  • A conversation observed on a failed fresh attempt is adopted without being marked fresh. If that failed stream includes a cumulative usage snapshot, it becomes the exact conversation baseline for recovery; the subsequent turn emits only the delta.
  • The regression test covers failed fresh attempt → exact conversation recovery.

The focused Antigravity handler suite, client typecheck, Biome, and diff checks pass. Please review the current head together with the previously posted fixes.

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

Fresh-head re-review of exact head 231ceea7613a2c2bb67999b5faec2e1b5256d275.

The original timeout replay-safety, complete-provider fixture, and usage-baseline findings are fixed on this head. One P1 lifecycle blocker remains:

suspend() / shutdown() still bypass exact-conversation adoption and replay-safe settlement. Both lifecycle methods set sessionActive = false and increment generation before aborting the process. Consequently, after runProcess() returns, the branch at packages/client/src/providers/antigravity/index.ts:738-741 always wins for a lifecycle cancellation. That branch unconditionally calls token.retry(...); it does not call adoptObservedSessionId(...) and does not inspect state.sawUnsafeTool.

On a first Turn where agy has already emitted one exact conversation ID and a mutating tool step, this discards both pieces of evidence. start() then returns an antigravity-pending-* synthetic ID, and a later resume of that pending ID clears providerSessionId and starts a fresh provider conversation. Redelivery can therefore repeat an external side effect.

I reproduced this deterministically on the current head with a controlled provider stream: emit init(conversation-lifecycle), emit a mutating run_command, then call handler.suspend(). Observed result: synthetic pending session ID, token.retry("antigravity_turn_aborted_or_timed_out"), no replaceSessionId, and no unsafe consumed completion.

Please make lifecycle cancellation preserve the single exact observed conversation identity and prevent replay after mutating provider activity, while still rejecting late callbacks after the lifecycle fence/quarantine. Add deterministic first-Turn suspend and shutdown coverage after init + mutating tool that proves recovery cannot start a fresh conversation or duplicate delivery.

Validation on this exact head:

  • focused client/Antigravity and retry/capability suites: 152/152 passed;
  • CLI capability refresher: 22/22 passed;
  • shared runtime provider catalog: 9/9 passed;
  • client typecheck: passed;
  • client/shared builds and git diff --check: passed;
  • complete GitHub checks: green.

This review does not authorize merge. agy is still absent on the review host, so there is no live evidence for Google auth/start/resume, tool execution, MCP credential/header handling, Skills projection, or process lifecycle. The external CLI/install path, Google host identity, managed MCP/Skills, and --dangerously-skip-permissions remain a major architecture/security/permissions/supply-chain hard stop requiring full-isolated live QA and human acceptance after the code blocker is fixed.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Fresh-head review follow-up for the lifecycle P1:

  • suspend() and shutdown() now adopt the single exact conversation ID observed before the lifecycle fence. A lifecycle-cancelled turn that emitted a mutating tool is routed through the replay-safety settlement path and completes as unsafe_replay instead of retrying the delivery.
  • shutdown() retains an exact ID long enough for an in-flight start()/resume() result to return it to SessionRuntime, so recovery uses the original conversation rather than an antigravity-pending-* replacement.
  • Deterministic coverage now exercises both first-turn suspend and shutdown, then verifies recovery passes --conversation conversation-lifecycle and forwards only the recovery result.

Validation on this head: Antigravity handler suite 9/9, related client capability suites 106/106, CLI capability refresher 22/22, client typecheck, Biome, and git diff --check all pass. Please re-review the current head.

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

Requesting changes on exact head cbe3f0a859b39a88b889f9e1cfaa52887cd15b21.

[P1] Preserve ACK-none custody during preemption and route retirement

The new lifecycle branch in packages/client/src/providers/antigravity/index.ts adopts the exact conversation ID, which fixes the previous synthetic-ID problem. However, when a mutating tool was observed it now always calls settleFailure(...) after any lifecycle cancellation and terminally completes the token as consumed. suspend(reason) and shutdown(reason) do not accept or inspect HandlerShutdownOptions.

That violates the existing AgentHandler custody contract: only operator suspend and full graceful drain pass { settleProviderEntered: true }; forced concurrency preemption and route retirement deliberately leave it unset so provider-entered work stays recoverable (ACK-none). The scheduler also marks working-session preemption with ackConsumedPrefix: false. As written, Antigravity can therefore ACK and discard interrupted mutating work during preemption/retirement instead of preserving recovery custody.

The new lifecycle tests currently encode this regression: they call plain handler.suspend(...) / handler.shutdown(...) with no settlement option and expect an unsafe_replay consumed completion. Please make settlement depend on opts?.settleProviderEntered === true, preserve the exact conversation identity, and add deterministic coverage that distinguishes:

  • operator suspend / graceful shutdown with the flag: terminal consumed settlement;
  • plain concurrency suspend / route-retire shutdown: no completion/ACK and recoverable custody;
  • exact-conversation recovery without duplicate prompt or tool delivery.

Focused validation on this head: Antigravity/client tests 154 passed; CLI capability tests 22 passed; shared provider catalog tests 9 passed; the three existing Pi custody-reference tests passed; client typecheck and git diff --check passed. These green tests do not remove this contract mismatch.

Separate release hard stop: agy is not installed on this host, so there is still no live Google auth/start/resume/tool/MCP/Skills/process-lifecycle evidence. The official CLI documentation also states that --dangerously-skip-permissions approves all tool calls, including file writes and command execution. Even after the code blocker is fixed, this external CLI/identity/credential/projection/permission boundary needs full isolated live QA plus yuezengwu human architecture, security, permissions, and supply-chain acceptance. This review is not approval to merge.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Fresh-head follow-up for the custody-contract review:

  • Antigravity now accepts HandlerShutdownOptions on both suspend() and shutdown().
  • Lifecycle cancellation still adopts the single exact conversation ID before the fence. It only settles an observed mutating turn as unsafe_replay when opts.settleProviderEntered === true (operator suspend / graceful shutdown).
  • Plain suspend/shutdown used for concurrency preemption or route retirement leaves the delivery recoverable with exactly one retry and no completion/ACK; the retained exact conversation ID is used by recovery.
  • Deterministic coverage covers all four combinations (suspend/shutdown × flag true/false), verifies exact --conversation recovery, ensures the original prompt is not duplicated, and confirms only one tool event.

Validation on this head: Antigravity handler suite 11/11, client typecheck, Biome, and git diff --check pass. Please re-review the current head.

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

Fresh-head re-review of exact head c7a9c03c8f6988e2fd15ef66ef4b93fb1372b832.

The new option-aware handler branch is directionally correct: settleProviderEntered: true now performs terminal unsafe settlement, while plain suspend/shutdown leaves the DeliveryToken retryable. However, one P1 remains at the real SessionRuntime boundary:

[P1] First-turn preemption still loses the exact Antigravity conversation and can replay the mutating delivery in a fresh conversation.

On lifecycle cancellation, the handler records the observed ID in pendingLifecycleSessionId and returns it from start() (packages/client/src/providers/antigravity/index.ts:744-769,1061-1081). But working-session preemption first invalidates the route transition. When the canceled start() later returns, SessionRuntime.routeMessage() hits the stale-transition guard and calls discardStaleRouteTransition() before assigning entry.claudeSessionId (packages/client/src/runtime/session-runtime.ts:2320-2325). The canceled unestablished entry is then dropped (:3064-3074,3124-3133), and this path never records an eviction resume mapping. The recovered inbox row therefore has no exact provider session handle and the replacement handler starts a new Antigravity conversation. The existing generic runtime regression at session-manager-edge-coverage.test.ts:4527-4573 explicitly expects that fresh start() behavior after a stale canceled producer.

The new handler test does not cover this boundary. It directly reuses the same handler and calls resume() with a different synthetic message, m-recovery / recover without replay (handler.test.ts:566-577), rather than allowing SessionRuntime/coordinator recovery to reset and redeliver the original inbox row. Its assertion that the original prompt is absent is therefore vacuous. In production, token.retry(messages, ...) preserves the original row for recovery; even where an established exact ID survives, sending that original mutation prompt into --conversation again is not evidence of no duplicate provider/tool delivery.

Please add a deterministic SessionRuntime-level test that exercises both working concurrency preemption and forced route retirement during a first Antigravity turn after init + a mutating tool event. It should prove: no ACK, server-faithful recovery of the same original inbox row, exact conversation identity retained across retired and replacement handlers, and no duplicate prompt/tool delivery. The implementation needs a provider-safe recovery/continuation contract rather than testing a manually substituted message.

Fresh-head validation:

  • focused Antigravity/retry/capability suites: all passed; the initial 5 s aggregate run had one host-sensitive Codex resolver timeout, and its full 59-test file passed with a 15 s timeout;
  • runtime edge/start suites: 162/162 passed;
  • CLI capability: 22/22; shared provider catalog: 9/9;
  • repository typecheck: 9/9 tasks; serial repository build: 5/5 tasks;
  • Biome completed with existing warnings; git diff --check passed;
  • all GitHub checks are green.

This review still does not authorize merge. agy is absent on this host, so there is no live Google auth/start/resume/tool/MCP/Skills/process-lifecycle evidence. Official CLI behavior also makes --dangerously-skip-permissions an all-tool permission grant. The external installer/CLI, Google host identity, MCP credentials/headers, Skills projection, and permission boundary still require full-isolated live QA plus yuezengwu human architecture, security, permissions, and supply-chain acceptance.

@L42y

L42y commented Aug 31, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up for the fresh-head lifecycle review, now on 9e7ed113e68ee8803cba2cf328778cb73d1f9bb5:

  • Added an explicit provider-owned continuation contract for deliveries that already entered an exact provider conversation. Antigravity resumes that custody with the exact --conversation identity and a provider-owned continuation instruction; it never serializes the original delivery content again.
  • Carried the continuation through stale start/resume receipts, SessionRuntime eviction mappings, the persisted session registry, scheduler retries, and replacement-handler recovery. Identity mismatches fail closed and retain recovery custody instead of silently falling back to a fresh prompt in the old conversation.
  • Added real SessionRuntime-level coverage for both working-session concurrency preemption and forced route retirement after an init plus mutating tool event. Both paths recover the same server-faithful inbox row, preserve the exact provider conversation, produce no ACK before successful recovery, and verify one prompt/tool delivery.

Validation on this head:

  • Antigravity handler + SessionRuntime regression: 162/162 passed.
  • Full repository typecheck: passed.
  • Repository Biome check: passed with existing warnings/info only.
  • git diff --check: passed.

Please fresh-review the current head. Live agy auth/start/resume/tool/MCP/Skills/process QA remains unavailable on this host because the CLI is not installed, and still needs the required isolated host-level/security acceptance.

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

Fresh-head review of exact head 9e7ed113e68ee8803cba2cf328778cb73d1f9bb5.

Requesting changes for two remaining custody/replay blockers and the current required-check regressions:

  1. [P1] The provider continuation is a new user turn, not an interrupted-turn resume primitive. ANTIGRAVITY_CONTINUATION_PROMPT explicitly acknowledges that Antigravity has no documented operation for resuming an interrupted turn, then resume() passes that text through runTurn() as a new prompt (packages/client/src/providers/antigravity/index.ts:73-81, 1135-1154). Google's headless CLI contract says --conversation starts a new process, prompts are user events, and each prompt executes a full turn; it also rejects control_request / control_response rather than offering an interrupt-resume control (official docs). Therefore this prompt can only advise the model not to repeat prior tool effects; it cannot prove that an already-executed tool whose terminal event was lost will not be executed again. The new tests mock the recovered process and return success without asking a real provider to reconcile an interrupted tool, so the single observed tool event is a fixture property, not an exactly-once guarantee. Please keep the original process/turn alive, make provider-entered turns ineligible for forced retirement until they settle, or use a provider-supported authoritative continuation/idempotency boundary; a natural-language instruction is not sufficient custody proof.

  2. [P1] Provider-turn retries still drop the continuation and resend the original delivery. When a retryable failure has sawProviderActivity, settleFailure() retries the token and calls failSessionForRecovery() (index.ts:652-667). That runtime method persists only claudeSessionId, not entry.providerContinuation (packages/client/src/runtime/session-runtime.ts:1784-1800). The recovered inbox row therefore reaches resume() without opts.continuation, takes the normal branch at index.ts:1147-1149, and serializes the original user content into the same conversation again. This bypasses the new lifecycle-only continuation path and recreates the duplicate-delivery risk for transient/provider-capacity failures after an init or other activity. Carry exact-message continuation custody through this recovery path as well, and add a SessionRuntime regression for provider activity -> retryable failure -> exact-row recovery that proves the original content is not submitted twice and no ACK occurs before successful recovery.

  3. The exact head fails the required Client test job. Both GitHub Test Client & Web and a clean local full Client run report the same two failures: contracts-entry.test.ts rejects the unallowlisted HandlerResumeOptions / ProviderContinuation exports, and session-runtime-authority-boundary.test.ts reports SessionProjectionAuthority.activateLiveSession returning private nested-container evictedMappings (ledger-identity-escape). Please restore both contract/ownership guardrails rather than treating them as incidental CI failures.

Fresh validation performed:

  • full Client suite: 219 files passed, 2 failed; 2881 tests passed, 2 failed, 7 skipped;
  • focused Antigravity/SessionRuntime suite: 200/200 passed;
  • repository typecheck: 9/9 tasks passed; Client typecheck/build passed;
  • repository Biome check and git diff --check passed;
  • agy is absent on this review host.

This review does not authorize merge. Even after the code blockers are fixed, the external agy install/CLI, host-local Google identity, MCP credentials/headers, managed Skills projection, and --dangerously-skip-permissions boundary still require an exact-head isolated live QA run plus yuezengwu's human architecture, security, permissions, and supply-chain acceptance.

@yuezengwu

Copy link
Copy Markdown
Contributor

Pushed dfa64a2 as a narrow CI-contract repair on top of reviewed head 9e7ed11.

This commit only addresses the two confirmed blockers:

  • Adds HandlerResumeOptions and ProviderContinuation to the authoritative runtime/contracts type allowlist and occupancy check. Both remain public because AgentHandler.resume and the Antigravity provider depend on them through the supported contracts entry.
  • Makes SessionProjectionAuthority.activateLiveSession return a field-by-field continuation snapshot, removing nested evictedMappings value identity from the public boundary without adding an audit exception or changing caller semantics.

Validation on the exact repaired head:

  • focused authority/contracts and adjacent Antigravity/session-registry tests: 89 passed
  • full @first-tree/client suite: 2,883 passed, 7 skipped
  • pnpm check: passed
  • pnpm typecheck: passed (9/9 tasks)
  • pnpm build: passed (5/5 tasks)
  • git diff --check: passed

Scope remains intentionally narrow. This does not resolve or approve the larger Antigravity continuation/exactly-once architecture questions, and it does not lift any architecture-review or live-QA hard stop.

@yuezengwu

Copy link
Copy Markdown
Contributor

Live follow-up: GitHub CI for dfa64a2 has now completed successfully, including Test Client & Web and the aggregate Test job. The PR remains blocked / changes requested; this CI repair does not supersede the required fresh-head architecture review or live QA.

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

I re-reviewed exact head dfa64a2007ef784cead04fedada594b8e73444d0 from zero. The narrow CI repair is correct: the public contract allowlist/occupancy now includes HandlerResumeOptions and ProviderContinuation, and activateLiveSession() returns a field-by-field continuation snapshot instead of leaking the stored nested identity. The two prior CI failures are resolved locally and in GitHub Actions.

Two P1 correctness blockers remain unchanged because this commit does not modify the affected runtime paths:

  1. The recovery instruction is a new natural-language user turn, not an authoritative interrupted-turn resume. ANTIGRAVITY_CONTINUATION_PROMPT explicitly acknowledges that Antigravity has no documented headless operation for resuming an interrupted turn without a new user event, and resume() sends that text through normal runTurn(). The current headless protocol documents each stdin prompt as a user event that executes a full turn. If a mutating tool completed before the terminal event was lost, “do not repeat” is advisory and cannot establish exactly-once behavior. The mock recovery tests only prove that their fixture chooses not to invoke the tool again. This needs either continued custody of the original live process/turn until a terminal outcome, or a provider-supported authoritative interrupted-turn/idempotency primitive—not a second prompt.

  2. A retryable failure after provider activity still drops continuation custody and redelivers the original request. In settleFailure(), sawProviderActivity takes the generic retry branch, calls token.retry(...), then failSessionForRecovery(reason, providerSessionId). SessionRuntime.failSessionForRecovery() records only the provider session ID and lastActivity; it does not record providerContinuation. The recovered row therefore reaches resume() without opts.continuation, takes the normal branch, and serializes the original message again into the same conversation. Please propagate exact-message continuation through this provider-turn retry path and add a SessionRuntime-level regression covering: provider activity -> retryable failure -> same-row recovery, no second original prompt, and no ACK until recovery succeeds.

Validation on this exact head:

  • focused runtime/contracts suite: 5 files, 223/223 passed;
  • full @first-tree/client suite: 221 files passed, 2 skipped; 2883 tests passed, 7 skipped;
  • pnpm check, pnpm typecheck, pnpm build, and git diff --check passed (existing non-failing lint/build warnings remain);
  • all current GitHub checks are green;
  • agy is not installed on this host, so there is still no exact-head live evidence for Google auth, start/resume, mutating tools, MCP/Skills projection, credential handling, or process lifecycle.

Separately from the code blockers, external agy installation/CLI, Google identity, managed MCP headers/credentials, Skills projection, and --dangerously-skip-permissions remain a major architecture/security/permissions/supply-chain hard stop. They require full isolated live QA and yuezengwu's explicit human acceptance before merge.

Protocol reference: https://www.antigravity.google/docs/cli/headless/

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

Fresh-head review of exact head 3d0eb11880163ecd43f58fd6d25cd85fd467ed31.

The new provider-turn liveness fence is directionally correct: concurrency/LRU/idle retirement no longer interrupts an active Antigravity process, forced recovery retirement waits for the provider turn to settle, and the single-row provider-failure path now carries an exact ProviderContinuation. The previous contracts/authority CI regressions also remain fixed, and all current GitHub checks are green. Two P1 custody gaps remain:

  1. The continuation is still an advisory second user turn, not an authoritative interrupted-turn or idempotency primitive. ANTIGRAVITY_CONTINUATION_PROMPT explicitly acknowledges the missing protocol operation, and resume() sends it through the normal runTurn() path (packages/client/src/providers/antigravity/index.ts:75-83,1162-1181). Google's current headless contract says --conversation starts a new process, every stdin prompt is a user event that executes a full turn, and control_request / control_response terminate as unsupported. The new liveness fence fixes host-initiated preemption while the original process is alive, but a retryable provider failure after activity still replaces the ambiguous failed turn with this new natural-language turn. If the provider completed a tool effect before losing the terminal event, “do not repeat” cannot prove exactly-once behavior. The regression fixture makes the recovered mock return success without invoking the tool; that validates plumbing, not the provider guarantee. This path needs a provider-supported authoritative continuation/idempotency boundary, or it must fail closed instead of auto-continuing an ambiguous provider-entered turn.

  2. Coalesced queued turns still discard continuation custody and replay original content. runQueued() combines every queued message into one provider prompt (index.ts:1023-1036), but both retry and lifecycle continuation construction are gated on messages.length === 1 (:667-681 and :776-794). With two injected inbox rows, an init/provider-activity event followed by a retryable failure calls failSessionForRecovery(..., continuation = undefined). Recovery retains the conversation ID but has no exact-message continuation, so resume() takes its normal branch and serializes an original row into the same conversation again (:1174-1181). The new SessionRuntime regressions all use one row and do not exercise this production batch path. Please either stop coalescing provider-custody rows, define an authoritative aggregate continuation identity, or fail closed; add a two-row provider-activity -> retryable-failure regression proving no original content is resubmitted and no ACK occurs before a safe terminal outcome.

Fresh validation:

  • focused Antigravity/SessionRuntime/provider-policy/contracts suite: 259/259 passed;
  • full @first-tree/client suite: 221 files passed, 2 skipped; 2,884 tests passed, 7 skipped;
  • Client typecheck/build and git diff --check: passed; repository Biome completed with existing non-failing warnings/info;
  • all current GitHub checks: pass/skipping only;
  • agy is absent on this host, so no live Google auth/start/resume/tool/MCP/Skills/process-lifecycle validation was possible.

This review does not authorize merge. Independently of the code blockers, the external agy install/CLI, host-local Google identity, MCP credentials/headers, managed Skills projection, and --dangerously-skip-permissions all-tool grant remain a major architecture/security/permissions/supply-chain hard stop requiring exact-head isolated live QA plus yuezengwu's explicit human acceptance.

@L42y

L42y commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up for the two fresh-head P1s, now on exact head af3a7b0a741d6d69d0d49e33b3ecf40d7ff27cf8:

  1. Removed the advisory continuation turn. Antigravity no longer sends ANTIGRAVITY_CONTINUATION_PROMPT as a new user event. Once a provider attempt observes any provider activity, it is classified as ambiguous and cannot be safely retried or auto-continued; terminal settlement is fail-closed (unsafe_replay). Explicit same-row recovery with an exact provider continuation also fails closed without spawning another provider turn.
  2. Stopped coalescing queued custody. The drain scheduler now takes exactly one inbox row per Antigravity turn. The prior truncation could discard later rows after removing them from the queue; the new regression covers two queued rows where the first observes provider activity and fails retryably. It proves three independent provider executions, exact --conversation identity, no second queued prompt in the first input, no first prompt in the second input, no retry/ACK for the ambiguous row, and safe completion of the second row.

Validation on this exact head:

  • Antigravity/provider-policy/capability suites: 10 files, 168/168 passed.
  • Adjacent contracts, session-registry, authority-boundary, and runtime-state suites: 5 files, 78/78 passed.
  • Repository typecheck: 9/9 tasks passed.
  • Targeted Biome and git diff --check: passed.

CI has started for af3a7b0a7. Live agy authentication, tool execution, MCP/Skills projection, process lifecycle, and the --dangerously-skip-permissions boundary remain outside this host and still require the isolated live QA plus human security/supply-chain acceptance noted in review.

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

Fresh-head review of exact head af3a7b0a741d6d69d0d49e33b3ecf40d7ff27cf8.

The two previous P1s are substantially addressed: the advisory natural-language continuation turn is removed, provider-entered failures are classified unsafe_replay, and the queue now preserves one inbox row per provider turn. The focused and full local client suites pass on this head.

One P1 fail-closed gap remains:

An unsafe turn is replayable when the required terminal notice cannot be posted. settleFailure() records ambiguity only in the handler-local ambiguousProviderTurnKeys and then calls token.complete(... consumed/unsafe_replay) (packages/client/src/providers/antigravity/index.ts:660-683). If posting the required runtime failure notice fails, SessionRuntime.completeDeliveryTurn() deliberately returns retry and moves the exact row back to recovery (packages/client/src/runtime/session-runtime.ts:1985-2003). The Antigravity handler then returns without persisting the ambiguity. A same-handler redelivery reaches the active-session inject() path, which never checks ambiguousProviderTurnKeys (index.ts:1192-1196); a replacement/restart is worse because shutdown() clears the set (:1214-1232). The recovered row can therefore be serialized into a new provider turn after the original provider attempt already had unobservable effects. The new tests all use a token whose complete() returns settled, so they do not exercise this required-notice/ACK-failure branch.

Please make the no-replay fence durable in the inbox/session custody path until the terminal notice and ACK settle, and apply it to every redelivery route (inject, resume, handler replacement, and restart). Add a SessionRuntime-level regression covering provider activity -> unsafe_replay -> terminal notice failure (or ACK retry) -> exact-row redelivery, proving no second agy process/prompt is started and the row can only retry the terminal disposition.

Fresh validation on this exact head:

  • focused Antigravity/provider-policy/capability/contracts/runtime suite: 15 files, 416/416 passed;
  • full @first-tree/client suite: 221 files passed, 2 skipped; 2,885 tests passed, 7 skipped;
  • client typecheck, client build, and git diff --check passed; worktree remained clean;
  • GitHub Test Server and Test Client & Web are currently failed on one timeout each; the client timeout passed in the full local run and neither failing file is changed by this PR, but the exact-head required checks are not green;
  • agy is absent on this host, so there is no live Google auth/start/resume/tool/MCP/Skills/process-lifecycle evidence.

This review does not authorize merge. Independently of the code blocker, external agy installation/CLI, host-local Google identity, managed MCP credentials/headers, Skills projection, and --dangerously-skip-permissions remain a major architecture/security/permissions/supply-chain hard stop requiring exact-head isolated live QA plus yuezengwu's explicit human acceptance.

@L42y

L42y commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up for the unsafe-replay notice/ACK custody P1, now on exact head 5da711b14765293e425af0cc4a4448dbade5ea3f:

  • A required terminal notice for an Antigravity consumed/unsafe_replay outcome is now durable in inbox custody when that notice cannot settle. The exact ledger row is marked notice-required and returns as retry instead of falling through generic provider recovery.
  • Redelivery of that row retries only the terminal disposition. Active injection blocks the continuation-backed row from starting another agy turn, replacement/resume preserves the exact ProviderContinuation, coordinator recovery retains notice-required custody, and continuation state is cleared only after confirmed ACK.
  • The provider-specific custody decision lives in the shared provider-policy seam, so generic/Pi terminal-notice failure behavior remains unchanged.
  • Added SessionRuntime-level coverage for provider activity → unsafe_replay → terminal-notice retry/recovery/redelivery. It verifies the same exact row, no replacement provider turn/prompt, and ACK only after the required notice settles.

Validation on this exact head:

  • Focused Pi, Antigravity, SessionRuntime, provider-boundary, authority, and contract suites: 238/238 passed.
  • Full @first-tree/client suite: 219 files passed, 2 skipped files; 2,882 tests passed, 5 known host-sensitive baseline failures, 7 skipped.
  • Repository typecheck: 9/9 tasks passed.
  • pnpm check and git diff --check pass, with existing repository Biome warnings only.
  • All GitHub checks are green on this head.

The live evidence gap remains unchanged: this host has no agy, so isolated live Google auth/start/resume/tool/MCP/Skills/process-lifecycle QA and the required human architecture/security/permissions/supply-chain acceptance are still necessary before merge.

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

All contributors are covered by the First Tree CLA.
Posted by the CLA Assistant Lite bot.

@L42y
L42y force-pushed the feat/antigravity-runtime-provider branch from 09ca454 to 38ec464 Compare September 1, 2026 13:51
@L42y

L42y commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

recheck

@L42y

L42y commented Sep 1, 2026

Copy link
Copy Markdown
Contributor Author

Follow-up for the remaining non-P1 hardening, now on exact head 38ec464da2467f77078c170535c57f207756b972:

  • Antigravity is release-gated until isolated live acceptance is complete. The provider remains absent from the enabled runtime-provider surface, while catalog/schema and capability-probe coverage verify that release state.
  • Antigravity shutdown no longer clears the process-wide provider attempt ledger. Cleanup is now session-scoped and pending-delivery-aware, so replacing an unrelated handler cannot reset retry accounting for an in-flight Antigravity session.
  • Added deterministic coverage proving that an unrelated handler shutdown preserves pending retry accounting across handler replacement.
  • Corrected the rewritten head so both the author and committer are L42y <423300@gmail.com>. CLA is green on this head. No other commit content was intentionally changed by that rewrite.

Local validation on this exact head:

  • Focused Antigravity/provider-policy/capability/CLI/Web suites: 295 tests across the affected surfaces passed.
  • Repository typecheck: 9/9 tasks passed.
  • Repository Biome check and build passed; Biome reports only existing non-failing warnings.
  • Full Client suite: 2,883 passed, 7 skipped, with the same five known host-sensitive baseline failures unrelated to this change.
  • git diff --check passed and the worktree was clean.

GitHub CI is green for this exact head, including Test Client & Web, Test Server, and the aggregate Test check.

This does not lift the prior P1 custody review, merge authorization, or the required isolated agy live QA. Google authentication, start/resume, mutating tool execution, MCP/Skills projection, process lifecycle, and the --dangerously-skip-permissions boundary still need exact-head isolated host QA and explicit human architecture/security/permissions/supply-chain acceptance.

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.

2 participants