fix: close the live V3 authority findings from the adapter re-review
LIVE-01. A credential collaborator that returns UNAVAILABLE, throws, rejects or answers off-contract is an outage of the auth integration, not evidence about the user's session. Each of those now closes as AUTH_INTEGRATION_FAILURE with zero fetches, so the composition root's logout path stays reserved for a genuinely absent session. The synchronous and asynchronous failure sites share one classifier. LIVE-02 / LIVE-03. Object.freeze(new Map(...)) freezes the wrapper, not the backing store, so an exported registry could still be cleared or replaced after composition. Both the installed REST auth profile registry and the composed HTTP/event lookups are now read facades over private stores, and every composed row is an exact own-data snapshot that rejects accessors, inherited and symbol-keyed fields. LIVE-04. The total deadline now bounds the physical waits rather than being checked between them: dispatch and response admission race the attempt signal, the bounded reader takes that signal, and an abandoned operation is still observed once so a late native rejection cannot surface unhandled. A body that completes after the deadline or the caller owns the execution is no longer admitted; a stale generation keeps its more specific SCOPE_FENCED verdict. LIVE-05. DEADLINE is no longer treated as a caller-owned cancellation, so a timeout reaches api.request.failed exactly once while caller, route, scope and shutdown aborts stay excluded. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
3b481eb4cf
commit
f4bfdf0365
@@ -226,15 +226,32 @@ export function createHttpObservationProjector(
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancellation and scope fencing are caller- or generation-owned decisions, not
|
||||
* API failures. They produce a diagnostic once and never `api.request.failed`.
|
||||
* LIVE-05. Cancellation and scope fencing are caller- or generation-owned
|
||||
* decisions, not API failures: they produce a diagnostic once and never
|
||||
* `api.request.failed`.
|
||||
*
|
||||
* A `DEADLINE` owner is the opposite case. Nobody asked for it — the API did
|
||||
* not answer inside the contract's own budget — so excluding it would hide
|
||||
* exactly the outage this event exists to report.
|
||||
*/
|
||||
const CALLER_OWNED_CANCELLATION: ReadonlySet<string> = new Set([
|
||||
"CALLER",
|
||||
"ROUTE_TRANSITION",
|
||||
"SCOPE_FENCE",
|
||||
"APPLICATION_SHUTDOWN",
|
||||
]);
|
||||
|
||||
function isTerminalNonAbortFailure(
|
||||
observation: HttpExecutionObservation,
|
||||
): boolean {
|
||||
if (observation.outcome === "SUCCESS") return false;
|
||||
if (observation.outcome === "CANCELLED") return false;
|
||||
if (observation.cancellationOwner !== undefined) return false;
|
||||
if (
|
||||
observation.cancellationOwner !== undefined &&
|
||||
CALLER_OWNED_CANCELLATION.has(observation.cancellationOwner)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return !(
|
||||
observation.outcome === "CONTRACT_VIOLATION" &&
|
||||
observation.errorKind === "SCOPE_FENCED"
|
||||
|
||||
Reference in New Issue
Block a user