import { HTTP_EXECUTION_CEILINGS, invokeValidator, type InstalledHttpContract, } from "../../contracts/external-contract-runtime.ts"; import type { CacheScopeSnapshot } from "../../contracts/server-state-scope.ts"; import { defineMutationIntent, MUTATION_INTENT_BOUNDS, type MutationIntent, } from "../../contracts/mutation-intent.ts"; import { decodeJsonBytes, isEffectivelyEmpty, isJsonMediaType, probeForbiddenBody, readBoundedBytes, } from "./bounded-body-reader.ts"; import { admitCredentialHeaders, checkFinalInvariants, projectRequest, type CredentialAdmissionFailure, type CredentialPatchOutcome, } from "./http-contract-bridge.ts"; import { INSTALLED_REST_AUTH_PROFILES, type InstalledRestAuthProfiles, } from "../../contracts/rest-profiles.ts"; import { certaintyForAbandonedAttempt, classifyProblemEffect, joinMutationEffectCertainty, type MutationEffectCertainty, type PhysicalAttemptState, } from "./http-effect-certainty.ts"; import { parseRetryAfter } from "./retry-policy.ts"; /** * §7–§8. Descriptor-driven HTTP execution. * * This is not a general purpose HTTP client. A caller passes an installed * contract and typed input; the runtime owns bounds, the total deadline, the * single retry authority and the effect-certainty verdict. */ export type SafeResponseMetadata = Readonly<{ status: number; correlationReference?: string; retryAfterMs?: number; validatorToken?: string; }>; export type HttpContractViolationKind = | "MISSING_IDEMPOTENCY_KEY" | "UNEXPECTED_IDEMPOTENCY_KEY" | "UNEXPECTED_STATUS" | "UNEXPECTED_EMPTY_BODY" | "UNEXPECTED_BODY" | "CONTENT_TYPE_MISMATCH" | "RESPONSE_TOO_LARGE" | "UTF8_INVALID" | "JSON_INVALID" | "SUCCESS_SCHEMA_INVALID" | "PROBLEM_SCHEMA_INVALID" | "VALIDATOR_RUNTIME_FAILURE" | "MAPPING_CONTRACT_VIOLATION" | "FINAL_REQUEST_INVARIANT_FAILED" | "SCOPE_FENCED"; export type HttpContractViolation = Readonly<{ kind: HttpContractViolationKind; operation: "REQUEST" | "RESPONSE" | "VALIDATION" | "MAPPING"; }>; export type HttpEffectCertainty = | "NOT_APPLICABLE" | "NOT_STARTED" | "NOT_APPLIED" | "APPLIED_CONFIRMED" | "MAYBE_APPLIED"; export type HttpTransportFailure = Readonly<{ kind: | "DNS_OR_CONNECT_FAILURE" | "TLS_OR_NETWORK_FAILURE" | "NETWORK_FAILURE" | "TIMEOUT" | "RESPONSE_STREAM_FAILURE" | "ABORTED_BY_SCOPE" | "ABORTED_BY_CALLER" | "OVERLOADED_BEFORE_SEND"; retryable: boolean; }>; export type HttpExecutionOutcome = | Readonly<{ kind: "SUCCESS"; value: Value; metadata: SafeResponseMetadata; effect: "NOT_APPLICABLE" | "APPLIED_CONFIRMED"; }> | Readonly<{ kind: "PROBLEM"; problem: Problem; metadata: SafeResponseMetadata; effect: "NOT_APPLIED" | "APPLIED_CONFIRMED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "UNAUTHENTICATED"; effect: "NOT_APPLICABLE" | "NOT_APPLIED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "FORBIDDEN"; effect: "NOT_APPLICABLE" | "NOT_APPLIED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "RATE_LIMITED"; retryAfterMs?: number; effect: "NOT_APPLICABLE" | "NOT_APPLIED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "CONTRACT_VIOLATION"; violation: HttpContractViolation; effect: HttpEffectCertainty; }> | Readonly<{ kind: "TRANSPORT_FAILURE"; failure: HttpTransportFailure; effect: "NOT_STARTED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "CANCELLED"; effect: "NOT_STARTED" | "MAYBE_APPLIED"; }> | Readonly<{ kind: "AUTH_INTEGRATION_FAILURE"; reason: AuthIntegrationFailureReason; effect: "NOT_APPLICABLE" | "NOT_STARTED"; }>; /** * §7.7 / VD-23. A configuration or collaborator contract breach, never a user * session state. `UNAUTHENTICATED` stays reserved for the latter. */ export type AuthIntegrationFailureReason = | "UNKNOWN_AUTH_PROFILE" /** * LIVE-01. The collaborator answered that the auth system itself cannot serve * this request. That is an outage of the integration, not a statement about * the user's session, so it must never reach the composition root's logout * path. */ | "CREDENTIAL_OWNER_UNAVAILABLE" /** LIVE-01. The collaborator threw, rejected, or answered off-contract. */ | "CREDENTIAL_OWNER_FAILED" | CredentialAdmissionFailure; /** * §8.5. Credential collaborators receive the operation lifetime so a * cooperative owner can abandon its own work; a non-cooperative one is still * bounded by the executor's race against the same signal. */ export type AuthOperationContext = Readonly<{ signal: AbortSignal; deadlineAtMonotonicMs: number; }>; export type CancellationOwner = | "CALLER" | "ROUTE_TRANSITION" | "SCOPE_FENCE" | "APPLICATION_SHUTDOWN" | "DEADLINE"; export interface HttpExecutionContext { /** * §7.4. The low-cardinality route identity that owns this logical execution. * It is required at the installed operation-executor boundary so a terminal * outcome can always be attributed without reconstructing it from a URL. */ readonly routeId: string; readonly signal?: AbortSignal; readonly scope: CacheScopeSnapshot; readonly intent?: MutationIntent; } export interface ContractHttpExecutor { execute( operation: InstalledHttpContract, input: Input, context: HttpExecutionContext, ): Promise>; } /** * §7.4 / VD-07. One typed internal record per logical execution. It is not an * arbitrary context map: the composition root owns the projection into the * closed diagnostics and telemetry buckets, and raw attempt count, duration and * status never leave that projection. */ export type HttpExecutionObservation = Readonly<{ routeId: string; operationId: string; diagnosticsOperation: string; outcome: HttpExecutionOutcome["kind"]; errorKind: string; status?: number; attemptCount: number; durationMs: number; effect: HttpEffectCertainty; cancellationOwner?: CancellationOwner; /** * The internal terminal-reason label recorded by the execution site. It is * evidence for the HTTP scenario catalog only; the composition-root * projection never forwards it to diagnostics or telemetry. */ terminalReason: string; }>; /** * The outcome is the single authority for the observed error kind. The terminal * reason only distinguishes an internal runtime failure from a transport * failure, because both surface as the same public outcome. */ function observationErrorKind( outcome: HttpExecutionOutcome, terminalReason: string, ): string { switch (outcome.kind) { case "SUCCESS": return "NONE"; case "PROBLEM": return "PROBLEM"; case "UNAUTHENTICATED": return "UNAUTHENTICATED"; case "FORBIDDEN": return "FORBIDDEN"; case "RATE_LIMITED": return "RATE_LIMITED"; case "CONTRACT_VIOLATION": return outcome.violation.kind; case "TRANSPORT_FAILURE": return terminalReason === "RUNTIME_FAILURE" ? "RUNTIME_FAILURE" : outcome.failure.kind; case "CANCELLED": return "REQUEST_ABORTED"; case "AUTH_INTEGRATION_FAILURE": return outcome.reason; } } function observationStatus( outcome: HttpExecutionOutcome, ): number | undefined { return outcome.kind === "SUCCESS" || outcome.kind === "PROBLEM" ? outcome.metadata.status : undefined; } export type ContractHttpExecutorDependencies = Readonly<{ baseUrl: string; /** §8.2. `MAX_RETRY_ATTEMPTS` from Runtime Config; the ceiling is still 2. */ maxRetryAttempts: number; /** The installed profile registry; the executor never invents a profile. */ authProfiles?: InstalledRestAuthProfiles; attachCredentials( operation: Readonly<{ operationId: string; authProfileId: string; method: string; }>, context: AuthOperationContext, ): Promise | CredentialPatchOutcome; fetcher?: typeof fetch; /** Adapter seam for the common bounded response reader. */ readBoundedResponseBytes?: typeof readBoundedBytes; monotonicNow?: () => number; sleep?: (ms: number, signal: AbortSignal) => Promise; random?: () => number; observe?: (observation: HttpExecutionObservation) => void; }>; const RETRYABLE_STATUSES: ReadonlySet = new Set([ 408, 425, 429, 502, 503, 504, ]); const RETRY_BASE_DELAY_MS = 250; const RETRY_MAX_LOCAL_DELAY_MS = 2_000; const RETRY_AFTER_CEILING_MS = 5_000; type MutationIntentValidation = | Readonly<{ ok: true; intent?: MutationIntent }> | Readonly<{ ok: false; violation: "MISSING_IDEMPOTENCY_KEY" | "UNEXPECTED_IDEMPOTENCY_KEY"; }>; function validateMutationIntent( contract: Readonly<{ operationId: string; retrySemantics: "SAFE" | "IDEMPOTENT" | "KEYED" | "NEVER"; commandEffect: unknown | null; }>, intent: MutationIntent | undefined, ): MutationIntentValidation { const isCommand = contract.commandEffect !== null; const requiresKey = contract.retrySemantics === "KEYED"; if (!isCommand) { return intent === undefined ? Object.freeze({ ok: true }) : Object.freeze({ ok: false, violation: "UNEXPECTED_IDEMPOTENCY_KEY", }); } if (intent === undefined) { return requiresKey ? Object.freeze({ ok: false, violation: "MISSING_IDEMPOTENCY_KEY" }) : Object.freeze({ ok: true }); } let validated: MutationIntent; try { validated = defineMutationIntent(intent); } catch { return Object.freeze({ ok: false, violation: requiresKey ? "MISSING_IDEMPOTENCY_KEY" : "UNEXPECTED_IDEMPOTENCY_KEY", }); } if (validated.operationId !== contract.operationId) { return Object.freeze({ ok: false, violation: requiresKey ? "MISSING_IDEMPOTENCY_KEY" : "UNEXPECTED_IDEMPOTENCY_KEY", }); } const key = validated.idempotencyKey; if (requiresKey && !validIdempotencyKey(key)) { return Object.freeze({ ok: false, violation: "MISSING_IDEMPOTENCY_KEY", }); } if (!requiresKey && key !== undefined) { return Object.freeze({ ok: false, violation: "UNEXPECTED_IDEMPOTENCY_KEY", }); } return Object.freeze({ ok: true, intent: validated }); } const UTF8 = new TextEncoder(); function validIdempotencyKey(value: unknown): value is string { return ( typeof value === "string" && value.trim().length > 0 && UTF8.encode(value).byteLength <= MUTATION_INTENT_BOUNDS.idempotencyKeyMaxBytes && !hasControlCharacter(value) ); } function hasControlCharacter(value: string): boolean { for (const character of value) { const codePoint = character.codePointAt(0) ?? 0; if ( codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f) ) { return true; } } return false; } export function createContractHttpExecutor( dependencies: ContractHttpExecutorDependencies, ): ContractHttpExecutor { const fetcher = dependencies.fetcher ?? fetch; const authProfiles = dependencies.authProfiles ?? INSTALLED_REST_AUTH_PROFILES; const readResponseBytes = dependencies.readBoundedResponseBytes ?? readBoundedBytes; const now = dependencies.monotonicNow ?? (() => performance.now()); const random = dependencies.random ?? Math.random; const sleep = dependencies.sleep ?? ((ms: number, signal: AbortSignal) => new Promise((resolve) => { const timer = setTimeout(resolve, ms); signal.addEventListener( "abort", () => { clearTimeout(timer); resolve(); }, { once: true }, ); })); async function execute( operation: InstalledHttpContract, input: Input, context: HttpExecutionContext, ): Promise> { const contract = operation.contract; const policy = operation.frontend; const isCommand = contract.commandEffect !== null; // §8.5. One monotonic deadline covers credential resolution, encoding, // backoff, every physical attempt, body read and validation. const startedAt = now(); const deadlineAt = startedAt + policy.totalDeadlineMs; const remaining = () => deadlineAt - now(); let attemptState: PhysicalAttemptState = "PREPARING"; let attempts = 0; /** * §8.7 / D-01. Per-attempt state stays local to the attempt; this monotonic * accumulator is the logical execution history. A retry that has not been * dispatched can never lower what an earlier attempt already established. */ let logicalCertainty: MutationEffectCertainty = "NOT_STARTED"; const observeCertainty = (observed: MutationEffectCertainty) => { logicalCertainty = joinMutationEffectCertainty(logicalCertainty, observed); return logicalCertainty; }; /** Pre-dispatch failures read the accumulator, never a fresh attempt. */ const logicalPreDispatchEffect = (): HttpEffectCertainty => isCommand ? logicalCertainty : "NOT_APPLICABLE"; const abandonedCertainty = (): MutationEffectCertainty => observeCertainty(certaintyForAbandonedAttempt(attemptState, isCommand)); const abandonedTransportFailure = ( kind: HttpTransportFailure["kind"], ): HttpExecutionOutcome => transportFailure(kind, false, abandonedCertainty()); let terminalCancellation: CancellationOwner | null = null; const lifetimeController = new AbortController(); const forwardCallerToLifetime = () => { terminalCancellation ??= "CALLER"; lifetimeController.abort(); }; const forwardScopeToLifetime = () => { terminalCancellation ??= "SCOPE_FENCE"; lifetimeController.abort(); }; const callerSignal = context.signal === context.scope.signal ? undefined : context.signal; if (callerSignal?.aborted) forwardCallerToLifetime(); else { callerSignal?.addEventListener("abort", forwardCallerToLifetime, { once: true, }); } if (context.scope.signal.aborted) forwardScopeToLifetime(); else { context.scope.signal.addEventListener("abort", forwardScopeToLifetime, { once: true, }); } const lifetimeDeadlineTimer = setTimeout(() => { terminalCancellation ??= "DEADLINE"; lifetimeController.abort(); }, policy.totalDeadlineMs); let lifetimeDisposed = false; const disposeLifetime = () => { if (lifetimeDisposed) return; lifetimeDisposed = true; clearTimeout(lifetimeDeadlineTimer); callerSignal?.removeEventListener("abort", forwardCallerToLifetime); context.scope.signal.removeEventListener("abort", forwardScopeToLifetime); lifetimeController.abort(); }; const finish = ( outcome: HttpExecutionOutcome, terminalReason: string, ): HttpExecutionOutcome => { disposeLifetime(); try { const status = observationStatus(outcome); dependencies.observe?.( Object.freeze({ routeId: context.routeId, operationId: contract.operationId, diagnosticsOperation: policy.diagnosticsOperation, outcome: outcome.kind, errorKind: observationErrorKind(outcome, terminalReason), ...(status === undefined ? {} : { status }), attemptCount: attempts, durationMs: Math.max(0, now() - startedAt), effect: outcome.effect, terminalReason, ...(terminalCancellation === null ? {} : { cancellationOwner: terminalCancellation }), }), ); } catch { // Observation is outside the execution authority. } return outcome; }; try { // §7.7. The installed registry is the only source of a profile. Composition // already rejects unknown identities; this is the runtime fail-close. const authProfile = authProfiles.get(policy.authProfileId); if (!authProfile) { return finish( authIntegrationFailure("UNKNOWN_AUTH_PROFILE", isCommand), "AUTH_INTEGRATION_FAILURE", ); } // §7.4 step 1-2: capture the scope and verify it is still current. if (!context.scope.isCurrent()) { return finish(scopeFenced(preDispatchEffect(isCommand)), "NOT_STARTED"); } const intentValidation = validateMutationIntent(contract, context.intent); if (!intentValidation.ok) { return finish( violation(intentValidation.violation, "REQUEST", "NOT_STARTED"), "NOT_STARTED", ); } const validated = invokeValidator(contract.inputValidator, input); if (validated.outcome === "THROWN") { return finish( violation( "VALIDATOR_RUNTIME_FAILURE", "VALIDATION", preDispatchEffect(isCommand), ), "NOT_STARTED", ); } if (validated.outcome === "INVALID") { return finish( violation( "FINAL_REQUEST_INVARIANT_FAILED", "REQUEST", preDispatchEffect(isCommand), ), "NOT_STARTED", ); } const projected = projectRequest( operation, validated.value, dependencies.baseUrl, ); if (!projected.ok) { return finish( violation( "FINAL_REQUEST_INVARIANT_FAILED", "REQUEST", preDispatchEffect(isCommand), ), "NOT_STARTED", ); } // §7.7 / §8.4. Credentials are resolved before send. A response 401 is // terminal; there is no hidden refresh-and-replay. // // LIVE-01. A synchronous throw and an asynchronous rejection are the same // event seen from two call sites, so one classifier owns both. Neither is // evidence about the user's session. let patchOperation: Promise; try { patchOperation = Promise.resolve( dependencies.attachCredentials( { operationId: contract.operationId, authProfileId: policy.authProfileId, method: contract.method, }, Object.freeze({ signal: lifetimeController.signal, deadlineAtMonotonicMs: deadlineAt, }), ), ); } catch { return finish( authIntegrationFailure("CREDENTIAL_OWNER_FAILED", isCommand), "AUTH_INTEGRATION_FAILURE", ); } let patchResult: CredentialPatchOutcome | typeof ABORTED; try { patchResult = await awaitWithAbort( patchOperation, lifetimeController.signal, ); } catch { return finish( authIntegrationFailure("CREDENTIAL_OWNER_FAILED", isCommand), "AUTH_INTEGRATION_FAILURE", ); } if (patchResult === ABORTED) { if (terminalCancellation === "SCOPE_FENCE") { return finish( abandonedTransportFailure("ABORTED_BY_SCOPE"), "SCOPE_FENCED", ); } return terminalCancellation === "CALLER" ? finish(cancelled("NOT_STARTED"), "CANCELLED") : finish( abandonedTransportFailure("TIMEOUT"), "TIMEOUT", ); } const patch = patchResult; if (patch?.kind === "SCOPE_FENCED") { return finish(scopeFenced(preDispatchEffect(isCommand)), "NOT_STARTED"); } if (patch?.kind === "UNAUTHENTICATED") { // A missing credential never downgrades into an anonymous request. return finish(unauthenticated("NOT_STARTED", isCommand), "NOT_STARTED"); } if (patch?.kind === "UNAVAILABLE") { return finish( authIntegrationFailure("CREDENTIAL_OWNER_UNAVAILABLE", isCommand), "AUTH_INTEGRATION_FAILURE", ); } if ( patch?.kind !== "READY" || patch.headers === null || typeof patch.headers !== "object" ) { // An off-contract answer is a collaborator breach, never a session // verdict the caller may act on. return finish( authIntegrationFailure("CREDENTIAL_OWNER_FAILED", isCommand), "AUTH_INTEGRATION_FAILURE", ); } // The idempotency key is contract-owned, so a credential owner supplying it // stays the more specific request-contract violation. if ( Object.keys(patch.headers).some( (name) => name.toLowerCase() === "idempotency-key", ) ) { return finish( violation("UNEXPECTED_IDEMPOTENCY_KEY", "REQUEST", "NOT_STARTED"), "NOT_STARTED", ); } // §7.7. The profile, not the patch, decides what may travel. Rejection here // means zero fetch calls. const admission = admitCredentialHeaders(patch.headers, authProfile); if (!admission.ok) { return finish( authIntegrationFailure(admission.failure, isCommand), "AUTH_INTEGRATION_FAILURE", ); } // Transport-owned headers are written last so no credential entry can // shadow Accept or Content-Type through key ordering. const headers: Record = { ...admission.headers, Accept: "application/json", }; if (contract.requestBody === "JSON") { headers["Content-Type"] = "application/json"; } if (intentValidation.intent?.idempotencyKey !== undefined) { headers["Idempotency-Key"] = intentValidation.intent.idempotencyKey; } const retryCeiling = Math.min( policy.retryBudget, dependencies.maxRetryAttempts, HTTP_EXECUTION_CEILINGS.hardRetryCount, ); for (let retryIndex = 0; ; retryIndex += 1) { if (callerSignal?.aborted) { terminalCancellation ??= "CALLER"; return finish( cancelled(abandonedCertainty()), "CANCELLED", ); } if (!context.scope.isCurrent()) { terminalCancellation ??= "SCOPE_FENCE"; return finish( scopeFenced(abandonedCertainty()), "SCOPE_FENCED", ); } const controller = new AbortController(); const budget = remaining(); if (budget <= 0) { return finish( abandonedTransportFailure("TIMEOUT"), "TIMEOUT", ); } const deadlineTimer = setTimeout(() => { terminalCancellation ??= "DEADLINE"; controller.abort(); }, budget); const forwardLifetime = () => { controller.abort(); }; if (lifetimeController.signal.aborted) forwardLifetime(); else { lifetimeController.signal.addEventListener("abort", forwardLifetime, { once: true, }); } const init: RequestInit = { method: contract.method, headers, redirect: "error", referrerPolicy: "no-referrer", credentials: authProfile.credentials, cache: "no-store", signal: controller.signal, ...(projected.request.bodyBytes ? { body: projected.request.bodyBytes.slice() } : {}), }; const invariantFailure = checkFinalInvariants({ request: projected.request, expectedMethod: contract.method, baseUrl: dependencies.baseUrl, init, headers, requestByteLimit: policy.requestByteLimit, deadlineRemainingMs: remaining(), scopeIsCurrent: context.scope.isCurrent(), authProfile, }); if (invariantFailure) { clearTimeout(deadlineTimer); lifetimeController.signal.removeEventListener("abort", forwardLifetime); return finish( invariantFailure === "SCOPE_FENCED" ? scopeFenced(logicalPreDispatchEffect()) : violation( "FINAL_REQUEST_INVARIANT_FAILED", "REQUEST", logicalPreDispatchEffect(), ), "NOT_STARTED", ); } let response: Response; attemptState = "READY_TO_SEND"; // LIVE-04. The dispatch wait is raced against the attempt signal, which // already carries the caller, the scope fence and the total deadline. A // `fetch` that ignores its own `signal` therefore still cannot outlive // the operation, and a response that lands late is drained, not admitted. let dispatch: BoundedRace; try { attempts += 1; const pending = fetcher(projected.request.url, init); attemptState = "DISPATCHED"; // D-01. Dispatch is the point of no return for the logical execution. // No later retry may claim the command never started. observeCertainty(certaintyForAbandonedAttempt("DISPATCHED", isCommand)); dispatch = await raceTerminal( pending, controller.signal, cancelResponseBody, ); } catch { dispatch = REJECTED_RACE; } if (dispatch.kind === "VALUE") { response = dispatch.value; attemptState = "RESPONSE_HEADERS"; } else { clearTimeout(deadlineTimer); lifetimeController.signal.removeEventListener("abort", forwardLifetime); const owner = terminalCancellation; if (owner === "CALLER") { return finish( cancelled(abandonedCertainty()), "CANCELLED", ); } if (owner === "SCOPE_FENCE") { return finish( abandonedTransportFailure("ABORTED_BY_SCOPE"), "SCOPE_FENCED", ); } const kind = owner === "DEADLINE" ? "TIMEOUT" : "NETWORK_FAILURE"; if ( owner === null && canRetryTransport(contract.retrySemantics, attemptState) && retryIndex < retryCeiling && remaining() > 0 ) { const delay = jitteredDelay(retryIndex, random); if (delay < remaining()) { const slept = await awaitWithAbort( sleep(delay, lifetimeController.signal), lifetimeController.signal, ); if (slept === ABORTED) { return terminalCancellation === "CALLER" ? finish( cancelled(abandonedCertainty()), "CANCELLED", ) : finish( abandonedTransportFailure("TIMEOUT"), "TIMEOUT", ); } continue; } } return finish( abandonedTransportFailure(kind), kind, ); } try { // LIVE-04. Response admission reads a body, so it is a physical wait // too. It is bounded by the same signal, the reader is handed that // signal so a cooperative stream stops early, and an admission that // completes after the terminal owner fired is discarded. const admission = await raceTerminal( admitResponse( operation, response, context, attemptState, readResponseBytes, controller.signal, ), controller.signal, () => cancelResponseBody(response), ); // LIVE-04. Once response headers are in hand the request demonstrably // reached the server, so a terminal owner that lands during admission // keeps the dispatched classification: a stale generation stays the // `SCOPE_FENCED` contract violation it has always been, and only the // deadline and the caller reclassify the outcome. const abandonAdmission = (): | HttpExecutionOutcome | null => { switch (terminalCancellation) { case "DEADLINE": return finish(abandonedTransportFailure("TIMEOUT"), "TIMEOUT"); case "CALLER": return finish(cancelled(abandonedCertainty()), "CANCELLED"); case "SCOPE_FENCE": return finish( scopeFenced(abandonedCertainty()), "SCOPE_FENCED", ); default: return null; } }; if (admission.kind !== "VALUE") { cancelResponseBody(response); return ( abandonAdmission() ?? finish( abandonedTransportFailure("NETWORK_FAILURE"), "NETWORK_FAILURE", ) ); } const outcome = admission.value; attemptState = "SETTLED"; const abandoned = abandonAdmission(); if (abandoned) return abandoned; if ( outcome.retryHint && retryIndex < retryCeiling && isRetryableSemantics(contract.retrySemantics) ) { const delay = retryDelayFor(outcome.retryAfterMs, retryIndex, random); if (delay !== null && delay < remaining()) { clearTimeout(deadlineTimer); lifetimeController.signal.removeEventListener( "abort", forwardLifetime, ); const slept = await awaitWithAbort( sleep(delay, lifetimeController.signal), lifetimeController.signal, ); if (slept === ABORTED) { return terminalCancellation === "CALLER" ? finish( cancelled(abandonedCertainty()), "CANCELLED", ) : finish( abandonedTransportFailure("TIMEOUT"), "TIMEOUT", ); } continue; } } return finish(outcome.result, outcome.certainty); } finally { clearTimeout(deadlineTimer); lifetimeController.signal.removeEventListener("abort", forwardLifetime); } } } catch { return finish( abandonedTransportFailure("NETWORK_FAILURE"), "RUNTIME_FAILURE", ); } finally { disposeLifetime(); } } return Object.freeze({ execute }); } type AdmissionOutcome = Readonly<{ result: HttpExecutionOutcome; certainty: string; retryHint: boolean; retryAfterMs: number | null; }>; /** * §7.9. Admission order is fixed: redirect, status allowlist, media type, * declared length, bounded stream, body policy, decode, validate, scope fence. * `response.ok` is never used on its own. */ async function admitResponse( operation: InstalledHttpContract, response: Response, context: HttpExecutionContext, attemptState: PhysicalAttemptState, readResponseBytes: typeof readBoundedBytes, signal: AbortSignal, ): Promise> { const contract = operation.contract; const policy = operation.frontend; const isCommand = contract.commandEffect !== null; const status = response.status; const retryAfterMs = parseRetryAfter(response.headers.get("retry-after")); if (response.redirected || response.type === "opaqueredirect") { await response.body?.cancel().catch(() => {}); return settled( violation( "UNEXPECTED_STATUS", "RESPONSE", postDispatchEffect(isCommand), ), "CONTRACT_VIOLATION", ); } const metadata = safeMetadata(response, retryAfterMs); if (!contract.acceptedStatuses.includes(status)) { if (status === 401) { await response.body?.cancel().catch(() => {}); return settled( unauthenticated( certaintyForAbandonedAttempt(attemptState, isCommand), isCommand, ), "UNAUTHENTICATED", ); } if (status === 403) { await response.body?.cancel().catch(() => {}); return settled( forbidden(certaintyForAbandonedAttempt(attemptState, isCommand), isCommand), "FORBIDDEN", ); } if (status === 429) { await response.body?.cancel().catch(() => {}); return Object.freeze({ result: Object.freeze({ kind: "RATE_LIMITED" as const, ...(retryAfterMs === null ? {} : { retryAfterMs }), effect: normalizeOptionalEffect( certaintyForAbandonedAttempt(attemptState, isCommand), isCommand, ), }), certainty: "RATE_LIMITED", retryHint: true, retryAfterMs, }); } return admitProblem( operation, response, status, metadata, attemptState, readResponseBytes, signal, ); } // Success status: body policy first. if (contract.responseBody === "NONE") { const probe = await probeForbiddenBody(response); if (!probe.ok) { return settled( transportFailure( "RESPONSE_STREAM_FAILURE", false, certaintyForAbandonedAttempt(attemptState, isCommand), ), probe.code, ); } if (probe.present) { return settled( violation("UNEXPECTED_BODY", "RESPONSE", postDispatchEffect(isCommand)), "CONTRACT_VIOLATION", ); } if (!context.scope.isCurrent()) { return settled( scopeFenced(postDispatchEffect(isCommand)), "SCOPE_FENCED", ); } return settled( Object.freeze({ kind: "SUCCESS" as const, value: undefined as WireOutput, metadata, effect: (isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE") as "NOT_APPLICABLE" | "APPLIED_CONFIRMED", }), isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE", ); } const emptyAllowed = contract.emptyBodyStatuses.includes(status); const mediaOk = isJsonMediaType(response.headers.get("content-type")); const bytes = await readResponseBytes( response, policy.responseByteLimit, signal, ); if (!bytes.ok) { return settled( bytes.code === "RESPONSE_TOO_LARGE" ? violation( "RESPONSE_TOO_LARGE", "RESPONSE", postDispatchEffect(isCommand), ) : transportFailure( "RESPONSE_STREAM_FAILURE", false, certaintyForAbandonedAttempt(attemptState, isCommand), ), bytes.code, ); } const empty = isEffectivelyEmpty(bytes.bytes); if (empty) { if (contract.responseBody === "REQUIRED_JSON" || !emptyAllowed) { return settled( violation( "UNEXPECTED_EMPTY_BODY", "RESPONSE", postDispatchEffect(isCommand), ), "CONTRACT_VIOLATION", ); } if (!context.scope.isCurrent()) { return settled( scopeFenced(postDispatchEffect(isCommand)), "SCOPE_FENCED", ); } return settled( Object.freeze({ kind: "SUCCESS" as const, value: undefined as WireOutput, metadata, effect: (isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE") as "NOT_APPLICABLE" | "APPLIED_CONFIRMED", }), isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE", ); } if (!mediaOk) { return settled( violation( "CONTENT_TYPE_MISMATCH", "RESPONSE", postDispatchEffect(isCommand), ), "CONTRACT_VIOLATION", ); } const decoded = decodeJsonBytes(bytes.bytes); if (!decoded.ok) { return settled( violation(decoded.code, "RESPONSE", postDispatchEffect(isCommand)), "CONTRACT_VIOLATION", ); } const validated = invokeValidator(contract.outputValidator, decoded.value); if (validated.outcome === "THROWN") { return settled( violation( "VALIDATOR_RUNTIME_FAILURE", "VALIDATION", postDispatchEffect(isCommand), ), "CONTRACT_VIOLATION", ); } if (validated.outcome === "INVALID") { return settled( violation( "SUCCESS_SCHEMA_INVALID", "VALIDATION", postDispatchEffect(isCommand), ), "CONTRACT_VIOLATION", ); } // §10.8. A successful response for a stale scope is discarded, not committed. if (!context.scope.isCurrent()) { return settled( scopeFenced(postDispatchEffect(isCommand)), "SCOPE_FENCED", ); } return settled( Object.freeze({ kind: "SUCCESS" as const, value: validated.value, metadata, effect: (isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE") as "NOT_APPLICABLE" | "APPLIED_CONFIRMED", }), isCommand ? "APPLIED_CONFIRMED" : "NOT_APPLICABLE", ); } /** * LIVE-04. The outcome of a physical wait that the operation's terminal signal * bounds. * * `REJECTED` is kept distinct from `TERMINAL` on purpose: a collaborator's own * rejection is evidence about the request, and forging it into a cancellation * state would erase the reason the attempt actually failed. */ type BoundedRace = | Readonly<{ kind: "VALUE"; value: Value }> | Readonly<{ kind: "REJECTED" }> | Readonly<{ kind: "TERMINAL" }>; const TERMINAL_RACE: BoundedRace = Object.freeze({ kind: "TERMINAL" as const, }); const REJECTED_RACE: BoundedRace = Object.freeze({ kind: "REJECTED" as const, }); /** * LIVE-04. Races a physical operation against the terminal signal so a * non-cooperative `fetch` or reader cannot hold the port result open past the * total deadline. * * Two properties matter beyond the race itself. A value that arrives while the * terminal owner has already fired is *late*, so it is compensated rather than * admitted. And the abandoned operation is still observed exactly once, so a * late native rejection never surfaces as an unhandled rejection. */ async function raceTerminal( operation: Promise, signal: AbortSignal, compensate: (value: Value) => void, ): Promise> { let landed: BoundedRace | null = null; const settled: Promise> = operation.then( (value) => (landed = Object.freeze({ kind: "VALUE" as const, value })), () => (landed = REJECTED_RACE), ); const observeLate = () => { void settled.then((outcome) => { if (outcome.kind !== "VALUE") return; try { compensate(outcome.value); } catch { // Compensation is outside the execution authority. } }); }; let onAbort: (() => void) | undefined; const terminal = new Promise>((resolve) => { if (signal.aborted) { resolve(TERMINAL_RACE); return; } onAbort = () => resolve(TERMINAL_RACE); signal.addEventListener("abort", onAbort, { once: true }); }); try { const winner = await Promise.race([settled, terminal]); if (winner !== TERMINAL_RACE) return winner; // The terminal owner reached the await first. Drain the microtask queue // once so an operation that had *already* settled can still hand over its // value: a microtask turn cannot be extended by a collaborator that has // not settled, so a non-cooperative operation is still abandoned here. for (let turn = 0; turn < 4 && landed === null; turn += 1) { await Promise.resolve(); } if (landed !== null) return landed; observeLate(); return TERMINAL_RACE; } finally { if (onAbort) signal.removeEventListener("abort", onAbort); } } function cancelResponseBody(response: Response): void { void response.body?.cancel().catch(() => {}); } const ABORTED = Symbol("http-operation-aborted"); async function awaitWithAbort( operation: Promise, signal: AbortSignal, ): Promise { if (signal.aborted) return ABORTED; let onAbort: (() => void) | undefined; const aborted = new Promise((resolve) => { onAbort = () => resolve(ABORTED); signal.addEventListener("abort", onAbort, { once: true }); }); try { return await Promise.race([operation, aborted]); } finally { if (onAbort) signal.removeEventListener("abort", onAbort); } } async function admitProblem( operation: InstalledHttpContract, response: Response, status: number, metadata: SafeResponseMetadata, attemptState: PhysicalAttemptState, readResponseBytes: typeof readBoundedBytes, signal: AbortSignal, ): Promise> { const contract = operation.contract; const isCommand = contract.commandEffect !== null; const retryable = RETRYABLE_STATUSES.has(status); const bytes = await readResponseBytes( response, HTTP_EXECUTION_CEILINGS.problemResponseBytes, signal, ); if (!bytes.ok || isEffectivelyEmpty(bytes.bytes)) { // An unclassifiable failure stays uncertain for a command. return Object.freeze({ result: violation( "PROBLEM_SCHEMA_INVALID", "VALIDATION", postDispatchEffect(isCommand), ), certainty: isCommand ? "MAYBE_APPLIED" : "NOT_STARTED", retryHint: retryable, retryAfterMs: metadata.retryAfterMs ?? null, }); } if (!isJsonMediaType(response.headers.get("content-type"))) { return Object.freeze({ result: violation( "CONTENT_TYPE_MISMATCH", "RESPONSE", postDispatchEffect(isCommand), ), certainty: isCommand ? "MAYBE_APPLIED" : "NOT_STARTED", retryHint: retryable, retryAfterMs: metadata.retryAfterMs ?? null, }); } const decoded = decodeJsonBytes(bytes.bytes); if (!decoded.ok) { return Object.freeze({ result: violation( decoded.code, "RESPONSE", postDispatchEffect(isCommand), ), certainty: isCommand ? "MAYBE_APPLIED" : "NOT_STARTED", retryHint: retryable, retryAfterMs: metadata.retryAfterMs ?? null, }); } const validated = invokeValidator(contract.problemValidator, decoded.value); if (validated.outcome !== "VALID") { return Object.freeze({ result: violation( validated.outcome === "THROWN" ? "VALIDATOR_RUNTIME_FAILURE" : "PROBLEM_SCHEMA_INVALID", "VALIDATION", postDispatchEffect(isCommand), ), certainty: isCommand ? "MAYBE_APPLIED" : "NOT_STARTED", retryHint: retryable, retryAfterMs: metadata.retryAfterMs ?? null, }); } const classification = classifyProblemEffect({ status, problem: validated.value, descriptor: contract.commandEffect, }); const effect = isCommand ? classification.effect : certaintyForAbandonedAttempt(attemptState, false); return Object.freeze({ result: Object.freeze({ kind: "PROBLEM" as const, problem: validated.value, metadata, effect: (effect === "NOT_STARTED" ? "NOT_APPLIED" : effect) as "NOT_APPLIED" | "APPLIED_CONFIRMED" | "MAYBE_APPLIED", }), certainty: effect, retryHint: retryable && effect !== "MAYBE_APPLIED", retryAfterMs: metadata.retryAfterMs ?? null, }); } /** * §8.3. `SAFE` and `IDEMPOTENT` may replay the same frozen request. `KEYED` * must not automatically retry once an attempt was dispatched and its response * was lost; that path goes to inspect/reconciliation instead. `NEVER` is zero. */ function canRetryTransport( semantics: InstalledHttpContract< unknown, unknown, unknown >["contract"]["retrySemantics"], attemptState: PhysicalAttemptState, ): boolean { if (semantics === "NEVER") return false; if (semantics === "KEYED") { return attemptState === "PREPARING" || attemptState === "READY_TO_SEND"; } return true; } function isRetryableSemantics( semantics: InstalledHttpContract< unknown, unknown, unknown >["contract"]["retrySemantics"], ): boolean { return semantics === "SAFE" || semantics === "IDEMPOTENT"; } /** §8.2. Full jitter over `min(2000, 250 * 2^index)`. */ function jitteredDelay(retryIndex: number, random: () => number): number { const ceiling = Math.min( RETRY_MAX_LOCAL_DELAY_MS, RETRY_BASE_DELAY_MS * 2 ** retryIndex, ); return Math.floor(random() * ceiling); } function retryDelayFor( retryAfterMs: number | null, retryIndex: number, random: () => number, ): number | null { const local = jitteredDelay(retryIndex, random); if (retryAfterMs === null) return local; if (retryAfterMs > RETRY_AFTER_CEILING_MS) return null; return Math.max(local, retryAfterMs); } /** §7.12. No raw header map, URL, cookie, traceparent or ETag value escapes. */ function safeMetadata( response: Response, retryAfterMs: number | null, ): SafeResponseMetadata { const correlation = response.headers.get("x-correlation-id"); return Object.freeze({ status: response.status, ...(correlation && /^[A-Za-z0-9._:-]{1,128}$/.test(correlation) ? { correlationReference: correlation } : {}), ...(retryAfterMs === null ? {} : { retryAfterMs }), }); } function settled( result: HttpExecutionOutcome, certainty: string, ): AdmissionOutcome { return Object.freeze({ result, certainty, retryHint: false, retryAfterMs: null, }); } function violation( kind: HttpContractViolationKind, operation: HttpContractViolation["operation"], effect: HttpEffectCertainty, ): HttpExecutionOutcome { return Object.freeze({ kind: "CONTRACT_VIOLATION" as const, violation: Object.freeze({ kind, operation }), effect, }); } function scopeFenced( effect: HttpEffectCertainty, ): HttpExecutionOutcome { return violation("SCOPE_FENCED", "RESPONSE", effect); } /** * §7.7. A credential collaborator or profile-binding breach. It always resolves * before dispatch, so the command effect is `NOT_STARTED` and fetch count zero. */ function authIntegrationFailure( reason: AuthIntegrationFailureReason, isCommand: boolean, ): HttpExecutionOutcome { return Object.freeze({ kind: "AUTH_INTEGRATION_FAILURE" as const, reason, effect: isCommand ? ("NOT_STARTED" as const) : ("NOT_APPLICABLE" as const), }); } function preDispatchEffect(isCommand: boolean): HttpEffectCertainty { return isCommand ? "NOT_STARTED" : "NOT_APPLICABLE"; } function postDispatchEffect(isCommand: boolean): HttpEffectCertainty { return isCommand ? "MAYBE_APPLIED" : "NOT_APPLICABLE"; } function unauthenticated( effect: string, isCommand: boolean, ): HttpExecutionOutcome { return Object.freeze({ kind: "UNAUTHENTICATED" as const, effect: normalizeOptionalEffect(effect, isCommand), }); } function forbidden( effect: string, isCommand: boolean, ): HttpExecutionOutcome { return Object.freeze({ kind: "FORBIDDEN" as const, effect: normalizeOptionalEffect(effect, isCommand), }); } function cancelled( effect: "NOT_STARTED" | "NOT_APPLIED" | "MAYBE_APPLIED" | "APPLIED_CONFIRMED", ): HttpExecutionOutcome { return Object.freeze({ kind: "CANCELLED" as const, effect: effect === "MAYBE_APPLIED" ? "MAYBE_APPLIED" : "NOT_STARTED", }); } function transportFailure( kind: HttpTransportFailure["kind"], retryable: boolean, effect: MutationEffectCertainty, ): HttpExecutionOutcome { return Object.freeze({ kind: "TRANSPORT_FAILURE" as const, failure: Object.freeze({ kind, retryable }), effect: effect === "MAYBE_APPLIED" ? "MAYBE_APPLIED" : "NOT_STARTED", }); } function normalizeOptionalEffect( effect: string, isCommand: boolean, ): "NOT_APPLICABLE" | "NOT_APPLIED" | "MAYBE_APPLIED" { if (!isCommand) return "NOT_APPLICABLE"; return effect === "MAYBE_APPLIED" ? "MAYBE_APPLIED" : "NOT_APPLIED"; }