Skip to content

fix: explain unavailable deployment acquisition - #699

Merged
alongubkin merged 11 commits into
mainfrom
alon/alien-948-acquire-outcome-reasons
Oct 8, 2026
Merged

alongubkin merged 11 commits into
mainfrom
alon/alien-948-acquire-outcome-reasons

Conversation

@alongubkin

@alongubkin alongubkin commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

Summary

  • return bounded reasons when explicitly requested deployments cannot be acquired
  • classify SQLite acquisition misses in the same transaction as lease selection and mutation
  • fail fast on permanent acquisition mismatches while retaining bounded retries for contention and deferral
  • preserve compatibility with older managers and downstream deployment stores

Validation

  • cargo check -p alien-manager --features sqlite,openapi
  • cargo test -p alien-manager --features sqlite explicit_acquire_ --test sqlite_store_tests -- --nocapture
  • cargo test -p alien-deployment explicit_acquire_mismatch_fails_without_retrying --lib -- --nocapture
  • pnpm run generate:manager-rust-sdk
  • generated TypeScript SDK build and compatibility tests

Linear: ALIEN-948

Refreshed against current main. Re-ran two SQLite acquisition classification tests and three generated client compatibility tests. Regenerated with pnpm run generate:manager-rust-sdk and pnpm run generate:manager-api; fresh schemas also reconcile existing external-binding schema drift. Live isolated API/manager proof distinguishes statusMismatch from a held lease and confirms successful lease release. The CLI transport HTTP regression executes all 60 contention attempts over 118 seconds and reports the held-lease explanation; a live CLI contention run now also passes. The test acquired and renewed an owned AWS deployment setup lease before launching the real CLI in supported standalone-manager mode against an isolated manager and API over local HTTPS. After the bounded wait, the CLI explained that another operation still held the lease and that this command had not acquired it. Holder release returned HTTP 200 / success=true. Earlier hosted-mode runs over the public tunnel ended with HTTP 503 and remain inconclusive for that routing path. Timeout text also distinguishes deferral and older managers without reasons. Normal platform SDK generation was run to align newly exposed reason fields.

Platform SDK

client-sdks/platform is reset to main in this PR. This repo has no generator for the platform spec, so the earlier platform SDK additions (UnacquiredDeployment, DeploymentAcquireUnavailableReason, the new SyncAcquireResponse fields) are dropped here. They come back on the next platform spec sync. Nothing in this repo depends on them: the CLI transport reads acquisition reasons only through the manager SDK (alien_manager_api::types).

Manager artifacts after merging main: alien-manager-schema-exporter output is byte-identical to crates/alien-manager/openapi.json; the generate:manager-rust-sdk down-convert/fix steps and pnpm run generate:manager-api (Speakeasy 1.680.11) produce no changes besides generation metadata.

@greptile-apps

greptile-apps Bot commented Sep 22, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Critical risk] Updates the public API contract for deployment acquisition.

The PR appears safe to merge; no outstanding correctness, compatibility, security, or repository-rule failures were identified.

Summary

This PR adds bounded explanations for explicitly requested deployments that cannot be acquired and surfaces those explanations through deployment clients.

  • Classifies acquisition misses atomically with SQLite lease selection and mutation.
  • Fails immediately for permanent request mismatches while retaining bounded retries for contention, deferral, and older managers.
  • Adds optional acquisition-reason models to the Manager API and generated clients without breaking the existing sync request model.
  • The previously reported AgentSyncRequest compatibility issue is resolved.

Diagram

sequenceDiagram
    participant C as Deployment client
    participant M as Manager sync route
    participant S as Deployment store
    C->>M: Acquire explicit deployment IDs
    M->>S: Select, lease, and classify in one transaction
    alt Deployment acquired
        S-->>M: Acquired deployment
        M-->>C: Deployment and execution claim
    else Temporary unavailability
        S-->>M: Contended or deferred
        M-->>C: Optional bounded reason
        C->>C: Retry within bounded wait
    else Permanent mismatch
        S-->>M: Model, platform, status, or mode mismatch
        M-->>C: Optional bounded reason
        C->>C: Fail without further retries
    end
