intent
field, see Security for what this closed.
Stage-by-stage status
What actually runs when you call POST /execute today
All eleven stages run, in order, on every request. Stage 8’s connector enforcement is real
only for the connectors actually wired into createConnectorRegistry.ts, an action with no
matching connector fails closed with 503 CONNECTOR_NOT_REGISTERED before anything is released, it does not
silently skip stages 7-8. See The gateway for the mechanism and
Quickstart for a live run through the full pipeline. Stage 3 (signal/intent
binding) is the one stage that can reject a transaction before stage 4 (policy evaluation)
ever runs a single rule, see Security for why that ordering matters.
One request, class by class
The same pipeline, traced through the classes that run it for onePOST /execute.
- Route.
packages/api/src/routes/execute.tscallsExecutionTrustApplication.execute()(packages/runtime/src/ExecutionTrustApplication.ts). The application is built once at startup byRuntimeFactory.create()and wired inpackages/api/src/application.ts. - Accept.
BusinessTransactionService.accept()stores the transaction as received, before any policy work. - Decide.
Runtime.execute()callsRuntimeEngine.execute()(packages/runtime/src/RuntimeEngine.ts), which in order: loads the policy (PolicyRouter.load), hashes its content, checks the policy’s approval record when policy governance is enforced (matchedRuleId: "policy-execution-verification-violation"), checks the capability is paired with its bound policy (CapabilityPolicyBinder,"capability-policy-binding-violation"), checks signals against the intent (SignalIntentBinder,"signal-intent-binding-violation"), and only then evaluates rules (PolicyEngine.evaluate). Each earlier check that fails becomes an ordinaryREJECTwith no rule evaluated. - Verify signals against real state. Only for a provisional
APPROVE, the configuredSignalStateVerifierruns. In production it is aCompositeSignalStateVerifierof the HubSpot verifier and theApprovalSignalVerifier(the policy’sapprovalSignals). A mismatch overrides the decision toREJECT("signal-state-verification-violation"). - Refuse or authorize. Any decision that is not
APPROVEDgets a signed Refusal Record (RFC-0021), thenExecutionGate.enforce()throws. An approved decision is signed byRuntimeAuthorizationSigner: the frozenExecutableContent, the policy content hash, the signals hash and a TTL. - Before release. The signing readiness check (G-52) proves the evidence signing path
works, and
ExecutionIntentService.prepare()signs and stores an Execution Intent (ADR-0012). If either fails, the caller gets 503 and nothing is released. - Runtime pipeline.
RuntimePipelinerunsTrustChainValidationComponent, thenExecutionComponent, which builds theExecutionRequestand calls the injectedExecutionSystem. In production that is alwaysExecutionGateway, bound inpackages/api/src/bootstrap/createExecutionSystem.ts. This is the boundary between runtime and gateway. - Gateway.
ExecutionGateway.execute()verifies again, independently: version, signature, expiry, TTL, the business transaction hash, that the policy is still current, its approval record, that the signals are still current, and finally the nonce, which is consumed last and only if everything else passed. It then deep freezes the content and callsExecutionControlService.execute()with a gateway attestation minted for this authorization. - Execution control.
ExecutionControlServiceauthenticates the gateway, resolves the connector for the action, opens a one timeGatewaySession, and recordssession.createdon the audit sink. - Credential isolation.
SessionCredentialSecureConnectorchecks the connector’s ownConnectorPolicyagain, issues a single use session credential, callsSdkConnectorExecutor, which calls the vendor adapter (GatewayHubSpotAdapter,GatewayPaytmAdapter,GatewayGitHubAdapter,GatewaySlackAdapterorGatewayHttpAdapter), then revokes the credential on every exit path and records the outcome. - Record. Back in
RuntimeEngine,BusinessTrustPipelinebuilds the signed Execution Trust Record andRuntimestores it. If the action ran but the record cannot be made or stored, the error says so explicitly rather than inviting a blind retry. - Verify and receipt.
ExecutionTrustApplicationcallsVerificationService.verify()andReceiptService.generate(), then returns the stored record as the response.
Where a request can stop
Fail-closed properties that do hold today
- A rejected Decision never produces a Signed Execution Authorization, authorization
signing happens only after
executionGate.enforce()approves (packages/runtime/src/RuntimeEngine.ts, CLAIMS.md 2.12,packages/runtime/tests/unit/execution-authorization-wiring.test.ts, “rejected transaction produces no authorization”). It throws rather than returning a rejected result, see Write your first policy. - Signing or verifying with the wrong key type (e.g. an Ed25519 key against an ML-DSA-65
provider) fails closed with a named error rather than silently dispatching on the key’s
own type (
assertKeyType, CLAIMS.md 2.13). - The Trust Record’s
authorizationIdis part of the canonically-hashed content, not attached alongside it, tampering with it changes the recomputed hash (CLAIMS.md 2.11).