# KEPs & Roadmap

> In-flight design proposals tracked under docs/keps (suspended state, metadata propagation, Python SDK refactor) and the published roadmap.

- Repository: kubernetes-sigs/agent-sandbox
- GitHub: https://github.com/kubernetes-sigs/agent-sandbox
- Human wiki: https://grok-wiki.com/public/wiki/kubernetes-sigs-agent-sandbox-c3f2597a654a
- Complete Markdown: https://grok-wiki.com/public/wiki/kubernetes-sigs-agent-sandbox-c3f2597a654a/llms-full.txt

## Source Files

- `roadmap.md`
- `docs/keps/README.md`
- `docs/keps/119-sandbox-suspended-state/README.md`
- `docs/keps/174-metadata-propagation/README.md`
- `docs/keps/359-refactor-python-sdk/README.md`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [roadmap.md](roadmap.md)
- [docs/keps/README.md](docs/keps/README.md)
- [docs/keps/NNNN-template/README.md](docs/keps/NNNN-template/README.md)
- [docs/keps/NNNN-template/kep.yaml](docs/keps/NNNN-template/kep.yaml)
- [docs/keps/119-sandbox-suspended-state/README.md](docs/keps/119-sandbox-suspended-state/README.md)
- [docs/keps/119-sandbox-suspended-state/kep.yaml](docs/keps/119-sandbox-suspended-state/kep.yaml)
- [docs/keps/174-metadata-propagation/README.md](docs/keps/174-metadata-propagation/README.md)
- [docs/keps/174-metadata-propagation/kep.yaml](docs/keps/174-metadata-propagation/kep.yaml)
- [docs/keps/359-refactor-python-sdk/README.md](docs/keps/359-refactor-python-sdk/README.md)
- [docs/keps/359-refactor-python-sdk/kep.yaml](docs/keps/359-refactor-python-sdk/kep.yaml)
</details>

# KEPs & Roadmap

This page documents the forward-looking design surface of `kubernetes-sigs/agent-sandbox`: the Agent Sandbox Enhancement Proposal (KEP) process, the three in-flight KEPs currently checked into `docs/keps/`, and the published `roadmap.md`. KEPs are how non-trivial changes are proposed, debated, and coordinated; the roadmap states the high-level strategic priorities for the calendar year. Together they describe what shape the project is likely to take next, independent of what is already implemented.

The body below pulls each proposal apart into its motivation, the API or behavior it changes, and what state of maturity it is in (per the `status` field in each `kep.yaml`). The roadmap section maps the roadmap bullets back to the KEPs and tracking issues they correspond to, so a reader can connect a strategic priority to the concrete design document that backs it.

## The KEP Process

