| Internet-Draft | EP Bounded Execution | August 2026 |
| Schrock | Expires 4 February 2027 | [Page] |
An authorization for one action does not by itself authorize an open-ended agent plan. This document defines an Experimental profile for a signed, finite, versioned directed acyclic graph of consequential action occurrences. The program binds a total retained-history ceiling. Each node binds an exact action or a pinned action-matching profile, an action- specific Trust Program, outcome-specific dependencies, an occurrence ceiling, and fixed charges against aggregate attempt budgets.¶
A conforming program-aware admission store evaluates reachability and budgets in the same linearizable transaction domain as the ordinary one-time execution right. It uses store-owned authorizer trust roots, clock, authenticated profile-match verification, and current program status; seals a deterministic execution-program resource into the AdmissionSnapshot; and fences the program's independent authorization digest against ordinary-path admission. The profile does not establish that natural-language intent was understood, that a plan is safe or lawful, that provider or effect evidence is true, or that every mutation path was mediated.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 4 February 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
Consequential agents often need authority for a bounded sequence of related actions. Requiring a new authorization ceremony for every action can be impractical, but treating a goal, generated plan, profile name, or signature as open-ended authority removes the boundary that a gate is supposed to enforce.¶
This document defines EP-BOUNDED-EXECUTION-PROGRAM-v1. An
authorizer signs one closed graph whose action occurrences, dependency
outcomes, node and total-history ceilings, attempt budgets, validity
interval, and supersession lineage are explicit. The runtime answers one narrow
question: is this exact occurrence reachable now under this exact signed
program, while all occurrence and attempt-budget limits remain
available?¶
The signed object and the runtime state machine are inseparable. A signed graph without shared state cannot prevent replay or concurrent over-reservation. A runtime ledger without a verified signed graph has no portable authority boundary.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
This profile adds cross-action reachability and aggregate attempt
accounting to an admission system. It does not replace the independent
authorization artifact bound by authorization_digest, the
action-specific evidence evaluation bound by
trust_program_digest, an AdmissionSnapshot's one-time execution
right, or any bounded capability receipt required for delegated scope
and resource authority.¶
A program authorizer decides which graph and limits to sign. An action verifier decides whether the evidence required for one action is satisfied. The program-aware admission store decides whether one occurrence is currently reachable and atomically reserves or consumes its runtime rights. An effect or outcome verifier remains responsible for claims about what happened after provider entry.¶
authorization_digest is an exact byte commitment used for
binding and exclusion. It does not by itself prove that a human
ceremony occurred, who participated, consent, comprehension,
presentation integrity, or legal authority. Those claims require their
own authenticated evidence and relying-party acceptance rules.¶
This profile is complementary to software-supply-chain frameworks such as in-toto. In-toto verifies signed layouts and signed evidence that designated functionaries performed supply-chain steps. This profile instead governs live consequence admission: it controls a one-time execution right under current authorization, occurrence ceilings, aggregate attempt budgets, post-entry uncertainty, and authenticated reconciliation. It does not replace in-toto or claim that no other system can express ordered work.¶
proof member omitted.¶
COMMITTED or PROVEN_NOT_COMMITTED.¶
ACTIVE, SUSPENDED, or
REVOKED observation for the exact program version and digest.¶
The unsigned construction input is a closed I-JSON object [RFC7493] containing exactly the following members:¶
{
"program_id": "program:production-remediation:01",
"tenant_id": "tenant:example",
"version": 1,
"subject_id": "agent:operations:01",
"audience": "gate:production:01",
"objective_digest": "sha256:<64 lowercase hexadecimal digits>",
"authorization_digest": "sha256:<64 lowercase hexadecimal digits>",
"presentation_digest": "sha256:<64 lowercase hexadecimal digits>",
"supersedes_program_digest": null,
"issued_at": "2026-07-30T19:55:00.000Z",
"valid_from": "2026-07-30T20:00:00.000Z",
"expires_at": "2026-07-30T21:00:00.000Z",
"max_total_occurrences": 64,
"max_concurrent_effects": 4,
"budgets": [
{ "budget_id": "attempts", "unit": "attempt", "limit": 3 }
],
"nodes": [ "<one or more nodes as defined below>" ]
}
¶
program_id, tenant_id, subject_id, and
audience are nonempty identifiers. An identifier MUST match:¶
^[A-Za-z0-9][A-Za-z0-9:_.@/+\-]{0,511}$
¶
A digest in this document is the string sha256: followed by
exactly 64 lowercase hexadecimal digits. Version and numeric limits MUST
be positive I-JSON safe integers. Version 1 MUST have a null
supersedes_program_digest; a later version MUST contain the exact
predecessor program digest.¶
objective_digest binds authorizer-selected objective bytes. It
does not prove that natural-language intent was understood or correctly
compiled. authorization_digest binds the independently verified
authorization evidence on which the program relies.
presentation_digest binds the approval or presentation material
selected by the authorizer; it does not prove display integrity, human
comprehension, or informed consent.¶
The three times use the RFC 3339 [RFC3339] date-time
production restricted to UTC with a trailing Z. They MUST satisfy
issued_at <= valid_from < expires_at. Expiration is
exclusive.¶
max_total_occurrences is REQUIRED and MUST be a positive safe
integer no greater than 1000000. It limits all retained occurrence
records for the program, including occurrences later released before
provider entry. Omission is a schema error.¶
max_concurrent_effects is REQUIRED and MUST be a positive
safe integer no greater than 1000000. It limits the number of occurrences
for this program that can be in INVOKING or
INDETERMINATE. Reservation does not consume this ceiling;
provider entry does. Omission is a schema error.¶
budgets contains between 1 and 64 closed objects. Each has
exactly budget_id, unit, and limit.
budget_id and unit are identifiers. Budget identifiers
MUST be unique. budget_id, not unit, identifies the
independent accounting dimension. Multiple budget dimensions MAY use
the same unit label without sharing a limit or accounting
state. The unit is a signed descriptive label and MUST NOT be used as
an alias key. limit MUST be a positive safe integer no greater
than 9007199254740991.¶
A budget is an attempt-accounting dimension, not proof of economic settlement or resource availability. A node's fixed charge is consumed at provider entry even if the later result is indeterminate.¶
nodes contains between 1 and 256 closed node objects. Node
identifiers MUST be unique. The complete dependency graph MUST be
acyclic and contain at least one root.¶
{
"node_id": "remediate",
"action": {
"mode": "profile",
"profile_id": "profile:terraform-reviewed-plan",
"profile_digest": "sha256:<64 lowercase hexadecimal digits>"
},
"trust_program_digest": "sha256:<64 lowercase hexadecimal digits>",
"depends_on": [
{ "node_id": "inspect", "outcomes": ["COMMITTED"] }
],
"max_occurrences": 1,
"charges": [
{ "budget_id": "attempts", "amount": 1 }
]
}
¶
trust_program_digest pins the action-specific Trust Program
that MUST govern the corresponding AdmissionSnapshot.
max_occurrences MUST be a positive safe integer no greater than
1000000.¶
depends_on contains at most 64 unique predecessor node
identifiers. Each dependency contains one or both unique strings
COMMITTED and PROVEN_NOT_COMMITTED. Every predecessor
MUST exist. Self-dependencies and cycles MUST be refused. Reserved,
released, invoking, expired, and indeterminate states are not dependency
outcomes.¶
charges contains between 1 and 64 objects with unique budget
identifiers. Every identifier MUST name a declared budget. Each
amount MUST be positive and MUST NOT exceed that budget's total
program limit.¶
A node's action member has exactly one of two closed
shapes:¶
{ "mode": "exact", "caid": "caid:1:...",
"action_digest": "sha256:<64 lowercase hexadecimal digits>" }
¶
{ "mode": "profile", "profile_id": "profile:...",
"profile_digest": "sha256:<64 lowercase hexadecimal digits>" }
¶
In exact mode, both the Canonical Action Identifier (CAID) and action digest MUST exactly equal the AdmissionSnapshot values. This version accepts the following closed CAID syntax, using the core ABNF rules from [RFC5234]:¶
caid = "caid:1:" action-name "." action-version
":jcs-sha256:" digest43
action-name = component *("." component)
component = LCALPHA *(LCALPHA / DIGIT / "-")
action-version = %x31-39 *DIGIT
digest43 = 43base64url-char
base64url-char = ALPHA / DIGIT / "-" / "_"
LCALPHA = %x61-7A
¶
Action-name interpretation is defined by the selected CAID profile; this document does not create a CAID registry.¶
Profile mode does not make profile_id self-authenticating.
A caller-supplied MATCH flag or result object is not evidence
and MUST NOT satisfy a node. The caller instead supplies an opaque
evidence artifact to the store's configured authenticated action-match
verifier. That verifier MUST authenticate the artifact under its pinned
evidence profile and return a closed valid: true,
result: MATCH result that exactly binds tenant, profile ID and
digest, program subject, operation ID, CAID, action digest, verifier ID,
evidence payload digest, evidence trust-configuration digest, trust
epoch, and AdmissionSnapshot trust-configuration digest.¶
The AdmissionSnapshot MUST already contain that evidence payload in
its singleton aeb input. The input subject MUST equal the
program subject, and its profile digest, verifier identifier, payload
digest, and trust-configuration digest MUST equal the authenticated
result. Missing evidence, a missing configured verifier, verifier
failure, an open result, or any substitution MUST fail closed.¶
Unknown members, omitted required members, duplicate identifiers, duplicate dependency outcomes, malformed values, non-safe integers, unknown outcomes, missing predecessors, and cyclic graphs MUST be refused at every signed-object boundary. Implementations MUST NOT silently discard unknown members before signature or schema validation.¶
Before signing, an implementation MUST validate the complete construction input and then normalize it as follows:¶
budget_id.¶
node_id.¶
node_id.¶
budget_id.¶
The signer adds the fixed version, claim boundary, and issuer:¶
{
"@version": "EP-BOUNDED-EXECUTION-PROGRAM-v1",
"<normalized program members>": "...",
"claim_boundary": "<CLAIM_BOUNDARY>",
"issuer": { "id": "customer:example", "key_id": "key:example" }
}
¶
In that example, CLAIM_BOUNDARY is the concatenation, with no
intervening octets, of the following two ASCII strings:¶
"typed_reachability_attempt_budget_and_effect_concurrency_not_" || "intent_safety_effect_truth_or_complete_mediation"¶
The || notation in this display means byte concatenation; it
is not part of the member value.¶
Let body_jcs be the UTF-8 encoding of the JSON Canonicalization
Scheme (JCS) [RFC8785] representation of that complete
body. The signer computes:¶
body_digest = "sha256:" || lowercase_hex(SHA-256(body_jcs))
signature_input = UTF8("EP-BOUNDED-EXECUTION-PROGRAM-v1")
|| 0x00 || body_jcs
signature = Ed25519-Sign(authorizer_private_key, signature_input)
¶
The signer attaches one closed proof object:¶
{
"algorithm": "Ed25519",
"key_id": "key:example",
"body_digest": "sha256:<64 lowercase hexadecimal digits>",
"signature_b64u": "<canonical unpadded base64url>"
}
¶
proof.key_id MUST equal issuer.key_id. The signature
uses Ed25519 [RFC8032]. The signature value uses the URL-
and filename-safe Base64 alphabet without padding
[RFC4648] and MUST decode to exactly 64 octets.¶
The program_digest is body_digest: the prefixed
lowercase SHA-256 digest of the JCS body with proof omitted. It
identifies the authorizer, program, and every signed boundary. It is not
the digest of the proof-bearing artifact.¶
The program-aware store MUST own its program-authorizer verification
policy and clock. The registration caller MUST NOT nominate trusted keys,
expected authorizer identity, verification time, key role, or key status.
The store policy binds each key identifier to an issuer identifier,
canonical Ed25519 public key, the exact role
program_authorizer, and one of ACTIVE,
SUSPENDED, or REVOKED. Only a pin whose role is
program_authorizer and whose key status is ACTIVE is
eligible to register or supersede a v1 program.¶
The artifact's issuer.key_id can select only among those
store-owned eligible pins; it cannot create or alter a trust root. The
store derives the expected authorizer identity from the selected pin and
obtains verification time from its own clock.¶
The caller supplies one closed relying-party context containing exactly:¶
Unknown or caller-added trust and clock members MUST be refused as an
invalid context. The store MUST validate the proof envelope, recompute
the body digest, require the exact pinned issuer and key, parse the key as
Ed25519, and verify the signature over the domain-separated canonical
body. All caller context values MUST exactly equal the signed values.
Acceptance is valid only while
valid_from <= store_now < expires_at. A valid signature over an
invalid, noncanonical, open-shaped, context-substituted, inactive-key, or
time-invalid program MUST be refused.¶
The store MUST obtain current program status from its configured
authoritative source at reservation and again immediately before
provider entry. The caller MUST NOT supply or select this source or its
observation. A closed EP-BOUNDED-EXECUTION-PROGRAM-STATUS-v1
observation contains the exact tenant ID, program ID, program digest,
version, status, nonnegative sequence, observation time, and expiry.¶
A program-capable store without a configured authoritative status
source MUST fail closed with
program_status_indeterminate; locally initialized
ACTIVE state is not current-status evidence. The validation
instant MUST be sampled after the source returns. Expiry and maximum
observation age MUST be evaluated against that post-response instant,
so a response that becomes stale while the source is queried cannot
authorize reservation or provider entry.¶
Status is one of ACTIVE, SUSPENDED, or
REVOKED. Only a current ACTIVE observation permits
reservation or begin. SUSPENDED refuses with
program_suspended. REVOKED refuses with
program_revoked and is sticky: a later observation MUST NOT
reopen that runtime.¶
The store MUST fail closed with
program_status_indeterminate when the source is unavailable or
throws; the observation is missing, malformed, open-shaped, future-
dated, stale, or expired; any program identity differs; the sequence
regresses; or a repeated sequence conflicts with the previously
recorded status or times. The maximum observation age is store policy
and MUST NOT be caller-selectable.¶
A status, program-validity, or status-currentness refusal at reserve
creates no occurrence or admission state. The same refusal at begin,
while the occurrence is still pre-entry RESERVED, MUST
atomically release the ordinary execution right and resources, the
node occurrence capacity, and every reserved budget charge, and mark
the occurrence RELEASED. Its occurrence identifier and total-
history count remain fenced. Work already INVOKING or
INDETERMINATE remains reconcilable.¶
A program occurrence MUST be represented inside its immutable
AdmissionSnapshot by exactly one resource whose kind is
execution_program. The resource is derived from this closed
binding object:¶
{
"@version": "EP-BOUNDED-EXECUTION-PROGRAM-ADMISSION-BINDING-v1",
"tenant_id": "tenant:example",
"program_digest": "sha256:<64 lowercase hexadecimal digits>",
"node_id": "remediate",
"occurrence_id": "occurrence:remediate:01",
"expires_at": "2026-07-30T20:10:00.000Z"
}
¶
The resource fields are computed exactly as follows:¶
identity_tuple = [tenant_id, program_digest, node_id, occurrence_id]
identity_domain =
"EP-BOUNDED-EXECUTION-PROGRAM-ADMISSION-" ||
"BINDING-v1:IDENTITY"
identity_input = UTF8(identity_domain) || 0x00 ||
UTF8(JCS(identity_tuple))
identity_digest =
"sha256:" || lowercase_hex(SHA-256(identity_input))
kind = "execution_program"
resource_id = "execution-program:" || identity_digest
reservation_id = "execution-program-reservation:" ||
identity_digest
digest_input =
UTF8("EP-BOUNDED-EXECUTION-PROGRAM-ADMISSION-BINDING-v1:DIGEST") ||
0x00 || UTF8(JCS(binding_object))
digest = "sha256:" || lowercase_hex(SHA-256(digest_input))
expires_at = binding_object.expires_at
¶
The binding's tenant_id, program_digest,
node_id, and occurrence_id MUST equal the values being
reserved. Its expires_at MUST equal the AdmissionSnapshot expiry.
The resource participates in the AdmissionSnapshot's normal resource
sorting and snapshot-digest computation.¶
The identity digest is over a structured JCS array, not a delimiter- joined string. The resulting resource and reservation identifiers are fixed-length digest keys. Implementations MUST NOT substitute raw caller- controlled identifiers, ambiguous delimiter concatenation, or another tuple encoding.¶
If the caller supplies mutable AdmissionSnapshot input without this resource, the program-aware store MUST add the resource and then compute the snapshot digest. If the caller supplies a precomputed immutable AdmissionSnapshot, the store MUST accept it only when it already contains exactly the expected resource. A snapshot with no binding, more than one execution-program resource, or a nonidentical binding MUST be refused with no state change.¶
Before adding or accepting the binding, the store MUST also require:
the candidate-manifest subject to equal the signed
subject_id; the authorization input payload digest to equal the
signed authorization_digest; the AdmissionSnapshot authorization
policy digest to equal the node's trust_program_digest; and the
exact or profile action match defined in Section 3.3.¶
The normalized AdmissionSnapshot expiry MUST be no later than the
signed program expiry. A later admission expiry MUST refuse with
program_expiration_mismatch before any occurrence, budget,
resource, operation-head, or journal state is created. Equality is
permitted because both expirations are exclusive.¶
Registration of an accepted version 1 program creates one active
runtime state. It records store-clock status metadata, initializes
total_occurrences to zero, initializes reserved and consumed
values to zero for every independent budget_id while retaining
each signed unit label, and contains no occurrences.¶
The program state, occurrence state, authorization-digest fence, AdmissionSnapshot, ordinary resource reservations, and one-time execution right MUST share one linearizable transaction domain. A compensating sequence across independent stores is not atomic and does not conform to this profile.¶
RESERVED -> INVOKING -> COMMITTED
\-> PROVEN_NOT_COMMITTED
\-> INDETERMINATE -> COMMITTED
\-> PROVEN_NOT_COMMITTED
RESERVED -> RELEASED
¶
A program-aware reservation MUST atomically verify all of the following:¶
ACTIVE status, and authorization-
digest fence;¶
total_occurrences < max_total_occurrences;¶
reserved + consumed + amount <= limit;¶
On success, the store permanently fences the occurrence identifier,
creates a RESERVED occurrence, increments
total_occurrences and the node's non-released count, increments
each named budget dimension's reserved value, and reserves the ordinary
admission and all of its resources. A refusal MUST make no state change
except that accepting a newer authoritative status observation updates
the program's status metadata before returning its corresponding
refusal.¶
An occurrence in RELEASED no longer counts against the
node's occurrence ceiling, but its occurrence identifier remains
fenced and MUST NOT be reused.¶
total_occurrences is monotonic for one program digest. It
increments exactly once for every successful occurrence reservation and
MUST NOT decrement when an occurrence is released, expires before
provider entry, begins, reaches a terminal outcome, or is reconciled.
The store MUST refuse further reservation with
program_total_occurrence_exhausted when it reaches the signed
max_total_occurrences.¶
The total ceiling bounds retained history, not concurrent work. The
per-node max_occurrences ceiling separately counts non-released
occurrences and restores capacity on pre-entry release. A released
occurrence therefore restores node and budget capacity but never total-
history capacity.¶
Occurrence identifiers remain permanently fenced within the program. A conforming transaction store SHOULD maintain atomic per-node counts and per-node terminal-outcome counts so reservation and dependency decisions do not require an unbounded scan. Those indexes MUST reconcile exactly with retained occurrence records and MUST be updated in the same transaction as their source transition.¶
The ordinary begin, release, and expiry paths MUST refuse a
program-linked admission with program_required. Conversely, a
program-aware begin, release, or expiry path MUST refuse an admission
that lacks the exact execution-program association.¶
Program-aware begin MUST recheck store-authoritative program status,
program validity, ordinary admission currentness, and the signed
concurrent-effect ceiling. Immediately before releasing the invocation
capability, the store MUST count every occurrence for this exact
program in INVOKING or INDETERMINATE. If the count is
greater than or equal to max_concurrent_effects, begin MUST
refuse with program_concurrency_exhausted without consuming
the execution right or moving any budget charge.¶
Otherwise begin atomically consumes the ordinary one-time execution
right, moves each node charge from reserved to consumed, and sets the
occurrence to INVOKING before releasing an invocation
capability. If program
status is suspended, revoked, stale, unavailable, malformed, or expired,
or if ordinary currentness fails before provider entry, the store MUST
atomically release the ordinary reservation and resources, node
capacity, and reserved budget charges. The occurrence remains in total
history as RELEASED.¶
Once begin succeeds, provider refusal, timeout, or uncertainty MUST NOT restore the occurrence or its attempt-budget charges. This rule prevents a retry from converting uncertainty after provider entry into unbounded authority.¶
Program-aware release and expiry are permitted only from
RESERVED. They decrement every reserved node charge, release
the ordinary execution right and resources, and set the occurrence to
RELEASED. Release after begin MUST be refused because the
execution right and charges are already consumed.¶
COMMITTED and PROVEN_NOT_COMMITTED are terminal
provider outcomes. INDETERMINATE records uncertainty after
provider entry, retains all consumed charges, and continues to occupy
one concurrent-effect slot. Reconciliation MAY move an indeterminate
occurrence to either terminal outcome and then releases that slot.
Reconciliation does not itself prove when the provider event occurred.¶
A dependency is satisfied only when at least one occurrence of each
named predecessor has a terminal state explicitly listed by that
dependency. Terminality alone is insufficient:
PROVEN_NOT_COMMITTED does not satisfy a dependency that lists
only COMMITTED.¶
DIVERGED, if represented by an effect-reconciliation layer,
is an observed-effect relation rather than a provider outcome. It MUST
NOT rewrite occurrence state, historical authorization, budgets, or
reachability and does not identify why an effect differed.¶
Programs are immutable. Replanning creates a newly signed and
independently accepted version. The predecessor MUST be the active head.
A successor MUST bind its exact program digest, have exactly
predecessor.version + 1, and preserve the predecessor's tenant ID,
program ID, subject ID, audience, objective digest, presentation digest,
and program-authorizer identity. These are frozen identity and intent
bindings for v1 supersession.¶
The successor MUST carry a distinct authorization digest that differs from the predecessor and has never previously been registered in the store's authorization-owner domain. The caller MUST supply that fresh digest in the closed relying-party registration context. Reuse, a skipped version, changed frozen binding, changed authorizer, wrong predecessor, or an already-owned authorization digest MUST fail closed.¶
Any predecessor occurrence still in RESERVED MUST block
supersession. On successful supersession, the store atomically marks the
predecessor SUPERSEDED, installs the successor as the active
head, and binds the successor's authorization digest into the ordinary-
path fence. The predecessor then refuses new reservations and new
invocation starts.¶
Already invoking or indeterminate predecessor work remains
reconcilable. The successor starts with zero reserved and consumed
budgets, total_occurrences zero, fresh node and terminal indexes,
and no occurrences. Budget, occurrence, evidence, and terminal state MUST
NOT silently carry forward. A successor can depend on earlier effects
only through separately verified evidence explicitly admitted by the
successor's own action-specific Trust Program.¶
Reservation and registration refusals are fail-closed and MUST NOT create occurrence, budget, admission, resource, operation-head, journal, or execution-right state. A store MAY retain a newer authenticated program-status observation. A begin refusal caused by program status, program expiry, or admission currentness deliberately performs the atomic pre-entry release defined in Section 5.2. Implementations MAY expose a more detailed local error vocabulary. The following reasons define interoperable semantic classes used by the reference profile:¶
| Reason | Meaning |
|---|---|
context_binding_required
|
Mandatory relying-party verification context is absent. |
program_required
|
An ordinary path attempted to use program-fenced authority or a linked admission. |
program_binding_mismatch
|
A signed, authorization, action, Trust Program, subject, or AdmissionSnapshot binding differs. |
program_node_unreachable
|
At least one outcome-specific dependency is unsatisfied. |
program_occurrence_conflict
|
The occurrence identifier was already fenced. |
program_occurrence_exhausted
|
The node occurrence ceiling is unavailable. |
program_total_occurrence_exhausted
|
The retained total-history ceiling is exhausted. |
program_budget_exhausted
|
At least one aggregate attempt budget is unavailable. |
program_concurrency_exhausted
|
The signed concurrent-effect ceiling is occupied. |
program_expiration_mismatch
|
The admission expires after the program. |
program_suspended
|
The authoritative current status is suspended. |
program_revoked
|
The authoritative current status is revoked. |
program_status_indeterminate
|
Current status is unavailable, stale, malformed, expired, or conflicting. |
program_reserved_work_exists
|
Reserved predecessor work blocks supersession. |
program_supersession_invalid
|
Version, predecessor, authorizer, frozen identity or intent, or fresh authorization requirements differ. |
The principal threats are open-ended authority, graph substitution, action substitution, profile-name trust, authorization reuse, ordinary- path bypass, replay, reserve-release history exhaustion, concurrent over- reservation, delimiter aliasing, stale or caller-selected status, budget restoration after provider entry, and unsafe retry after an indeterminate outcome. Closed signed shapes, store-owned trust and clock, authenticated profile evidence, current status, total-history and occurrence fences, structured resource keys, the authorization-digest fence, and one linearizable state domain address those threats at the admission boundary.¶
Private signing keys and store-owned out-of-band key pins require lifecycle, rotation, compromise, role, suspension, revocation, and audit controls. A caller MUST NOT be able to extend the trust-root set or choose the verification clock. A signature establishes that an eligible pinned key signed canonical bytes. It does not establish that the key holder understood the objective, that a presentation was faithful, that a profile is safe, or that the selected limits are appropriate.¶
Profile matching is security-critical. The store MUST configure the
authenticated verifier and pin both the profile identifier and digest.
Free-form model assertions, caller-authored MATCH objects, an
unverified profile name, or evidence not sealed into the singleton AEB
input MUST NOT satisfy a node.¶
The total-history ceiling intentionally does not restore capacity on
release. This bounds retained state but also lets an authorized requester
consume the signed history allowance through repeated reserve-release
cycles. Authorizers SHOULD choose the ceiling and admission rate controls
for that denial-of-service exposure; implementations MUST NOT evade it by
deleting records or decrementing total_occurrences.¶
The authorization-digest fence closes bypass only within its shared transaction and enforcement domain. A deployment with another mutation credential, provider path, replica, or store outside that domain does not have complete mediation. Such a deployment MUST NOT claim program-wide enforcement merely because the signed object verifies.¶
INDETERMINATE is material uncertainty, not failure and not
permission to retry. It continues to occupy a concurrent-effect slot
until authenticated reconciliation records a terminal outcome.
Reconciliation can change the recorded provider outcome but cannot
reconstruct event order from evidence that does not establish it.¶
Programs and AdmissionSnapshots can reveal objectives, tenant and subject identifiers, action relationships, provider operations, timing, budgets, and incident-response structure. Implementations SHOULD use pseudonymous identifiers where accountability permits, minimize program duration and graph detail, disclose digests instead of underlying evidence when appropriate, and enforce access controls and retention periods for runtime records.¶
Digesting low-entropy or guessable material does not make it secret. Sensitive objective, authorization, and presentation material SHOULD use confidentiality and selective-disclosure controls outside this profile.¶
An Apache-2.0 same-team reference implementation defines closed program construction, normalization, Ed25519 signing, verification, program digests, mandatory total-history fencing, structured deterministic AdmissionSnapshot resource binding, store-owned program trust and clock, authenticated action-match verification, current-status processing, in-memory and PostgreSQL program-aware admission surfaces, and language-neutral syntax and runtime vectors. The repository also contains bounded state-machine analysis.¶
These artifacts are implementation and regression evidence for this Experimental profile. They are not evidence of an independent implementation, cross-vendor interoperability, a durable production deployment, complete mediation, unbounded formal proof, standardization, certification, or legal effect.¶
The separate signed EP-BOUNDED-EXECUTION-REPORT-v1 artifact can
authenticate a relying-party-generated snapshot of the runtime state and
retained occurrence inventory for one verified program. It is not an
authorization and is not required to execute this protocol.¶
That report's boundary is Gate-recorded program occurrences only. It does not prove external effect truth, event chronology, program safety, complete mediation of mutation paths, the absence of actions performed outside Gate, or that an action was "executed outside the plan". An outside-plan claim requires a separately signed external inventory root with its own population-completeness and capture-topology boundary.¶
This document has no IANA actions. Protocol identifiers, resource-kind strings, refusal reasons, and action-profile identifiers in this revision are closed by the profile and are not IANA registries. A future revision can request registries or media types after implementation and interoperability experience justifies them.¶
Verification can establish that a pinned authorizer signed one canonical program. A conforming runtime can establish that it admitted or refused an occurrence according to that program's typed reachability, current-status, total-history, node-occurrence, attempt-budget, AdmissionSnapshot-binding, and supersession rules within one transaction domain, including the signed provider-entry concurrency ceiling.¶
It does not establish that natural-language intent was understood or correctly compiled; that an action profile is sound; that a plan is safe, lawful, optimal, or free of prompt injection; that provider evidence, observed effects, or production event chronology are true; that every mutation path was mediated; that no action occurred outside Gate or the program; or why an observed effect diverged.¶