Loading

Reviews (3) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

Comment thread client-sdks/manager/openapi.json Outdated
@alongubkin

Copy link
Copy Markdown
Member Author

@greptileai review

# Conflicts:
#	client-sdks/platform/openapi.json
#	client-sdks/platform/rust/openapi-3.0.json
#	client-sdks/platform/rust/openapi.json
#	client-sdks/platform/typescript/.speakeasy/gen.lock
#	client-sdks/platform/typescript/docs/models/deploymentdeployersecret.md
#	client-sdks/platform/typescript/docs/models/deploymentdetailresponsedeployersecret.md
#	client-sdks/platform/typescript/docs/models/deploymentdetailresponselocation.md
#	client-sdks/platform/typescript/docs/models/deploymentlocation.md
#	client-sdks/platform/typescript/docs/models/deploymentstatedeployersecret.md
#	client-sdks/platform/typescript/docs/models/deploymentstatelocation.md
#	client-sdks/platform/typescript/docs/models/persistimporteddeploymentrequestdeployersecret.md
#	client-sdks/platform/typescript/docs/models/persistimporteddeploymentrequestlocation.md
#	client-sdks/platform/typescript/docs/models/publicendpoint.md
#	client-sdks/platform/typescript/docs/models/synclistresponsedeployersecret.md
#	client-sdks/platform/typescript/docs/models/synclistresponselocation.md
#	crates/alien-deployment/src/manager_api_transport.rs
@alongubkin

Copy link
Copy Markdown
Member Author

@greptileai review

@alongubkin
alongubkin merged commit e2e2e63 into main Oct 8, 2026
25 checks passed
@alongubkin
alongubkin deleted the alon/alien-948-acquire-outcome-reasons branch October 8, 2026 13:08
alongubkin added a commit that referenced this pull request Oct 8, 2026
Repeated `alien deploy` commands accept an unchanged saved public
subdomain and explicitly requeue failed setup operations before
acquiring execution. Routing changes fail with an actionable resume
command.

When the manager finishes between the status read and acquisition, the
CLI inspects structured acquisition errors throughout the source chain
and confirms completion from an authoritative deployment snapshot.
Success requires Running, an installed release, no desired release, and
no active or queued update. Other rejection reasons and failed
completion reads remain failures.

Resource progress starts after acquisition. The progress callback is
released after the runner finishes so setup rows stop redrawing during
manager handoff.

Validation:
- Earlier controlled AWS before/after run reproduced a false
statusMismatch after update completion and successful recovery with the
candidate CLI.
- HTTP regressions cover completion, pending work, missing state, other
rejections, transport failure, and both actual acquisition helpers.
- Fresh CI and Greptile review run on the updated branch.

Refs ALIEN-1317. The shared acquisition contract from #699 is merged and
included in this branch.
alongubkin added a commit that referenced this pull request Oct 8, 2026
Sync the generated hosted API SDK with the acquisition outcome contract
introduced in #699. Explicit requests now expose `notAcquired` with
bounded rejection reasons, while responses from older servers can omit
the field.

This dedicated SDK sync also preserves the operations configuration
added on main instead of regenerating against an older schema. All three
Rust/TypeScript OpenAPI inputs come from the source API generation
pipeline; TypeScript models were generated with the pinned Speakeasy
1.799.0 CLI. Unrelated documentation example rewrites were restored as
complete files.

Validation: TypeScript SDK build passes with
`NODE_OPTIONS=--max-old-space-size=16384 pnpm -C
client-sdks/platform/typescript build`. The generated Rust response has
a default-empty `not_acquired` collection for compatibility with older
servers. All 36 hosted controller deployment-store regressions pass,
including acquisition outcome propagation and older responses without
`notAcquired`.
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