The KEP process is modeled directly on the upstream [Kubernetes Enhancement Proposal](https://github.com/kubernetes/enhancements/tree/master/keps) workflow. Writing one is optional and reserved for "non-trivial changes" — controversial proposals, new features, major changes to existing features, and anything with wide project impact. Lightweight changes go straight to PRs. Discussion happens on the `#sig-apps` Kubernetes Slack channel and the SIG-Apps mailing list before a KEP is drafted.

Each KEP lives in a folder under `docs/keps/<NNN>-<short-name>/` and consists of two files:

| File | Purpose |
| :--- | :--- |
| `README.md` | The proposal itself: summary, motivation, proposal, API changes, alternatives. Sections are generated from `docs/keps/NNNN-template/README.md`. |
| `kep.yaml` | Structured metadata — title, `kep-number`, authors, reviewers, approvers, `status`, `creation-date`, and optionally `stage` and `last-updated`. |

The `NNN` prefix is the tracking issue number on the `agent-sandbox` GitHub repo, which gives every proposal a stable identifier and a single place to discuss live state. The template embeds an auto-generated `<!-- toc -->` block maintained by `make toc-update`.

Sources: [docs/keps/README.md:1-30](), [docs/keps/NNNN-template/README.md:1-94](), [docs/keps/NNNN-template/kep.yaml:1-18]()

### KEP Lifecycle and Status Vocabulary

`status` in `kep.yaml` is the canonical truth for where a proposal sits. The template offers `implementable|implemented` as the example vocabulary; existing KEPs use `provisional` and `implementable`. The optional `stage` field (e.g., `alpha`) tracks rollout maturity once an implementation lands.

```text
   draft  ─►  provisional  ─►  implementable  ─►  implemented
                                    │
                                    └─►  stage: alpha → beta → ga
```

Sources: [docs/keps/NNNN-template/kep.yaml:5](), [docs/keps/119-sandbox-suspended-state/kep.yaml:1-10](), [docs/keps/174-metadata-propagation/kep.yaml:1-9](), [docs/keps/359-refactor-python-sdk/kep.yaml:1-10]()

## In-Flight KEPs

Three KEPs are currently checked in. The table below is a quick index; full detail follows in dedicated sections.

| KEP | Title | Status | Stage | Authors | Created |
| :--- | :--- | :--- | :--- | :--- | :--- |
| 119 | Agent Sandbox Suspended Condition Status | `implementable` | — | @SHRUTI6991 | 2026-03-16 |
| 174 | Label and Annotation Propagation to Sandbox Pods | `provisional` | `alpha` | @chenyiwang | 2026-03-18 |
| 359 | Python SDK Refactor From Context Manager to Resource Handle | `implementable` | — | @SHRUTI6991 | 2026-03-03 |

Note that the `kep-number` field inside `docs/keps/359-refactor-python-sdk/kep.yaml` is currently `174` — the folder name (`359-...`) reflects the tracking issue, while the YAML field has not been updated to match.

Sources: [docs/keps/119-sandbox-suspended-state/kep.yaml:1-10](), [docs/keps/174-metadata-propagation/kep.yaml:1-9](), [docs/keps/359-refactor-python-sdk/kep.yaml:1-10]()

### KEP-119: Sandbox `Suspended` Condition

KEP-119 adds an explicit `Suspended` status condition to the `Sandbox` CRD so that observers can distinguish "scaling down" from "scaled down" without inspecting child Pods, PVCs, or Services. Today there is only the aggregate `Ready` condition; once a suspension is requested, that single signal cannot say whether the termination is in progress or already complete, and it cannot model future "soft pause" modes such as freezing container processes or hibernating to disk.

The proposal defines two conditions and a Reason-driven hierarchy that the controller evaluates top-down:

| Scenario | `Suspended` | Suspended Reason | Pod Phase | `Ready` (Root) | Ready Reason |
| :--- | :--- | :--- | :--- | :--- | :--- |
| Provisioning | None | None | None | `False` | `DependenciesNotReady` |
| Pod Starting | None | None | Pending | `False` | `DependenciesNotReady` |
| Operational | None | None | Running & Ready | `True` | `DependenciesReady` |
| Suspending | `False` | `PodNotTerminated` | Running / Terminating | `False` | `SandboxSuspended` |
| Suspended | `True` | `PodTerminated` | None | `False` | `SandboxSuspended` |

The moment a suspension is requested (e.g., `replicas: 0`), `Ready` immediately flips to `False` with reason `SandboxSuspended`, and the `Suspended` condition tracks the actual progress. This lets standard tooling drive automation directly:

```bash
kubectl wait --for=condition=Ready sandbox/my-env
kubectl wait --for=condition=Suspended=True sandbox/my-env
```

The KEP rejects two alternatives: retaining the legacy `status.phase` string (deprecated by Kubernetes API conventions and prone to combinatorial explosion as new suspension modes are added) and overloading `Ready` with reason codes (no headroom to distinguish "freeze" vs "hibernate" vs "scale-to-zero" in the future).

```mermaid
stateDiagram-v2
    [*] --> Provisioning
    Provisioning --> PodStarting: dependencies created
    PodStarting --> Operational: Pod Ready
    Operational --> Suspending: replicas=0 / suspend request
    Suspending --> Suspended: Pod terminated
    Suspended --> Provisioning: scale back up

    Provisioning: Ready=False<br/>DependenciesNotReady
    PodStarting: Ready=False<br/>DependenciesNotReady
    Operational: Ready=True<br/>DependenciesReady
    Suspending: Ready=False / SandboxSuspended<br/>Suspended=False / PodNotTerminated
    Suspended: Ready=False / SandboxSuspended<br/>Suspended=True / PodTerminated
```

Sources: [docs/keps/119-sandbox-suspended-state/README.md:1-82]()

### KEP-174: Metadata Propagation to Sandbox Pods

KEP-174 standardizes how labels and annotations flow from a top-level `SandboxClaim` through the `Sandbox` and finally onto the backing `Pod`. The motivation is twofold: enabling per-claim "personalization" (cost attribution, observability, stateful session identifiers) on otherwise homogeneous warm-pool pods, and avoiding "template explosion" caused by creating a new `SandboxTemplate` for every unique session.

The design adds a single new field, `additionalPodMetadata`, on `SandboxClaim`. `SandboxTemplate` and `SandboxWarmPool` are left untouched so that pool resources remain interchangeable.

```go
// sandbox_types.go (existing)
type PodMetadata struct {
    Labels      map[string]string `json:"labels,omitempty" protobuf:"bytes,1,rep,name=labels"`
    Annotations map[string]string `json:"annotations,omitempty" protobuf:"bytes,2,rep,name=annotations"`
}

// sandboxclaim_types.go (new)
type SandboxClaimSpec struct {
    // ...
    AdditionalPodMetadata sandboxv1alpha1.PodMetadata `json:"additionalPodMetadata,omitempty"`
}
```

The data flow and safety contract:

```text
SandboxClaim.spec.additionalPodMetadata
        │   (SandboxClaim controller)
        ▼
Sandbox.spec.podTemplate.metadata           ◄── merged with SandboxTemplate
        │   (Sandbox controller)
        ▼
Pod.metadata.{labels,annotations}
        │
        ├── agents.x-k8s.io/propagated-labels       = "k1,k2,..."
        └── agents.x-k8s.io/propagated-annotations  = "a1,a2,..."
```

Two annotations on the resulting Pod — `agents.x-k8s.io/propagated-labels` and `agents.x-k8s.io/propagated-annotations` — record which keys the controller put there, so it can later prune removed keys without disturbing labels added by mutating webhooks or other actors. The controller refuses requests where a key collides between the template and the claim with conflicting values ("Safety Principle: No Overrides").

Two propagation scenarios are spelled out:

| Scenario | Trigger | Controller behavior |
| :--- | :--- | :--- |
| Cold Start (new Pod) | First creation, no warmpool | Sandbox controller merges template + claim metadata before Pod creation. |
| Cold Start (Pod exists) | `SandboxClaim` metadata updated after creation | In-place patch of Pod `metadata`, no restart. |
| Warmpool adoption | Claim binds to a pre-warmed Sandbox | `SandboxClaim` controller patches the Sandbox's `spec.podTemplate.metadata` for sub-millisecond dispatch; no resource re-creation. |
| Warmpool post-adoption update | Claim metadata changes later | `SandboxClaim` controller re-syncs the metadata into the Sandbox. |

The scope is intentionally narrow: only label/annotation propagation that does not require a Pod restart. Anything that imposes functional control needing a restart is deferred to [Issue 208](https://github.com/kubernetes-sigs/agent-sandbox/issues/208). For metadata that must apply uniformly across an entire pool, users still modify `SandboxTemplate` directly per [Issue 347](https://github.com/kubernetes-sigs/agent-sandbox/issues/347).

Sources: [docs/keps/174-metadata-propagation/README.md:1-108]()

### KEP-359: Python SDK Refactor — Context Manager → Resource Handle

KEP-359 reshapes the Python client from a transient `with Sandbox() as sbx:` context manager into a persistent **Resource Handle** keyed by `sandbox_id`. The context-manager pattern fits short scripts but is a poor match for long-lived agent workflows: an agent may suspend a sandbox for hours, hand ownership across processes, juggle multiple sandboxes concurrently, or reattach to one created by a different component. None of those are expressible inside a single `with` block.

The new SDK is layered into three tiers:

```mermaid
classDiagram
    class SandboxClient {
        +router_dns: str
        +create_sandbox(template, namespace) Sandbox
        +get_sandbox(sandbox_id) Sandbox
    }
    class Sandbox {
        +id: str
        +commands: CoreExecution
        +files: Filesystem
        +status()
        +suspend()
        +resume()
        +terminate()
    }
    class CoreExecution {
        +run_code()
        +run_cmd()
    }
    class Filesystem {
        +read()
        +write()
        +list()
    }
    class ProcessSystem {
        +create_process()
        +kill_process()
    }
    SandboxClient ..> Sandbox : factory / reattach
    Sandbox *-- CoreExecution
    Sandbox *-- Filesystem
    Sandbox ..> ProcessSystem : sbx.process
```

`SandboxClient` is the entry point and factory; it owns global configuration such as `router_dns`. `Sandbox` is a stable handle around a `sandbox_id` and exposes lifecycle verbs (`status`, `suspend`, `resume`, `terminate`) plus dot-namespaced engines (`sbx.files`, `sbx.commands`, `sbx.process`). Engines talk to the Sandbox Router over a stable DNS name and pass an `X-Sandbox-Id` header for session affinity.

The motivating properties the design calls out:

1. **Identity stability** — the same `Sandbox` object remains valid whether the underlying Pod is running, suspended, or resuming.
2. **Orchestration vs. execution split** — management calls go through the control plane; execution calls go through the router.
3. **Capability discovery** — new functionality slots into a new engine namespace rather than the root object.
4. **Distributed ownership** — a `sandbox_id` can be handed to another process which calls `get_sandbox(id)` and continues from there.
5. **Non-linear logic** — multiple long-lived sandboxes coexist as plain objects, no nested `with` blocks.

Worked example from the KEP:

```python
client = SandboxClient(router_dns="router.sandbox.svc")

sbx = client.create_sandbox(template="python-ml")
sbx.files.write("data.py", "x = 42")
sbx.core.run_code("import data; print(data.x)")
sbx.suspend()

# Re-attach later, possibly in a different process
old_sbx = client.get_sandbox("sbx_123")
old_sbx.resume()
```

A proof-of-concept implementation lives at [PR #365](https://github.com/kubernetes-sigs/agent-sandbox/pull/365). The PoC initiates the router session at `Sandbox` construction time and updates the test client to use the handle-based flow. The "Scalability" section notes a future hook for a pluggable Sandbox Manager.

Sources: [docs/keps/359-refactor-python-sdk/README.md:1-129]()

## Roadmap

`roadmap.md` lists the project's "main strategic priorities for 2026." The bullets span documentation, distribution, SDK functionality, API shape, observability, isolation technology, and ecosystem integrations. Many bullets carry a GitHub issue number that links the strategic intent to the live tracking issue.

### Roadmap → KEP / Issue Map

The roadmap items split into ones that already have a KEP in flight versus ones that are tracked only by an issue and a sentence of intent.

| Roadmap theme | Tracking issue | KEP |
| :--- | :--- | :--- |
| Status Updates | [#119](https://github.com/kubernetes-sigs/agent-sandbox/issues/119) | KEP-119 (Suspended condition) |
| Metadata Propagation | [#174](https://github.com/kubernetes-sigs/agent-sandbox/issues/174) | KEP-174 |
| Expand SDK functionality (`read`, `write`, `run_code`, …) | — | KEP-359 (resource handle + engines) |
| Website Refresh | [#166](https://github.com/kubernetes-sigs/agent-sandbox/issues/166) | — |
| PyPI Distribution of `agent-sandbox-client` | [#146](https://github.com/kubernetes-sigs/agent-sandbox/issues/146) | — |
| Strict Sandbox-to-Pod Mapping | [#127](https://github.com/kubernetes-sigs/agent-sandbox/issues/127) | — |
| Go Client | [#227](https://github.com/kubernetes-sigs/agent-sandbox/issues/227) | — |
| Startup Actions | [#58](https://github.com/kubernetes-sigs/agent-sandbox/issues/58) | — |
| Creation Latency Metrics | [#123](https://github.com/kubernetes-sigs/agent-sandbox/issues/123) | — |
| Headless Service Port Handling | [#154](https://github.com/kubernetes-sigs/agent-sandbox/issues/154) | — |
| OpenEnv Support | [#132](https://github.com/kubernetes-sigs/agent-sandbox/issues/132) | — |

### Themes Without Linked Issues

Several priorities currently exist only as roadmap prose:

- **Documentation overhaul** — restructure and expand current documentation to lower the barrier to entry.
- **Benchmarking Guide** — published guidance for measuring Agent Sandbox performance.
- **Expand Sandbox use cases** — Computer Use, browser use, additional base images.
- **Decouple API from Runtime** — let users fully customize the runtime without breaking the API.
- **Scale-down / Resume PVC based** — preserve PVC when replicas drop to 0; restore on scale-up.
- **Complete CR, SDK, and template support** — feature-parity across surfaces.
- **API Support for Multi-Sandbox per Pod** — multiple sandboxes inside a single Pod.
- **Auto-deletion of bursty sandboxes** — typical RL training pattern.
- **Runtime API OTEL/Tracing instrumentation** — instrument and document.
- **Detailed Falco config extension** — surface gVisor logging configuration through the Agent Sandbox API.
- **Other isolation technologies** — QEMU, Firecracker, process isolation (pydantic).
- **Agent & RL framework integration** — CrewAI, Ray RLlib.
- **Integration with kAgent** and other sandbox offerings.
- **Deliver Beta/GA versions.**

Sources: [roadmap.md:1-29]()

## Reading and Contributing to a KEP

A practical workflow for a contributor proposing a non-trivial change:

1. Socialize the idea on `#sig-apps` Slack or the SIG-Apps mailing list.
2. Open a tracking issue on `kubernetes-sigs/agent-sandbox`; the issue number becomes the KEP's `NNN` prefix and folder name.
3. Copy `docs/keps/NNNN-template/` to `docs/keps/<NNN>-<short-name>/` and fill in the `README.md` sections (Summary, Motivation, Proposal, API Changes, Implementation Guidance, Scalability, Alternatives).
4. Populate `kep.yaml` — `title`, `kep-number`, `authors`, `reviewers`, `approvers`, `status`, `creation-date`, optionally `stage`, `last-updated`, `see-also`, and `replaces`.
5. Regenerate the table of contents with `make toc-update`.
6. Land the KEP through normal review; update `status` (and `stage` once implementation begins) as the proposal moves through `provisional` → `implementable` → `implemented`.

Sources: [docs/keps/README.md:1-30](), [docs/keps/NNNN-template/README.md:1-94](), [docs/keps/NNNN-template/kep.yaml:1-18]()

## Summary

The `docs/keps/` tree is the project's design archive: three live proposals (119 surfacing a `Suspended` status condition on the `Sandbox` CRD, 174 wiring `SandboxClaim` labels and annotations down to the backing Pod without breaking warm-pool homogeneity, and 359 rebuilding the Python SDK around a persistent `Sandbox` handle with namespaced engines) plus a template and process document. `roadmap.md` sits alongside as the 2026 strategic agenda; many of its bullets reference the same GitHub issues used to number the KEPs, making the roadmap → KEP → tracking-issue chain the natural path for anyone trying to understand where Agent Sandbox is heading next.
