Protected Execution Boundaries

Three distinct authority properties compose ADK’s execution-governance claim. It is important not to conflate them:

Property

Question it answers

Established by

Logical authority

What action is authorized?

PR #1350–#1352 (execution decision model)

Execution faithfulness

Did the adapter enact exactly the authorized action?

PR #1350–#1352 (enactment receipts)

Execution exclusivity

Can no other path execute the action without ADK?

Phase 4 (this document)

PRs #1350–#1352 established logical authority and faithfulness: ADK decides the one authorized action, and the enactment receipt proves the governed adapter enacted exactly it. But faithfulness says nothing about alternate paths — a second publisher, a credential holder, another process, a DDS participant, a service account, or an API client that could execute the governed action without passing through ADK at all. Phase 4 closes that gap with the Protected Execution Boundary (PEB).

The model

Untrusted Producer → ADK Decision Runtime → Authorized Action → Governed Adapter → Protected Boundary → Target

A Protected Execution Boundary is a signed-manifest declaration that a class of actions may be executed only through a named enforcement adapter reaching a protected target, and that the proposer has no direct path to that target. ADK does not build the boundary — it declares the expected boundary, validates it through a domain boundary provider, binds each decision + receipt to it, fails closed when it cannot be validated, and audits its state. The external mechanism (SROS 2 permissions, Kubernetes RBAC, Unix socket ownership) is the provider’s domain; ADK remains an execution-governance runtime, not a policy controller, DDS implementation, or credential vault.

Domain-neutral by construction

The core (runtime/executionboundary, the manifest block, the decision/receipt binding) knows nothing about DDS domains, SROS 2 XML, RoleBindings, or socket modes. A Boundary Provider owns all of that. ROS 2 / SROS 2 is the first concrete provider; Kubernetes RBAC and Unix-socket providers prove the model is not robotics-specific. The generic runtime imports no provider package (INV-PEB-4).

Manifest: execution_boundaries

Each boundary binds action_kinds to an adapter{id,identity}, a target{kind,resource[,schema,namespace]}, a protection{provider, provider_version,configuration}, and requirements (exclusivity, proposer- blocked, preflight_validation: required|advisory|disabled, runtime_attestation, fail-closed posture). A protected action kind maps to exactly one boundary (INV-PEB-1). Declared at schema v1.8; a pre-1.8 runtime that can’t enforce it refuses the bundle rather than silently ignoring the exclusivity guarantee.

Boundary provider interface

executionboundary.Provider (ProviderID/Version/Supports(targetKind)/ ValidateConfiguration/Preflight/Attest) is held in an explicit, injected Registry (not global init()), so the runtime’s dependencies are explicit and tests use isolated registries. Preflight returns a BoundaryValidationResult whose Valid/Exclusive/ProposerBlocked/AdapterAuthorized flags the runtime checks against the boundary’s requirements — and a provider must set them from positive evidence; silence is not success (INV-PEB-5).

Fail-closed at three points

  1. Activation preflight — at bundle startup / hot-swap, every required boundary is validated; an unresolvable provider, unsupported target kind, malformed configuration, or unmet exclusivity/proposer/adapter guarantee refuses the bundle and keeps the prior one live (unknown = failure, error = failure, incomplete evidence = failure). advisory records findings without blocking; disabled skips.

  2. Decision binding — a decision on a protected action kind stamps execution_boundary_id, provider id/version, expected_adapter_identity, target, and boundary_state_at_decision on the audit frame (INV-PEB-9).

  3. Receipt binding — an enactment receipt from an enforcer other than the declared adapter identity is a deviation: a faithful action enacted through the wrong boundary is still a deviation (INV-PEB-7/8).

Runtime attestation & health

Preflight proves the boundary at activation, but permissions and identities can drift afterward. Each boundary is baseline-attested when its manifest installs, then re-attested by its declared runtime_attestation mode: periodic (a background loop at the shortest declared interval) or per_enactment (re-checked immediately before each protected decision). A required boundary that becomes — or cannot be proven — healthy is marked unhealthy: the runtime stops authorizing its protected action kind (execution-boundary: unhealthy), emits a high-severity autonomy.boundary_health event, and resumes only after a successful re-attestation (INV-PEB-6). Health is surfaced at GET /v1/boundaries and via autonomy runtime boundaries (human + JSON).

Each failure class has a distinct reason code so a boundary problem is never confused with a policy deny, an enactment deviation, or an unverifiable receipt. They share the execution-boundary: layer prefix (the repo-wide <layer>: <subreason> wire shape operators + SIEM grep on) with a distinguishing subreason: missing, invalid, unhealthy, attestation_stale, identity_mismatch, target_mismatch, bypass_detected, provider_unavailable, receipt_mismatch.

Authorized-action schema validation & resolved-binding audit

Deciding which action is authorized is not enough — the authorized action must also be well-formed before it reaches an adapter. Every authorized action passes through an injected SchemaValidators registry (runtime/actionschema) that runs each validator claiming the action’s (kind, schema) pair. A universal, domain-neutral floor (builtin.finite) always runs: it rejects non-finite numbers (a NaN/±Inf velocity or replica count) and non-serializable values, recursively — the safety net a buggy provider or policy cannot skip.

Validation is symmetric (INV-PEB-11): it applies equally to a provider-generated authorized action (validated against the transform’s declared output_schema) and a policy-direct authorized_action replacement. A trusted provider’s output is not exempt. A validation failure fails closed — the replace denies and no authorized action rides the response.

The runtime then stamps the resolved binding on the decision frame for deterministic investigation and replay: the resolved provider id/version, action kind, input/output schema, the policy’s requested inputs versus the constraint-capped effective inputs, and the ids of the schema validators that ran. A policy-direct action records the action kind and validators with no provider fields. This closes the loop between “what the policy asked for” and “what the runtime actually authorized” (INV-PEB-9).

Invariants

  • INV-PEB-1 — Every action requiring protected execution resolves to exactly one signed boundary.

  • INV-PEB-2 — Only the declared enforcement principal may invoke the protected target.

  • INV-PEB-3 — The proposing principal must not possess equivalent direct execution authority.

  • INV-PEB-4 — Boundary providers are domain-specific; the generic runtime knows no provider internals.

  • INV-PEB-5 — A required boundary that cannot be validated is unhealthy, not implicitly trusted.

  • INV-PEB-6 — An unhealthy or stale boundary cannot authorize executable actions.

  • INV-PEB-7 — An enactment receipt must match the declared adapter, target, boundary, and authorization digest.

  • INV-PEB-8 — A faithful action executed through the wrong boundary is still a deviation.

  • INV-PEB-9 — Boundary identity, provider version, validation result, and attestation state are audited.

  • INV-PEB-10 — No decision verdict or transformation can bypass the protected execution boundary.

  • INV-PEB-11 — Authorized actions from both direct policy replacement and provider transformation are schema-validated.

  • INV-PEB-12 — Unknown providers, schemas, codecs, boundaries, identities, targets, or validation states fail closed.

The INV-EDM-* invariants (execution decision model) are preserved unchanged.

Rollout

Phase 4 lands as a sequence of PRs on the epic: this core (manifest + provider interface + registry + activation preflight + decision/receipt binding); then the concrete providers — builtin.sros2 (ROS 2 / DDS), builtin.kubernetes_rbac, builtin.unix_permissions; then runtime attestation + boundary health + diagnostics; then authorized-action schema validation, resolved-binding audit, and the codec/registry hardening. Provider-specific bring-up + validation lives in the *-protected-execution runbooks.