Agentic Sandbox v2026.5.6

Agentic Sandbox v2026.5.6

Released: 2026-05-20 Tag: `v2026.5.6` Previous: `v2026.5.5` (2026-05-20) Compare: `v2026.5.5...v2026.5.6`


What this release is

The A2A routing patch for VM-backed agents. One operator-visible bug fix.

In v2026.5.5 and earlier, agents provisioned via `provision-vm.sh` registered over gRPC and appeared in `/api/v1/agents` — but `/agents/{instance_id}/.well-known/agent-card.json` returned `instance.not_found`. The v2/A2A `InstanceRegistry` was only populated by the admin-v2 provisioning path (`admin_v2.rs`); the gRPC registration path didn't insert anything, so VM-backed agents were invisible to A2A routing.

v2026.5.6 wires the bridge: every gRPC `Registration` now inserts a matching `InstanceContext` into the executor `InstanceRegistry` using the same `instance_id` the v1 listing exposes. AgentCard discovery, the rest of the `/agents/*` surface, and `messages:send` dispatch now work for VM-provisioned agents the same way they work for Docker admin-v2 instances.

What changed since v2026.5.5

  • gRPC registration bridges into the v2/A2A `InstanceRegistry` (#317). `AgentServiceImpl` gained optional `instance_registry` + `signing_keys_dir` fields, wired in `main.rs` whenever the executor surface is mounted (always, when `TaskStore` is available). On every `Registration` message:
  • The canonical `instance_id` assigned by `ConnectedAgent::new` is read back from the v1 registry.
  • A new `bridge_register_instance` helper builds an `InstanceContext` with the per-instance signing key under `<secrets_dir>/instances/<instance_id>/signing.pem` (matches admin-v2 behavior — AgentCard JWS `kid` stays stable across server restarts).
  • Empty `loadout` in the Registration message → `RuntimeKind::Container` (legacy `POST /api/v1/containers` path). Non-empty `loadout` → `RuntimeKind::Vm` (cloud-init always materializes a loadout).
  • The bridge is idempotent on duplicate `instance_id`: admin-v2's pre-registration is preserved, and the cached AgentCard isn't thrown away when the same agent reconnects.
  • Disconnect cleanup. The disconnect path pulls `instance_id` from the v1 registry before unregistering, then removes the matching `InstanceContext`. Order matters — the v1 entry owns the id, so the lookup has to happen first.
  • Three regression tests in `management/src/grpc.rs::tests` exercise the bridge directly: `bridge_registers_vm_instance_with_loadout_kind`, `bridge_registers_container_instance_when_loadout_empty`, `bridge_is_idempotent_on_duplicate_instance_id`. Full suite 516 passed locally.

Reproduction the fix addresses

From the agent-ops M011 dual-substrate smoke against v2026.5.5:

$ images/qemu/provision-vm.sh agentops-m011-codex-smoke \
    --loadout profiles/codex-only.yaml \
    --ssh-key ~/.ssh/vm_ed25519.pub \
    --ip 192.168.122.230 \
    --management 192.168.122.1:8120 \
    --agentshare --network-mode full --wait-ready

# management log:
# Agent registered: agentops-m011-codex-smoke (192.168.122.230)

# /api/v1/agents — visible, instance_id assigned:
$ curl -s http://192.168.122.1:8122/api/v1/agents | jq '.[]'
{
  "id": "agentops-m011-codex-smoke",
  "instance_id": "019e4392-7e61-7582-8d91-936096a14c8a",
  ...
}

# A2A AgentCard discovery — 404 instance.not_found:
$ curl -s http://192.168.122.1:8122/agents/019e4392-7e61-7582-8d91-936096a14c8a/.well-known/agent-card.json
{
  "type": "instance.not_found",
  "title": "Instance not found",
  "status": 404,
  ...
}

After upgrade to v2026.5.6, the same `GET` returns the signed AgentCard with `runtime_kind: "vm"`, the loadout, host, and the instance_id propagated through.

Upgrade matrix

If you are…Do this
Provisioning VMs via `provision-vm.sh` and consuming A2AUpgrade — without this fix, AgentCard discovery 404s on VM-backed agents and orchestrators have no `messages:send` routing target.
Provisioning via admin-v2 only (Docker or QEMU through `POST /api/v2/admin/instances`)Upgrade is safe and brings the gRPC bridge for any future direct-gRPC connections, but admin-v2 was already wired correctly — no behavioral change.
Running a single-host local sandbox without A2A clientsUpgrade is safe; no behavioral change.
Building against the gRPC protoNo proto change — `AgentRegistration.instance_id` semantics unchanged.
Running CI in tag contextE2E gate from v2026.5.5 stays in place.

How to verify the upgrade

git fetch --tags origin
git checkout v2026.5.6
make build

# Versions
./management/target/release/agentic-mgmt --version    # 2026.5.6
./cli/target/release/sandboxctl --version             # 2026.5.6
./agent-rs/target/release/agent-client --version      # 2026.5.6

# Provision and validate A2A resolves
./images/qemu/provision-vm.sh smoke-a2a \
    --loadout profiles/agentic-dev.yaml \
    --ssh-key ~/.ssh/vm_ed25519.pub \
    --wait-ready

INSTANCE_ID=$(curl -s http://127.0.0.1:8122/api/v1/agents \
    | jq -r '.[] | select(.id=="smoke-a2a") | .instance_id')

curl -s -o /dev/null -w "%{http_code}\
" \
    "http://127.0.0.1:8122/agents/${INSTANCE_ID}/.well-known/agent-card.json"
# Expect: 200

./scripts/destroy-vm.sh --force smoke-a2a

Issues closed

  • #317 — VM-provisioned agents register in v1 registry but are not routable A2A instances.

Known limitations / deferred

Carried forward from v2026.5.5, unchanged:

  • #917 identity-across-reconnects (a Registration with a re-used `instance_id` is reused; a Registration with an empty `instance_id` synthesizes a fresh one per connection). The bridge follows the v1 registry's lead, so the longer-term identity story isn't blocked by this fix.
  • #256 / #257 WS bearer-auth-on-upgrade and full TLS wiring stay open.
  • #114 + children (Alpine + Proxmox provisioning) deferred to 2026-08-17 check date.

Full change log

See [`CHANGELOG.md` `[2026.5.6]`](../../CHANGELOG.md#202656-2026-05-20) for the Fixed / Documentation / Operator-notes / Issues-closed breakdown.

Tagging procedure

git tag -a v2026.5.6 -m "$(cat <<'EOF'
v2026.5.6 — A2A routing patch for VM-backed agents

One operator-visible bug fix. VM-provisioned agents register over gRPC and
appear in /api/v1/agents but /agents/{instance_id}/.well-known/agent-card.json
returned 404 instance.not_found because the v2/A2A InstanceRegistry was only
populated by the admin-v2 provision path. The gRPC Registration handler now
bridges every connecting agent into the executor InstanceRegistry using the
same instance_id the v1 listing exposes; idempotent on duplicates so admin-v2
pre-registration survives, with matching disconnect cleanup. Three regression
tests cover VM kind, Container fallback, and idempotency.

Closes #317.

Full notes: docs/releases/v2026.5.6.md and CHANGELOG.md [2026.5.6]
EOF
)"

git push origin v2026.5.6
git push github v2026.5.6