Files
Mrunal Patel c502be9fd7 feat(api): return typed deletion outcomes with explicit missing-target semantics (#3317)
* feat(api): return typed deletion outcomes with explicit missing-target semantics

Implement phase 2 of #3051 across the public gateway API and first-party SDKs. Preserve asynchronous sandbox deletion and observed resource identities, reserve legacy wire fields, and document the coordinated migration.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

* fix(sdk): bind deletion waits to sandbox identity

Track accepted deletions by original sandbox identity in Rust and TypeScript. Preserve name-only waits and cover replacement races and lookup failures.

Merge the phase-one cleanup fix and adapt its interceptor regressions to typed deletion outcomes.

Refs #3051.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

* test(e2e): accept asynchronous stopped sandbox deletion

Allow either completed or accepted deletion output, then continue polling for actual sandbox absence. This preserves the lifecycle assertion under the phase-two deletion contract.

Refs #3051.

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>

---------

Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
2026-09-16 22:11:19 +00:00

34 lines
902 B
Python

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Typed mutation results, separate from transport success."""
from dataclasses import dataclass
from enum import IntEnum
class DeletionOutcome(IntEnum):
"""Only COMPLETED and ALREADY_ABSENT establish logical deletion completion."""
UNSPECIFIED = 0
COMPLETED = 1
ACCEPTED = 2
ALREADY_ABSENT = 3
@classmethod
def _missing_(cls, value):
if not isinstance(value, int):
return None
member = int.__new__(cls, value)
member._name_ = f"UNKNOWN_{value}"
member._value_ = value
return member
@dataclass(frozen=True)
class DeletionResult:
"""Outcome for the original target; unknown outcomes never imply completion."""
outcome: DeletionOutcome
sandbox_id: str | None = None