Commit Graph
34 Commits
Author SHA1 Message Date
Dmitry Berkovich 37b5006d92 DurableDir support (#295)
Implement a layer allowing to take durableDir snapshot only, without
taking snapshot of entire memory. This is a part of the #119 feature.

The "durableDir" support is introduced via adding Volumes support to
ActorTemplate.

## Knowns issues / limitations


1. No MicroVM support for homedir yet. Will be implemented in following
PR.

2. Resume from SNAPSHOT_SCOPE_DATA temporary behavior
Current behavior of resume from durableStorage returns immediately after
gVisor process is started, it means container's bootstrap is not
completed by the time resume API returned to the caller. It causes the
issue that first curl request for suspended actor throws an HTTP
exception, since webserver listening on the port inside container is not
running yet.
PR #330 fixes the issue, for a meantime the workaround is to call `
kubectl ate resume actor` and after it call to the curl itself.

- [X ] Unit tests  pass
- [X ] E2E tests are updated and pass
2026-06-26 20:05:03 -07:00
Benjamin Elder 3d53de85eb microvm MVP cleanup: align rootfs behavior to gvisor, ... (#313)
Follow-up to https://github.com/agent-substrate/substrate/pull/287 /
#123

- align snapshot behavior: use a tmpfs (for writes) on top of read-only
viritio-fs mount for the container image rootfs instead of ext4 images
- enable multiple container support
- cleanup stale comments

> It's a good idea to open an issue first for discussion.

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-26 20:02:11 -07:00
Dmitry Berkovich 125180ea65 feat: implement container readiness probes with custom HTTP endpoint … (#330)
Extends ActorTemplate.Container spec to allow defining a readyz probe. 
* ateoms (both gVisor & microVM) are updated and wait for readyz signal
if it was enabled on container when creating a new container or resume
from a snapshot.
* actorTemplates controller has been updated not to wait 20 sec during
golden snapshot creation, if readyz is enabled on actor. It assumes,
atelet call returns when all containers passed readyz.

Tested manually both counters: 
* gVisor 
* microvm 

Fixes #316 

- [x] e2e tests pass 
- [X] Appropriate changes to documentation are included in the PR
2026-06-26 18:59:56 -07:00
Bowei Du 35150f2508 Update documentation references 2026-06-26 10:18:53 -07:00
mesutoezdil 416b0706c1 fix: add missing subcommand in kubectl ate logs examples 2026-06-25 17:14:42 -07:00
mesutoezdil 3d4118cb27 fix: correct code examples in tracing best practices doc 2026-06-25 16:51:56 -07:00
Mesut Oezdil 2560f931dc fix: misc doc fixes across multiple files (#310)
- roadmap.md: remove empty bullet point
- hack/update/README.md: fix self-referential path (`../update` ->
`../update-all.sh`)
- hack/verify/README.md: fix self-referential path (`../verify` ->
`../verify-all.sh`)
- cmd/atenet/internal/dns/README.md: fix typo (`orchsterates` ->
`orchestrates`)
- docs/dev/valkey-direct-access.md: add context and warning about
destructive commands
2026-06-25 15:25:20 -07:00
Benjamin Elder 833920b8e9 address review: controller/test/docs fixes
- workerpool_apply: rename applyMicroVMPodShape -> maybeApplyMicroVMPodShape and
  pass wp.Spec.SandboxClass instead of the whole WorkerPool.
- sandboxconfig validation test: add an arm64 micro-VM asset-set case.
- specconv: TODO to forward Seccomp/Sysctl + Apparmor/SELinux for OCI parity.
- run.go: clarify the dialAgentRetry per-attempt cap vs retry-gap comment.
- roadmap: drop the microVM line (shipped).
2026-06-25 13:44:25 -07:00
Benjamin Elder 2c50d282e2 hack,demos,docs: micro-VM asset tooling, base image, demo runner, docs
Assemble + stage the micro-VM runtime assets, an ateom-base image (debian-slim +
e2fsprogs for mkfs.ext4), and run-microvm-demo.sh to build + deploy the
counter-microvm demo end to end (overriding the worker base via KO_CONFIG_PATH so
no committed file is edited). Document the micro-VM sandbox class.
2026-06-25 13:44:25 -07:00
Frederick F. Kautz IV bd33e07606 docs: name resource-model namespaces by owning server
Rename the class-diagram namespaces from the abstract categories
(KubernetesObjects / ControlPlaneRecords) to the servers that actually
own the records: kube-apiserver (ActorTemplate/WorkerPool CRDs,
Deployment, WorkerPod) and ate-api-server (Actor/Worker, the proto
records persisted in Redis). Per review feedback on #245.

Uses the hyphenated ate-api-server to match the deployed Service and
Deployment, the client dial address, and the rest of this doc, rather
than the ate-apiserver spelling that only appears in an install flag.
2026-06-24 22:46:46 -07:00
Frederick F. Kautz IV c8cc795898 docs: add architecture diagrams (resource model, activation, lifecycle)
Add the sequence, class, and state diagrams to architecture.md, where
people look for diagrams when modifying the system. Each lands in the
section whose prose already describes it: the resource model under API
Resource Models, and the activation flow and lifecycle state machine
under Actor Lifecycle.

This is the companion to #200, which drops the same diagrams from the
glossary to keep it a plain list of terms (per review feedback).

Every diagram claim was verified against the current implementation. The
activation note no longer implies idle-triggered suspend, since
SuspendActor is an explicit call with no idle-detection mechanism.
2026-06-24 22:46:46 -07:00
Benjamin Elder f5df01bd82 ateom-gvisor: tag forwarded actor logs with ate.dev/container_name (#290)
While working on multi-container support for uVM in
https://github.com/agent-substrate/substrate/pull/287 I noticed how
difficult it is to debug multi-container workloads.

This makes it a lot easier. TODO: We could support filtering on this in
kubectl ate (cc @HavenXia)
2026-06-23 19:40:49 -04:00
Julian Gutierrez Oschmann b4c82fe383 Add resources field to WorkerPool. (#279)
Allow WorkerPool resources to specify resource requirements its worker
pods.

Partially addresses
https://github.com/agent-substrate/substrate/issues/212.
2026-06-23 15:30:01 -07:00
Frederick F. Kautz IV d0c7f57214 docs: add a glossary of core terms (#200)
Addresses #131

Adds `docs/glossary.md`: a single place that defines the terms used
across
Agent Substrate and shows how they relate.

### What it covers
- Resources (ActorTemplate, WorkerPool), control-plane records (Actor,
Worker),
  components (ate-api-server, atecontroller, atelet, ateom, atenet,
podcertcontroller, kubectl-ate), runtime/sandbox concepts (gVisor,
runsc,
pause container, checkpoint/restore), snapshots (golden, last, storage),
and
  the Uniform DNS Mesh.
- Three UML diagrams: a sequence diagram (activation/resume flow), a
class
  diagram (resource/ownership model, grouped into Kubernetes-object and
control-plane-record packages), and a state-machine diagram (actor
lifecycle).
- Linked from the README documentation section.

### Scope
Per the issue thread, this documents the names as they exist in the
codebase;
rename proposals are intentionally left to a separate discussion, so
this PR is
documentation-only (not a renaming proposal).

### Accuracy
Every term and diagram was checked against the code and existing docs.
Project
terminology and casing are reused where things are already named (for
example
"Uniform DNS Mesh", the atelet "Herder", and the "interior gVisor"
coordinator),
and component responsibilities, RPC names, relationships, and the actor
status
lifecycle map to their sources.

- [x] Tests pass (documentation-only change)
- [x] Appropriate changes to documentation are included in the PR
2026-06-22 17:43:47 -07:00
Benjamin Elder fe93d160a1 feat: add SandboxClass support to ActorTemplate (#285)
Big UX improvement for iterating on #123 

Follow-up to https://github.com/agent-substrate/substrate/pull/270
(previously worker pools were directly referenced by actors so you just
made sure to pick an appropriate workerpool, we discussed there)

> It's a good idea to open an issue first for discussion.

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-22 13:56:54 -07:00
Julian Gutierrez Oschmann 9f8475493b Decouple ActorTemplates from WorkerPools. (#270)
This change removes the hard-link from templates to worker pools,
allowing pools to be selected using k8s labels.

Both actors and actor templates are augmented with a label selector
field.

When an actor is resumed, we resolve the set of *eligible* worker pools
by evaluating the intersection of both actor and template selectors.
Then we find a free worker from one of them. The overall design is
described in [1].

[1]:
https://github.com/agent-substrate/substrate/issues/47#issuecomment-4712334620
2026-06-18 10:58:34 -07:00
Benjamin Elder 00a90a8eda Decouple Sandbox Binaries / Config from ActorTemplate (#261)
Fixes https://github.com/agent-substrate/substrate/issues/253

> It's a good idea to open an issue first for discussion.

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR

Should make something like
https://github.com/agent-substrate/substrate/pull/239 less awkward, and
also https://github.com/agent-substrate/substrate/issues/255 (we don't
have to cram more fields into actortemplate for the shim binary and
update _all_ of the demo actortemplates to include them).
2026-06-17 09:46:46 -07:00
han2ni3bal-pixel 962ff6b1ae Add WorkerPool scheduling fields (#247)
**Updated Original PR Description**
## Summary

This PR adds a small, controlled set of scheduling fields to WorkerPool
so WorkerPool-managed Pods can be placed onto appropriate Kubernetes
nodes.

Added fields:

- `nodeSelector`
- `tolerations`
- `priorityClassName`
- `nodeAffinity`

## Scope

This intentionally does not expose a full `PodTemplateSpec`, and does
not add support for full `affinity`, `podAffinity`, or
`podAntiAffinity`.

Resource requests/limits are intentionally left out of scope for this CL
while the WorkerPool resource model is still being discussed separately.

The goal is to keep the first version small while addressing the
WorkerPool-to-Kubernetes-Node scheduling gap discussed in
[#212](https://github.com/agent-substrate/substrate/issues/212).

`nodeAffinity` is included to support heterogeneous node pools where
`nodeSelector` is too limited, such as requiring or preferring one of
several equivalent accelerator/local-SSD/cache node pools, or expressing
soft preferences during node pool migration.

`priorityClassName` is included to help preserve warm WorkerPool
capacity under cluster pressure. Since WorkerPool pods are the slots
available for actor resume, higher-priority pools can protect
latency-sensitive or interactive actor workloads from displacement by
lower-priority batch workloads, and allow different WorkerPools to
represent different service classes, e.g. interactive vs. batch.

## Related issue

Part of #212.
Related to #47.
2026-06-17 10:33:00 -04:00
Dmitry Berkovich c1b51134e7 Actor Pause/Resume flow (#227)
Implements  `PAUSED` state for issue #119.

The snapshot files are kept locally on node VM in a separate folder. At
resume time, scheduler uses a node VM hint and picks up a worker from
the same node where files were stored at suspend time.

The local file management solution is temporary and will be replaced
once @msau42 introduces a new component that is supposed to manage files
on the node VM.

- [X] Tests pass
- [X] Manual tests with counter demo
```
>kubectl ate create actor my-counter-1 --template ate-demo-counter/counter
>curl -X POST -H "Host: my-counter-1.actors.resources.substrate.ate.dev" http://localhost:8000
hello from: 169.254.17.2 | preserved memory count: 1
>curl -X POST -H "Host: my-counter-1.actors.resources.substrate.ate.dev" http://localhost:8000
hello from: 169.254.17.2 | preserved memory count: 2
>kubectl ate pause actor my-counter-1 -o json
> curl -X POST -H "Host: my-counter-1.actors.resources.substrate.ate.dev" http://localhost:8000
hello from: 169.254.17.2 | preserved memory count: 3
```

### Breaking change
This PR introduces a breaking change in the Actor proto. All existing
actor needs to be recreated, prior testing PAUSE functionality.
2026-06-16 13:15:36 -07:00
Frederick F. Kautz IV 1f2c27b228 feat(atelet): expose actor identity via /run/ate/actor-id
Gives an actor a reliable way to learn its own ID without parsing the
Host header. atelet populates a per-actor identity directory (currently
the single file actor-id) and bind-mounts it read-only at /run/ate into
each app container; the pause container gets none.

- A directory rather than a single-file mount, per the discussion on
  #178, so future late-bound data can land as sibling files without
  changing the mount shape.
- The bundle is regenerated on every resume and external bind mounts are
  re-attached from the restore-time config.json, so the value stays
  correct per-actor through a golden-snapshot restore; an env var (or a
  file baked into the image) would be frozen at the golden actor's ID,
  since it lives in the checkpointed process memory.
- actor-id is written atomically (temp file, fsync, rename, parent
  fsync): the directory is visible to a possibly-running actor, so a
  reader must never observe a torn value.
- The identity dir is cleared and recreated with the other per-actor
  dirs in resetActorDirs.
- The in-rootfs mount point is created via os.Root, so a symlink planted
  in the image cannot redirect the write outside the extracted rootfs.

Documented for actor authors in docs/api-guide.md: read it fresh on use;
raw ID, no trailing newline.
2026-06-16 11:06:05 -07:00
Zoe Zhao fd9446ea3c Created a demo with 2 actortemplates in different namespaces sharing one workerpool (#210)
Fixes #211 : Create a demo that shows any worker can run any
actortemplates. Workers and actortemplates live in different namespaces.

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR

Tested:
Deployed the demo and tested create, suspend, resume, delete actors in
both namepsaces. https://paste.googleplex.com/4999545124683776
2026-06-10 09:48:59 -07:00
Haven Xia 91d1a75260 Move monitoring/dashboards under tools/setup-gcp. (#209)
Fixes #204

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-09 21:25:44 -04:00
Eitan Yarmush 0076b20c1a Support actortemplate secret env (#20)
A couple of TODOs/Discussions which I think are important to have based
on these changes.
1. Do we need a caching client for this to avoid calling the apiserver
every time?
2. Where/how do we want to resolve secrets generally? I think there are
good arguments to be made for the control-plane OR the "node" component.
In my mind this also related to:
https://github.com/agent-substrate/substrate/issues/18

Fixes #15 

> It's a good idea to open an issue first for discussion.

- [ x ] Tests pass
- [ x ] Appropriate changes to documentation are included in the PR
2026-06-08 16:04:50 -07:00
Haven Xia 36b43f5b71 Update the variable name used in logging to be actual Actor Template Namespace (#191)
It was using a wrong name `Actor Namespace` before, which doesn't exist
yet.


- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-08 13:38:20 -04:00
Haven Xia d238411c85 Add monitoring/README.md to list emitted metrics paths (#167)
Submit after #157 #160 

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-05 14:37:47 -04:00
Kyosuke Konishi ff7a4b5a19 feat(observability): add Prometheus to the kind dev stack (#145)
Adds a Prometheus server to the kind dev stack (in `otel-system`,
alongside the OpenTelemetry Collector and Jaeger). It scrapes component
`/metrics` via the existing `prometheus.io/scrape` annotations on
`ate-api-server` and `atelet`, scoped to the `ate-system`/`otel-system`
namespaces.

Fixes #106

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-06-04 12:00:01 -04:00
Tim Hockin d9773e7d03 Remove trailing space from md files 2026-05-31 19:45:36 -07:00
Haven Xia 3f4aa5d010 Refactor logging (#65)
This PR refactors `ateom-gvisor` and `kubectl-ate` to adopt a
flat-merged logging architecture, eliminating server-side and
client-side field guessing:
1. **Cloud Logging**: `ateom-gvisor` parses actor JSON, injects actor
labels/time, and outputs the flat map directly. GKE Cloud Logging
built-in rules parse native severity/message fields automatically.
2. **CLI Logging**: Removed the `--raw` flag. `kubectl ate logs` strips
Substrate metadata and outputs clean, consistent JSON lines with the
`time` field prepended first.
<img width="3235" height="306" alt="image"
src="https://github.com/user-attachments/assets/4a6ca291-db8d-45dc-b840-43efa74739f0"
/>

3. **Documentation**: Updated `docs/observability.md`

- [x] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-05-27 10:50:10 -07:00
Julian Gutierrez Oschmann 9bd41df2a3 Document code layout. (#87)
Document the rationale behind each directory and guidelines on how to
decide where to put new code in a dedicated markdown file.

Update AGENTS.md with a summary and a reference to the new markdown
file.
2026-05-26 19:42:21 -07:00
Julian Gutierrez Oschmann b1fe163fcf Run tools/reorg tool.
This commit was automatically generated by the tools/reorg tool.

```
go run ./tools/reorg
go generate ./...
bash benchmarking/locust/generate_protos.sh
```
2026-05-22 14:43:26 -07:00
Dmitry Berkovich c996c82577 Reoganize demo folders (#60)
Reorganize demo folders by moving manifests files inside the demo folder
from shared manifest folder
2026-05-22 11:01:19 -04:00
Haven Xia acee90f9e5 Support streaming actor logs with --follow/-f for kubectl ate logs (#28)
This PR adds live-streaming log support (`--follow/-f`) to `kubectl-ate
logs actors`. Unlike static container logs, this implementation is
actor-aware and resilient to virtual actor suspensions and migrations:

Suspend Lifecycle:
<img width="3700" height="1856" alt="image"
src="https://github.com/user-attachments/assets/38568108-8229-40b0-afc7-d1d5ddc817e1"
/>

Resume Lifecycle:
<img width="3696" height="1530" alt="image"
src="https://github.com/user-attachments/assets/cf934608-62fe-4fb8-bd2c-5e6e7a0af776"
/>



> It's a good idea to open an issue first for discussion.

- [ ] Tests pass
- [x] Appropriate changes to documentation are included in the PR
2026-05-21 18:09:07 -07:00
Benjamin Elder 6e57515fdf add otel collector in kind (#5)
* add open telemetry collector when running with kind

* update oversability docs with jaeger in kind
2026-05-19 21:52:39 -04:00
+7 af3c65088e Initial commit of Agent Substrate
This is the initial release of the Agent Substrate.

Agent substrate is a system built on top of Kubernetes which manages agent-like
workloads to achieve higher scale and efficiency than Kubernetes alone can
offer, with lower latency.  It builds on top of Kubernetes features like
Pods and Pod autoscaling, but takes the Kubernetes control-plane out of the
critical path to achieve lower latency.

It can run on any Kubernetes cluster and does not inhibit “regular” use of
Kubernetes in any way. Kubernetes provides the infrastructure provisioning and
management for all types of workloads, while Agent Substrate provides
agent-specific scheduling and control.

At its core, Agent Substrate maps a larger set of “actors” (applications such
as agents) onto a smaller set of ready “workers” (Kubernetes Pods), relying on
the fact that agent-like applications tend to be idle most of the time to
achieve heavy multiplexing.  It provides functionality to manage an actor’s
lifecycle (e.g. create/destroy, suspend/resume), to assign actors to workers in real
time, and to route incoming traffic to them.

Agent Substrate is intended to be a low-opinion system.  The workloads it
manages don't have to be literal AI agents, but those are the best example of
the kind of applications it is designed for.  It is not an SDK for building
agents, but rather a system for running them at scale.

Agent Substrate is currently in VERY early development.  It is not ready for
production use, and the APIs are almost guaranteed to change.  We are not
making any guarantees about backward compatibility at this stage, and
everything in this project may be changed.

Co-authored-by: Alex Bulankou <alexbu@google.com>
Co-authored-by: Benjamin Elder <bentheelder@google.com>
Co-authored-by: Bowei Du <bowei@google.com>
Co-authored-by: Dmitry Berkovich <dberkov@google.com>
Co-authored-by: Fabricio Voznika <fvoznika@google.com>
Co-authored-by: Francisco Cabrera <fclieutier@google.com>
Co-authored-by: Haven Xia <haoyuxia@google.com>
Co-authored-by: Julian Gutierrez Oschmann <juliangut@google.com>
Co-authored-by: Kevin Steuer <ksteuer@google.com>
Co-authored-by: Max Smythe <smythe@google.com>
Co-authored-by: Maya Wang <mymaya@google.com>
Co-authored-by: Michael Taufen <mtaufen@google.com>
Co-authored-by: Shruti Nair <shrutinair@google.com>
Co-authored-by: Taahir Ahmed <taahm@google.com>
Co-authored-by: Tim Hockin <thockin@google.com>
Co-authored-by: Zoe Zhao <zoezhao@google.com>
2026-05-19 16:57:14 -07:00