diff --git a/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-log.md b/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-log.md new file mode 100644 index 00000000..2aa21556 --- /dev/null +++ b/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-log.md @@ -0,0 +1,124 @@ +# Implementation Log - AAuth protocol draft-09 migration + +> Append-only record for decisions, deviations, and owner inputs. See +> [`research.md`](research.md) and +> [`implementation-plan.md`](implementation-plan.md). + +## Decisions taken + +### [2026-07-19] [Phase 0] Q1 - Public error detail API + +**RESOLVED.** Rename `AAuthTokenExchangeException.ErrorDescription` and +`TokenErrorResponse.ErrorDescription` to `Detail`. Producers and consumers use +only the draft-09 `detail` wire member; no public alias and no +`error_description` fallback will be retained. The owner ruled that exact +latest-spec compliance takes priority over backward compatibility. + +### [2026-07-20] [Phase 0] Q2 - RFC 9457 on R3 runtime endpoints + +**RESOLVED.** Include R3 token, document, challenge, and enforcement error +bodies in the common draft-09 RFC 9457 cutover. Their status codes and AAuth +`error` values remain unchanged; error bodies use +`application/problem+json` and optional `detail`. + +### [2026-07-20] [Phase 0] Q3 - Bootstrap and MockAgentProvider errors + +**RESOLVED.** Leave the informational, byte-unchanged Bootstrap companion and +the MockAgentProvider enrollment/refresh error format unchanged in this +migration. Create a focused research-and-plan spin-off; do not silently broaden +the draft-09 main-protocol error cutover into that companion. + +### [2026-07-20] [Phase 0] Q4 - Missing AS clarification receiver + +**RESOLVED.** Apply the draft-09 `action` cutover to the implemented +agent-to-PS clarification flow. The AS clarification receiver was already +missing under draft-08 and requires a complete pending-state/federation flow, so +create a separate research-and-plan initiative rather than adding a partial +receiver here. + +### [2026-07-20] [Phase 0] Q5 - AAuth Events companion + +**RESOLVED.** Spin off the complete AAuth Events protocol and all of its source +seams, including optional `event_endpoint` metadata, token-type APIs, +subscription registration, delivery, persistence, replay controls, agent +verification, discovery, samples, and e2e. The current AP does not support +Events, so omitting the conditional metadata remains conformant; this migration +must state the unsupported boundary explicitly. + +### [2026-07-20] [Phase 0] Q6 - Revised R3 AsyncAPI behavior + +**RESOLVED.** Spin off the new R3 AsyncAPI vocabulary/model and subscription +handoff with AAuth Events. Existing R3 token, document, challenge, and +enforcement endpoints remain in this migration only for the Q2 RFC 9457 error +format cutover. + +### [2026-07-20] [Phase 0] Q7 - Signature Keys self-jwt + +**RESOLVED.** Spin off `sig=self-jwt` as a dedicated dependency/use-case +initiative. It has no current main-protocol attachment point. Its future +discovery/cache implementation must coordinate with Events on one admitted +`{iss}/.well-known/{dwk}` JWKS seam while preserving distinct schemes and token +validation. + +## Deviations from plan + +No deviations have occurred. + +## Open questions / inputs needed + +### [2026-07-19] [Phase 0] Q1 - Public error detail API + +**BLOCKED.** Decide whether `AAuthTokenExchangeException.ErrorDescription` and +`TokenErrorResponse.ErrorDescription` become `Detail`, or retain their .NET +names while consuming the draft-09 `detail` wire member. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q1 entry under +> Decisions taken: rename both APIs to `Detail` with no compatibility alias. + +### [2026-07-19] [Phase 0] Q2 - RFC 9457 on R3 runtime endpoints + +**BLOCKED.** Decide whether the R3 token, document, challenge, and enforcement +error bodies join the common draft-09 problem-details cutover. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q2 entry under +> Decisions taken: include all listed R3 runtime errors. + +### [2026-07-19] [Phase 0] Q3 - Bootstrap and MockAgentProvider errors + +**BLOCKED.** Decide whether errors belonging to the unchanged Bootstrap +companion remain unchanged and move to a spin-off, or adopt RFC 9457 here. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q3 entry under +> Decisions taken: leave them unchanged and create a focused spin-off. + +### [2026-07-19] [Phase 0] Q4 - Missing AS clarification receiver + +**BLOCKED.** Decide whether to build the pre-existing missing AS clarification +response flow now or spin it off while migrating the implemented PS flow. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q4 entry under +> Decisions taken: migrate the PS flow and spin off the AS receiver. + +### [2026-07-19] [Phase 0] Q5 - AAuth Events companion + +**BLOCKED.** Decide whether to implement the complete Events companion and its +protocol metadata/registry seams here or create a separate initiative. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q5 entry under +> Decisions taken: spin off all Events source seams. + +### [2026-07-19] [Phase 0] Q6 - Revised R3 AsyncAPI behavior + +**BLOCKED.** Decide whether to add the multi-member AsyncAPI operation model and +Events handoff here or spin it off with Events. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q6 entry under +> Decisions taken: spin off R3 AsyncAPI with Events. + +### [2026-07-19] [Phase 0] Q7 - Signature Keys self-jwt + +**BLOCKED.** Decide whether to implement `self-jwt` here or create a separate +dependency/use-case initiative. + +> **Resolution (2026-07-20): RESOLVED.** Superseded by the Q7 entry under +> Decisions taken: create a coordinated `self-jwt` spin-off. diff --git a/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-plan.md b/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-plan.md new file mode 100644 index 00000000..9ee7b6d1 --- /dev/null +++ b/.agent/plans/2026-07-19-aauth-v09-spec-migration/implementation-plan.md @@ -0,0 +1,264 @@ +# Implementation Plan - AAuth SDK migration to protocol draft-09 + +Companion to [`research.md`](research.md). All Phase 0 scope rulings are recorded +in [`implementation-log.md`](implementation-log.md); this completed plan is +awaiting explicit owner approval. + +> Status: **Plan approval gate.** The immutable draft-09 snapshot and evidence +> map are approved, and Q1-Q7 are resolved. No SDK code changes are permitted +> until this complete plan is explicitly approved. + +## Guiding principles + +- **Spec accuracy over compatibility.** This is an alpha SDK. Wire and public API + changes use one coordinated draft-09 shape; no dual-format shims or stale + aliases unless the owner explicitly approves an exception. +- **Construction and verification move together.** Error producers/consumers and + clarification producers/consumers cut over atomically. +- **Do not imply unsupported companion support.** Events, R3 AsyncAPI, + `self-jwt`, Bootstrap error normalization, and the missing AS clarification + flow are research-and-plan spin-offs; this migration adds no partial runtime + API for them. +- **Keep compiled consumers green in-phase.** Non-compiled prose and illustrative + snippets wait for the post-code sweep; executable samples and e2e assertions + move with the behavior they exercise. +- **Re-check target citations before edits.** Every phase begins by verifying its + cited target lines against `aauth-spec/v09/`. +- **Validate every phase boundary.** Run `make build`, `make test-unit`, + `make test-conformance`, and `make e2e`. An unavailable e2e environment is a + blocker requiring an owner ruling. + +## Phase 0 - owner decision gate + +Resolve every open question from `research.md`, one at a time, and append each +ruling with rationale to `implementation-log.md`. + +### Implementation decisions + +- [x] **Q1:** Rename public `ErrorDescription` APIs to `Detail`; use only the + draft-09 `detail` wire member, with no alias or compatibility fallback. +- [x] **Q2:** Include R3 token, document, challenge, and enforcement error + bodies in the common RFC 9457 cutover. +- [x] **Q3:** Leave MockAgentProvider/Bootstrap errors unchanged and create a + focused research-and-plan spin-off. +- [x] **Q4:** Migrate the implemented PS clarification flow and create a + separate initiative for the pre-existing missing AS receiver. +- [x] **Q5:** Spin off the complete Events protocol and all optional + metadata/registry source seams. +- [x] **Q6:** Spin off the revised R3 AsyncAPI model and subscription handoff + with Events; retain Q2's RFC 9457 update for existing R3 endpoints. +- [x] **Q7:** Spin off Signature Keys `self-jwt` as a coordinated + dependency/use-case initiative. +- [ ] The completed dependency-ordered plan is explicitly approved. + +### Definition of Done + +- [x] Every open question has a `RESOLVED` ruling in + `implementation-log.md`. +- [x] The plan's phases and spin-off boundaries match those rulings. +- [ ] The owner has approved the final plan before SDK code changes. + +## Phase 1 - coordinated RFC 9457 error cutover + +Target: protocol `#error-responses` and `#error-response-format`, L2230-L2243, +plus the token/polling examples at L2259-L2292. This phase has no dependency on +Phase 2. + +### Scope + +- Add `src/AAuth/Server/AAuthProblemDetails.cs` as the shared result seam for a + required AAuth `error`, optional `detail`, and endpoint-specific extension + members, always serialized as `application/problem+json`. +- Move all approved AAuth error producers to + `application/problem+json`, `error`, and optional `detail`, without touching + success responses. +- Preserve endpoint status codes, `Signature-Error`, `AAuth-Requirement`, and + endpoint-specific extension members; clients branch only on `error`. +- Move `TokenExchangeClient` and `AccessServerClient` to `detail` only. Do not + retain an `error_description` fallback. +- Rename public `AAuthTokenExchangeException.ErrorDescription` and + `TokenErrorResponse.ErrorDescription` to `Detail`, including compiled + consumers. +- Include R3 token, document, challenge, and enforcement error bodies under Q2. +- Exclude MockAgentProvider enrollment/refresh errors under Q3. + +### Primary files + +- `src/AAuth/Server/AAuthProblemDetails.cs` (new) +- `src/AAuth/Agent/TokenExchangeClient.cs` +- `src/AAuth/Access/AccessServerClient.cs` +- `src/AAuth/Errors/AAuthTokenExchangeException.cs` +- `src/AAuth/Errors/TokenError.cs` +- `src/AAuth/Person/AAuthPersonServerEndpoints.cs` +- `src/AAuth/Access/AAuthAccessServerEndpoints.cs` +- `src/AAuth/DependencyInjection/AAuthApplicationBuilderExtensions.cs` +- `src/AAuth/DependencyInjection/AAuthGovernanceApplicationBuilderExtensions.cs` +- `src/AAuth/Server/RevocationEndpoint.cs` +- `src/AAuth/Server/Governance/GovernanceEndpoints.cs` +- `src/AAuth/Server/ResourceManaged/AAuthInteractionEndpointExtensions.cs` +- `src/AAuth/Server/Verification/AAuthHttpContextExtensions.cs` +- `src/AAuth.R3/R3AccessTokenEndpoint.cs` +- `src/AAuth.R3/R3DocumentEndpoint.cs` +- `src/AAuth.R3/R3Challenge.cs` +- `src/AAuth.R3/R3Enforcement.cs` +- `samples/LiveWhoAmITest/Program.cs` +- `tests/AAuth.Tests/Agent/ChallengeHandlerTests.cs` +- `tests/AAuth.Tests/AccessServerClientTests.cs` +- `tests/AAuth.Conformance/Errors/ProblemDetailsTests.cs` (new) +- `tests/AAuth.Conformance/Errors/TokenErrorTests.cs` +- `tests/AAuth.Conformance/Errors/PollingErrorTests.cs` +- `tests/AAuth.Conformance/Person/PersonServerMapperTests.cs` +- `tests/AAuth.Conformance/Discovery/JtiStoreAndRevocationTests.cs` +- `tests/AAuth.Conformance/Missions/GovernanceServerTests.cs` +- `tests/AAuth.R3.Tests/AccessEndpointR3Tests.cs` +- `tests/AAuth.R3.Tests/ResourceR3Tests.cs` + +### Definition of Done + +- [ ] Every approved error body uses `application/problem+json`; success + response media types are unchanged. +- [ ] `error` remains the only AAuth behavior discriminator. +- [ ] Human-readable text uses `detail` end to end, including public .NET API + names and compiled consumers. +- [ ] No consumer branches on RFC 9457 `type`. +- [ ] No `error_description` remains in migrated `src/`, fixtures, or compiled + consumers; Q3's MockAgentProvider residue is explicitly excluded. +- [ ] Representative PS, AS, authorization, interaction, governance, challenge, + revocation, and R3 tests assert status, media type, `error`, and `detail`. +- [ ] Optional RFC 9457 members do not affect client error classification. +- [ ] Targeted unit, conformance, and R3 tests pass. +- [ ] `make build`, `make test-unit`, `make test-conformance`, and `make e2e` + pass. + +## Phase 2 - coordinated clarification `action` cutover + +Target: protocol `#agent-response-to-clarification`, L1012-L1080. Depends on +Phase 1 so invalid action responses use the approved problem-details seam. + +### Scope + +- Define the two exact action strings once and use them in agent construction + and PS validation. +- Emit `action=clarification_response` and `action=updated_request` from + `ClarificationExchange`. +- At the PS, reject missing or unknown actions with `400`; apply defensive + `invalid_request` validation when a recognized action lacks its matching + `clarification_response` or `resource_token`. +- Stop inferring the operation from payload-member presence. +- Update manual compiled producers and all directly coupled fixtures/mocks. +- Leave cancellation as `DELETE`. +- Do not add an AS clarification receiver under Q4. + +### Primary files + +- `src/AAuth/AAuthConstants.cs` +- `src/AAuth/Agent/ClarificationExchange.cs` +- `src/AAuth/Person/AAuthPersonServerEndpoints.cs` +- `samples/GuidedTour/TourSession.cs` +- `tests/AAuth.Conformance/Missions/ClarificationChatTests.cs` +- `tests/AAuth.Conformance/Missions/ChallengeClarificationSeamTests.cs` +- `tests/AAuth.Conformance/Missions/GovernanceClientTests.cs` +- `tests/AAuth.Conformance/Person/PersonServerMapperTests.cs` +- `tests/AAuth.Tests/Integration/MissionAgentFlowTests.cs` +- `samples/GuidedTour/playwright-tests/mission-call-chain.spec.ts` +- `samples/SampleApp/playwright-tests/mission-call-chain.spec.ts` + +### Definition of Done + +- [ ] Both POST actions use the exact draft-09 strings. +- [ ] Missing and unknown actions return `400` as draft-09 mandates. +- [ ] Recognized actions without their required payload fail as defensive + `invalid_request` validation; this is not reported as a spec status-code + requirement. +- [ ] Cancel remains a bodyless `DELETE`. +- [ ] SDK, PS, manual sample producers, and fixtures are symmetric. +- [ ] Captured-wire tests prove both emitted JSON shapes. +- [ ] The live clarification flow exposes and exercises + `action=clarification_response`. +- [ ] No AS clarification receiver or partial AS state machine is introduced. +- [ ] `make build`, `make test-unit`, `make test-conformance`, and `make e2e` + pass. + +## Phase 3 - frozen-surface inventory and update + +After all approved code phases are green, run the post-code checklist from +`REVIEW-CHECKLISTS.md` with independent read-only reviewers split by surface. +Present the resulting `surface | file | delta | required edit` table and wait +for approval before edits. + +The approved sweep covers string-literal snippets, illustrative code, READMEs, +docs, e2e assertions, and version tracking. Tracking documents name draft-09 as +the SDK target only after the approved runtime work and explicitly list +unsupported/spun-off companion behavior. + +Expected direct surfaces include: + +- `samples/GuidedTour/CodeSnippets.cs` +- `docs/advanced/error-handling.md` +- `docs/advanced/clarification-chat.md` +- top-level and sample READMEs discovered by the approved inventory +- `aauth-spec/SPEC-VERSION.md` and `aauth-spec/CHANGELOG.md` + +### Definition of Done + +- [ ] The owner approved the complete surface inventory. +- [ ] Every approved non-compiled edit is present. +- [ ] Stale `error_description`, old clarification bodies, and outdated version + claims are absent or explicitly justified; MockAgentProvider Bootstrap + errors remain only under the Q3 disposition. +- [ ] Tracking names draft-09 as the SDK target and states that Events, R3 + AsyncAPI, `self-jwt`, and AS clarification remain unsupported/spun off. +- [ ] A fresh full-stack e2e boot exercises affected samples. +- [ ] All four validation targets pass. + +## Phase 4 - research-and-plan-only spin-offs + +Create these separate initiatives without implementing their source changes: + +| Initiative | Required research boundary | +|---|---| +| Bootstrap problem-details format | Q3 MockAgentProvider enrollment/refresh errors and companion ownership | +| Access Server clarification | Q4 pending state, PS-to-AS signed response, polling/federation, and e2e | +| AAuth Events plus R3 AsyncAPI | Q5/Q6 complete Events feature groups, R3 multi-member operations, persistence, replay, routing, samples, and e2e | +| Signature Keys `self-jwt` | Q7 concrete use case, parser/provider APIs, admitted discovery, cache, `cnf` rejection, SSRF, and tests | + +The Events and `self-jwt` initiatives cross-reference one shared admitted +`{iss}/.well-known/{dwk}` JWKS resolution/cache primitive while preserving +their distinct wire schemes and token-type checks. + +### Definition of Done + +- [ ] All four initiatives have research, a Phase 0 decision gate, a + dependency-ordered implementation plan, and an implementation log. +- [ ] The Events initiative accounts for every Events section and the complete + revised R3 AsyncAPI delta. +- [ ] The `self-jwt` and Events initiatives cross-link their shared discovery + seam without conflating the wire schemes. +- [ ] This migration links each spin-off and states its unsupported runtime + boundary. + +## Phase 5 - independent final review + +Give a fresh read-only reviewer the complete diff, target specifications, +research, approved plan, and implementation log. Present every severity-graded +finding before edits and obtain one owner ruling per finding. + +### Definition of Done + +- [ ] Every finding has a recorded disposition. +- [ ] Every approved fix is validated. +- [ ] A materially changed design receives a fresh review. +- [ ] The final full validation matrix is green. +- [ ] All changes remain uncommitted for owner inspection. + +## Out of scope + +| Item | Reason | +|---|---| +| Compatibility aliases or dual-wire parsing | Conflicts with the owner's exact latest-spec ruling | +| MockAgentProvider/Bootstrap error normalization | Q3 spin-off | +| Access Server clarification receiver | Q4 spin-off | +| AAuth Events runtime and metadata/token seams | Q5 spin-off | +| R3 AsyncAPI vocabulary/model and Events handoff | Q6 spin-off | +| Signature Keys `self-jwt` support | Q7 spin-off | +| Unrelated pre-existing defects | Not part of the draft-09 cutover | diff --git a/.agent/plans/2026-07-19-aauth-v09-spec-migration/research.md b/.agent/plans/2026-07-19-aauth-v09-spec-migration/research.md new file mode 100644 index 00000000..f53b8379 --- /dev/null +++ b/.agent/plans/2026-07-19-aauth-v09-spec-migration/research.md @@ -0,0 +1,398 @@ +# Research - AAuth SDK migration to protocol draft-09 + +> Research-only. Implementation work belongs in +> [`implementation-plan.md`](implementation-plan.md); owner rulings and later +> deviations belong in [`implementation-log.md`](implementation-log.md). + +## Goal + +Determine the complete repository impact of moving the SDK from protocol +**draft-08** to the published **draft-09** snapshot. The target also ships a +revised R3 draft, a new AAuth Events companion draft, and HTTP Signature Keys +draft-06. The snapshot is vendored at +[`aauth-spec/v09/`](../../../aauth-spec/v09/); the confirmed baseline is +[`aauth-spec/v08/`](../../../aauth-spec/v08/). + +## Method + +Four independent read-only subagents analyzed non-overlapping logical change +sets: RFC 9457 errors, clarification actions, AAuth Events plus R3, and +Signature Keys `self-jwt`. Their reports were collated and then checked directly +against the vendored specifications and current repository code. + +The following high-stakes findings were directly re-verified: + +- the exact `action` values and the server's new `400` rejection requirement; +- the `application/problem+json`, `detail`, and `error` requirements; +- every newly introduced token type, metadata member, and R3 wire member; +- the Events draft's `dwk`-without-`cnf` verification extension; +- the separate Signature Keys `self-jwt` trust and cache requirements; +- construction/verification symmetry in the current clarification and error + paths; and +- claims that Events and `self-jwt` have no current runtime attachment point. + +Repository citations below are workspace-relative. Protocol and companion +citations use stable anchors where available and exact lines in the vendored +target. + +## Authoritative sources + +| Source | Role | +|---|---| +| [`v09/draft-hardt-oauth-aauth-protocol.md`](../../../aauth-spec/v09/draft-hardt-oauth-aauth-protocol.md) | Published protocol draft-09 target | +| [`v08/draft-hardt-oauth-aauth-protocol.md`](../../../aauth-spec/v08/draft-hardt-oauth-aauth-protocol.md) | Confirmed protocol draft-08 baseline | +| [`v09/draft-hardt-aauth-events.md`](../../../aauth-spec/v09/draft-hardt-aauth-events.md) | New Events draft-00 companion source | +| [`v09/draft-hardt-aauth-r3.md`](../../../aauth-spec/v09/draft-hardt-aauth-r3.md) | Revised R3 draft-00 companion | +| [`v09/draft-hardt-httpbis-signature-key-06.txt`](../../../aauth-spec/v09/draft-hardt-httpbis-signature-key-06.txt) | Target Signature Keys dependency | +| [`v08/draft-hardt-httpbis-signature-key-05.txt`](../../../aauth-spec/v08/draft-hardt-httpbis-signature-key-05.txt) | Baseline Signature Keys dependency | +| [`aauth-spec/CHANGELOG.md`](../../../aauth-spec/CHANGELOG.md) | Vendored snapshot catalogue | + +## Snapshot accounting + +| Document | Baseline-to-target status | Research disposition | +|---|---|---| +| Protocol | Revised | Two wire cutovers plus Events integration | +| Bootstrap | Byte-identical | No migration delta | +| R3 | Revised | Explicit include-or-spin-off ruling required | +| Interop Demo Profile | Byte-identical | No migration delta | +| AAuth Events | New draft-00 companion | Explicit include-or-spin-off ruling required | +| HTTP Signature Keys | draft-05 -> draft-06 | Adds `self-jwt`; explicit include-or-spin-off ruling required | + +The byte-identical Bootstrap and Interop claims were confirmed with direct byte +comparisons. The new Events file is pinned by the protocol draft-09 tag but had +no separate published tag or Datatracker revision when vendored. + +## Cross-cutting conclusions + +1. **Two draft-09 changes attach directly to implemented flows.** RFC 9457 + errors and clarification `action` values require coordinated producer and + consumer cutovers. +2. **Events is a new protocol, not a small extension.** Its normative flow + requires token builders and verifiers, resource registration endpoints, + subscription storage, an AP delivery endpoint, durable routing, replay + enforcement, agent verification, and AsyncAPI discovery. None exists today. +3. **R3 exposes an existing model boundary.** Current R3 operations deliberately + support one-member objects, while a valid AsyncAPI operation has + `operationId` plus optional `action`. +4. **`self-jwt` and the Events JWT extension are not the same wire scheme.** + Signature Keys draft-06 defines `sig=self-jwt`; Events presents + `sig=jwt` with `dwk` and no `cnf`. Both discover a key and use it for JWT and + HTTP signatures, but they are specified separately and must not be conflated. + +## Change set 1 - RFC 9457 AAuth error responses + +### Target and baseline + +Draft-09 makes the common error body an RFC 9457 problem-details object with +`Content-Type: application/problem+json`. `error` remains REQUIRED and controls +AAuth behavior; `detail` replaces `error_description`; standard `type`, `title`, +`status`, and `instance` members MAY appear, but receivers MUST NOT identify an +AAuth error from `type` (`#error-responses`, `#error-response-format`, +L2230-L2243). The token and polling examples use the new media type and `detail` +(L2259-L2268, L2283-L2292). + +The draft-08 baseline limited the named format to token endpoints and used +`application/json` plus optional `error_description` +(`#error-response-format`, L2242-L2247). + +Draft-09 also points authorization endpoint, interaction endpoint, and +mission-status errors at the common format (protocol L704-L714, L1296-L1306, +L1419-L1434). Authentication failures still use the `Signature-Error` header +(L2232-L2234); a JSON body, when present, is still an error body governed by the +common format. + +### Current repository state + +No `application/problem+json` occurrence exists in `src/`, `tests/`, `samples/`, +or `docs/`. + +Most PS and AS errors already serialize `error` plus `detail`, but use +`Results.Json` or typed convenience results without an explicit problem-details +media type. Representative producers are +[`AAuthPersonServerEndpoints.cs`](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs) +(L284-L310, L417-L434, L506-L596, L643-L757) and +[`AAuthAccessServerEndpoints.cs`](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs) +(L214-L238, L272-L325, L378-L444, L491-L591). `Results.NotFound` error bodies +on the same endpoints also default to ordinary JSON. + +The complete directly attached producer inventory includes: + +| Surface | Evidence | Classification | +|---|---|---| +| PS and AS endpoints | `AAuthPersonServerEndpoints.cs` L284-L909; `AAuthAccessServerEndpoints.cs` L214-L601 | `detail` mostly present; media type missing | +| Governance endpoints | `AAuthGovernanceApplicationBuilderExtensions.cs` L88-L164 and L227-L396; `GovernanceEndpoints.cs` L113-L123 | Media type missing | +| Resource-managed interaction | `AAuthInteractionEndpointExtensions.cs` L41-L74 | Media type missing | +| Authorization helper | `AAuthApplicationBuilderExtensions.cs` L138-L170 | Still emits `error_description`; media type missing | +| Revocation | `RevocationEndpoint.cs` L62-L98 | Still emits `error_description`; media type missing | +| Resource challenge helper | `AAuthHttpContextExtensions.cs` L62-L70 | Error body media type missing | +| R3 runtime endpoints | `R3AccessTokenEndpoint.cs`, `R3DocumentEndpoint.cs`, `R3Enforcement.cs`, `R3Challenge.cs` | Uses AAuth-shaped errors; scope ruling required | +| Mock Agent Provider | `samples/MockAgentProvider/Program.cs` L86-L270 | Bootstrap-family errors still use `error_description`; scope ruling required | + +This inventory is broader than the initial subagent report: direct search found +the governance application mappings and challenge helper as additional +producers. Success responses in the same files are not part of the cutover and +must not be bulk-rewritten. + +Both SDK error consumers still parse only `error_description`: + +- [`TokenExchangeClient.cs`](../../../src/AAuth/Agent/TokenExchangeClient.cs) + L196-L249; and +- [`AccessServerClient.cs`](../../../src/AAuth/Access/AccessServerClient.cs) + L470-L515. + +They already branch on the required `error` member and do not inspect RFC 9457 +`type`, so the `MUST NOT rely on type` requirement is already satisfied. Reading +only `error_description` loses human-readable detail from the existing PS/AS +producers even before the content-type migration; this is a tightly coupled +pre-existing defect. + +Two public API names mirror the removed wire member: + +- `AAuthTokenExchangeException.ErrorDescription` + ([`AAuthTokenExchangeException.cs`](../../../src/AAuth/Errors/AAuthTokenExchangeException.cs), + L9-L45); and +- `TokenErrorResponse.ErrorDescription` + ([`TokenError.cs`](../../../src/AAuth/Errors/TokenError.cs), L43-L50). + +The repository's spec-accuracy posture forbids a dual-wire fallback unless the +owner approves an exception. A clean cutover therefore reads `detail`, not +`detail ?? error_description`. Whether the public .NET names also become +`Detail` is an explicit API decision. + +Tests currently mock `error_description` in +`AccessServerClientTests.cs` L311 and `ChallengeHandlerTests.cs` L328, while +`PersonServerMapperTests.cs` and the error conformance tests assert codes but +not `application/problem+json`. `docs/advanced/error-handling.md` contains the +same stale wire member and public API names at L97-L149 and L323. + +### Classification and validation evidence + +The core error work is a **coordinated wire and public-API cutover**: + +- producers must emit the new media type and `detail`; +- consumers must read `detail` while continuing to branch on `error`; +- error fixtures and public API references must move with them; and +- success responses and header-only authentication failures must remain + unchanged. + +Evidence must include positive media-type/body assertions for representative PS, +AS, authorization, interaction, governance, challenge, and revocation errors; +client parsing of `detail`; tolerance of optional RFC 9457 members; and a search +showing no consumer relies on `type`. R3 and Mock Agent Provider coverage depend +on owner scope rulings. + +## Change set 2 - clarification response `action` + +### Target and baseline + +Every clarification POST body now MUST carry `action`. The two recognized values +are `clarification_response` and `updated_request`; a server MUST reject a +missing or unrecognized value with `400 Bad Request` +(`#agent-response-to-clarification`, L1012-L1021). The two request examples show +the exact body shapes (L1022-L1062). Cancellation remains `DELETE` and has no +body (L1064-L1068). + +Draft-08 inferred the response type from `clarification_response` or +`resource_token` and defined no `action` member (protocol draft-08 L1022-L1071). + +### Current repository state + +The implemented producer and consumer are symmetric for draft-08 and both must +move together: + +| Role | Evidence | Current behavior | +|---|---|---| +| Agent producer | `ClarificationExchange.cs` L149-L165 | Sends only `clarification_response` or `resource_token` | +| PS consumer | `AAuthPersonServerEndpoints.cs` L420-L446 | Infers type from key presence; never validates `action` | +| Manual sample producer | `samples/GuidedTour/TourSession.cs` L4997-L5008 | Posts an anonymous body without `action` | +| Test bypass producers | `PersonServerMapperTests.cs` L479, L568, L575 | Post old draft-08 bodies | +| Test consumers | `ClarificationChatTests.cs` L201-L212; `ChallengeClarificationSeamTests.cs` L201; `GovernanceClientTests.cs` L299 | Do not assert `action` | + +The public `ClarificationResponse` model already distinguishes Respond, Update, +and Cancel (`ClarificationExchange.cs` L15-L71); no public model redesign is +needed. `DeferredExchange` delegates to this serializer, so it inherits the +wire fix. + +Compiled SampleApp paths use the SDK model and inherit the change. GuidedTour +constructs one body manually and must move with the code phase. Non-compiled +prose and the displayed snippet in `samples/GuidedTour/CodeSnippets.cs` +L472-L480 belong in the post-code sweep. Existing Playwright mission-flow tests +exercise the exchange but do not inspect the new member. + +The baseline already said that both PSes and ASes can issue clarification +requirements (draft-08 L1018-L1022). The current AS has no clarification +response receiver, so that is a **pre-existing unattached flow**, not a new +draft-09 delta. Whether to add it now is an explicit scope ruling. + +### Classification and validation evidence + +This is a **coordinated wire cutover**. Producer and consumer must use the same +two exact action strings. The server MUST reject missing and unknown actions. +Rejecting a recognized action whose required payload is missing or mismatched is +defensive `invalid_request` validation implied by the selected operation's body +shape, but draft-09 does not mandate its status code. + +Required evidence includes captured producer JSON for both actions; positive PS +acceptance; negative `400` tests for missing and unknown values; negative tests +for defensive handling of a recognized action without its required payload; the +existing end-to-end clarification round trip; and a GuidedTour e2e assertion +exposing the action member. + +## Change set 3 - AAuth Events and protocol integration + +### Protocol integration + +Draft-09 adds optional `event_endpoint` to agent-provider metadata, required when +the AP supports Events (`#metadata-documents`, protocol L2482-L2510), and records +the companion's `aa-subscribe+jwt` and `aa-event+jwt` types (L2899-L2915). It +also describes the AP as an event router and asynchronous delivery as a protocol +capability (L142-L146, L377-L382). + +Current `AAuthAgentMetadataOptions` has no `EventEndpoint` property +([`AAuthAgentMetadataOptions.cs`](../../../src/AAuth/Server/Metadata/AAuthAgentMetadataOptions.cs), +L8-L49), `BuildAgentMetadata` does not emit it +([`WellKnownEndpoints.cs`](../../../src/AAuth/Server/Metadata/WellKnownEndpoints.cs), +L208-L223), and the discovery model does not parse it +([`ServerMetadata.cs`](../../../src/AAuth/Discovery/ServerMetadata.cs), +L10-L87). The Events token strings do not occur outside the vendored spec and +tracking documents. + +### New Events companion + +The new companion is a complete protocol. Its normative groups are: + +| Feature group | Target evidence | +|---|---| +| AP metadata | `#ap-metadata`, Events L190-L202 | +| Subscribe token claims, presentation, verification | `#subscribe-token`, L204-L283 | +| Public and protected registration | `#subscription-registration`, `#protected-subscriptions`, L285-L339 | +| Event token claims | `#event-token`, L340-L374 | +| Resource-to-AP delivery and AP validation | `#event-delivery`, L376-L429 | +| AP-to-agent routing and agent verification | `#ap-to-agent`, L430-L447 | +| AsyncAPI discovery and security scheme | `#event-discovery`, L449-L573 | +| Replay, ticket, privacy, and retention constraints | L574-L616 | +| JWT type and vocabulary registrations | L618-L632 | + +No runtime attachment exists for any complete group: + +- no subscribe/event token builder or verifier; +- no subscription registration or ticket endpoint; +- no subscription record or `eid` context store; +- no AP `event_endpoint` implementation or durable-delivery queue; +- no resource event-delivery client; +- no agent event verifier or deduplication path; and +- no AsyncAPI vocabulary constant or sample. + +The Events verification boundary is especially important. Event delivery uses +`sig=jwt` with a JWT carrying `dwk` but no `cnf`; the AP must discover the +resource key by `iss`, `dwk`, and `kid`, verify the JWT, and verify the HTTP +signature with the same key (`#event-delivery`, L391-L410). Current +`SignatureKeyParser` accepts `scheme=jwt`, but `DefaultSignatureKeyResolver` +requires `cnf.jwk` (`SignatureKeyParser.cs` L89-L101; +`DefaultSignatureKeyResolver.cs` L28-L48). Supporting Events would therefore +introduce a new trust branch and token-type separation, not a harmless reuse of +the agent-token path. + +### Classification and validation evidence + +The full companion is **unsupported by any current flow**. Its trust, storage, +delivery, and replay requirements should be implemented only as an approved +initiative with its own research and plan. If included here, validation would +need positive and negative token verification, ticket single-use and +agent-binding tests, atomic `max_uses`, durable-before-`202`, replay and expiry +tests, resource/AP/agent integration, AsyncAPI discovery, and a fresh full-stack +e2e scenario. + +The small protocol metadata and registry additions are additive, but exposing +them without the underlying flow can imply support that does not exist. Their +include-versus-spin-off disposition should follow an explicit owner ruling. + +## Change set 4 - revised R3 AsyncAPI vocabulary + +R3 keeps draft number 00 but revises the AsyncAPI operation: `operationId` +remains REQUIRED, `action` becomes OPTIONAL, and an R3-granted subscription +hands off to AAuth Events using a subscription ticket and subscribe token +(`#asyncapi-vocabulary`, R3 L186-L200). + +Current `Vocabulary` defines only MCP and OpenAPI +([`Vocabulary.cs`](../../../src/AAuth.R3/Model/Vocabulary.cs), L1-L8). More +importantly, `R3Operation` deliberately accepts exactly one string member and +documents AsyncAPI as unsupported +([`R3Operation.cs`](../../../src/AAuth.R3/Model/R3Operation.cs), L6-L14, +L55-L84). A valid AsyncAPI operation can carry both `operationId` and `action`, +so current deserialization rejects it. No sample or test uses the AsyncAPI +vocabulary. + +This is a **changed companion with no current runtime attachment point**. Adding +only a vocabulary constant is safe but incomplete; full conformance needs a +multi-member operation model and Events registration semantics. Include or +spin-off requires an explicit owner ruling independent of the Events ruling. + +## Change set 5 - HTTP Signature Keys `self-jwt` + +Signature Keys draft-06 adds `sig=self-jwt`. The JWT MUST contain HTTPS `iss` +and `dwk`, MUST have `kid`, MUST NOT contain `cnf`, and SHOULD contain standard +claims. Verification discovers the issuer JWKS, rejects `cnf`, verifies the JWT, +then verifies the HTTP signature with the same key (draft-06 section 3.7, +L757-L830). Discovered keys are cached by `iss + kid` until JWT expiry +(section 6.2, L1412-L1421). The issuer-controlled discovery path inherits SSRF +admission requirements, and a JWT containing `cnf` MUST be rejected +(section 6.3, L1494-L1502). + +The main AAuth protocol still requires agents to use `scheme=jwt` for resource, +PS, and AS requests and does not attach `self-jwt` to an implemented protocol +flow (`#keying-material`, protocol L2334-L2341). + +Current code has no `self-jwt` constant, formatter, parser branch, provider, +resolver, builder, test, sample, or documentation. Direct searches found no +occurrence in `src/`, `tests/`, `samples/`, or `docs/`. Relevant dispatch points +are `AAuthConstants.Schemes` (`AAuthConstants.cs` L41-L57), +`SignatureKeyHeader` L16-L88, `SignatureKeyParser.ParseAny` L89-L101, and +`DefaultSignatureKeyResolver.ResolveAsync` L28-L48. `JwksClient` caches JWKS +documents by URI with a fixed TTL, not discovered keys by `iss + kid` bounded by +JWT expiry (`JwksClient.cs` L15-L68). + +This dependency feature has **no current attachment point** and requires an +explicit include-or-spin-off ruling. + +If implementation is approved, two upstream example inconsistencies need a +ruling first: the example uses `typ=aauth-resource+jwt` and +`dwk=aauth-resource`, while this repository and the AAuth protocol use +`aa-resource+jwt` and `aauth-resource.json` (draft-06 L829-L872). These values +are illustrative rather than an AAuth protocol mandate, but they prevent a +safe implementation from being inferred without a selected use case. + +Although Events `sig=jwt` without `cnf` and Signature Keys `sig=self-jwt` are +distinct wire paths, both need the same admitted +`{iss}/.well-known/{dwk}` -> JWKS -> `kid` discovery primitive. Separate +spin-off plans must coordinate on one shared resolver/cache seam so SSRF, +refresh, and expiry behavior cannot diverge. + +## Surface inventory + +| Surface | Draft-09 impact | +|---|---| +| SDK model/wire | Error media type/member; clarification action; conditional Events/R3/self-jwt additions | +| Trust/policy | `error` remains discriminator; Events no-`cnf` branch and self-jwt discovery are new conditional trust boundaries | +| Endpoint/client pairs | PS/AS errors and clients; clarification producer/PS consumer | +| Tests | Error media-type/body tests; strict action positives/negatives; conditional companion suites | +| Compiled samples | GuidedTour manual clarification body; LiveWhoAmITest if error API is renamed | +| Non-compiled surfaces | Error and clarification docs/snippets; version statements after code freeze | +| Runtime verification | Existing mission clarification e2e; no Events/self-jwt e2e attachment | +| Version tracking | Vendoring correctly says latest v09 and SDK target v08 until migration completes | +| Companions | Bootstrap/interop unchanged; R3 revised; Events new; Signature Keys revised | + +## Gaps and open questions + +| ID | Question | Recommended ruling | +|---|---|---| +| Q1 | **Resolved:** public `ErrorDescription` members become `Detail`. | Clean spec-shaped cutover; no alias or dual-wire fallback | +| Q2 | **Resolved:** RFC 9457 applies to all runtime R3 error endpoints in this migration. | Include them in the common error cutover | +| Q3 | **Resolved:** unchanged Bootstrap/MockAgentProvider errors do not move to RFC 9457 here. | Create a focused research-and-plan spin-off | +| Q4 | **Resolved:** do not build the missing AS clarification receiver here. | Migrate the implemented PS flow and create an AS clarification spin-off | +| Q5 | **Resolved:** do not implement AAuth Events or its source seams here. | Spin off the complete Events protocol into a separate initiative | +| Q6 | **Resolved:** revised R3 AsyncAPI support is not implemented here. | Spin off the AsyncAPI model and subscription handoff with Events | +| Q7 | **Resolved:** Signature Keys `self-jwt` is not implemented here. | Create a coordinated dependency/use-case spin-off | + +The Events and `self-jwt` spin-offs must share one admitted `dwk` discovery +primitive while preserving their different wire schemes and token checks. diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/api-surface-map.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/api-surface-map.md new file mode 100644 index 00000000..b7b49f17 --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/api-surface-map.md @@ -0,0 +1,3153 @@ +--- +description: Complete migration public API inventory and reviewed ownership, defaults and verification. +--- + +# Public API surface map + +Phase 11, 2026-09-09. Implementation baseline: `ba768f1`. This is the complete migration source inventory, +not a claim that the trailing Phase 12 security review or Phase 13 docs sweep +has finished. The generated appendix includes tracked and untracked SDK source. + +Historical status (Phase 13, 2026-09-09): Phase 12 security closure and Phase 13 +documentation alignment are complete; the paragraphs reporting Phase 11 totals +below retain that checkpoint's history. API freshness then covered 196 changed files, ++761/-149 declarations and zero unmapped files. The current +[docs inventory](docs-surface-map.md) replaces representative snippet coverage +with every discovered display block and explicit validation classes. Final +Release is 2128 tests; browsers are 68 live and 67 stub plus one live-only skip. +Independent Phase 14 review and Phase 15 post-review alignment remain open. + +Final authorization repairs supersede that checkpoint's source surface: +197 changed public-source files, +777/-149 declarations, zero unmapped files, +with non-writing freshness verified. The generated appendix includes the new +Documents session and current mission consent contracts. Full Release is 2160 +passed; browsers are 72 live and 71 stub plus one live-only skip. Details are in the +[implementation log](implementation-log.md); this update does not complete the +independent review. + +Current Phase 14 repair checkpoint (2026-09-09): 198 changed public-source files, ++790/-152 declarations, zero unmapped files. `ChallengeHandler` now takes the +shared verifier, metadata and JWKS clients; the builder owns its discovery +dependencies while manual hosts retain ownership. Verification precedes any +exchange and uses the original signed request context. R3 issuance retains +verified mission and checks the authenticated PS approver. The sample AP exposes +an entry marker for actual-host testing and a configurable isolated key directory. +Documents/Events provide ten exact compiled step templates. Full Release passes +2234 tests; fresh browsers pass 72 live and 71 stub plus one live-only skip, +all with zero retries. This supersedes earlier counts, not independent review. + +## Reading the map + +Final Phase 14 focused repair delta (2026-09-09): 200 changed public-source files, ++800/-162 declarations, zero unmapped files. `AgentId.Parse/TryParse`, the actor +builder/reader helpers, `ActChainsMatch`, and `AgentAuthTokenValidator.Validate` +accept an optional explicit egress policy; production remains the default. +Agent domains remain host-only even under HTTPS loopback origin admission. +`R3Parameter.Json` and `Inline` accept nullable JSON values through a non-null +parameter wrapper. Factory-backed refresh-only clients retain live sources and +check cancellation before publishing renewed state. These ownership and null +semantics are covered by the focused tests in the append-only implementation log. +Bootstrap enrollment still exposes concrete Ed25519 keys; the documented limit +does not apply to algorithm-neutral single-key refresh or signing/verification. +No compatibility alias, new enrollment abstraction, or independent-review closure +is implied by this source inventory. + +Remaining-repair checkpoint (2026-09-09): 201 changed public-source files, ++810/-162 declarations, zero unmapped files. `TokenRequestBody.ReadAsync` +returns structurally checked but unverified JSON; only subsequent verification +can establish trusted claims. `TokenCredential`, the exception's optional +credential context, `UpstreamTokenValidationResult.FailureCode`, and +`AAuthProblemDetails.TokenFailure` preserve typed token/expiry classification +without treating body parameters as failed request authentication. Existing +success bodies and trust boundaries are unchanged. Tests cover every credential +field, raw duplicate JSON, pending replacement/claims non-mutation, and carrier +401 headers. Release passes 2859 tests; independent review remains open. + +Each concept row applies to every explicitly listed file/member in its appendix +group. The appendix records exact old/new declarations, including defaults and +mandatory inputs, rather than relying on the earlier phase handoff lists. +Behavior-only changed files are retained. Spec references name concepts, not +required .NET method names. Public options and store interfaces remain explicit +capabilities; convenience never grants trust, selects accounts or manufactures +verified context. + +Reproduce with `dotnet run --project tools/ApiSurface -- . ba768f1 --write`. +Omit `--write` to fail on a stale inventory. Roslyn comes from the installed .NET +SDK, so no new NuGet package is needed. The source scanner inventories declared +APIs, not binary compatibility or compiler-generated member expansion. + +## Agent clients + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Agent provisioning, distinct from Signature-Key scheme | Bootstrap, From, Enrolled, SelfIssuing | EnrolWithKeyAsync; optional requested ID; EnrollResult.AgentId | Bootstrap.WithKey/WithEgressPolicy; Enrolled.RefreshingFrom.WithKeyStore | Signed enrollment; provider assigns identity; default production admission; factory owns HTTP, store/key borrowed | SampleApp EnrollmentService; AgentConsole; GuidedTour enrollment | AP enrollment HTTP tests; BootstrapTests; snippet compilation | +| Issued agent JWT as resource credential | From(EnrollResult), UseJwt | Fixed token and Func carrier APIs | From defaults to enrollment AgentToken, never key URL; UseJwt parameter is token, not agentToken | No network at construction; no implicit refresh/topology; explicit scheme after refresh disables refresh; later refresh selects jwt | AgentConsole; docs bootstrap and JWT; fixed auth-token tour steps | ClientCompositionTests carrier matrix | +| AP refresh with fixed durable key | Enrolled, AgentProviderTokenRefresher.Create | ITokenRefresher; TokenRefreshContext.Account; admitted refresh transport | Direct resource-managed forwarder; ToBuilder transition | Built pipeline owns factory refresher/client; injected refresher/client borrowed; reuse builds independent owned resources; cancellation forwarded | SampleApp Inbox; docs resource-managed | ClientCompositionTests; AgentProviderTokenRefresherTests; TokenRefreshHandlerTests | +| Two-key AP refresh | AgentProviderClient.RefreshTwoKeyAsync | TwoKeyRefreshResult.EphemeralKey/AgentToken | Keep explicit advanced result; no rotating-key wrapper | Fixed-key Enrolled rejects TwoKey; raw refresher supports advanced coordinated rotation; no stale fixed signer | JktJwt generic demonstration; AgentConsole | Both refresh carriers captured; fixed-key rejection regression | +| Self-issued agent token | SelfIssuing.As.WithKid | SelfIssuedTokenRefresher with explicit egress policy | WithResourceManagedAccess, WithInteractionHandling, ToBuilder | Locally issues aa-agent+jwt with cnf; not self-jwt; issuer/key must be published; key borrowed | GuidedTour Inbox; SampleApp Calendar/Bookings | SelfIssuingBuilderTests; ClientCompositionTests; browsers | +| Challenge, deferred, clarification and chaining | WithChallengeHandling, WithInteractionHandling, WithCallChaining, WithMission | DeferredExchange/ClarificationExchange; required action; exact token/account context | Existing options already express callbacks, polling and mission; retain advanced exchange/poller | Flow options do not choose carriers; PS/AS requests require agent JWT; origin/account/key-bound carriers | GuidedTour individual steps; SampleApp deferred/federated/mission | Core challenge, clarification, deferred and chain tests; full browsers | + +## Discovery + +Phase 12 adds `DeferredPollerOptions.TimeProvider` and +`InteractionHandler.TimeProvider`, both defaulting to `TimeProvider.System`. +These borrowed clock sources control Retry-After dates, elapsed budgets, delays +and cancellation deadlines; no production timing requirement becomes optional. +The internal delay hook exists only for deterministic friend-assembly tests. +Mission state keeps its public init-only API; session completion and terminal +errors now update its one-way internal lifecycle. Approval bytes remain exact. + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Admitted metadata, JWKS and interaction URLs | MetadataClient, JwksClient, AAuthUrl, ServerId | AAuthEgressPolicy, AAuthHttpTransport, AAuthTransportContract, bounded cache inputs, URI ResolveKeyAsync | WithEgressPolicy/WithDevelopmentLoopback across provisioning builders; DI discovery options | Production rejects private/HTTP destinations; explicit narrow development origins; injected transport declares obligations; MetadataClient disposes internally created HTTP only | All sample hosts use SampleEgress; tests use InProcessOnly; AP refresh now honors supplied transport | Discovery policy/cache/transport tests; AP transport regression; R3 ownership tests | + +## Signatures + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Six Signature-Key carriers and fully specified algorithms | UseHwk/UseJwt/UseJktJwt/UseJwksUri, key factories, signer/verifier | UseJwks, UseSelfJwt, typed key-validation errors, structured fields, resolver context, SignAsync, ISignatureTokenVerifier | Keep one selector per actual scheme; custom provider and sign-only operation remain advanced | No selector authorizes a resource; jwt token purpose independent; default AAuth verification disallows generic carriers; Ed25519/ES256, public key material | Generic Profile demos vs AAuth access flows; Events uses self-jwt for event tokens only | SignatureConformanceTests and negative carrier fixtures; override matrix; Events verification | +| Authenticated assertions vs parsed claims | AAuthVerifier, UseAAuth, GetAAuthVerification | AAuthVerifiedAssertion; typed verification results/options | Existing middleware/context extensions; companion verifier opt-in | Required issuer/type/key/audience/expiry/replay checks preserved; no fluent trusted-claims shortcut | PS/AS/R3/Events endpoints; SDK DI | Conformance verification, wrong-token and forged-context tests | + +## Tokens + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Verified issuance ceilings and claim ownership | AuthTokenBuilder, ResourceTokenBuilder, AgentTokenBuilder, TokenVerifier | AgentTokenExpiresAt; AgentIssuanceContext; reserved claims; AuthTokenExpiredException; AgentAuthTokenValidator | Existing object initializers with required verified context; no optional expiry overload | Agent/auth/delegation ceilings explicit; caller cannot replace reserved claims; stale deferred approvals rejected | PS/AS endpoints; R3 issuance; sample issuer snippets | Token builder, deferred expiry, reserved-claim and conformance tests | +| Account selection and grant narrowing | ResourceTokenBuilder/TokenExchangeRequest | AccountBinding; account-aware verification and upstream validators | Required request Account on existing request objects, not a global implicit selection | Exact opaque account value; omission distinct; resource-token/auth-token/R3 binding; PS not an account selector | Bookings personal/work flows; AAuthRequestOptions | Account isolation tests, R3 subset tests, both browser accounts | +| Delegation and sub-agent hierarchy | ActChainBuilder/Reader, UpstreamTokenValidator | Validated child/parent context; narrower identities and expiration | Existing builders and validators retained | No invented trusted parent or unbounded lifetime; exact key/audience/mission/chain checks | FederatedWorkerScenario; SubAgent flow | Core/conformance delegation; R3 worker cases; full browsers | + +## Consent + +Resource-token `interaction` is now coordinated by the internal +`PersonResourceInteraction`, mapped under the configured PS `InteractionPath`. +`AAuthPersonServerOptions.ResourceInteractionSessions` borrows the host's +authenticated browser authorization configuration; its default denies people +without authorization. `PersonPendingEntry.AwaitingResourceInteraction` is the +public host guard before presenting or recording ordinary consent. Callback +state and resource snapshots stay internal, not caller-mutable approval APIs. +Both Documents apps use the same `DocumentDemoSession`; its low-level exchanges +are deliberate numbered steps, not a second authorization protocol. + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Authenticated human consent vs correlation code | PS/AS endpoint mappers and pending stores | BrowserConsentSessions, BrowserConsentIdentity, decision artifacts; DeferredState, owner/generation-bound stores | Retain explicit service/store contracts and endpoint options | Correlation alone is not approval; signed pending operations require stored verified owner; browser decision requires identity/session/CSRF; production decision capability opt-in | MockPersonServer, Federated AS, R3 AS, Inbox consent pages | HTTP owner/key/correlation/CSRF/terminal races; live Keycloak bypass tests | +| PS claims and AS authorization/clarification | AccessServerClient, IAccessPolicy, IIdentityClaimsAsserter | Expanded requests, pending snapshots, decision results, explicit clarification action | Existing policy interfaces and options; no wrapper around policy decisions | Trust and authorization explicit; claims assertion not AS authorization; retries retain narrowed request and account | Federated policy; PS triage/relay; sample consent | AS clarification, client normalization, consent generation tests | + +## Resource managed + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Agent JWT plus opaque AAuth-Access | WithResourceManagedAccess, AddAAuthResourceManaged | Account/key-qualified IAAuthAccessStore, AAuthRequestOptions, owner-aware pending/opaque stores | Direct Enrolled and SelfIssuing forwarders; existing server module | No PS/AS exchange; default isolated in-memory cache; authorization covered by signature; required account/key context preserved | Both Inbox pages and six tour steps | Actual Inbox consent browsers; ClientCompositionTests replay/party assertions; resource-managed owner isolation | + +## Revocation + +The existing inventory API now checks all locally retained ancestors under its +registration lock, rejects cycles and prevents extension after revocation. +The endpoint traverses descendants with a visited set and notifies each recorded +grant. No API claims global remote revocation or distributed transactional +guarantees for custom providers. + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Issuer-qualified revocation and cascades | MapAAuthRevocation, IJtiStore | TokenKey, TokenRegistration, TokenGrant, RevocationClient, expanded AAuthRevocationOptions | Keep endpoint/client pair and typed registration; no alias to jti-only API | (iss,jti) identity; authenticated caller issuer; durable/idempotent store and cascade obligations explicit; production providers implement persistence | PS/AS token issuance and revocation; conformance fixtures | JtiStoreAndRevocationTests; HTTP mixed-issuer/cascade/retry tests | + +## Governance + +`MissionTokenConsentContext.ConsentAgentId` distinguishes the consenting parent +from the worker's token identity. `UpstreamAuthorization` retains verified +delegation and `ValidatedApproval` is SDK-set after local owner/approver checks; +host policy cannot set that property outside the assembly. Immediate and deferred +identity assertions use the same consenting principal, while tokens remain bound +to the worker. Replacement resource tokens cannot discard an upstream mission. + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Mission/permission/audit/interaction and call chaining | BuildGovernance, AAuthGovernanceClient.Create, MissionSession | Expanded consent/log/mission context and expiry; disposable facade | Existing facade now accepts enrolled/self-issued configuration; no additional wrapper | Build owns signed and discovery channels; constructor/Create borrow; explicit PS and verified mission context; no implicit approval | MissionAgent; SampleApp mission pages; advanced docs | Governance tests; builder ownership test; mission browser cases | + +## R3 + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Eight vocabularies, operation subsets and typed identity | R3Document, R3Operation, R3Operations, R3Request | R3OperationIdentity, R3VocabularySchemas, qualifiers, proposal/readership models | Existing R3Operation factories and document object initializers | Vocabulary-specific validation and directional coverage remain mandatory; no generic wildcard wrapper | Bookings HTTP, GraphQL, gRPC, MCP etc. fixtures; R3 docs | All R3 vocabulary, projection and subset tests | +| R3 discovery, proposals, audit and authorization | R3FetchClient, R3DocumentEndpoint, R3AccessTokenEndpoint, R3Enforcement | R3DocumentReaderPolicy, required agent/account/expiry, bounded process-lifetime proposal storage, audit headers/options | Existing endpoint/fetch/request APIs; R3ProposalStore(maxEntries: 1024) | Explicit signed PS readership; exact bytes/hash, no eviction of published references, no restart durability, proposal ownership, admission, failure-before-release audit | Bookings/R3 AS; both apps; representative request snippets | Full R3 suite, real HTTP two-account and tamper regressions, unexpired-grant retention and capacity tests; bookings/richrequests browsers | + +## Events + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Subscribe vs event JWT purpose | New companion; shared core verifier/signer | EventsProtocol, SubscribeTokenBuilder, EventTokenBuilder, EventsTokens, EventsSignatureTokenVerifier | AddAAuthEvents registers explicit verifier capability; existing token builders | Subscribe jwt binds AP namespace/agent/key; event self-jwt has no cnf; no implicit generic token acceptance | EventSupport, MockAgentProvider, Bookings, EventAgent | SubscribeTokenTests, EventTokenTests, real HTTP forged issuer/context tests | +| Subscription, bounded inbox and durable delivery | Events endpoint extensions, EventReceiver | Durable subscription/delivery/receipt store interfaces and request/result objects | Keep typed endpoints/receiver; no wrapper that hides transactional provider obligations | Atomic quota/ticket/receipt/account binding; SQLite is sample-owned, not SDK default persistence; signed body, deduplication and restart safety explicit | Both Events pages; AP sample; AsyncAPI registration | Events HTTP/SQLite tests and four browser flows; lost-response replay tests | + +## DI + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Explicit server capabilities and policy | AddAAuthAgent/Discovery/Resource/Federation/ResourceManaged, UseAAuth, governance mappers | Expanded options, AAuthFederationOptions, contextual endpoint inputs | Reuse options/registrations; AddAAuthEvents in companion | Fail closed without issuer/trust/authorization policy; registered transport obligations and service lifetimes explicit; no convenience trust bypass | Every sample Program; dependency-injection docs | DI pipeline/trust diagnostics, HTTP endpoint integration and full solution | + +## Server contracts + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Problem details, response shaping, endpoint requirements and metadata | Existing clients, mappers, requirement/header helpers | AAuthProblemDetails, AuthTokenResponse; Detail rename; new metadata/endpoint context | Reuse shared result/writer and options; removed old error aliases | error controls behavior; application/problem+json; successful responses unchanged; scopes/account/expiry context not inferred | PS/AS/R3/resource endpoints and all error consumers | Problem-details HTTP tests; conformance error and scope tests | + +## Sample runtime + +| Spec concept | Existing entry point | New low-level contract | Chosen convenience | Ownership/defaults | Callers/snippets | Validation | +|---|---|---|---|---|---|---| +| Runnable providers, consent decisions and primary-app workflows | Sample hosts, TourSession, EnrollmentService, EventDemoSession | Public sample policies/SQLite stores, enrollment identity records, R3 catalogs and UI state | Existing SDK builders and explicit sample services; no packaged sample facade | Sample runtime is not a production SDK API; host/circuit owns clients/state, persisted private keys stay local, consent policy requires authenticated sessions; loopback/demo admission is explicit | All primary-app steps, console scenarios and sample endpoints | Full compiled solution, fresh browser stack, live Keycloak, Events/R3 HTTP persistence tests | + +## Review scope + +Protocol [L2420](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2420) +and [L2422](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2422) +(#keying-material) require JWT resource credentials. Inbox remains conformant +resource-managed access, not generic pseudonymous signing. GuidedTour self-issues +locally; SampleApp signs AP enrollment on first use and lazily refreshes. Issuer +metadata/key discovery is verification, not PS/AS authorization. The Profile +pseudonymous endpoints remain separately labeled generic demonstrations. + +The inventory includes public SDK and sample runtime declarations; tests are +verification callers, not exported runtime API. Compilation coverage is +representative, not one executable snippet per declaration. Interface contracts +are exercised by their existing provider/consumer tests. External production +provider deployment, arbitrary OAuth comparisons, all Phase 12 security closure +and the final Phase 13 docs sweep are not implied by a passing Phase 11 gate. + +Final evidence: 1967 Release tests (913 core, 777 conformance, 206 R3, 71 Events), +zero failures/skips; Release/make builds zero warnings/errors. All 56 browser +cases pass across fresh stub and live-Keycloak policy configurations, retries=0. +Exact snippet compilation: 17 cases (8 GuidedTour, 4 Razor, 5 docs). The inventory +contains 154 SDK and 28 sample-runtime changed public-source files. Default DI +requires AgentToken/TokenRefresher or an explicit generic SignatureKeyProvider; +no implicit HWK fallback. Metadata and JWKS clients both dispose internal HTTP +only. No known Phase 11 finding remains open; see the implementation log for +failures, repairs, provenance and mobile screenshot evidence. + + + +## Complete declaration delta + +Baseline `ba768f1`; 201 changed public-source files, 810 added/replacement declarations, 162 removed/replaced declarations. + +Generated from all current SDK source files, including untracked additions, and the baseline tree. Public/protected declarations include containing namespaces/types, overload parameters, required members, attributes, optional defaults, primary constructors and interface members. Compiler-synthesized/inherited members are represented by their source declarations, not expanded. Unchanged signatures in changed files are listed by containing type as behavior-review entries; the concept table above supplies their entry point, ownership, callers and tests. No source file is excluded by guessed file role. + +### samples/CapabilitySupport/CatalogDemoSession.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [CatalogDemoSession.cs](../../../samples/CapabilitySupport/CatalogDemoSession.cs). + +```diff ++ AAuth.Samples.Capabilities.CatalogDemoSession: public Func < Task > ? Changed { get ; set ; } ++ AAuth.Samples.Capabilities.CatalogDemoSession: public List < ScenarioExchange > Exchanges { get ; } = [ ] ++ AAuth.Samples.Capabilities.CatalogDemoSession: public async Task NextAsync ( CancellationToken cancellationToken ) ++ AAuth.Samples.Capabilities.CatalogDemoSession: public int Step { get ; private set ; } ++ AAuth.Samples.Capabilities.CatalogDemoSession: public static string [ ] Steps { get ; } = [ "Discover catalog services" , "Authorize selected service" , "Read selected catalog" , "Reject a sibling-service grant" , "Authorize sibling and recover" ] ++ AAuth.Samples.Capabilities.CatalogDemoSession: public string ? ConsentUrl { get ; private set ; } ++ AAuth.Samples.Capabilities.CatalogDemoSession: public string ? Result { get ; private set ; } ++ AAuth.Samples.Capabilities.CatalogDemoSession: public string OtherService ++ AAuth.Samples.Capabilities.CatalogDemoSession: public string Service { get ; set ; } = "destinations" ++ AAuth.Samples.Capabilities.CatalogDemoSession: public void Dispose ( ) ++ AAuth.Samples.Capabilities: public sealed class CatalogDemoSession ( string provider , string person , string resource ) : IDisposable +``` + +Public owners: `AAuth.Samples.Capabilities.CatalogDemoSession`, `AAuth.Samples.Capabilities`. + +### samples/CapabilitySupport/DocumentDemoSession.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [DocumentDemoSession.cs](../../../samples/CapabilitySupport/DocumentDemoSession.cs). + +```diff ++ AAuth.Samples.Capabilities.DocumentDemoSession: public Func < Task > ? Changed { get ; set ; } ++ AAuth.Samples.Capabilities.DocumentDemoSession: public List < ScenarioExchange > Exchanges { get ; } = [ ] ++ AAuth.Samples.Capabilities.DocumentDemoSession: public async Task NextAsync ( CancellationToken cancellationToken ) ++ AAuth.Samples.Capabilities.DocumentDemoSession: public bool Denied { get ; private set ; } ++ AAuth.Samples.Capabilities.DocumentDemoSession: public int Step { get ; private set ; } ++ AAuth.Samples.Capabilities.DocumentDemoSession: public static string [ ] Steps { get ; } = [ "Enroll document agent" , "Request document release" , "Authorize document access" , "Download released document" ] ++ AAuth.Samples.Capabilities.DocumentDemoSession: public string ? ConsentUrl { get ; private set ; } ++ AAuth.Samples.Capabilities.DocumentDemoSession: public string ? Result { get ; private set ; } ++ AAuth.Samples.Capabilities.DocumentDemoSession: public void Dispose ( ) ++ AAuth.Samples.Capabilities: public sealed class DocumentDemoSession ( string provider , string person , string resource ) : IDisposable +``` + +Public owners: `AAuth.Samples.Capabilities.DocumentDemoSession`, `AAuth.Samples.Capabilities`. + +### samples/CapabilitySupport/ScenarioWireHandler.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [ScenarioWireHandler.cs](../../../samples/CapabilitySupport/ScenarioWireHandler.cs). + +```diff ++ AAuth.Samples.Capabilities.ScenarioWireHandler: protected override async Task < HttpResponseMessage > SendAsync ( HttpRequestMessage request , CancellationToken cancellationToken ) ++ AAuth.Samples.Capabilities.ScenarioWireHandler: public static JsonNode ? Display ( string ? text ) ++ AAuth.Samples.Capabilities.ScenarioWireHandler: public static JsonObject Claims ( string token ) ++ AAuth.Samples.Capabilities: public sealed class ScenarioWireHandler ( Action < ScenarioExchange > record ) : DelegatingHandler ++ AAuth.Samples.Capabilities: public sealed record ScenarioExchange ( string Method , string Url , int Status , string ? Scheme , string ? Requirement , JsonNode ? Request , JsonNode ? Response ) +``` + +Public owners: `AAuth.Samples.Capabilities.ScenarioWireHandler`, `AAuth.Samples.Capabilities`. + +### samples/CapabilitySupport/WalletDemoSession.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [WalletDemoSession.cs](../../../samples/CapabilitySupport/WalletDemoSession.cs). + +```diff ++ AAuth.Samples.Capabilities.WalletDemoSession: public Func < Task > ? Changed { get ; set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public List < ScenarioExchange > Exchanges { get ; } = [ ] ++ AAuth.Samples.Capabilities.WalletDemoSession: public WalletFlow Flow { get ; set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public async Task NextAsync ( CancellationToken cancellationToken ) ++ AAuth.Samples.Capabilities.WalletDemoSession: public bool Cancelled { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public int Step { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public static JsonSerializerOptions Pretty { get ; } = new ( ) { WriteIndented = true } ++ AAuth.Samples.Capabilities.WalletDemoSession: public string ? Agent { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public string ? ConsentUrl { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public string ? Question { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public string ? Result { get ; private set ; } ++ AAuth.Samples.Capabilities.WalletDemoSession: public string [ ] Steps ++ AAuth.Samples.Capabilities.WalletDemoSession: public void Answer ( string text ) ++ AAuth.Samples.Capabilities.WalletDemoSession: public void Cancel ( ) ++ AAuth.Samples.Capabilities.WalletDemoSession: public void Dispose ( ) ++ AAuth.Samples.Capabilities.WalletFlow: Clarification ++ AAuth.Samples.Capabilities.WalletFlow: DirectAs ++ AAuth.Samples.Capabilities.WalletFlow: Revocation ++ AAuth.Samples.Capabilities: public enum WalletFlow ++ AAuth.Samples.Capabilities: public sealed class WalletDemoSession ( string provider , string person , string wallet , string concierge ) : IDisposable +``` + +Public owners: `AAuth.Samples.Capabilities.WalletDemoSession`, `AAuth.Samples.Capabilities.WalletFlow`, `AAuth.Samples.Capabilities`. + +### samples/CapabilitySupport/WalletScenarioCode.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [WalletScenarioCode.cs](../../../samples/CapabilitySupport/WalletScenarioCode.cs). + +```diff ++ AAuth.Samples.Capabilities.WalletScenarioCode: public const string Clarification = """ + public static Task ClarifyAsync(HttpClient signedAgent, MetadataClient metadata, + string personServer, string resourceToken, + Func consent, + Func> answer, + CancellationToken cancellationToken) + => new TokenExchangeClient(signedAgent, metadata).ExchangeAsync(personServer, resourceToken, + new TokenExchangeRequest { OnInteractionRequired = consent, OnClarificationRequired = answer }, + cancellationToken); + + public static ClarificationResponse Answer(string justification) + => ClarificationResponse.Respond(justification); + + public static ClarificationResponse Cancel() => ClarificationResponse.Cancel(); + """ ; ++ AAuth.Samples.Capabilities.WalletScenarioCode: public const string DirectAs = """ + public static async Task ReadWalletAsync(IAAuthKey key, string issuer, string agent, + string kid, string upstreamToken, string wallet, AAuthEgressPolicy egress, + CancellationToken cancellationToken) + { + using var client = AAuthClientBuilder.SelfIssuing(key).As(issuer, agent).WithKid(kid) + .WithEgressPolicy(egress).WithCallChaining(upstreamToken) + .WithChallengeHandling(options => options.Capabilities = Array.Empty()).Build(); + using var response = await client.GetAsync(wallet + "/wallet", cancellationToken); + response.EnsureSuccessStatusCode(); + return await response.Content.ReadAsStringAsync(cancellationToken); + } + """ ; ++ AAuth.Samples.Capabilities.WalletScenarioCode: public const string Revocation = """ + public static Task RevokeAsync(HttpClient signedPersonServer, + Uri resourceRevocationEndpoint, string issuer, string tokenId, CancellationToken cancellationToken) + => new RevocationClient(signedPersonServer).RevokeAsync(resourceRevocationEndpoint, + new TokenKey(issuer, tokenId), cancellationToken); + + public static Task RecoverAsync(HttpClient signedAgent, MetadataClient metadata, + string personServer, string freshResourceToken, + Func consent, CancellationToken cancellationToken) + => new TokenExchangeClient(signedAgent, metadata).ExchangeAsync(personServer, freshResourceToken, + new TokenExchangeRequest { OnInteractionRequired = consent }, cancellationToken); + """ ; ++ AAuth.Samples.Capabilities.WalletScenarioCode: public static string For ( WalletFlow flow ) ++ AAuth.Samples.Capabilities: public static class WalletScenarioCode +``` + +Public owners: `AAuth.Samples.Capabilities.WalletScenarioCode`, `AAuth.Samples.Capabilities`. + +### samples/Concierge/ChainCaptureHandler.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [ChainCaptureHandler.cs](../../../samples/Concierge/ChainCaptureHandler.cs). + +```diff ++ Concierge.ChainCaptureHandler: protected override async Task < HttpResponseMessage > SendAsync ( HttpRequestMessage request , CancellationToken cancellationToken ) ++ Concierge.ChainCaptureHandler: public List < ChainExchange > Exchanges { get ; } = [ ] ++ Concierge: public sealed class ChainCaptureHandler : DelegatingHandler ++ Concierge: public sealed record ChainExchange ( string Method , string Url , string ? Scheme , string [ ] Fields , int Status ) +``` + +Public owners: `Concierge.ChainCaptureHandler`, `Concierge`. + +### samples/Concierge/PendingStore.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [PendingStore.cs](../../../samples/Concierge/PendingStore.cs). + +```diff ++ Concierge.PendingStore.Entry: public DateTimeOffset ExpiresAt { get ; } = DateTimeOffset . FromUnixTimeSeconds ( JsonNode . Parse ( Base64UrlEncoder . DecodeBytes ( UpstreamToken . Split ( '.' ) [ 1 ] ) ) ! [ "exp" ] ! . GetValue < long > ( ) ) ++ Concierge.PendingStore.Entry: public DeferredState Lifecycle { get ; } = new ( ) ++ Concierge.PendingStore.Entry: public bool Matches ( string ? upstreamToken ) +``` + +Public owners: `Concierge.PendingStore.Entry`, `Concierge.PendingStore`, `Concierge`. + +### samples/Concierge/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/Concierge/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Concierge`. + +### samples/EventSupport/BookingsEvents.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [BookingsEvents.cs](../../../samples/EventSupport/BookingsEvents.cs). + +```diff ++ AAuth.Samples.Events.BookingsEvents: public JsonObject Document ( ) ++ AAuth.Samples.Events.BookingsEvents: public const string EventType = "reservation.available" ; ++ AAuth.Samples.Events.BookingsEvents: public const string Operation = "receiveReservationAvailable" ; ++ AAuth.Samples.Events.BookingsEvents: public object IssueTicket ( TokenVerifier . VerifiedToken authorization ) ++ AAuth.Samples.Events.BookingsEvents: public void Map ( IEndpointRouteBuilder routes ) ++ AAuth.Samples.Events: public sealed class BookingsEvents ( string issuer , IAAuthKey key , string keyId , EventsProtocol protocol , SqliteEventStore store ) +``` + +Public owners: `AAuth.Samples.Events.BookingsEvents`, `AAuth.Samples.Events`. + +### samples/EventSupport/EventDemoCode.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [EventDemoCode.cs](../../../samples/EventSupport/EventDemoCode.cs). + +```diff ++ AAuth.Samples.Events.EventDemoCode: public const string Delivery = """ + public static async Task TriggerSampleEventAsync(EventsProtocol protocol, string resource, + string eid, IAAuthKey agentKey, string agentToken, string? account, CancellationToken cancellationToken) + { + using var response = await protocol.SendAsync(HttpMethod.Post, + new Uri(resource + "/local/events/" + eid + "/notify" + + (account is null ? "" : "?account=" + Uri.EscapeDataString(account))), agentKey, agentToken, + selfIssued: false, cancellationToken: cancellationToken); + response.EnsureSuccessStatusCode(); + } + + public static async Task DeliverResourceEventAsync(EventsProtocol protocol, string resource, + string provider, string agent, string eid, IAAuthKey resourceKey, string resourceKid, + byte[] payload, CancellationToken cancellationToken) + { + var token = new EventTokenBuilder + { + Issuer = resource, Audience = agent, Eid = eid, Key = resourceKey, + KeyId = resourceKid, Verifier = protocol.TokenVerifier, + }.Build(); + var endpoint = await protocol.ResolveEventEndpointAsync(provider, cancellationToken); + using var response = await protocol.SendAsync(HttpMethod.Post, endpoint, + resourceKey, token, selfIssued: true, body: payload, cancellationToken: cancellationToken); + response.EnsureSuccessStatusCode(); + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string Discover = """ + public static async Task DiscoverChannelsAsync(HttpClient http, + EventsProtocol protocol, string resource, string provider, CancellationToken cancellationToken) + { + using var metadata = new MetadataClient(http); + var resourceMetadata = await metadata.FetchAsync( + new Uri(resource + "/.well-known/aauth-resource.json"), cancellationToken); + var documentUrl = resourceMetadata["r3_vocabularies"]!["urn:aauth:vocabulary:asyncapi"]!.GetValue(); + var channels = await http.GetFromJsonAsync( + new Uri(new Uri(resource), documentUrl), cancellationToken); + var eventEndpoint = await protocol.ResolveEventEndpointAsync(provider, cancellationToken); + return channels!; + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string Example = """ + builder.Services.AddAAuthEvents(); + var app = builder.Build(); + using var http = AAuthHttpTransport.CreateClient(egressPolicy); + var protocol = new EventsProtocol(http, + app.Services.GetServices()); + + // Public registration uses an AsyncAPI channel URL; protected + // registration uses the ticket from an authorized Bookings response. + using var registration = await protocol.SendAsync(HttpMethod.Post, + subscriptionUrl, agentKey, subscribeToken, selfIssued: false, + body: subscriptionParameters); + + // Resource signs both JWT and HTTP with the same discoverable key. + var eventToken = new EventTokenBuilder + { + Issuer = resource, Audience = agent, Eid = subscription.Eid, + Key = resourceKey, KeyId = resourceKid, + Verifier = protocol.TokenVerifier + }.Build(); + var endpoint = await protocol.ResolveEventEndpointAsync(subscription.Provider); + using var delivery = await protocol.SendAsync(HttpMethod.Post, + endpoint, resourceKey, eventToken, selfIssued: true, body: payloadBytes); + + // AP endpoint requires a durable transactional quota/outbox store. + app.MapAAuthEventEndpoint("/events", protocol, providerStore); + + // Agent verifies the issuer JWT and context before persisting receipt. + var receiver = new EventReceiver(protocol, agentStore, agent); + var firstReceipt = await receiver.ReceiveAsync(eventToken, payloadBytes); + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string Receipt = """ + public static async Task VerifyInboxAsync(EventsProtocol protocol, IAgentEventStore store, + string provider, string agent, string eid, IAAuthKey key, string agentToken, + CancellationToken cancellationToken) + { + using var response = await protocol.SendAsync(HttpMethod.Get, + new Uri(provider + "/local/events/inbox"), key, agentToken, + selfIssued: false, cancellationToken: cancellationToken); + response.EnsureSuccessStatusCode(); + var pending = (await response.Content.ReadFromJsonAsync(cancellationToken))!; + var item = pending.Single(delivery => delivery.Event.Eid == eid); + var receiver = new EventReceiver(protocol, store, agent); + await receiver.ReceiveAsync(item.Event.Token, item.Event.Body, cancellationToken); + var duplicate = await receiver.ReceiveAsync(item.Event.Token, item.Event.Body, cancellationToken); + if (duplicate) throw new InvalidOperationException("Duplicate event was not suppressed."); + using var acknowledged = await protocol.SendAsync(HttpMethod.Post, + new Uri(provider + "/local/events/inbox/" + item.Receipt + "/ack"), key, agentToken, + selfIssued: false, cancellationToken: cancellationToken); + acknowledged.EnsureSuccessStatusCode(); + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string Registration = """ + public static async Task RegisterSubscriptionAsync(EventsProtocol protocol, + Uri subscriptionUrl, IAAuthKey key, string subscribeToken, CancellationToken cancellationToken) + { + using var response = await protocol.SendAsync(HttpMethod.Post, subscriptionUrl, + key, subscribeToken, selfIssued: false, + body: "{\"event_types\":[\"reservation.available\"]}"u8.ToArray(), + cancellationToken: cancellationToken); + response.EnsureSuccessStatusCode(); + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string SubscribeToken = """ + public static async Task AcquireSubscribeTokenAsync(EventsProtocol protocol, + IAgentEventStore store, IAAuthKey key, string agentToken, string agent, + string provider, string resource, string context, CancellationToken cancellationToken) + { + var body = System.Text.Encoding.UTF8.GetBytes(new JsonObject + { ["resource"] = resource, ["max_uses"] = 1 }.ToJsonString()); + using var response = await protocol.SendAsync(HttpMethod.Post, + new Uri(provider + "/local/events/subscribe"), key, agentToken, + selfIssued: false, body: body, cancellationToken: cancellationToken); + response.EnsureSuccessStatusCode(); + var result = (await response.Content.ReadFromJsonAsync(cancellationToken))!; + store.Remember(new(result["eid"]!.GetValue(), resource, agent, context)); + return result; + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public const string SubscriptionUrl = """ + public static async Task<(string Agent, string AgentToken, string SubscriptionUrl)> ObtainSubscriptionUrlAsync(AAuthKey key, + string provider, string person, string resource, string account, bool protectedChannel, + string publicSubscriptionUrl, AAuthEgressPolicy policy, + Func showConsent, CancellationToken cancellationToken) + { + var enrolled = await AAuthClientBuilder.Bootstrap(provider + "/enrol") + .WithKey(key).WithKeyStore(new InMemoryKeyStore()).WithPersonServer(person) + .WithEgressPolicy(policy).EnrolAsync(cancellationToken); + if (!protectedChannel) return (enrolled.AgentId!, enrolled.AgentToken!, publicSubscriptionUrl); + using var agent = new AAuthClientBuilder(key).UseJwt(enrolled.AgentToken!) + .WithEgressPolicy(policy).WithChallengeHandling(person, + options => options.OnInteractionRequired = showConsent).Build(); + using var request = new HttpRequestMessage(HttpMethod.Get, + resource + "/search_availability?account=" + Uri.EscapeDataString(account)); + request.Options.Set(AAuthRequestOptions.Account, account); + using var response = await agent.SendAsync(request, cancellationToken); + response.EnsureSuccessStatusCode(); + var result = await response.Content.ReadFromJsonAsync(cancellationToken); + return (enrolled.AgentId!, enrolled.AgentToken!, result!["notifications"]!["subscribe_url"]!.GetValue()); + } + """ ; ++ AAuth.Samples.Events.EventDemoCode: public static readonly string [ ] Steps = [ Discover , SubscriptionUrl , SubscribeToken , Registration , Delivery , Receipt ] ; ++ AAuth.Samples.Events: public static class EventDemoCode +``` + +Public owners: `AAuth.Samples.Events.EventDemoCode`, `AAuth.Samples.Events`. + +### samples/EventSupport/EventDemoSession.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [EventDemoSession.cs](../../../samples/EventSupport/EventDemoSession.cs). + +```diff ++ AAuth.Samples.Events.EventDemoSession: public EventDemoSession ( string directory , string provider = "http://localhost:5301" , string resource = "http://localhost:5005" , string person = "http://localhost:5100" , HttpClient ? http = null ) ++ AAuth.Samples.Events.EventDemoSession: public Func < Task > ? Changed { get ; set ; } ++ AAuth.Samples.Events.EventDemoSession: public List < EventDemoEvidence > Evidence { get ; } = [ ] ++ AAuth.Samples.Events.EventDemoSession: public async Task NextAsync ( CancellationToken cancellationToken = default ) ++ AAuth.Samples.Events.EventDemoSession: public bool Protected { get ; set ; } = true ++ AAuth.Samples.Events.EventDemoSession: public int Step { get ; private set ; } ++ AAuth.Samples.Events.EventDemoSession: public static readonly string [ ] Steps = [ "Discover event channels" , "Obtain subscription URL" , "Acquire subscribe token" , "Register subscription" , "Deliver sample event" , "Verify inbox event" ] ; ++ AAuth.Samples.Events.EventDemoSession: public string ? ConsentUrl { get ; private set ; } ++ AAuth.Samples.Events.EventDemoSession: public string ? Context { get ; private set ; } ++ AAuth.Samples.Events.EventDemoSession: public string ? Eid { get ; private set ; } ++ AAuth.Samples.Events.EventDemoSession: public string ? Payload { get ; private set ; } ++ AAuth.Samples.Events.EventDemoSession: public string Account { get ; set ; } = "personal" ++ AAuth.Samples.Events.EventDemoSession: public string Agent { get ; private set ; } = "" ++ AAuth.Samples.Events.EventDemoSession: public void Dispose ( ) ++ AAuth.Samples.Events: public sealed class EventDemoSession : IDisposable ++ AAuth.Samples.Events: public sealed record EventDemoEvidence ( int Step , string Exchange , int StatusCode , string Json ) +``` + +Public owners: `AAuth.Samples.Events.EventDemoSession`, `AAuth.Samples.Events`. + +### samples/EventSupport/LocalEventProvider.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [LocalEventProvider.cs](../../../samples/EventSupport/LocalEventProvider.cs). + +```diff ++ AAuth.Samples.Events.LocalEventProvider: public static void MapLocalEventProvider ( this IEndpointRouteBuilder routes , string issuer , IAAuthKey key , string keyId , EventsProtocol protocol , IAgentProviderEventStore store ) ++ AAuth.Samples.Events: public static class LocalEventProvider +``` + +Public owners: `AAuth.Samples.Events.LocalEventProvider`, `AAuth.Samples.Events`. + +### samples/EventSupport/SampleAgentEnrollment.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [SampleAgentEnrollment.cs](../../../samples/EventSupport/SampleAgentEnrollment.cs). + +```diff ++ AAuth.Samples.Events.SampleAgentEnrollment: public static void MapSampleAgentEnrollment ( this IEndpointRouteBuilder routes , string issuer , IAAuthKey key , string keyId , AAuthEgressPolicy policy , SampleAgentRegistry registry ) ++ AAuth.Samples.Events: public static class SampleAgentEnrollment +``` + +Public owners: `AAuth.Samples.Events.SampleAgentEnrollment`, `AAuth.Samples.Events`. + +### samples/EventSupport/SampleAgentRegistry.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [SampleAgentRegistry.cs](../../../samples/EventSupport/SampleAgentRegistry.cs). + +```diff ++ AAuth.Samples.Events.SampleAgentRegistry: public IReadOnlyList < SampleAgentRecord > List ( ) ++ AAuth.Samples.Events.SampleAgentRegistry: public SampleAgentRecord ? Enrol ( string issuer , string ? requestedId , IAAuthKey publicKey , string ? personServer ) ++ AAuth.Samples.Events.SampleAgentRegistry: public SampleAgentRecord ? Find ( string agent ) ++ AAuth.Samples.Events.SampleAgentRegistry: public SampleAgentRecord ? FindByKey ( string thumbprint ) ++ AAuth.Samples.Events.SampleAgentRegistry: public SampleAgentRegistry ( string path ) ++ AAuth.Samples.Events: public sealed class SampleAgentRegistry ++ AAuth.Samples.Events: public sealed record SampleAgentRecord ( string AgentId , IAAuthKey PublicKey , string KeyId , DateTimeOffset RegisteredAt , string ? PersonServer ) +``` + +Public owners: `AAuth.Samples.Events.SampleAgentRegistry`, `AAuth.Samples.Events`. + +### samples/EventSupport/SqliteEventStore.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [SqliteEventStore.cs](../../../samples/EventSupport/SqliteEventStore.cs). + +```diff ++ AAuth.Samples.Events.SqliteEventStore: public AgentEventContext ? FindContext ( string eid ) ++ AAuth.Samples.Events.SqliteEventStore: public EventAcceptance Accept ( EventEnvelope envelope , DateTimeOffset now ) ++ AAuth.Samples.Events.SqliteEventStore: public EventEnvelope PrepareDelivery ( string provider , string eid , Func < EventEnvelope > create ) ++ AAuth.Samples.Events.SqliteEventStore: public IReadOnlyList < PendingEvent > Pending ( string agent , int limit = 100 , string ? after = null ) ++ AAuth.Samples.Events.SqliteEventStore: public IReadOnlyList < ProcessedEvent > ReadEvents ( string agent ) ++ AAuth.Samples.Events.SqliteEventStore: public RegistrationResult Register ( ResourceSubscription subscription , string ? ticket , DateTimeOffset now ) ++ AAuth.Samples.Events.SqliteEventStore: public ResourceSubscription ? Find ( string provider , string eid , DateTimeOffset now ) ++ AAuth.Samples.Events.SqliteEventStore: public ResourceSubscription ? FindNotification ( string provider , string eid ) ++ AAuth.Samples.Events.SqliteEventStore: public SqliteEventStore ( string path ) ++ AAuth.Samples.Events.SqliteEventStore: public bool Acknowledge ( string agent , string receipt ) ++ AAuth.Samples.Events.SqliteEventStore: public bool RecordOnce ( ProcessedEvent received , DateTimeOffset now ) ++ AAuth.Samples.Events.SqliteEventStore: public const int InboxMaxBytes = 1024 * 1024 ; ++ AAuth.Samples.Events.SqliteEventStore: public static JsonSerializerOptions InboxJson { get ; } = new ( JsonSerializerDefaults . Web ) ++ AAuth.Samples.Events.SqliteEventStore: public string ? DeliveryReceipt ( ResourceSubscription subscription ) ++ AAuth.Samples.Events.SqliteEventStore: public string EnsureState ( string operation , string ? account , string initialState ) ++ AAuth.Samples.Events.SqliteEventStore: public string RecordDelivery ( ResourceSubscription subscription , string response , bool complete ) ++ AAuth.Samples.Events.SqliteEventStore: public void Complete ( string provider , string eid ) ++ AAuth.Samples.Events.SqliteEventStore: public void Create ( ProviderSubscription subscription ) ++ AAuth.Samples.Events.SqliteEventStore: public void IssueTicket ( SubscriptionTicket ticket ) ++ AAuth.Samples.Events.SqliteEventStore: public void Remember ( AgentEventContext context ) ++ AAuth.Samples.Events.SqliteEventStore: public void SetState ( string operation , string ? account , string state ) ++ AAuth.Samples.Events: public sealed class SqliteEventStore : IAgentProviderEventStore , IResourceEventStore , IAgentEventStore +``` + +Public owners: `AAuth.Samples.Events.SqliteEventStore`, `AAuth.Samples.Events`. + +### samples/FederatedWorkerScenario.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [FederatedWorkerScenario.cs](../../../samples/FederatedWorkerScenario.cs). + +```diff ++ AAuth.Samples.FederatedWorkerScenario: public Func < Interaction , CancellationToken , Task > ? OnInteraction { get ; set ; } ++ AAuth.Samples.FederatedWorkerScenario: public async Task CallWalletAsync ( CancellationToken ct = default ) ++ AAuth.Samples.FederatedWorkerScenario: public async Task ExchangeAsync ( CancellationToken ct = default ) ++ AAuth.Samples.FederatedWorkerScenario: public async Task ObtainResourceAsync ( CancellationToken ct = default ) ++ AAuth.Samples.FederatedWorkerScenario: public async Task ObtainUpstreamAsync ( CancellationToken ct = default ) ++ AAuth.Samples.FederatedWorkerScenario: public static IReadOnlyDictionary < string , string > ScopeDescriptions { get ; } = new Dictionary < string , string > { [ "delegation.invoke" ] = "Delegate a wallet lookup to the parent and worker" } ++ AAuth.Samples.FederatedWorkerScenario: public static JsonObject Payload ( string jwt ) ++ AAuth.Samples.FederatedWorkerScenario: public string ? AuthToken { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? InteractionUrl { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? ParentToken { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? ResourceResponse { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? ResourceToken { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? UpstreamToken { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ? WorkerToken { get ; private set ; } ++ AAuth.Samples.FederatedWorkerScenario: public string ParentId ++ AAuth.Samples.FederatedWorkerScenario: public string WorkerId ++ AAuth.Samples.FederatedWorkerScenario: public void Dispose ( ) ++ AAuth.Samples.FederatedWorkerScenario: public void IssueParent ( ) ++ AAuth.Samples.FederatedWorkerScenario: public void IssueWorker ( ) ++ AAuth.Samples: public sealed class FederatedWorkerScenario ( IAAuthKey providerKey , string providerKid , string provider , string personServer , string wallet ) : IDisposable +``` + +Public owners: `AAuth.Samples.FederatedWorkerScenario`, `AAuth.Samples`. + +### samples/GuidedTour/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/GuidedTour/Program.cs). + +Public signatures unchanged (2); behavior reviewed under sample-runtime. + +Public owners: `GuidedTour`. + +### samples/GuidedTour/TourOptions.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [TourOptions.cs](../../../samples/GuidedTour/TourOptions.cs). + +```diff +- GuidedTour.SigningMode: JwksUri ++ GuidedTour.SigningMode: Jwks +``` + +Public owners: `GuidedTour.SigningMode`, `GuidedTour.TourMode`, `GuidedTour.TourOptions`, `GuidedTour`. + +### samples/GuidedTour/TourSession.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [TourSession.cs](../../../samples/GuidedTour/TourSession.cs). + +```diff ++ GuidedTour.TourSession: public BookingAccount [ ] BookingsAccounts { get ; private set ; } = [ ] ++ GuidedTour.TourSession: public async Task CheckPreviousAccountAsync ( ) ++ GuidedTour.TourSession: public async Task LoadBookingsAccountsAsync ( ) ++ GuidedTour.TourSession: public bool CanCheckPreviousAccount ++ GuidedTour.TourSession: public sealed record BookingAccount ( string Id , string Name ) ++ GuidedTour.TourSession: public string ? AccountProbeResult { get ; private set ; } ++ GuidedTour.TourSession: public string ? BookingsAccount { get ; private set ; } ++ GuidedTour.TourSession: public string ? WorkerConsentUrl { get ; private set ; } ++ GuidedTour.TourSession: public void SelectBookingsAccount ( string ? account ) +``` + +Public owners: `GuidedTour.TourSession`, `GuidedTour`. + +### samples/MockAccessServers/Federated/Policy/KeycloakAccessPolicy.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [KeycloakAccessPolicy.cs](../../../samples/MockAccessServers/Federated/Policy/KeycloakAccessPolicy.cs). + +```diff +- MockAccessServer.Policy.KeycloakAccessPolicy: public KeycloakAccessPolicy ( HttpClient http , KeycloakOptions options ) ++ MockAccessServer.Policy.KeycloakAccessPolicy: public KeycloakAccessPolicy ( HttpClient http , KeycloakOptions options , WalletPolicyRules ? walletRules = null ) +``` + +Public owners: `MockAccessServer.Policy.KeycloakAccessPolicy`, `MockAccessServer.Policy`. + +### samples/MockAccessServers/Federated/Policy/StubAccessPolicy.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [StubAccessPolicy.cs](../../../samples/MockAccessServers/Federated/Policy/StubAccessPolicy.cs). + +```diff +- MockAccessServer.Policy.StubAccessPolicy: public StubAccessPolicy ( IReadOnlyList < string > ? requiredClaims = null , bool requireConsent = false ) ++ MockAccessServer.Policy.StubAccessPolicy: public StubAccessPolicy ( IReadOnlyList < string > ? requiredClaims = null , bool requireConsent = false , WalletPolicyRules ? walletRules = null ) +``` + +Public owners: `MockAccessServer.Policy.StubAccessPolicy`, `MockAccessServer.Policy`. + +### samples/MockAccessServers/Federated/Policy/WalletPolicyRules.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [WalletPolicyRules.cs](../../../samples/MockAccessServers/Federated/Policy/WalletPolicyRules.cs). + +```diff ++ MockAccessServer.Policy.WalletPolicyRules: public AccessDecision ? Evaluate ( AccessPolicyRequest request ) ++ MockAccessServer.Policy.WalletPolicyRules: public const string ReviewScope = "wallet.review" ; ++ MockAccessServer.Policy: public sealed class WalletPolicyRules ( string wallet , string concierge ) +``` + +Public owners: `MockAccessServer.Policy.WalletPolicyRules`, `MockAccessServer.Policy`. + +### samples/MockAccessServers/Federated/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockAccessServers/Federated/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Federated`. + +### samples/MockAccessServers/R3/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockAccessServers/R3/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `R3AccessServer`. + +### samples/MockAccessServers/R3/SqliteR3AuditSink.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [SqliteR3AuditSink.cs](../../../samples/MockAccessServers/R3/SqliteR3AuditSink.cs). + +```diff ++ R3AccessServer.SqliteR3AuditSink: public IReadOnlyList < R3TokenIssuanceAuditRecord > ReadRecords ( ) ++ R3AccessServer.SqliteR3AuditSink: public SqliteR3AuditSink ( string path ) ++ R3AccessServer.SqliteR3AuditSink: public Task RecordTokenIssuanceAsync ( R3TokenIssuanceAuditRecord record , CancellationToken cancellationToken = default ) ++ R3AccessServer: public sealed class SqliteR3AuditSink : IR3AuditSink +``` + +Public owners: `R3AccessServer.SqliteR3AuditSink`, `R3AccessServer`. + +### samples/MockAgentProvider/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockAgentProvider/Program.cs). + +```diff ++ MockAgentProvider: public sealed class Entry +``` + +Public owners: `MockAgentProvider`. + +### samples/MockPersonServer/ConsentBridgePersonPendingStore.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [ConsentBridgePersonPendingStore.cs](../../../samples/MockPersonServer/ConsentBridgePersonPendingStore.cs). + +```diff +- MockPersonServer.ConsentBridgePersonPendingStore: public PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , JsonObject ? upstreamAct = null , MissionClaim ? mission = null ) ++ MockPersonServer.ConsentBridgePersonPendingStore: public PersonPendingEntry ? GetByCode ( string code ) ++ MockPersonServer.ConsentBridgePersonPendingStore: public PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , DateTimeOffset agentTokenExpiresAt , JsonObject ? upstreamAct = null , MissionClaim ? mission = null , DateTimeOffset ? authorizationExpiresAt = null ) +``` + +Public owners: `MockPersonServer.ConsentBridgePersonPendingStore`, `MockPersonServer`. + +### samples/MockPersonServer/ConsentStore.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [ConsentStore.cs](../../../samples/MockPersonServer/ConsentStore.cs). + +```diff +- MockPersonServer.ConsentStore: public bool IsConsented ( string agent , string resource , string scope ) +- MockPersonServer.ConsentStore: public void Grant ( string agent , string resource , string scope ) +- MockPersonServer.ConsentStore: public void Revoke ( string agent , string resource , string scope ) ++ MockPersonServer.ConsentStore: public bool IsConsented ( string agent , string resource , string scope , string ? account = null , string ? key = null ) ++ MockPersonServer.ConsentStore: public void Grant ( string agent , string resource , string scope , string ? account = null , string ? key = null ) ++ MockPersonServer.ConsentStore: public void Revoke ( string agent , string resource , string scope , string ? account = null , string ? key = null ) +``` + +Public owners: `MockPersonServer.ConsentStore`, `MockPersonServer`. + +### samples/MockPersonServer/MissionGovernance.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [MissionGovernance.cs](../../../samples/MockPersonServer/MissionGovernance.cs). + +```diff +- MockPersonServer.MissionConsentScript: public static string ScopeKey ( string resource , string scope ) +- MockPersonServer.MissionConsentScript: public void SeedInScope ( string resource , string scope ) +- MockPersonServer.MissionPolicyStore: public bool IsInScope ( string s256 , string resource , string scope ) ++ MockPersonServer.MissionConsentScript: public static string ScopeKey ( string resource , string scope , string ? account = null ) ++ MockPersonServer.MissionConsentScript: public void SeedInScope ( string resource , string scope , string ? account = null ) ++ MockPersonServer.MissionPendingEntry: public AAuth . Server . BrowserInteraction Browser { get ; } = new ( ) ++ MockPersonServer.MissionPendingEntry: public AAuth . Server . DeferredState Lifecycle { get ; } = new ( ) ++ MockPersonServer.MissionPendingEntry: public DateTimeOffset ExpiresAt { get ; } = DateTimeOffset . UtcNow . AddMinutes ( 10 ) ++ MockPersonServer.MissionPendingEntry: public bool Decide ( bool allow ) ++ MockPersonServer.MissionPendingEntry: public bool MatchesOwner ( Microsoft . AspNetCore . Http . HttpContext context ) ++ MockPersonServer.MissionPendingEntry: public string ? OwnerIssuer { get ; init ; } ++ MockPersonServer.MissionPendingEntry: public string ? OwnerKeyThumbprint { get ; init ; } ++ MockPersonServer.MissionPendingStore: public MissionPendingEntry ? GetByCode ( string code ) ++ MockPersonServer.MissionPolicyStore: public bool IsInScope ( string s256 , string resource , string scope , string ? account = null ) +``` + +Public owners: `MockPersonServer.MissionConsentScript`, `MockPersonServer.MissionPendingEntry`, `MockPersonServer.MissionPendingKind`, `MockPersonServer.MissionPendingState`, `MockPersonServer.MissionPendingStore`, `MockPersonServer.MissionPolicyStore`, `MockPersonServer.SampleAuditSink`, `MockPersonServer.SampleInteractionRelay`, `MockPersonServer.SamplePermissionDecider`, `MockPersonServer`. + +### samples/MockPersonServer/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockPersonServer/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `MockPersonServer`. + +### samples/MockPersonServer/SampleIdentityClaimsAsserter.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [SampleIdentityClaimsAsserter.cs](../../../samples/MockPersonServer/SampleIdentityClaimsAsserter.cs). + +```diff ++ MockPersonServer.SampleIdentityClaimsAsserter: public static string DirectedSubject ( string resource ) +``` + +Public owners: `MockPersonServer.SampleIdentityClaimsAsserter`, `MockPersonServer`. + +### samples/MockPersonServer/ScriptMissionTokenConsent.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [ScriptMissionTokenConsent.cs](../../../samples/MockPersonServer/ScriptMissionTokenConsent.cs). + +Public signatures unchanged (3); behavior reviewed under sample-runtime. + +Public owners: `MockPersonServer.ScriptMissionTokenConsent`, `MockPersonServer`. + +### samples/MockResourceServers/Bookings/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Bookings/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Bookings`. + +### samples/MockResourceServers/Calendar/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Calendar/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Calendar`. + +### samples/MockResourceServers/Catalog/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Catalog/Program.cs). + +```diff ++ Catalog: public sealed class Entry +``` + +Public owners: `Catalog`. + +### samples/MockResourceServers/Inbox/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Inbox/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Inbox`. + +### samples/MockResourceServers/Profile/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Profile/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Profile`. + +### samples/MockResourceServers/Trips/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Trips/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Trips`. + +### samples/MockResourceServers/Wallet/Program.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [Program.cs](../../../samples/MockResourceServers/Wallet/Program.cs). + +Public signatures unchanged (1); behavior reviewed under sample-runtime. + +Public owners: `Wallet`. + +### samples/SampleApp/EnrollmentService.cs + +Concept/decision: [sample-runtime](#sample-runtime). Source: [EnrollmentService.cs](../../../samples/SampleApp/EnrollmentService.cs). + +Public signatures unchanged (10); behavior reviewed under sample-runtime. + +Public owners: `SampleApp.EnrollmentService`, `SampleApp`. + +### src/AAuth.Events/EventReceiver.cs + +Concept/decision: [events](#events). Source: [EventReceiver.cs](../../../src/AAuth.Events/EventReceiver.cs). + +```diff ++ AAuth.Events.EventReceiver: public async Task < bool > ReceiveAsync ( string token , byte [ ] body , CancellationToken cancellationToken = default ) ++ AAuth.Events: public sealed class EventReceiver ( EventsProtocol protocol , IAgentEventStore store , string agent ) +``` + +Public owners: `AAuth.Events.EventReceiver`, `AAuth.Events`. + +### src/AAuth.Events/EventStores.cs + +Concept/decision: [events](#events). Source: [EventStores.cs](../../../src/AAuth.Events/EventStores.cs). + +```diff ++ AAuth.Events.IAgentEventStore: AgentEventContext ? FindContext ( string eid ) ++ AAuth.Events.IAgentEventStore: IReadOnlyList < ProcessedEvent > ReadEvents ( string agent ) ++ AAuth.Events.IAgentEventStore: bool RecordOnce ( ProcessedEvent received , DateTimeOffset now ) ++ AAuth.Events.IAgentEventStore: void Remember ( AgentEventContext context ) ++ AAuth.Events.IAgentProviderEventStore: EventAcceptance Accept ( EventEnvelope envelope , DateTimeOffset now ) ++ AAuth.Events.IAgentProviderEventStore: IReadOnlyList < PendingEvent > Pending ( string agent , int limit = 100 , string ? after = null ) ++ AAuth.Events.IAgentProviderEventStore: bool Acknowledge ( string agent , string receipt ) ++ AAuth.Events.IAgentProviderEventStore: void Create ( ProviderSubscription subscription ) ++ AAuth.Events.IResourceEventStore: RegistrationResult Register ( ResourceSubscription subscription , string ? ticket , DateTimeOffset now ) ++ AAuth.Events.IResourceEventStore: ResourceSubscription ? Find ( string provider , string eid , DateTimeOffset now ) ++ AAuth.Events.IResourceEventStore: void Complete ( string provider , string eid ) ++ AAuth.Events.IResourceEventStore: void IssueTicket ( SubscriptionTicket ticket ) ++ AAuth.Events.IResourceEventStore: void SetState ( string operation , string ? account , string state ) ++ AAuth.Events: public interface IAgentEventStore ++ AAuth.Events: public interface IAgentProviderEventStore ++ AAuth.Events: public interface IResourceEventStore ++ AAuth.Events: public sealed record AgentEventContext ( string Eid , string Resource , string Agent , string Context ) ++ AAuth.Events: public sealed record EventAcceptance ( int StatusCode , long ? RemainingUses = null ) ++ AAuth.Events: public sealed record EventEnvelope ( string Token , string Eid , string Issuer , string Agent , DateTimeOffset ExpiresAt , byte [ ] Body ) ++ AAuth.Events: public sealed record PendingEvent ( string Receipt , EventEnvelope Event ) ++ AAuth.Events: public sealed record ProcessedEvent ( AgentEventContext Context , EventEnvelope Event ) ++ AAuth.Events: public sealed record ProviderSubscription ( string Eid , string Agent , string Resource , DateTimeOffset ExpiresAt , long ? MaxUses ) ++ AAuth.Events: public sealed record RegistrationResult ( int StatusCode , ResourceSubscription ? Subscription = null ) ++ AAuth.Events: public sealed record ResourceSubscription ( string Eid , string Provider , string Agent , string Operation , string ? Account , string State , DateTimeOffset ExpiresAt ) ++ AAuth.Events: public sealed record SubscriptionTicket ( string Ticket , string Agent , string Operation , string ? Account , string State , DateTimeOffset ExpiresAt ) +``` + +Public owners: `AAuth.Events.IAgentEventStore`, `AAuth.Events.IAgentProviderEventStore`, `AAuth.Events.IResourceEventStore`, `AAuth.Events`. + +### src/AAuth.Events/EventTokenBuilders.cs + +Concept/decision: [events](#events). Source: [EventTokenBuilders.cs](../../../src/AAuth.Events/EventTokenBuilders.cs). + +```diff ++ AAuth.Events.EventTokenBuilder: public TimeSpan Lifetime { get ; init ; } = TimeSpan . FromMinutes ( 5 ) ++ AAuth.Events.EventTokenBuilder: public TokenVerifier Verifier { get ; init ; } = new ( ) ++ AAuth.Events.EventTokenBuilder: public required IAAuthKey Key { get ; init ; } ++ AAuth.Events.EventTokenBuilder: public required string Audience { get ; init ; } ++ AAuth.Events.EventTokenBuilder: public required string Eid { get ; init ; } ++ AAuth.Events.EventTokenBuilder: public required string Issuer { get ; init ; } ++ AAuth.Events.EventTokenBuilder: public required string KeyId { get ; init ; } ++ AAuth.Events.EventTokenBuilder: public string Build ( ) ++ AAuth.Events.SubscribeTokenBuilder: public TimeSpan Lifetime { get ; init ; } = TimeSpan . FromMinutes ( 5 ) ++ AAuth.Events.SubscribeTokenBuilder: public TokenVerifier Verifier { get ; init ; } = new ( ) ++ AAuth.Events.SubscribeTokenBuilder: public long ? MaxUses { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required IAAuthKey ConfirmationKey { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required IAAuthKey Key { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required string Audience { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required string Eid { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required string Issuer { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required string KeyId { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public required string Subject { get ; init ; } ++ AAuth.Events.SubscribeTokenBuilder: public string Build ( ) ++ AAuth.Events: public sealed class EventTokenBuilder ++ AAuth.Events: public sealed class SubscribeTokenBuilder +``` + +Public owners: `AAuth.Events.EventTokenBuilder`, `AAuth.Events.SubscribeTokenBuilder`, `AAuth.Events`. + +### src/AAuth.Events/EventsEndpoints.cs + +Concept/decision: [events](#events). Source: [EventsEndpoints.cs](../../../src/AAuth.Events/EventsEndpoints.cs). + +```diff ++ AAuth.Events.EventsEndpoints: public static IEndpointConventionBuilder MapAAuthEventEndpoint ( this IEndpointRouteBuilder routes , string path , EventsProtocol protocol , IAgentProviderEventStore store ) ++ AAuth.Events.EventsEndpoints: public static IEndpointConventionBuilder MapAAuthSubscriptionEndpoint ( this IEndpointRouteBuilder routes , string path , string resource , string operation , bool protectedChannel , EventsProtocol protocol , IResourceEventStore store , Func < JsonObject , bool > validateParameters , TimeSpan ? subscriptionLifetime = null ) ++ AAuth.Events: public static class EventsEndpoints +``` + +Public owners: `AAuth.Events.EventsEndpoints`, `AAuth.Events`. + +### src/AAuth.Events/EventsProtocol.cs + +Concept/decision: [events](#events). Source: [EventsProtocol.cs](../../../src/AAuth.Events/EventsProtocol.cs). + +```diff ++ AAuth.Events.EventsProtocol: public EventsProtocol ( HttpClient http , IEnumerable < ISignatureTokenVerifier > tokenVerifiers , Func < DateTimeOffset > ? clock = null ) ++ AAuth.Events.EventsProtocol: public TokenVerifier TokenVerifier { get ; } ++ AAuth.Events.EventsProtocol: public async Task < AAuthVerifiedAssertion ? > VerifyRequestAsync ( HttpContext context , string type , string ? audience = null ) ++ AAuth.Events.EventsProtocol: public async Task < HttpResponseMessage > SendAsync ( HttpMethod method , Uri url , IAAuthKey key , string jwt , bool selfIssued , byte [ ] ? body = null , CancellationToken cancellationToken = default ) ++ AAuth.Events.EventsProtocol: public async Task < TokenVerifier . VerifiedToken > VerifyEventAsync ( string jwt , string agent , CancellationToken cancellationToken = default ) ++ AAuth.Events.EventsProtocol: public async Task < Uri > ResolveEventEndpointAsync ( string provider , CancellationToken cancellationToken = default ) ++ AAuth.Events: public sealed class EventsProtocol +``` + +Public owners: `AAuth.Events.EventsProtocol`, `AAuth.Events`. + +### src/AAuth.Events/EventsSignatureTokenVerifier.cs + +Concept/decision: [events](#events). Source: [EventsSignatureTokenVerifier.cs](../../../src/AAuth.Events/EventsSignatureTokenVerifier.cs). + +```diff ++ AAuth.Events.EventsServiceExtensions: public static IServiceCollection AddAAuthEvents ( this IServiceCollection services ) ++ AAuth.Events.EventsSignatureTokenVerifier: public Task < TokenVerifier . VerifiedToken > VerifyAsync ( string jwt , IAAuthKey issuerKey , TokenVerifier verifier , CancellationToken cancellationToken ) ++ AAuth.Events.EventsSignatureTokenVerifier: public string Scheme ++ AAuth.Events.EventsSignatureTokenVerifier: public string TokenType ++ AAuth.Events: public sealed class EventsSignatureTokenVerifier ( bool subscribe ) : ISignatureTokenVerifier ++ AAuth.Events: public static class EventsServiceExtensions +``` + +Public owners: `AAuth.Events.EventsServiceExtensions`, `AAuth.Events.EventsSignatureTokenVerifier`, `AAuth.Events`. + +### src/AAuth.Events/EventsTokens.cs + +Concept/decision: [events](#events). Source: [EventsTokens.cs](../../../src/AAuth.Events/EventsTokens.cs). + +```diff ++ AAuth.Events.EventsTokens: public const string AgentDwk = "aauth-agent.json" ; ++ AAuth.Events.EventsTokens: public const string EventType = "aa-event+jwt" ; ++ AAuth.Events.EventsTokens: public const string ResourceDwk = "aauth-resource.json" ; ++ AAuth.Events.EventsTokens: public const string SubscribeType = "aa-subscribe+jwt" ; ++ AAuth.Events.EventsTokens: public static TokenVerifier . VerifiedToken Verify ( string jwt , IAAuthKey issuerKey , bool subscribe , TokenVerifier verifier , string ? audience = null ) ++ AAuth.Events.EventsTokens: public static string Create ( IAAuthKey key , string keyId , JsonObject payload , bool subscribe , TokenVerifier ? verifier = null ) ++ AAuth.Events.EventsTokens: public static string RequireText ( JsonObject value , string name ) ++ AAuth.Events: public static class EventsTokens +``` + +Public owners: `AAuth.Events.EventsTokens`, `AAuth.Events`. + +### src/AAuth.R3/Model/R3Document.cs + +Concept/decision: [r3](#r3). Source: [R3Document.cs](../../../src/AAuth.R3/Model/R3Document.cs). + +```diff +- AAuth.R3.Model.R3Document: public byte [ ] ToUtf8Bytes ( JsonSerializerOptions ? options = null ) +- AAuth.R3.Model.R3Document: public static R3Document FromUtf8Bytes ( ReadOnlySpan < byte > bytes , JsonSerializerOptions ? options = null ) +- AAuth.R3.Model.R3Document: public void Validate ( ) ++ AAuth.R3.Model.R3Document: [ JsonPropertyName ( "account" ) ] [ JsonIgnore ( Condition = JsonIgnoreCondition . WhenWritingNull ) ] public string ? Account { get ; init ; } ++ AAuth.R3.Model.R3Document: public byte [ ] ToUtf8Bytes ( JsonSerializerOptions ? options = null , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.Model.R3Document: public static R3Document FromUtf8Bytes ( ReadOnlySpan < byte > bytes , JsonSerializerOptions ? options = null , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.Model.R3Document: public void Validate ( R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.Model.R3Document`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3Grant.cs + +Concept/decision: [r3](#r3). Source: [R3Grant.cs](../../../src/AAuth.R3/Model/R3Grant.cs). + +```diff +- AAuth.R3.Model.R3Grant: public bool Contains ( string operationId ) +- AAuth.R3.Model.R3Grant: public void Validate ( bool allowEmpty = false ) ++ AAuth.R3.Model.R3Grant: public bool Contains ( R3OperationIdentity operation ) ++ AAuth.R3.Model.R3Grant: public void Validate ( bool allowEmpty = false , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.Model.R3Grant`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3Json.cs + +Concept/decision: [r3](#r3). Source: [R3Json.cs](../../../src/AAuth.R3/Model/R3Json.cs). + +Public signatures unchanged (2); behavior reviewed under r3. + +Public owners: `AAuth.R3.Model.R3Json`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3Operation.cs + +Concept/decision: [r3](#r3). Source: [R3Operation.cs](../../../src/AAuth.R3/Model/R3Operation.cs). + +```diff ++ AAuth.R3.Model.R3Operation: public IReadOnlyDictionary < string , JsonElement > ? Extensions { get ; init ; } ++ AAuth.R3.Model.R3Operation: public IReadOnlyList < string > ? Methods { get ; init ; } ++ AAuth.R3.Model.R3Operation: public static R3Operation AsyncApi ( string operationId , string ? action = null ) ++ AAuth.R3.Model.R3Operation: public static R3Operation GraphQl ( string operation , string type ) ++ AAuth.R3.Model.R3Operation: public static R3Operation Grpc ( string method ) ++ AAuth.R3.Model.R3Operation: public static R3Operation OData ( string operation , params string [ ] methods ) ++ AAuth.R3.Model.R3Operation: public static R3Operation OpenApiGateway ( string service , string operationId ) ++ AAuth.R3.Model.R3Operation: public static R3Operation Wsdl ( string operation , string ? service = null ) ++ AAuth.R3.Model.R3Operation: public string ? Action { get ; init ; } ++ AAuth.R3.Model.R3Operation: public string ? Service { get ; init ; } ++ AAuth.R3.Model.R3Operation: public string ? Type { get ; init ; } ++ AAuth.R3.Model.R3OperationConverter: public R3OperationConverter ( ) ++ AAuth.R3.Model.R3OperationConverter: public R3OperationConverter ( string identifierMember ) +``` + +Public owners: `AAuth.R3.Model.R3OperationConverter`, `AAuth.R3.Model.R3Operation`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3OperationIdentity.cs + +Concept/decision: [r3](#r3). Source: [R3OperationIdentity.cs](../../../src/AAuth.R3/Model/R3OperationIdentity.cs). + +```diff ++ AAuth.R3.Model.R3OperationIdentity: public bool Covers ( R3OperationIdentity requested ) ++ AAuth.R3.Model.R3OperationIdentity: public bool Matches ( string vocabulary , R3Operation operation ) ++ AAuth.R3.Model.R3OperationIdentity: public static R3OperationIdentity Mcp ( string tool ) ++ AAuth.R3.Model.R3OperationIdentity: public static R3OperationIdentity OpenApi ( string operationId ) ++ AAuth.R3.Model: public sealed record R3OperationIdentity ( string Vocabulary , R3Operation Operation ) +``` + +Public owners: `AAuth.R3.Model.R3OperationIdentity`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3Operations.cs + +Concept/decision: [r3](#r3). Source: [R3Operations.cs](../../../src/AAuth.R3/Model/R3Operations.cs). + +```diff +- AAuth.R3.Model.R3Operations: public void Validate ( ) ++ AAuth.R3.Model.R3Operations: public void Validate ( R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.Model.R3Operations`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3Parameter.cs + +Concept/decision: [r3](#r3). Source: [R3Parameter.cs](../../../src/AAuth.R3/Model/R3Parameter.cs). + +```diff +- AAuth.R3.Model.R3Parameter: public required JsonNode Json { get ; init ; } +- AAuth.R3.Model.R3Parameter: public static R3Parameter Inline ( JsonNode value ) ++ AAuth.R3.Model.R3Parameter: public required JsonNode ? Json { get ; init ; } ++ AAuth.R3.Model.R3Parameter: public static R3Parameter Inline ( JsonNode ? value ) ++ AAuth.R3.Model.R3Parameter: public void Validate ( ) +``` + +Public owners: `AAuth.R3.Model.R3Parameter`, `AAuth.R3.Model.R3PresentedParameters`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3ProposalDocument.cs + +Concept/decision: [r3](#r3). Source: [R3ProposalDocument.cs](../../../src/AAuth.R3/Model/R3ProposalDocument.cs). + +```diff +- AAuth.R3.Model.R3ProposalDocument: public byte [ ] ToUtf8Bytes ( JsonSerializerOptions ? options = null ) +- AAuth.R3.Model.R3ProposalDocument: public static R3ProposalDocument FromUtf8Bytes ( ReadOnlySpan < byte > bytes , JsonSerializerOptions ? options = null ) +- AAuth.R3.Model.R3ProposalDocument: public void Validate ( ) ++ AAuth.R3.Model.R3ProposalDocument: [ JsonPropertyName ( "account" ) ] [ JsonIgnore ( Condition = JsonIgnoreCondition . WhenWritingNull ) ] public string ? Account { get ; init ; } ++ AAuth.R3.Model.R3ProposalDocument: public byte [ ] ToUtf8Bytes ( JsonSerializerOptions ? options = null , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.Model.R3ProposalDocument: public static R3ProposalDocument FromUtf8Bytes ( ReadOnlySpan < byte > bytes , JsonSerializerOptions ? options = null , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.Model.R3ProposalDocument: public void Validate ( R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.Model.R3ProposalDocument`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/R3VocabularySchemas.cs + +Concept/decision: [r3](#r3). Source: [R3VocabularySchemas.cs](../../../src/AAuth.R3/Model/R3VocabularySchemas.cs). + +```diff ++ AAuth.R3.Model.R3VocabularySchemas: public JsonSerializerOptions CreateJsonOptions ( string vocabulary , JsonSerializerOptions ? options = null ) ++ AAuth.R3.Model.R3VocabularySchemas: public R3VocabularySchemas ( IReadOnlyDictionary < string , R3VocabularySchema > ? custom = null ) ++ AAuth.R3.Model.R3VocabularySchemas: public static R3VocabularySchemas Standard { get ; } = new ( ) ++ AAuth.R3.Model.R3VocabularySchemas: public static void ValidateUri ( string vocabulary ) ++ AAuth.R3.Model.R3VocabularySchemas: public void Validate ( string vocabulary , R3Operation operation ) ++ AAuth.R3.Model.R3VocabularySchemas: public void ValidateVocabulary ( string vocabulary ) ++ AAuth.R3.Model: public sealed class R3VocabularySchemas ++ AAuth.R3.Model: public sealed record R3VocabularySchema ( string IdentifierMember , Action < R3Operation > Validate ) +``` + +Public owners: `AAuth.R3.Model.R3VocabularySchemas`, `AAuth.R3.Model`. + +### src/AAuth.R3/Model/Vocabulary.cs + +Concept/decision: [r3](#r3). Source: [Vocabulary.cs](../../../src/AAuth.R3/Model/Vocabulary.cs). + +```diff ++ AAuth.R3.Model.Vocabulary: public const string AsyncApi = "urn:aauth:vocabulary:asyncapi" ; ++ AAuth.R3.Model.Vocabulary: public const string GraphQl = "urn:aauth:vocabulary:graphql" ; ++ AAuth.R3.Model.Vocabulary: public const string Grpc = "urn:aauth:vocabulary:grpc" ; ++ AAuth.R3.Model.Vocabulary: public const string OData = "urn:aauth:vocabulary:odata" ; ++ AAuth.R3.Model.Vocabulary: public const string OpenApiGateway = "urn:aauth:vocabulary:openapi-gateway" ; ++ AAuth.R3.Model.Vocabulary: public const string Wsdl = "urn:aauth:vocabulary:wsdl" ; +``` + +Public owners: `AAuth.R3.Model.Vocabulary`, `AAuth.R3.Model`. + +### src/AAuth.R3/R3AccessTokenEndpoint.cs + +Concept/decision: [r3](#r3). Source: [R3AccessTokenEndpoint.cs](../../../src/AAuth.R3/R3AccessTokenEndpoint.cs). + +```diff +- AAuth.R3.R3AccessTokenEndpointOptions: public Func < Model . R3Operation , bool > ? IsConditionalOperation { get ; init ; } +- AAuth.R3.R3AccessTokenEndpointOptions: public IR3AuditSink AuditSink { get ; init ; } = R3NoOpAuditSink . Instance +- AAuth.R3.R3AccessTokenEndpointOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.R3.R3AccessTokenEndpointOptions: public AAuth . Discovery . AAuthTransportContract ? FetchTransportContract { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public BrowserConsentSessions ? BrowserConsent { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public Func < R3OperationIdentity , bool > ? IsConditionalOperation { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public Func < R3OperationIdentity , bool > ? IsOperationAllowed { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public Func < R3ProposalDocument , bool > ? IsProposalAllowed { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public Func < string , string , bool > ? IsScopeAllowed { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public R3VocabularySchemas VocabularySchemas { get ; init ; } = R3VocabularySchemas . Standard ++ AAuth.R3.R3AccessTokenEndpointOptions: public required IR3AuditSink AuditSink { get ; init ; } ++ AAuth.R3.R3AccessTokenEndpointOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } +``` + +Public owners: `AAuth.R3.R3AccessTokenEndpointOptions`, `AAuth.R3.R3AccessTokenEndpoint`, `AAuth.R3`. + +### src/AAuth.R3/R3Audit.cs + +Concept/decision: [r3](#r3). Source: [R3Audit.cs](../../../src/AAuth.R3/R3Audit.cs). + +```diff +- AAuth.R3.R3NoOpAuditSink: public Task RecordTokenIssuanceAsync ( R3TokenIssuanceAuditRecord record , CancellationToken cancellationToken = default ) +- AAuth.R3.R3NoOpAuditSink: public static R3NoOpAuditSink Instance { get ; } = new ( ) +- AAuth.R3: public sealed class R3NoOpAuditSink : IR3AuditSink ++ AAuth.R3.R3TokenIssuanceAuditRecord: public required string TokenId { get ; init ; } ++ AAuth.R3.R3TokenIssuanceAuditRecord: public required string TokenS256 { get ; init ; } ++ AAuth.R3.R3TokenIssuanceAuditRecord: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.R3.IR3AuditSink`, `AAuth.R3.InMemoryR3AuditSink`, `AAuth.R3.R3NoOpAuditSink`, `AAuth.R3.R3TokenIssuanceAuditRecord`, `AAuth.R3.R3TokenIssuanceKind`, `AAuth.R3`. + +### src/AAuth.R3/R3AuthClaims.cs + +Concept/decision: [r3](#r3). Source: [R3AuthClaims.cs](../../../src/AAuth.R3/R3AuthClaims.cs). + +```diff +- AAuth.R3.R3AuthClaims: public static IReadOnlyDictionary < string , JsonNode ? > AuthToken ( string r3Uri , string r3S256 , R3Grant granted , R3Grant ? conditional = null ) ++ AAuth.R3.R3AuthClaims: public static IReadOnlyDictionary < string , JsonNode ? > AuthToken ( string r3Uri , string r3S256 , R3Grant granted , R3Grant ? conditional = null , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.R3AuthClaims`, `AAuth.R3`. + +### src/AAuth.R3/R3Challenge.cs + +Concept/decision: [r3](#r3). Source: [R3Challenge.cs](../../../src/AAuth.R3/R3Challenge.cs). + +```diff +- AAuth.R3.R3Challenge: public IResult Challenge ( HttpContext context , string agent , string agentJkt , string r3Uri , string r3S256 , string ? scope = null ) +- AAuth.R3.R3Challenge: public string BuildResourceToken ( string agent , string agentJkt , string r3Uri , string r3S256 , string ? scope = null ) ++ AAuth.R3.R3Challenge: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.R3.R3Challenge: public IResult Challenge ( HttpContext context , string agent , string agentJkt , string r3Uri , string r3S256 , string ? scope = null , string ? account = null ) ++ AAuth.R3.R3Challenge: public string BuildResourceToken ( string agent , string agentJkt , string r3Uri , string r3S256 , string ? scope = null , string ? account = null ) +``` + +Public owners: `AAuth.R3.R3Challenge`, `AAuth.R3`. + +### src/AAuth.R3/R3ClaimReader.cs + +Concept/decision: [r3](#r3). Source: [R3ClaimReader.cs](../../../src/AAuth.R3/R3ClaimReader.cs). + +```diff +- AAuth.R3.R3ClaimReader: public static AuthTokenClaims ReadAuthToken ( JsonObject payload ) +- AAuth.R3.R3ClaimReader: public static R3Grant ? ReadGrant ( JsonNode ? node ) ++ AAuth.R3.R3ClaimReader.AuthTokenClaims: public string ? Account { get ; init ; } ++ AAuth.R3.R3ClaimReader.ResourceDocumentClaims: public string ? Account { get ; init ; } ++ AAuth.R3.R3ClaimReader: public static AuthTokenClaims ReadAuthToken ( JsonObject payload , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.R3ClaimReader: public static R3Grant ? ReadGrant ( JsonNode ? node , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.R3ClaimReader.AuthTokenClaims`, `AAuth.R3.R3ClaimReader.ResourceDocumentClaims`, `AAuth.R3.R3ClaimReader`, `AAuth.R3`. + +### src/AAuth.R3/R3DocumentEndpoint.cs + +Concept/decision: [r3](#r3). Source: [R3DocumentEndpoint.cs](../../../src/AAuth.R3/R3DocumentEndpoint.cs). + +```diff +- AAuth.R3: public sealed record R3VerifiedFetcher ( string Scheme , Uri ? JwksUri , string ? Kid , string ? KeyThumbprint , SignatureKeyParser . ParsedSignatureKeyInfo ParsedKey ) ++ AAuth.R3.R3DocumentEndpoint: public static IEndpointRouteBuilder MapR3Document ( this IEndpointRouteBuilder endpoints , string pattern , Func < HttpContext , byte [ ] ? > getBytes , R3DocumentReaderPolicy readerPolicy ) ++ AAuth.R3: public sealed record R3VerifiedFetcher ( string Scheme , string Identifier , string ? Kid , string ? KeyThumbprint , SignatureKeyParser . ParsedSignatureKeyInfo ParsedKey ) +``` + +Public owners: `AAuth.R3.R3DocumentEndpoint`, `AAuth.R3.R3FetchVerificationException`, `AAuth.R3.R3UntrustedJwksUriException`, `AAuth.R3`. + +### src/AAuth.R3/R3DocumentReaderPolicy.cs + +Concept/decision: [r3](#r3). Source: [R3DocumentReaderPolicy.cs](../../../src/AAuth.R3/R3DocumentReaderPolicy.cs). + +```diff ++ AAuth.R3.R3DocumentReaderPolicy: public R3DocumentReaderPolicy ( string designatedAccessServer , IEnumerable < string > ? personServerEvaluators = null , AAuthEgressPolicy ? egressPolicy = null ) ++ AAuth.R3.R3DocumentReaderPolicy: public bool Allows ( R3VerifiedFetcher fetcher ) ++ AAuth.R3: public sealed class R3DocumentReaderPolicy +``` + +Public owners: `AAuth.R3.R3DocumentReaderPolicy`, `AAuth.R3`. + +### src/AAuth.R3/R3Enforcement.cs + +Concept/decision: [r3](#r3). Source: [R3Enforcement.cs](../../../src/AAuth.R3/R3Enforcement.cs). + +```diff +- AAuth.R3.R3Enforcement: public R3Enforcement ( R3ProposalStore proposalStore , Uri resourceBaseUri , string proposalPathPrefix = "/r3/proposals" ) +- AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( JsonObject verifiedAuthTokenPayload , string operation , IReadOnlyDictionary < string , R3Parameter > ? parameters = null , string ? approvedProposalS256 = null ) +- AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( R3ClaimReader . AuthTokenClaims claims , string operation , IReadOnlyDictionary < string , R3Parameter > ? parameters = null , Func < string , IReadOnlyDictionary < string , R3Parameter > , R3Display ? > ? displayFactory = null , string ? approvedProposalS256 = null ) +- AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( R3ClaimReader . AuthTokenClaims claims , string operation , R3PresentedParameters presentedParameters , string approvedProposalS256 ) ++ AAuth.R3.R3Enforcement: public R3Enforcement ( R3ProposalStore proposalStore , Uri resourceBaseUri , string proposalPathPrefix = "/r3/proposals" , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( JsonObject verifiedAuthTokenPayload , R3OperationIdentity operation , IReadOnlyDictionary < string , R3Parameter > ? parameters = null , string ? approvedProposalS256 = null , string ? expectedAccount = null ) ++ AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( R3ClaimReader . AuthTokenClaims claims , R3OperationIdentity operation , IReadOnlyDictionary < string , R3Parameter > ? parameters = null , Func < R3OperationIdentity , IReadOnlyDictionary < string , R3Parameter > , R3Display ? > ? displayFactory = null , string ? approvedProposalS256 = null , string ? expectedAccount = null ) ++ AAuth.R3.R3Enforcement: public R3EnforcementDecision Evaluate ( R3ClaimReader . AuthTokenClaims claims , R3OperationIdentity operation , R3PresentedParameters presentedParameters , string approvedProposalS256 , string ? expectedAccount = null ) ++ AAuth.R3.R3EnforcementDecision: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.R3.R3EnforcementDecisionKind`, `AAuth.R3.R3EnforcementDecision`, `AAuth.R3.R3Enforcement`, `AAuth.R3`. + +### src/AAuth.R3/R3FetchClient.cs + +Concept/decision: [r3](#r3). Source: [R3FetchClient.cs](../../../src/AAuth.R3/R3FetchClient.cs). + +```diff +- AAuth.R3.R3FetchClient: public R3FetchClient ( HttpClient http ) +- AAuth.R3.R3FetchClient: public static R3FetchClient Create ( IAAuthKey signingKey , string jwksUri , string kid , HttpMessageHandler ? innerHandler = null ) +- AAuth.R3.R3FetchClient: public static Uri ValidateFetchTarget ( string r3Uri , string resourceIssuer ) +- AAuth.R3: public sealed class R3FetchClient ++ AAuth.R3.R3FetchClient: public R3FetchClient ( HttpClient http , bool ownsClient = false ) ++ AAuth.R3.R3FetchClient: public static R3FetchClient Create ( IAAuthKey signingKey , string identifier , string dwk , string kid , HttpMessageHandler ? innerHandler = null , AAuthEgressPolicy ? policy = null , AAuthTransportContract ? transportContract = null ) ++ AAuth.R3.R3FetchClient: public static Uri ValidateFetchTarget ( string r3Uri , string resourceIssuer , AAuthEgressPolicy ? policy = null ) ++ AAuth.R3.R3FetchClient: public void Dispose ( ) ++ AAuth.R3: public sealed class R3FetchClient : IDisposable +``` + +Public owners: `AAuth.R3.R3FetchClient`, `AAuth.R3`. + +### src/AAuth.R3/R3Metadata.cs + +Concept/decision: [r3](#r3). Source: [R3Metadata.cs](../../../src/AAuth.R3/R3Metadata.cs). + +```diff ++ AAuth.R3.R3Metadata: public static JsonObject AddVocabularies ( JsonObject metadata , IReadOnlyDictionary < string , JsonNode ? > vocabularies , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.R3Metadata: public static void ValidateOperations ( R3Operations request , JsonObject metadata , IEnumerable < R3OperationIdentity > authoritativeOperations , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.R3Metadata`, `AAuth.R3`. + +### src/AAuth.R3/R3ProposalStore.cs + +Concept/decision: [r3](#r3). Source: [R3ProposalStore.cs](../../../src/AAuth.R3/R3ProposalStore.cs). + +```diff +- AAuth.R3.R3ProposalStore: public R3ProposalStore ( TimeProvider ? timeProvider = null ) +- AAuth.R3.R3ProposalStore: public StoredR3Proposal Add ( R3ProposalDocument proposal , Uri baseUri , string pathPrefix = "/r3/proposals" ) ++ AAuth.R3.R3ProposalStore: public R3ProposalStore ( int maxEntries = 1024 ) ++ AAuth.R3.R3ProposalStore: public StoredR3Proposal Add ( R3ProposalDocument proposal , Uri baseUri , string pathPrefix = "/r3/proposals" , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.R3ProposalStore`, `AAuth.R3`. + +### src/AAuth.R3/R3Request.cs + +Concept/decision: [r3](#r3). Source: [R3Request.cs](../../../src/AAuth.R3/R3Request.cs). + +```diff +- AAuth.R3.R3Request: public static JsonObject CreateBody ( R3Operations operations ) +- AAuth.R3.R3Request: public static async Task < HttpResponseMessage > PostAuthorizeAsync ( HttpClient http , string authorizationEndpoint , R3Operations operations , CancellationToken cancellationToken = default ) ++ AAuth.R3.R3Request: public static JsonObject CreateBody ( R3Operations operations , string ? account = null , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.R3Request: public static R3Operations ReadOperations ( JsonObject body , R3VocabularySchemas ? schemas = null ) ++ AAuth.R3.R3Request: public static async Task < HttpResponseMessage > PostAuthorizeAsync ( HttpClient http , string authorizationEndpoint , R3Operations operations , CancellationToken cancellationToken = default , string ? account = null , R3VocabularySchemas ? schemas = null ) +``` + +Public owners: `AAuth.R3.R3Request`, `AAuth.R3`. + +### src/AAuth/AAuthClientBuilder.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [AAuthClientBuilder.cs](../../../src/AAuth/AAuthClientBuilder.cs). + +```diff +- AAuth.AAuthClientBuilder: public AAuthClientBuilder UseJwksUri ( string uri , string kid ) +- AAuth.AAuthClientBuilder: public AAuthClientBuilder UseJwt ( string agentToken ) +- AAuth.AAuthClientBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler ) +- AAuth.AAuthClientBuilder: public static BootstrapBuilder Bootstrap ( string enrollEndpoint , string agentId ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder UseJwks ( string url , string kid ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder UseJwksUri ( string id , string dwk , string kid ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder UseJwt ( string token ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder UseSelfJwt ( Func < string > tokenFactory ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder WithDevelopmentLoopback ( params string [ ] origins ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder WithEgressPolicy ( AAuthEgressPolicy policy ) ++ AAuth.AAuthClientBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler , AAuthTransportContract ? transportContract = null ) ++ AAuth.AAuthClientBuilder: public static BootstrapBuilder Bootstrap ( string enrollEndpoint , string ? agentId = null ) +``` + +Public owners: `AAuth.AAuthClientBuilder`, `AAuth`. + +### src/AAuth/AAuthConstants.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthConstants.cs](../../../src/AAuth/AAuthConstants.cs). + +```diff ++ AAuth.AAuthConstants.Schemes: public const string Jwks = "jwks" ; ++ AAuth.AAuthConstants.Schemes: public const string SelfJwt = "self-jwt" ; +``` + +Public owners: `AAuth.AAuthConstants.AccessModes`, `AAuth.AAuthConstants.DwkFiles`, `AAuth.AAuthConstants.Headers`, `AAuth.AAuthConstants.Schemes`, `AAuth.AAuthConstants.TokenTypes`, `AAuth.AAuthConstants`, `AAuth`. + +### src/AAuth/Access/AAuthAccessServerEndpoints.cs + +Concept/decision: [consent](#consent). Source: [AAuthAccessServerEndpoints.cs](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs). + +```diff +- AAuth.Access.AAuthAccessServerOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } +- AAuth.Access.AAuthAccessServerOptions: public string FallbackSubject { get ; init ; } = "pairwise-sub" ++ AAuth.Access.AAuthAccessServerOptions: public AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuthEgressPolicy . Production ++ AAuth.Access.AAuthAccessServerOptions: public Action < AAuthRevocationOptions > ? ConfigureRevocation { get ; init ; } ++ AAuth.Access.AAuthAccessServerOptions: public TimeProvider TimeProvider { get ; init ; } = TimeProvider . System ++ AAuth.Access.AAuthAccessServerOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } ++ AAuth.Access.AAuthAccessServerOptions: public string RevocationPath { get ; init ; } = "/revoke" +``` + +Public owners: `AAuth.Access.AAuthAccessServerEndpoints`, `AAuth.Access.AAuthAccessServerOptions`, `AAuth.Access`. + +### src/AAuth/Access/AccessServerClient.cs + +Concept/decision: [consent](#consent). Source: [AccessServerClient.cs](../../../src/AAuth/Access/AccessServerClient.cs). + +Public signatures unchanged (3); behavior reviewed under consent. + +Public owners: `AAuth.Access.AccessServerClient`, `AAuth.Access`. + +### src/AAuth/Access/AccessServerRequest.cs + +Concept/decision: [consent](#consent). Source: [AccessServerRequest.cs](../../../src/AAuth/Access/AccessServerRequest.cs). + +```diff +- AAuth.Access.AccessServerRequest: public string ? RequestedScope { get ; init ; } ++ AAuth.Access.AccessServerRequest: public Func < ClarificationRequirement , CancellationToken , Task < ClarificationResponse > > ? OnClarificationRequired { get ; init ; } ++ AAuth.Access.AccessServerRequest: public MissionClaim ? ExpectedMission { get ; set ; } ++ AAuth.Access.AccessServerRequest: public required DateTimeOffset AuthorizationExpiresAt { get ; init ; } ++ AAuth.Access.AccessServerRequest: public string ? Account { get ; init ; } ++ AAuth.Access.AccessServerRequest: public string ? RequestedScope { get ; set ; } ++ AAuth.Access.AccessServerRequest: public string ? SubagentToken { get ; init ; } +``` + +Public owners: `AAuth.Access.AccessServerRequest`, `AAuth.Access`. + +### src/AAuth/Access/IAccessPendingStore.cs + +Concept/decision: [consent](#consent). Source: [IAccessPendingStore.cs](../../../src/AAuth/Access/IAccessPendingStore.cs). + +```diff +- AAuth.Access.AccessPendingEntry: public required string Scope { get ; init ; } +- AAuth.Access.IAccessPendingStore: AccessPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey agentConfirmationKey , JsonObject ? claims , IReadOnlyList < string > ? requiredClaims = null ) +- AAuth.Access.InMemoryAccessPendingStore: public AccessPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey agentConfirmationKey , JsonObject ? claims , IReadOnlyList < string > ? requiredClaims = null ) ++ AAuth.Access.AccessPendingEntry: public AAuth . Headers . ClarificationRequirement ? Clarification { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public AAuth . Server . BrowserInteraction Browser { get ; } = new ( ) ++ AAuth.Access.AccessPendingEntry: public AAuth . Server . DeferredState Lifecycle { get ; } = new ( ) ++ AAuth.Access.AccessPendingEntry: public AAuth . Tokens . UpstreamTokenValidationResult ? UpstreamAuthorization { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public DateTimeOffset ? AuthorizationExpiresAt { get ; init ; } ++ AAuth.Access.AccessPendingEntry: public DateTimeOffset ? ClarificationDeadline { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public DateTimeOffset ExpiresAt ++ AAuth.Access.AccessPendingEntry: public DateTimeOffset PendingExpiresAt ++ AAuth.Access.AccessPendingEntry: public IReadOnlyList < AAuth . Server . TokenKey > SourceTokens { get ; set ; } = [ ] ++ AAuth.Access.AccessPendingEntry: public JsonObject ? ResourceContext { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public JsonObject ? UpstreamAct { get ; init ; } ++ AAuth.Access.AccessPendingEntry: public List < string > ClarificationAnswers { get ; } = [ ] ++ AAuth.Access.AccessPendingEntry: public int ClarificationRounds { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public required DateTimeOffset AgentTokenExpiresAt { get ; init ; } ++ AAuth.Access.AccessPendingEntry: public required string Scope { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public string ? Account ++ AAuth.Access.AccessPendingEntry: public string ? OwnerAgentIssuer { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public string ? OwnerAgentSubject { get ; set ; } ++ AAuth.Access.AccessPendingEntry: public string ? OwnerKeyThumbprint { get ; set ; } ++ AAuth.Access.AccessPendingStatus: AwaitingClarification ++ AAuth.Access.AccessPendingStatus: Review ++ AAuth.Access.IAccessPendingStore: AccessPendingEntry ? GetByCode ( string code ) ++ AAuth.Access.IAccessPendingStore: AccessPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey agentConfirmationKey , DateTimeOffset agentTokenExpiresAt , JsonObject ? claims , IReadOnlyList < string > ? requiredClaims = null , DateTimeOffset ? authorizationExpiresAt = null , JsonObject ? upstreamAct = null ) ++ AAuth.Access.InMemoryAccessPendingStore: public AccessPendingEntry ? GetByCode ( string code ) ++ AAuth.Access.InMemoryAccessPendingStore: public AccessPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey agentConfirmationKey , DateTimeOffset agentTokenExpiresAt , JsonObject ? claims , IReadOnlyList < string > ? requiredClaims = null , DateTimeOffset ? authorizationExpiresAt = null , JsonObject ? upstreamAct = null ) +``` + +Public owners: `AAuth.Access.AccessPendingEntry`, `AAuth.Access.AccessPendingStatus`, `AAuth.Access.IAccessPendingStore`, `AAuth.Access.InMemoryAccessPendingStore`, `AAuth.Access`. + +### src/AAuth/Access/IAccessPolicy.cs + +Concept/decision: [consent](#consent). Source: [IAccessPolicy.cs](../../../src/AAuth/Access/IAccessPolicy.cs). + +```diff ++ AAuth.Access.AccessDecision: public ClarificationRequirement ? Clarification { get ; private init ; } ++ AAuth.Access.AccessDecision: public static AccessDecision NeedsClarification ( string question , int ? timeoutSeconds = null , IReadOnlyList < string > ? options = null ) ++ AAuth.Access.AccessDecisionKind: NeedsClarification ++ AAuth.Access.AccessPolicyRequest: public AAuth . Tokens . UpstreamTokenValidationResult ? UpstreamAuthorization { get ; init ; } ++ AAuth.Access.AccessPolicyRequest: public IReadOnlyList < string > ClarificationHistory { get ; init ; } = [ ] ++ AAuth.Access.AccessPolicyRequest: public JsonObject ? ResourceContext { get ; init ; } ++ AAuth.Access.AccessPolicyRequest: public string ? Account ++ AAuth.Access.AccessPolicyRequest: public string ? PersonServerIssuer { get ; init ; } +``` + +Public owners: `AAuth.Access.AccessDecisionKind`, `AAuth.Access.AccessDecision`, `AAuth.Access.AccessPolicyRequest`, `AAuth.Access.IAccessPolicy`, `AAuth.Access.IInteractiveAccessPolicy`, `AAuth.Access`. + +### src/AAuth/Agent/AAuthAccessHandler.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [AAuthAccessHandler.cs](../../../src/AAuth/Agent/AAuthAccessHandler.cs). + +```diff +- AAuth.Agent.AAuthAccessHandler: public AAuthAccessHandler ( IAAuthAccessStore store ) ++ AAuth.Agent.AAuthAccessHandler: public AAuthAccessHandler ( IAAuthAccessStore store , string ? signingKeyThumbprint = null ) +``` + +Public owners: `AAuth.Agent.AAuthAccessHandler`, `AAuth.Agent`. + +### src/AAuth/Agent/AAuthRequestOptions.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [AAuthRequestOptions.cs](../../../src/AAuth/Agent/AAuthRequestOptions.cs). + +```diff ++ AAuth.Agent.AAuthRequestOptions: public static readonly HttpRequestOptionsKey < string > Account = new ( "AAuth.Account" ) ; ++ AAuth.Agent.AAuthRequestOptions: public static readonly HttpRequestOptionsKey < string > PresentedToken = new ( "AAuth.PresentedToken" ) ; ++ AAuth.Agent.AAuthRequestOptions: public static readonly HttpRequestOptionsKey < string > ResourceIdentifier = new ( "AAuth.ResourceIdentifier" ) ; ++ AAuth.Agent.AAuthRequestOptions: public static string ? GetAccount ( HttpRequestMessage request ) ++ AAuth.Agent: public static class AAuthRequestOptions +``` + +Public owners: `AAuth.Agent.AAuthRequestOptions`, `AAuth.Agent`. + +### src/AAuth/Agent/AAuthTokenHolder.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [AAuthTokenHolder.cs](../../../src/AAuth/Agent/AAuthTokenHolder.cs). + +```diff ++ AAuth.Agent.AAuthTokenHolder: public string SelectForRequest ( System . Net . Http . HttpRequestMessage request , string agentToken , string signingKeyThumbprint ) +``` + +Public owners: `AAuth.Agent.AAuthTokenHolder`, `AAuth.Agent`. + +### src/AAuth/Agent/AgentProviderClient.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [AgentProviderClient.cs](../../../src/AAuth/Agent/AgentProviderClient.cs). + +```diff +- AAuth.Agent.AgentProviderClient: public async Task < EnrollResult > EnrolAsync ( string apIssuer , string agentId , string enrollEndpoint , string ? personServer = null , CancellationToken ct = default ) ++ AAuth.Agent.AgentProviderClient: public async Task < EnrollResult > EnrolAsync ( string apIssuer , string ? agentId , string enrollEndpoint , string ? personServer = null , CancellationToken ct = default ) ++ AAuth.Agent.AgentProviderClient: public async Task < EnrollResult > EnrolWithKeyAsync ( string apIssuer , string ? agentId , string enrollEndpoint , AAuthKey key , string ? personServer = null , CancellationToken ct = default ) ++ AAuth.Agent.EnrollResult: public string ? AgentId { get ; init ; } +``` + +Public owners: `AAuth.Agent.AgentProviderClient`, `AAuth.Agent.EnrollResult`, `AAuth.Agent.TwoKeyRefreshResult`, `AAuth.Agent`. + +### src/AAuth/Agent/AgentProviderTokenRefresher.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [AgentProviderTokenRefresher.cs](../../../src/AAuth/Agent/AgentProviderTokenRefresher.cs). + +```diff +- AAuth.Agent: public sealed class AgentProviderTokenRefresher : ITokenRefresher ++ AAuth.Agent.AgentProviderTokenRefresher.RefresherBuilder: public RefresherBuilder WithEgressPolicy ( Discovery . AAuthEgressPolicy policy ) ++ AAuth.Agent.AgentProviderTokenRefresher: public void Dispose ( ) ++ AAuth.Agent: public sealed class AgentProviderTokenRefresher : ITokenRefresher , IDisposable +``` + +Public owners: `AAuth.Agent.AgentProviderTokenRefresher.RefresherBuilder`, `AAuth.Agent.AgentProviderTokenRefresher`, `AAuth.Agent.RefreshMode`, `AAuth.Agent`. + +### src/AAuth/Agent/ChallengeHandler.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [ChallengeHandler.cs](../../../src/AAuth/Agent/ChallengeHandler.cs). + +```diff +- AAuth.Agent.ChallengeHandler: public ChallengeHandler ( TokenExchangeClient exchange , AAuthTokenHolder holder , string ? personServer , Func < Interaction , CancellationToken , Task > ? onInteractionRequired , DeferredPollerOptions ? pollerOptions , Func < string ? > ? upstreamTokenProvider ) +- AAuth.Agent.ChallengeHandler: public ChallengeHandler ( TokenExchangeClient exchange , AAuthTokenHolder holder , string personServer , Func < Interaction , CancellationToken , Task > ? onInteractionRequired = null , DeferredPollerOptions ? pollerOptions = null ) ++ AAuth.Agent.ChallengeHandler: public ChallengeHandler ( TokenExchangeClient exchange , AAuthTokenHolder holder , TokenVerifier verifier , MetadataClient metadata , JwksClient jwks , string ? personServer , Func < Interaction , CancellationToken , Task > ? onInteractionRequired , DeferredPollerOptions ? pollerOptions , Func < string ? > ? upstreamTokenProvider ) ++ AAuth.Agent.ChallengeHandler: public ChallengeHandler ( TokenExchangeClient exchange , AAuthTokenHolder holder , TokenVerifier verifier , MetadataClient metadata , JwksClient jwks , string personServer , Func < Interaction , CancellationToken , Task > ? onInteractionRequired = null , DeferredPollerOptions ? pollerOptions = null ) +``` + +Public owners: `AAuth.Agent.ChallengeHandler`, `AAuth.Agent`. + +### src/AAuth/Agent/ClarificationExchange.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [ClarificationExchange.cs](../../../src/AAuth/Agent/ClarificationExchange.cs). + +Public signatures unchanged (21); behavior reviewed under agent-clients. + +Public owners: `AAuth.Agent.ClarificationExchange`, `AAuth.Agent.ClarificationResponse.Kind`, `AAuth.Agent.ClarificationResponse`, `AAuth.Agent`. + +### src/AAuth/Agent/DeferredPoller.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [DeferredPoller.cs](../../../src/AAuth/Agent/DeferredPoller.cs). + +```diff +- AAuth.Agent.DeferredPoller: public async Task < HttpResponseMessage > PollAsync ( Uri pendingUrl , CancellationToken cancellationToken = default ) ++ AAuth.Agent.DeferredPoller: public Task < HttpResponseMessage > PollAsync ( Uri pendingUrl , CancellationToken cancellationToken = default ) ++ AAuth.Agent.DeferredPollerOptions: public TimeProvider TimeProvider { get ; init ; } = TimeProvider . System +``` + +Public owners: `AAuth.Agent.DeferredPollerOptions`, `AAuth.Agent.DeferredPoller`, `AAuth.Agent`. + +### src/AAuth/Agent/Governance/AAuthGovernanceClient.cs + +Concept/decision: [governance](#governance). Source: [AAuthGovernanceClient.cs](../../../src/AAuth/Agent/Governance/AAuthGovernanceClient.cs). + +```diff +- AAuth.Agent.Governance: public sealed class AAuthGovernanceClient ++ AAuth.Agent.Governance.AAuthGovernanceClient: public void Dispose ( ) ++ AAuth.Agent.Governance: public sealed class AAuthGovernanceClient : IDisposable +``` + +Public owners: `AAuth.Agent.Governance.AAuthGovernanceClient`, `AAuth.Agent.Governance`. + +### src/AAuth/Agent/Governance/GovernanceOptions.cs + +Concept/decision: [governance](#governance). Source: [GovernanceOptions.cs](../../../src/AAuth/Agent/Governance/GovernanceOptions.cs). + +Public signatures unchanged (5); behavior reviewed under governance. + +Public owners: `AAuth.Agent.Governance.GovernanceOptions`, `AAuth.Agent.Governance`. + +### src/AAuth/Agent/Governance/MissionClient.cs + +Concept/decision: [governance](#governance). Source: [MissionClient.cs](../../../src/AAuth/Agent/Governance/MissionClient.cs). + +Public signatures unchanged (3); behavior reviewed under governance. + +Public owners: `AAuth.Agent.Governance.MissionClient`, `AAuth.Agent.Governance`. + +### src/AAuth/Agent/Governance/MissionSession.cs + +Concept/decision: [governance](#governance). Source: [MissionSession.cs](../../../src/AAuth/Agent/Governance/MissionSession.cs). + +```diff +- AAuth.Agent.Governance.MissionSession: public Task < bool > ProposeCompletionAsync ( string summary , GovernanceOptions ? options = null , CancellationToken cancellationToken = default ) ++ AAuth.Agent.Governance.MissionSession: public async Task < bool > ProposeCompletionAsync ( string summary , GovernanceOptions ? options = null , CancellationToken cancellationToken = default ) +``` + +Public owners: `AAuth.Agent.Governance.MissionSession`, `AAuth.Agent.Governance`. + +### src/AAuth/Agent/Governance/PermissionClient.cs + +Concept/decision: [governance](#governance). Source: [PermissionClient.cs](../../../src/AAuth/Agent/Governance/PermissionClient.cs). + +Public signatures unchanged (4); behavior reviewed under governance. + +Public owners: `AAuth.Agent.Governance.PermissionClient`, `AAuth.Agent.Governance`. + +### src/AAuth/Agent/IAAuthAccessStore.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [IAAuthAccessStore.cs](../../../src/AAuth/Agent/IAAuthAccessStore.cs). + +```diff +- AAuth.Agent.IAAuthAccessStore: bool TryGet ( string origin , out string token ) +- AAuth.Agent.IAAuthAccessStore: void Remove ( string origin ) +- AAuth.Agent.IAAuthAccessStore: void Set ( string origin , string token ) +- AAuth.Agent.InMemoryAAuthAccessStore: public bool TryGet ( string origin , out string token ) +- AAuth.Agent.InMemoryAAuthAccessStore: public void Remove ( string origin ) +- AAuth.Agent.InMemoryAAuthAccessStore: public void Set ( string origin , string token ) ++ AAuth.Agent.IAAuthAccessStore: bool TryGet ( string origin , out string token , string ? account = null , string ? signingKeyThumbprint = null ) ++ AAuth.Agent.IAAuthAccessStore: void Remove ( string origin , string ? account = null , string ? signingKeyThumbprint = null ) ++ AAuth.Agent.IAAuthAccessStore: void Set ( string origin , string token , string ? account = null , string ? signingKeyThumbprint = null ) ++ AAuth.Agent.InMemoryAAuthAccessStore: public bool TryGet ( string origin , out string token , string ? account = null , string ? signingKeyThumbprint = null ) ++ AAuth.Agent.InMemoryAAuthAccessStore: public void Remove ( string origin , string ? account = null , string ? signingKeyThumbprint = null ) ++ AAuth.Agent.InMemoryAAuthAccessStore: public void Set ( string origin , string token , string ? account = null , string ? signingKeyThumbprint = null ) +``` + +Public owners: `AAuth.Agent.IAAuthAccessStore`, `AAuth.Agent.InMemoryAAuthAccessStore`, `AAuth.Agent`. + +### src/AAuth/Agent/ITokenRefresher.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [ITokenRefresher.cs](../../../src/AAuth/Agent/ITokenRefresher.cs). + +```diff ++ AAuth.Agent.TokenRefreshContext: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Agent.ITokenRefresher`, `AAuth.Agent.TokenRefreshContext`, `AAuth.Agent`. + +### src/AAuth/Agent/InteractionHandler.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [InteractionHandler.cs](../../../src/AAuth/Agent/InteractionHandler.cs). + +```diff ++ AAuth.Agent.InteractionHandler: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Agent.InteractionHandler: public AAuth . Discovery . AAuthTransportContract ? TransportContract { get ; init ; } ++ AAuth.Agent.InteractionHandler: public TimeProvider TimeProvider { get ; init ; } = TimeProvider . System +``` + +Public owners: `AAuth.Agent.InteractionHandler`, `AAuth.Agent`. + +### src/AAuth/Agent/Mission.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [Mission.cs](../../../src/AAuth/Agent/Mission.cs). + +```diff +- AAuth.Agent.AAuthMissionHeader: public static bool TryParseStructured ( string ? value , out string ? approver , out string ? s256 ) +- AAuth.Agent.Mission: public MissionState State { get ; init ; } = MissionState . Active ++ AAuth.Agent.AAuthMissionHeader: public static bool TryParseStructured ( string ? value , out string ? approver , out string ? s256 , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Agent.Mission: public MissionState State { get ; init ; } +``` + +Public owners: `AAuth.Agent.AAuthMissionHeader`, `AAuth.Agent.Mission`, `AAuth.Agent`. + +### src/AAuth/Agent/MissionForwardingHandler.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [MissionForwardingHandler.cs](../../../src/AAuth/Agent/MissionForwardingHandler.cs). + +Public signatures unchanged (3); behavior reviewed under agent-clients. + +Public owners: `AAuth.Agent.MissionForwardingHandler`, `AAuth.Agent`. + +### src/AAuth/Agent/SelfIssuedTokenRefresher.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [SelfIssuedTokenRefresher.cs](../../../src/AAuth/Agent/SelfIssuedTokenRefresher.cs). + +```diff +- AAuth.Agent.SelfIssuedTokenRefresher: public SelfIssuedTokenRefresher ( AAuthKey key , string issuer , string subject , string kid , string ? personServer = null , TimeSpan ? lifetime = null ) +- AAuth.Agent.SelfIssuedTokenRefresher: public static RefresherBuilder Create ( AAuthKey key , string issuer , string subject ) ++ AAuth.Agent.SelfIssuedTokenRefresher.RefresherBuilder: public RefresherBuilder WithEgressPolicy ( AAuth . Discovery . AAuthEgressPolicy policy ) ++ AAuth.Agent.SelfIssuedTokenRefresher: public SelfIssuedTokenRefresher ( IAAuthKey key , string issuer , string subject , string kid , string ? personServer = null , TimeSpan ? lifetime = null , AAuth . Discovery . AAuthEgressPolicy ? egressPolicy = null ) ++ AAuth.Agent.SelfIssuedTokenRefresher: public static RefresherBuilder Create ( IAAuthKey key , string issuer , string subject ) +``` + +Public owners: `AAuth.Agent.SelfIssuedTokenRefresher.RefresherBuilder`, `AAuth.Agent.SelfIssuedTokenRefresher`, `AAuth.Agent`. + +### src/AAuth/Agent/TokenExchangeClient.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [TokenExchangeClient.cs](../../../src/AAuth/Agent/TokenExchangeClient.cs). + +```diff ++ AAuth.Agent.TokenExchangeClient: public AAuthEgressPolicy EgressPolicy { get ; } +``` + +Public owners: `AAuth.Agent.TokenExchangeClient`, `AAuth.Agent`. + +### src/AAuth/Agent/TokenExchangeRequest.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [TokenExchangeRequest.cs](../../../src/AAuth/Agent/TokenExchangeRequest.cs). + +```diff ++ AAuth.Agent.TokenExchangeRequest: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Agent.TokenExchangeRequest`, `AAuth.Agent`. + +### src/AAuth/BootstrapBuilder.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [BootstrapBuilder.cs](../../../src/AAuth/BootstrapBuilder.cs). + +```diff ++ AAuth.BootstrapBuilder: public BootstrapBuilder WithDevelopmentLoopback ( params string [ ] origins ) ++ AAuth.BootstrapBuilder: public BootstrapBuilder WithEgressPolicy ( Discovery . AAuthEgressPolicy policy ) ++ AAuth.BootstrapBuilder: public BootstrapBuilder WithKey ( AAuthKey key ) +``` + +Public owners: `AAuth.BootstrapBuilder`, `AAuth`. + +### src/AAuth/Crypto/AAuthKey.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthKey.cs](../../../src/AAuth/Crypto/AAuthKey.cs). + +```diff +- AAuth.Crypto.AAuthKey: public const string Algorithm = "EdDSA" ; +- AAuth.Crypto.AAuthKey: public const string Ed25519Algorithm = "EdDSA" ; ++ AAuth.Crypto.AAuthKey: public const string Ed25519Algorithm = "Ed25519" ; +``` + +Public owners: `AAuth.Crypto.AAuthKey`, `AAuth.Crypto`. + +### src/AAuth/Crypto/EcdsaAAuthKey.cs + +Concept/decision: [signatures](#signatures). Source: [EcdsaAAuthKey.cs](../../../src/AAuth/Crypto/EcdsaAAuthKey.cs). + +Public signatures unchanged (13); behavior reviewed under signatures. + +Public owners: `AAuth.Crypto.EcdsaAAuthKey`, `AAuth.Crypto`. + +### src/AAuth/Crypto/IAAuthKey.cs + +Concept/decision: [signatures](#signatures). Source: [IAAuthKey.cs](../../../src/AAuth/Crypto/IAAuthKey.cs). + +Public signatures unchanged (8); behavior reviewed under signatures. + +Public owners: `AAuth.Crypto.IAAuthKey`, `AAuth.Crypto`. + +### src/AAuth/Crypto/JwkValidationException.cs + +Concept/decision: [signatures](#signatures). Source: [JwkValidationException.cs](../../../src/AAuth/Crypto/JwkValidationException.cs). + +```diff ++ AAuth.Crypto.JwkValidationException: public JwkValidationException ( SignatureErrorCode code , string message , Exception ? inner = null ) ++ AAuth.Crypto.JwkValidationException: public SignatureErrorCode Code { get ; } ++ AAuth.Crypto: public sealed class JwkValidationException : ArgumentException +``` + +Public owners: `AAuth.Crypto.JwkValidationException`, `AAuth.Crypto`. + +### src/AAuth/Crypto/KeyFactory.cs + +Concept/decision: [signatures](#signatures). Source: [KeyFactory.cs](../../../src/AAuth/Crypto/KeyFactory.cs). + +```diff ++ AAuth.Crypto.KeyFactory: public static IAAuthKey FromPublicJwk ( JsonObject jwk ) +``` + +Public owners: `AAuth.Crypto.KeyFactory`, `AAuth.Crypto`. + +### src/AAuth/DependencyInjection/AAuthAgentOptions.cs + +Concept/decision: [di](#di). Source: [AAuthAgentOptions.cs](../../../src/AAuth/DependencyInjection/AAuthAgentOptions.cs). + +```diff ++ AAuth.AAuthAgentOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.AAuthAgentOptions: public AAuth . HttpSig . ISignatureKeyProvider ? SignatureKeyProvider { get ; set ; } ++ AAuth.AAuthAgentOptions: public string ? AgentToken { get ; set ; } +``` + +Public owners: `AAuth.AAuthAgentOptions`, `AAuth`. + +### src/AAuth/DependencyInjection/AAuthAgentServiceCollectionExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthAgentServiceCollectionExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthAgentServiceCollectionExtensions.cs). + +Public signatures unchanged (2); behavior reviewed under di. + +Public owners: `Microsoft.Extensions.DependencyInjection.AAuthAgentServiceCollectionExtensions`, `Microsoft.Extensions.DependencyInjection`. + +### src/AAuth/DependencyInjection/AAuthApplicationBuilderExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthApplicationBuilderExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthApplicationBuilderExtensions.cs). + +Public signatures unchanged (7); behavior reviewed under di. + +Public owners: `Microsoft.AspNetCore.Builder.AAuthApplicationBuilderExtensions`, `Microsoft.AspNetCore.Builder`. + +### src/AAuth/DependencyInjection/AAuthDiscoveryOptions.cs + +Concept/decision: [di](#di). Source: [AAuthDiscoveryOptions.cs](../../../src/AAuth/DependencyInjection/AAuthDiscoveryOptions.cs). + +```diff ++ AAuth.AAuthDiscoveryOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.AAuthDiscoveryOptions: public TimeSpan MaxCacheAge { get ; set ; } = TimeSpan . FromHours ( 24 ) ++ AAuth.AAuthDiscoveryOptions: public int MaxCacheEntries { get ; set ; } = 1024 +``` + +Public owners: `AAuth.AAuthDiscoveryOptions`, `AAuth`. + +### src/AAuth/DependencyInjection/AAuthDiscoveryServiceCollectionExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthDiscoveryServiceCollectionExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthDiscoveryServiceCollectionExtensions.cs). + +Public signatures unchanged (2); behavior reviewed under di. + +Public owners: `Microsoft.Extensions.DependencyInjection.AAuthDiscoveryServiceCollectionExtensions`, `Microsoft.Extensions.DependencyInjection`. + +### src/AAuth/DependencyInjection/AAuthFederationOptions.cs + +Concept/decision: [di](#di). Source: [AAuthFederationOptions.cs](../../../src/AAuth/DependencyInjection/AAuthFederationOptions.cs). + +```diff ++ AAuth.AAuthFederationOptions: public AAuthTransportContract ? TransportContract { get ; set ; } ++ AAuth: public sealed class AAuthFederationOptions +``` + +Public owners: `AAuth.AAuthFederationOptions`, `AAuth`. + +### src/AAuth/DependencyInjection/AAuthFederationServiceCollectionExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthFederationServiceCollectionExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthFederationServiceCollectionExtensions.cs). + +```diff +- Microsoft.Extensions.DependencyInjection.AAuthFederationServiceCollectionExtensions: public static IServiceCollection AddAAuthFederation ( this IServiceCollection services , AAuthKey personServerKey , string personServerIssuer , string personServerKeyId ) ++ Microsoft.Extensions.DependencyInjection.AAuthFederationServiceCollectionExtensions: public static IServiceCollection AddAAuthFederation ( this IServiceCollection services , IAAuthKey personServerKey , string personServerIssuer , string personServerKeyId ) +``` + +Public owners: `Microsoft.Extensions.DependencyInjection.AAuthFederationServiceCollectionExtensions`, `Microsoft.Extensions.DependencyInjection`. + +### src/AAuth/DependencyInjection/AAuthGovernanceApplicationBuilderExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthGovernanceApplicationBuilderExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthGovernanceApplicationBuilderExtensions.cs). + +Public signatures unchanged (2); behavior reviewed under di. + +Public owners: `Microsoft.AspNetCore.Builder.AAuthGovernanceApplicationBuilderExtensions`, `Microsoft.AspNetCore.Builder`. + +### src/AAuth/DependencyInjection/AAuthResourceOptions.cs + +Concept/decision: [di](#di). Source: [AAuthResourceOptions.cs](../../../src/AAuth/DependencyInjection/AAuthResourceOptions.cs). + +```diff +- AAuth.AAuthResourceOptions: public Dictionary < string , AAuthKey > SigningKeys { get ; set ; } = new ( ) ++ AAuth.AAuthResourceOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.AAuthResourceOptions: public Dictionary < string , IAAuthKey > SigningKeys { get ; set ; } = new ( ) ++ AAuth.AAuthResourceOptions: public string ? RevocationEndpoint { get ; set ; } +``` + +Public owners: `AAuth.AAuthResourceOptions`, `AAuth`. + +### src/AAuth/DependencyInjection/AAuthResourcePipelineOptions.cs + +Concept/decision: [di](#di). Source: [AAuthResourcePipelineOptions.cs](../../../src/AAuth/DependencyInjection/AAuthResourcePipelineOptions.cs). + +```diff +- AAuth.AAuthResourcePipelineOptions: public bool RequireIssuerVerification { get ; set ; } = true ++ AAuth.AAuthResourcePipelineOptions: public Func < Microsoft . AspNetCore . Http . HttpContext , string ? > ? AccountSelector { get ; set ; } +``` + +Public owners: `AAuth.AAuthResourcePipelineOptions`, `AAuth`. + +### src/AAuth/DependencyInjection/AAuthResourceServiceCollectionExtensions.cs + +Concept/decision: [di](#di). Source: [AAuthResourceServiceCollectionExtensions.cs](../../../src/AAuth/DependencyInjection/AAuthResourceServiceCollectionExtensions.cs). + +Public signatures unchanged (6); behavior reviewed under di. + +Public owners: `Microsoft.Extensions.DependencyInjection.AAuthResourceServiceCollectionExtensions`, `Microsoft.Extensions.DependencyInjection`. + +### src/AAuth/Discovery/AAuthEgressPolicy.cs + +Concept/decision: [discovery](#discovery). Source: [AAuthEgressPolicy.cs](../../../src/AAuth/Discovery/AAuthEgressPolicy.cs). + +```diff ++ AAuth.Discovery.AAuthEgressPolicy: public AAuthEgressPolicy ( IEnumerable < string > ? developmentLoopbackOrigins = null , IEnumerable < ( string Source , string Target ) > ? crossOriginJwks = null , int maxResponseBytes = 1024 * 1024 , TimeSpan ? requestTimeout = null , IAAuthDnsResolver ? dnsResolver = null ) ++ AAuth.Discovery.AAuthEgressPolicy: public TimeSpan RequestTimeout { get ; } ++ AAuth.Discovery.AAuthEgressPolicy: public Uri ValidateJwksUrl ( string value , string metadataIdentifier ) ++ AAuth.Discovery.AAuthEgressPolicy: public Uri ValidatePendingLocation ( Uri endpoint , Uri location ) ++ AAuth.Discovery.AAuthEgressPolicy: public Uri ValidateUrl ( string value , bool endpoint = false ) ++ AAuth.Discovery.AAuthEgressPolicy: public async Task ValidateDestinationAsync ( string value , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.AAuthEgressPolicy: public bool IsValidIdentifier ( string ? identifier ) ++ AAuth.Discovery.AAuthEgressPolicy: public int MaxResponseBytes { get ; } ++ AAuth.Discovery.AAuthEgressPolicy: public static AAuthEgressPolicy ForDevelopmentLoopback ( params string [ ] origins ) ++ AAuth.Discovery.AAuthEgressPolicy: public static AAuthEgressPolicy Production { get ; } = new ( ) ++ AAuth.Discovery.AAuthEgressPolicy: public void ValidateIdentifier ( string identifier ) ++ AAuth.Discovery.IAAuthDnsResolver: Task < IPAddress [ ] > ResolveAsync ( string host , CancellationToken cancellationToken ) ++ AAuth.Discovery: public interface IAAuthDnsResolver ++ AAuth.Discovery: public sealed class AAuthEgressPolicy +``` + +Public owners: `AAuth.Discovery.AAuthEgressPolicy`, `AAuth.Discovery.IAAuthDnsResolver`, `AAuth.Discovery`. + +### src/AAuth/Discovery/AAuthHttpTransport.cs + +Concept/decision: [discovery](#discovery). Source: [AAuthHttpTransport.cs](../../../src/AAuth/Discovery/AAuthHttpTransport.cs). + +```diff ++ AAuth.Discovery.AAuthHttpTransport: public static AAuthEgressPolicy GetPolicy ( HttpClient client ) ++ AAuth.Discovery.AAuthHttpTransport: public static HttpClient AttachPolicy ( HttpClient client , AAuthEgressPolicy policy , AAuthTransportContract contract ) ++ AAuth.Discovery.AAuthHttpTransport: public static HttpClient CreateClient ( AAuthEgressPolicy ? policy = null ) ++ AAuth.Discovery.AAuthHttpTransport: public static HttpMessageHandler CreateHandler ( AAuthEgressPolicy ? policy = null , HttpMessageHandler ? innerHandler = null , AAuthTransportContract ? contract = null ) ++ AAuth.Discovery.AAuthHttpTransport: public static Task < HttpResponseMessage > SendAsync ( HttpClient client , HttpRequestMessage request , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.AAuthHttpTransport: public static Task AdmitInteractionAsync ( HttpClient client , string url , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.AAuthTransportContract: EnforcesEgressPolicy ++ AAuth.Discovery.AAuthTransportContract: InProcessOnly ++ AAuth.Discovery: public enum AAuthTransportContract ++ AAuth.Discovery: public static class AAuthHttpTransport +``` + +Public owners: `AAuth.Discovery.AAuthHttpTransport`, `AAuth.Discovery.AAuthTransportContract`, `AAuth.Discovery`. + +### src/AAuth/Discovery/JwksClient.cs + +Concept/decision: [discovery](#discovery). Source: [JwksClient.cs](../../../src/AAuth/Discovery/JwksClient.cs). + +```diff +- AAuth.Discovery.JwksClient: public JwksClient ( HttpClient http , TimeSpan ? cacheTtl = null , TimeSpan ? minRefreshInterval = null , Func < DateTimeOffset > ? clock = null ) +- AAuth.Discovery.JwksClient: public async Task < IAAuthKey ? > ForceRefreshKeyAsync ( Uri jwksUri , string kid , CancellationToken cancellationToken = default ) +- AAuth.Discovery.JwksClient: public async Task < IAAuthKey ? > ResolveKeyAsync ( Uri jwksUri , string kid , CancellationToken cancellationToken = default ) +- AAuth.Discovery: public sealed class JwksClient ++ AAuth.Discovery.JwksClient: public AAuthEgressPolicy Policy { get ; } ++ AAuth.Discovery.JwksClient: public JwksClient ( HttpClient ? http = null , TimeSpan ? cacheTtl = null , TimeSpan ? minRefreshInterval = null , Func < DateTimeOffset > ? clock = null , int maxCacheEntries = 1024 , TimeSpan ? maxCacheAge = null , AAuthEgressPolicy ? policy = null , AAuthTransportContract ? transportContract = null ) ++ AAuth.Discovery.JwksClient: public Task < IAAuthKey ? > ForceRefreshKeyAsync ( Uri jwksUri , string kid , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.JwksClient: public Task < IAAuthKey ? > ForceRefreshKeyAsync ( Uri jwksUri , string kid , string issuer , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.JwksClient: public Task < IAAuthKey ? > ResolveKeyAsync ( Uri jwksUri , string kid , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.JwksClient: public Task < IAAuthKey ? > ResolveKeyAsync ( Uri jwksUri , string kid , string issuer , CancellationToken cancellationToken = default ) ++ AAuth.Discovery.JwksClient: public void Dispose ( ) ++ AAuth.Discovery: public sealed class JwksClient : IDisposable +``` + +Public owners: `AAuth.Discovery.JwksClient`, `AAuth.Discovery`. + +### src/AAuth/Discovery/MetadataClient.cs + +Concept/decision: [discovery](#discovery). Source: [MetadataClient.cs](../../../src/AAuth/Discovery/MetadataClient.cs). + +```diff +- AAuth.Discovery.MetadataClient: public MetadataClient ( HttpClient http , TimeSpan ? cacheTtl = null , Func < DateTimeOffset > ? clock = null ) +- AAuth.Discovery.MetadataClient: public static Uri BuildUrl ( string issuer , string dwk ) +- AAuth.Discovery: public sealed class MetadataClient ++ AAuth.Discovery.MetadataClient: public AAuthEgressPolicy Policy { get ; } ++ AAuth.Discovery.MetadataClient: public MetadataClient ( HttpClient ? http = null , TimeSpan ? cacheTtl = null , Func < DateTimeOffset > ? clock = null , AAuthEgressPolicy ? policy = null , AAuthTransportContract ? transportContract = null , int maxCacheEntries = 1024 , TimeSpan ? maxCacheAge = null ) ++ AAuth.Discovery.MetadataClient: public Uri GetUrl ( string issuer , string dwk ) ++ AAuth.Discovery.MetadataClient: public static Uri BuildUrl ( string issuer , string dwk , AAuthEgressPolicy ? policy = null ) ++ AAuth.Discovery.MetadataClient: public void Dispose ( ) ++ AAuth.Discovery: public sealed class MetadataClient : IDisposable +``` + +Public owners: `AAuth.Discovery.MetadataClient`, `AAuth.Discovery`. + +### src/AAuth/Discovery/ServerMetadata.cs + +Concept/decision: [discovery](#discovery). Source: [ServerMetadata.cs](../../../src/AAuth/Discovery/ServerMetadata.cs). + +Public signatures unchanged (37); behavior reviewed under discovery. + +Public owners: `AAuth.Discovery.MetadataClientExtensions`, `AAuth.Discovery.ResourceMetadata`, `AAuth.Discovery.ServerMetadata`, `AAuth.Discovery`. + +### src/AAuth/EnrolledBuilder.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [EnrolledBuilder.cs](../../../src/AAuth/EnrolledBuilder.cs). + +```diff +- AAuth.EnrolledBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler ) ++ AAuth.EnrolledBuilder: public AAuthClientBuilder ToBuilder ( ) ++ AAuth.EnrolledBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler , AAuth . Discovery . AAuthTransportContract ? transportContract = null ) ++ AAuth.EnrolledBuilder: public AAuthClientBuilder WithResourceManagedAccess ( IAAuthAccessStore ? store = null ) ++ AAuth.EnrolledBuilder: public EnrolledBuilder WithDevelopmentLoopback ( params string [ ] origins ) ++ AAuth.EnrolledBuilder: public EnrolledBuilder WithEgressPolicy ( AAuth . Discovery . AAuthEgressPolicy policy ) +``` + +Public owners: `AAuth.EnrolledBuilder`, `AAuth`. + +### src/AAuth/Errors/AAuthMetadataException.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthMetadataException.cs](../../../src/AAuth/Errors/AAuthMetadataException.cs). + +```diff ++ AAuth.Errors.AAuthMetadataException: public SignatureErrorCode Code ++ AAuth.Errors.AAuthMetadataException: public string ErrorCode +``` + +Public owners: `AAuth.Errors.AAuthMetadataException`, `AAuth.Errors`. + +### src/AAuth/Errors/AAuthTokenExchangeException.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthTokenExchangeException.cs](../../../src/AAuth/Errors/AAuthTokenExchangeException.cs). + +```diff +- AAuth.Errors.AAuthTokenExchangeException: public AAuthTokenExchangeException ( string errorCode , string ? errorDescription , int statusCode , bool isTerminal ) +- AAuth.Errors.AAuthTokenExchangeException: public string ? ErrorDescription { get ; } ++ AAuth.Errors.AAuthTokenExchangeException: public AAuthTokenExchangeException ( string errorCode , string ? detail , int statusCode , bool isTerminal ) ++ AAuth.Errors.AAuthTokenExchangeException: public string ? Detail { get ; } +``` + +Public owners: `AAuth.Errors.AAuthTokenExchangeException`, `AAuth.Errors`. + +### src/AAuth/Errors/SignatureError.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [SignatureError.cs](../../../src/AAuth/Errors/SignatureError.cs). + +```diff +- AAuth.Errors.SignatureError: public static string Format ( SignatureErrorCode code , string [ ] ? requiredInput = null , string [ ] ? supportedAlgorithms = null ) ++ AAuth.Errors.SignatureError: public static string Format ( SignatureErrorCode code , string [ ] ? requiredInput = null ) ++ AAuth.Errors.SignatureErrorCode: IssuerMismatch ++ AAuth.Errors.SignatureErrorCode: IssuerMissing ++ AAuth.Errors.SignatureErrorCode: UnsupportedScheme +``` + +Public owners: `AAuth.Errors.SignatureErrorCode`, `AAuth.Errors.SignatureError`, `AAuth.Errors`. + +### src/AAuth/Errors/TokenError.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [TokenError.cs](../../../src/AAuth/Errors/TokenError.cs). + +```diff +- AAuth.Errors: public sealed record TokenErrorResponse ( TokenErrorCode Error , string ? ErrorDescription = null ) ++ AAuth.Errors: public sealed record TokenErrorResponse ( TokenErrorCode Error , string ? Detail = null ) +``` + +Public owners: `AAuth.Errors.TokenErrorCode`, `AAuth.Errors.TokenErrorResponse`, `AAuth.Errors`. + +### src/AAuth/Headers/ClaimsResponse.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [ClaimsResponse.cs](../../../src/AAuth/Headers/ClaimsResponse.cs). + +Public signatures unchanged (4); behavior reviewed under server-contracts. + +Public owners: `AAuth.Headers.ClaimsResponse`, `AAuth.Headers`. + +### src/AAuth/Headers/Interaction.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [Interaction.cs](../../../src/AAuth/Headers/Interaction.cs). + +```diff +- AAuth.Headers.Interaction: public static Interaction ? FromRequirement ( AAuthRequirementHeader . ParsedRequirement requirement ) +- AAuth.Headers.Interaction: public static string Format ( string url , string code ) ++ AAuth.Headers.Interaction: public static Interaction ? FromRequirement ( AAuthRequirementHeader . ParsedRequirement requirement , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Headers.Interaction: public static string Format ( string url , string code , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Headers.Interaction`, `AAuth.Headers`. + +### src/AAuth/HttpSig/AAuthSigningHandler.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthSigningHandler.cs](../../../src/AAuth/HttpSig/AAuthSigningHandler.cs). + +```diff +- AAuth.HttpSig.AAuthSigningHandler: public AAuthSigningHandler ( AAuthKey key , Func < string > tokenFactory , Func < DateTimeOffset > ? clock = null ) ++ AAuth.HttpSig.AAuthSigningHandler: public AAuthSigningHandler ( IAAuthKey key , Func < string > tokenFactory , Func < DateTimeOffset > ? clock = null ) ++ AAuth.HttpSig.AAuthSigningHandler: public async Task SignAsync ( HttpRequestMessage request , CancellationToken cancellationToken = default ) ++ AAuth.HttpSig.AAuthSigningHandler: public string Label { get ; init ; } = "sig" +``` + +Public owners: `AAuth.HttpSig.AAuthSigningHandler`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/AAuthVerifier.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthVerifier.cs](../../../src/AAuth/HttpSig/AAuthVerifier.cs). + +```diff +- AAuth.HttpSig.AAuthVerifier: public void Verify ( string method , string authority , string path , string signatureKey , string signatureInput , string signatureHeader , IAAuthKey publicKey , string ? authorization = null , string ? mission = null ) ++ AAuth.HttpSig.AAuthVerificationException: public AAuth . Errors . SignatureErrorCode Code { get ; } ++ AAuth.HttpSig.AAuthVerificationException: public AAuthVerificationException ( AAuth . Errors . SignatureErrorCode code , string message , Exception ? inner = null ) ++ AAuth.HttpSig.AAuthVerifier: public IReadOnlyDictionary < string , StructuredFieldType > StructuredFieldTypes { get ; init ; } = new Dictionary < string , StructuredFieldType > ( StringComparer . Ordinal ) { [ "signature-key" ] = StructuredFieldType . Dictionary , [ "signature-input" ] = StructuredFieldType . Dictionary , [ "signature" ] = StructuredFieldType . Dictionary , [ "content-digest" ] = StructuredFieldType . Dictionary , [ "repr-digest" ] = StructuredFieldType . Dictionary , } ++ AAuth.HttpSig.AAuthVerifier: public string Verify ( string method , string authority , string path , string signatureKey , string signatureInput , string signatureHeader , IAAuthKey publicKey , string ? authorization = null , string ? mission = null , string label = "sig" , IReadOnlyDictionary < string , string > ? fields = null , IReadOnlyCollection < string > ? requiredComponents = null , string ? keyId = null , IReadOnlyDictionary < string , string [ ] > ? fieldValues = null , string ? requestScheme = null , string ? query = null , string ? requestTarget = null ) +``` + +Public owners: `AAuth.HttpSig.AAuthVerificationException`, `AAuth.HttpSig.AAuthVerifier`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/DefaultSignatureKeyResolver.cs + +Concept/decision: [signatures](#signatures). Source: [DefaultSignatureKeyResolver.cs](../../../src/AAuth/HttpSig/DefaultSignatureKeyResolver.cs). + +```diff +- AAuth.HttpSig.DefaultSignatureKeyResolver: public DefaultSignatureKeyResolver ( JwksClient ? jwksClient = null ) ++ AAuth.HttpSig.DefaultSignatureKeyResolver: public DefaultSignatureKeyResolver ( JwksClient ? jwksClient = null , MetadataClient ? metadataClient = null , TokenVerifier ? tokenVerifier = null , IEnumerable < ISignatureTokenVerifier > ? tokenVerifiers = null ) +``` + +Public owners: `AAuth.HttpSig.DefaultSignatureKeyResolver`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/HwkSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [HwkSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/HwkSignatureKeyProvider.cs). + +```diff +- AAuth.HttpSig.HwkSignatureKeyProvider: public HwkSignatureKeyProvider ( IAAuthKey key ) ++ AAuth.HttpSig.HwkSignatureKeyProvider: public HwkSignatureKeyProvider ( IAAuthKey key , string label = "sig" ) +``` + +Public owners: `AAuth.HttpSig.HwkSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/ISignatureKeyResolver.cs + +Concept/decision: [signatures](#signatures). Source: [ISignatureKeyResolver.cs](../../../src/AAuth/HttpSig/ISignatureKeyResolver.cs). + +```diff ++ AAuth.HttpSig.SignatureKeyResolution: public AAuth . Tokens . TokenVerifier . VerifiedToken ? VerifiedToken { get ; init ; } ++ AAuth.HttpSig.SignatureKeyResolution: public IAAuthKey ? IssuerKey { get ; init ; } ++ AAuth.HttpSig.SignatureKeyResolution: public string ? DurableThumbprint { get ; init ; } ++ AAuth.HttpSig.SignatureKeyResolution: public string ? KeyId { get ; init ; } ++ AAuth.HttpSig.SignatureKeyResolution: public string ? VerifiedIdentifier { get ; init ; } +``` + +Public owners: `AAuth.HttpSig.ISignatureKeyResolver`, `AAuth.HttpSig.SignatureKeyResolution`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/ISignatureTokenVerifier.cs + +Concept/decision: [signatures](#signatures). Source: [ISignatureTokenVerifier.cs](../../../src/AAuth/HttpSig/ISignatureTokenVerifier.cs). + +```diff ++ AAuth.HttpSig.ISignatureTokenVerifier: Task < TokenVerifier . VerifiedToken > VerifyAsync ( string jwt , IAAuthKey issuerKey , TokenVerifier verifier , CancellationToken cancellationToken ) ++ AAuth.HttpSig.ISignatureTokenVerifier: string Scheme { get ; } ++ AAuth.HttpSig.ISignatureTokenVerifier: string TokenType { get ; } ++ AAuth.HttpSig: public interface ISignatureTokenVerifier +``` + +Public owners: `AAuth.HttpSig.ISignatureTokenVerifier`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/JktJwtSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [JktJwtSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/JktJwtSignatureKeyProvider.cs). + +```diff +- AAuth.HttpSig.JktJwtSignatureKeyProvider: public JktJwtSignatureKeyProvider ( Func < string > namingJwtFactory ) ++ AAuth.HttpSig.JktJwtSignatureKeyProvider: public JktJwtSignatureKeyProvider ( Func < string > namingJwtFactory , string label = "sig" ) +``` + +Public owners: `AAuth.HttpSig.JktJwtSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/JwksSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [JwksSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/JwksSignatureKeyProvider.cs). + +```diff ++ AAuth.HttpSig.JwksSignatureKeyProvider: public string GetSignatureKeyHeader ( ) ++ AAuth.HttpSig: public sealed class JwksSignatureKeyProvider ( string url , string kid , string label = "sig" ) : ISignatureKeyProvider +``` + +Public owners: `AAuth.HttpSig.JwksSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/JwksUriSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [JwksUriSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/JwksUriSignatureKeyProvider.cs). + +```diff +- AAuth.HttpSig.JwksUriSignatureKeyProvider: public JwksUriSignatureKeyProvider ( string uri , string kid ) ++ AAuth.HttpSig.JwksUriSignatureKeyProvider: public JwksUriSignatureKeyProvider ( string id , string dwk , string kid , string label = "sig" ) +``` + +Public owners: `AAuth.HttpSig.JwksUriSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/JwtSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [JwtSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/JwtSignatureKeyProvider.cs). + +```diff +- AAuth.HttpSig.JwtSignatureKeyProvider: public JwtSignatureKeyProvider ( Func < string > tokenFactory ) ++ AAuth.HttpSig.JwtSignatureKeyProvider: public JwtSignatureKeyProvider ( Func < System . Net . Http . HttpRequestMessage , string > tokenFactory , string label = "sig" ) ++ AAuth.HttpSig.JwtSignatureKeyProvider: public JwtSignatureKeyProvider ( Func < string > tokenFactory , string label = "sig" ) ++ AAuth.HttpSig.JwtSignatureKeyProvider: public string GetSignatureKeyHeader ( System . Net . Http . HttpRequestMessage request ) +``` + +Public owners: `AAuth.HttpSig.JwtSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/NamingTokenVerifier.cs + +Concept/decision: [signatures](#signatures). Source: [NamingTokenVerifier.cs](../../../src/AAuth/HttpSig/NamingTokenVerifier.cs). + +```diff ++ AAuth.HttpSig.NamingTokenVerifier: public sealed record VerifiedNamingToken ( IAAuthKey DurableKey , IAAuthKey ConfirmationKey , string Issuer , DateTimeOffset ExpiresAt ) ++ AAuth.HttpSig.NamingTokenVerifier: public static VerifiedNamingToken Verify ( string jwt , DateTimeOffset now , TimeSpan clockSkew ) ++ AAuth.HttpSig: public static class NamingTokenVerifier +``` + +Public owners: `AAuth.HttpSig.NamingTokenVerifier`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/SelfJwtSignatureKeyProvider.cs + +Concept/decision: [signatures](#signatures). Source: [SelfJwtSignatureKeyProvider.cs](../../../src/AAuth/HttpSig/SelfJwtSignatureKeyProvider.cs). + +```diff ++ AAuth.HttpSig.SelfJwtSignatureKeyProvider: public string GetSignatureKeyHeader ( ) ++ AAuth.HttpSig: public sealed class SelfJwtSignatureKeyProvider ( Func < string > tokenFactory , string label = "sig" ) : ISignatureKeyProvider +``` + +Public owners: `AAuth.HttpSig.SelfJwtSignatureKeyProvider`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/SignatureKeyHeader.cs + +Concept/decision: [signatures](#signatures). Source: [SignatureKeyHeader.cs](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs). + +```diff +- AAuth.HttpSig.SignatureKeyHeader: public static ( string Scheme , IReadOnlyDictionary < string , string > Parameters ) Parse ( string headerValue ) +- AAuth.HttpSig.SignatureKeyHeader: public static string ? GetJwt ( string headerValue ) +- AAuth.HttpSig.SignatureKeyHeader: public static string FormatHwk ( string jkt , string jwkBase64Url ) +- AAuth.HttpSig.SignatureKeyHeader: public static string FormatJktJwt ( string jwt ) +- AAuth.HttpSig.SignatureKeyHeader: public static string FormatJwksUri ( string uri , string kid ) +- AAuth.HttpSig.SignatureKeyHeader: public static string FormatJwt ( string jwt ) ++ AAuth.HttpSig.SignatureKeyHeader: public static ( string Scheme , IReadOnlyDictionary < string , object > Parameters ) Parse ( string headerValue , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string ? GetJwt ( string headerValue , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatHwk ( IAAuthKey key , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatJktJwt ( string jwt , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatJwks ( string url , string kid , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatJwksUri ( string id , string dwk , string kid , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatJwt ( string jwt , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyHeader: public static string FormatSelfJwt ( string jwt , string label = "sig" ) +``` + +Public owners: `AAuth.HttpSig.SignatureKeyHeader`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/SignatureKeyParser.cs + +Concept/decision: [signatures](#signatures). Source: [SignatureKeyParser.cs](../../../src/AAuth/HttpSig/SignatureKeyParser.cs). + +```diff +- AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKey: public DateTimeOffset ? Expiration { get ; } +- AAuth.HttpSig.SignatureKeyParser: public sealed record ParsedSignatureKey ( string Jwt , JsonObject Header , JsonObject Payload , AAuthKey ConfirmationKey ) +- AAuth.HttpSig.SignatureKeyParser: public static ParsedSignatureKey Parse ( string signatureKeyHeader ) +- AAuth.HttpSig.SignatureKeyParser: public static ParsedSignatureKeyInfo ParseAny ( string signatureKeyHeader ) ++ AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKey: public DateTimeOffset ? Expiration ++ AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKeyInfo: public string ? Dwk { get ; init ; } ++ AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKeyInfo: public string ? Identifier { get ; init ; } ++ AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKeyInfo: public string Label { get ; init ; } = "sig" ++ AAuth.HttpSig.SignatureKeyParser: public sealed record ParsedSignatureKey ( string Jwt , JsonObject Header , JsonObject Payload , IAAuthKey ConfirmationKey ) ++ AAuth.HttpSig.SignatureKeyParser: public static ParsedSignatureKey Parse ( string signatureKeyHeader , string label = "sig" ) ++ AAuth.HttpSig.SignatureKeyParser: public static ParsedSignatureKeyInfo ParseAny ( string signatureKeyHeader , string label = "sig" ) +``` + +Public owners: `AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKeyInfo`, `AAuth.HttpSig.SignatureKeyParser.ParsedSignatureKey`, `AAuth.HttpSig.SignatureKeyParser`, `AAuth.HttpSig`. + +### src/AAuth/HttpSig/StructuredFieldType.cs + +Concept/decision: [signatures](#signatures). Source: [StructuredFieldType.cs](../../../src/AAuth/HttpSig/StructuredFieldType.cs). + +```diff ++ AAuth.HttpSig.StructuredFieldType: Dictionary ++ AAuth.HttpSig.StructuredFieldType: Item ++ AAuth.HttpSig.StructuredFieldType: List ++ AAuth.HttpSig: public enum StructuredFieldType +``` + +Public owners: `AAuth.HttpSig.StructuredFieldType`, `AAuth.HttpSig`. + +### src/AAuth/Identifiers/AgentId.cs + +Concept/decision: [discovery](#discovery). Source: [AgentId.cs](../../../src/AAuth/Identifiers/AgentId.cs). + +```diff +- AAuth.Identifiers.AgentId: public static AgentId Parse ( string input ) +- AAuth.Identifiers.AgentId: public static bool TryParse ( string ? input , out AgentId result , out string ? error ) ++ AAuth.Identifiers.AgentId: public static AgentId Parse ( string input , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Identifiers.AgentId: public static bool TryParse ( string ? input , out AgentId result , out string ? error , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Identifiers.AgentId`, `AAuth.Identifiers`. + +### src/AAuth/Identifiers/ServerId.cs + +Concept/decision: [discovery](#discovery). Source: [ServerId.cs](../../../src/AAuth/Identifiers/ServerId.cs). + +```diff +- AAuth.Identifiers.ServerId: public static ServerId Parse ( string input ) +- AAuth.Identifiers.ServerId: public static bool TryParse ( string ? input , out ServerId result , out string ? error ) ++ AAuth.Identifiers.ServerId: public static ServerId Parse ( string input , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Identifiers.ServerId: public static bool TryParse ( string ? input , out ServerId result , out string ? error , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Identifiers.ServerId`, `AAuth.Identifiers`. + +### src/AAuth/Person/AAuthPersonServerEndpoints.cs + +Concept/decision: [consent](#consent). Source: [AAuthPersonServerEndpoints.cs](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs). + +```diff +- AAuth.Person.AAuthPersonServerOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuthEgressPolicy . Production ++ AAuth.Person.AAuthPersonServerOptions: public Action < AAuthRevocationOptions > ? ConfigureRevocation { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public BrowserConsentSessions ? ResourceInteractionSessions { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public Func < PersonPendingEntry , ClarificationRequirement , System . Threading . CancellationToken , Task < ClarificationResponse ? > > ? TriageClarificationAsync { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public IReadOnlyList < string > ? ScopesSupported { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public TimeProvider TimeProvider { get ; init ; } = TimeProvider . System ++ AAuth.Person.AAuthPersonServerOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } ++ AAuth.Person.AAuthPersonServerOptions: public string RevocationPath { get ; init ; } = "/revoke" +``` + +Public owners: `AAuth.Person.AAuthPersonServerEndpoints`, `AAuth.Person.AAuthPersonServerOptions`, `AAuth.Person`. + +### src/AAuth/Person/IIdentityClaimsAsserter.cs + +Concept/decision: [consent](#consent). Source: [IIdentityClaimsAsserter.cs](../../../src/AAuth/Person/IIdentityClaimsAsserter.cs). + +```diff ++ AAuth.Person.IdentityAssertionRequest: public JsonObject ? ResourceContext { get ; init ; } ++ AAuth.Person.IdentityAssertionRequest: public UpstreamTokenValidationResult ? UpstreamAuthorization { get ; init ; } ++ AAuth.Person.IdentityAssertionRequest: public string ? Account { get ; init ; } ++ AAuth.Person.IdentityAssertionRequest: public string ? AgentKeyThumbprint { get ; init ; } +``` + +Public owners: `AAuth.Person.DefaultIdentityClaimsAsserter`, `AAuth.Person.IIdentityClaimsAsserter`, `AAuth.Person.IdentityAssertionKind`, `AAuth.Person.IdentityAssertionRequest`, `AAuth.Person.IdentityAssertion`, `AAuth.Person`. + +### src/AAuth/Person/IPersonPendingStore.cs + +Concept/decision: [consent](#consent). Source: [IPersonPendingStore.cs](../../../src/AAuth/Person/IPersonPendingStore.cs). + +```diff +- AAuth.Person.IPersonPendingStore: PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , JsonObject ? upstreamAct = null , MissionClaim ? mission = null ) +- AAuth.Person.InMemoryPersonPendingStore: public PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , JsonObject ? upstreamAct = null , MissionClaim ? mission = null ) +- AAuth.Person.PersonPendingEntry: public MissionClaim ? Mission { get ; init ; } +- AAuth.Person.PersonPendingEntry: public required string Scope { get ; init ; } ++ AAuth.Person.IPersonPendingStore: PersonPendingEntry ? GetByCode ( string code ) ++ AAuth.Person.IPersonPendingStore: PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , DateTimeOffset agentTokenExpiresAt , JsonObject ? upstreamAct = null , MissionClaim ? mission = null , DateTimeOffset ? authorizationExpiresAt = null ) ++ AAuth.Person.InMemoryPersonPendingStore: public PersonPendingEntry ? GetByCode ( string code ) ++ AAuth.Person.InMemoryPersonPendingStore: public PersonPendingEntry Add ( string resourceUrl , string scope , string agentId , IAAuthKey ? agentConfirmationKey , DateTimeOffset agentTokenExpiresAt , JsonObject ? upstreamAct = null , MissionClaim ? mission = null , DateTimeOffset ? authorizationExpiresAt = null ) ++ AAuth.Person.PersonPendingEntry: public AAuth . Server . BrowserInteraction Browser { get ; } = new ( ) ++ AAuth.Person.PersonPendingEntry: public AAuth . Server . DeferredState Lifecycle { get ; } = new ( ) ++ AAuth.Person.PersonPendingEntry: public DateTimeOffset ? AuthorizationExpiresAt { get ; init ; } ++ AAuth.Person.PersonPendingEntry: public DateTimeOffset ? ClarificationDeadline { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public DateTimeOffset ExpiresAt ++ AAuth.Person.PersonPendingEntry: public DateTimeOffset PendingExpiresAt ++ AAuth.Person.PersonPendingEntry: public IReadOnlyList < AAuth . Server . TokenKey > SourceTokens { get ; set ; } = [ ] ++ AAuth.Person.PersonPendingEntry: public IReadOnlyList < string > ? RequiredIdentityClaims { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public JsonObject ? ResourceContext { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public MissionClaim ? Mission { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public System . Threading . CancellationTokenSource FederationCancellation { get ; } = new ( ) ++ AAuth.Person.PersonPendingEntry: public TaskCompletionSource < AAuth . Agent . ClarificationResponse > ? FederationAnswer { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public TaskCompletionSource < IdentityAssertion > ? FederationConsent { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public UpstreamTokenValidationResult ? UpstreamAuthorization { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public bool AwaitingFederationConsent ++ AAuth.Person.PersonPendingEntry: public bool AwaitingResourceInteraction ++ AAuth.Person.PersonPendingEntry: public int ClarificationRounds { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public required DateTimeOffset AgentTokenExpiresAt { get ; init ; } ++ AAuth.Person.PersonPendingEntry: public required string Scope { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? Account ++ AAuth.Person.PersonPendingEntry: public string ? OwnerIssuer { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? OwnerKeyThumbprint { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? OwnerSubject { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? ResourceAudience { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? ResourceKeyThumbprint { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ? ResourceToken { get ; set ; } ++ AAuth.Person.PersonPendingEntry: public string ConsentAgentId +``` + +Public owners: `AAuth.Person.IPersonPendingStore`, `AAuth.Person.InMemoryPersonPendingStore`, `AAuth.Person.PersonPendingEntry`, `AAuth.Person.PersonPendingStatus`, `AAuth.Person`. + +### src/AAuth/SelfIssuingBuilder.cs + +Concept/decision: [agent-clients](#agent-clients). Source: [SelfIssuingBuilder.cs](../../../src/AAuth/SelfIssuingBuilder.cs). + +```diff +- AAuth.SelfIssuingBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler ) ++ AAuth.SelfIssuingBuilder: public AAuthClientBuilder ToBuilder ( ) ++ AAuth.SelfIssuingBuilder: public AAuthClientBuilder WithInnerHandler ( HttpMessageHandler handler , AAuth . Discovery . AAuthTransportContract ? transportContract = null ) ++ AAuth.SelfIssuingBuilder: public AAuthClientBuilder WithInteractionHandling ( ) ++ AAuth.SelfIssuingBuilder: public AAuthClientBuilder WithInteractionHandling ( Action < InteractionHandlingOptions > configure ) ++ AAuth.SelfIssuingBuilder: public AAuthClientBuilder WithResourceManagedAccess ( Agent . IAAuthAccessStore ? store = null ) ++ AAuth.SelfIssuingBuilder: public SelfIssuingBuilder WithDevelopmentLoopback ( params string [ ] origins ) ++ AAuth.SelfIssuingBuilder: public SelfIssuingBuilder WithEgressPolicy ( AAuth . Discovery . AAuthEgressPolicy policy ) +``` + +Public owners: `AAuth.SelfIssuingBuilder`, `AAuth`. + +### src/AAuth/Server/AAuthAuthorizationRequest.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthAuthorizationRequest.cs](../../../src/AAuth/Server/AAuthAuthorizationRequest.cs). + +```diff ++ AAuth.Server.AAuthAuthorizationRequest: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Server.AAuthAuthorizationRequest`, `AAuth.Server`. + +### src/AAuth/Server/AAuthProblemDetails.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthProblemDetails.cs](../../../src/AAuth/Server/AAuthProblemDetails.cs). + +```diff ++ AAuth.Server.AAuthProblemDetails: public const string ContentType = "application/problem+json" ; ++ AAuth.Server.AAuthProblemDetails: public static IResult Create ( string error , string ? detail = null , int statusCode = StatusCodes . Status400BadRequest , IDictionary < string , object ? > ? extensions = null ) ++ AAuth.Server.AAuthProblemDetails: public static IResult TokenFailure ( Tokens . TokenVerificationException exception , Tokens . TokenCredential credential = Tokens . TokenCredential . Agent ) ++ AAuth.Server.AAuthProblemDetails: public static Task WriteAsync ( HttpContext context , string error , string ? detail = null , int statusCode = StatusCodes . Status400BadRequest , IDictionary < string , object ? > ? extensions = null ) ++ AAuth.Server: public static class AAuthProblemDetails +``` + +Public owners: `AAuth.Server.AAuthProblemDetails`, `AAuth.Server`. + +### src/AAuth/Server/AAuthRevocationOptions.cs + +Concept/decision: [revocation](#revocation). Source: [AAuthRevocationOptions.cs](../../../src/AAuth/Server/AAuthRevocationOptions.cs). + +```diff +- AAuth.Server.AAuthRevocationOptions: public Func < string , bool > ? IsTrustedRevoker { get ; set ; } +- AAuth.Server.AAuthRevocationOptions: public IReadOnlyCollection < string > ? TrustedRevokers { get ; set ; } ++ AAuth.Server.AAuthRevocationOptions: public Func < TokenGrant , CancellationToken , Task < bool > > ? RevokeGrantAsync { get ; set ; } ++ AAuth.Server.AAuthRevocationOptions: public Func < string , TokenKey , bool > ? IsTrustedPersonServer { get ; set ; } ++ AAuth.Server.AAuthRevocationOptions: public IReadOnlyCollection < string > ? TrustedPersonServers { get ; set ; } ++ AAuth.Server.AAuthRevocationOptions: public bool AllowTokenIssuer { get ; set ; } +``` + +Public owners: `AAuth.Server.AAuthRevocationOptions`, `AAuth.Server`. + +### src/AAuth/Server/AuthTokenResponse.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AuthTokenResponse.cs](../../../src/AAuth/Server/AuthTokenResponse.cs). + +```diff ++ AAuth.Server.AuthTokenResponse: public static IResult Create ( Func < string > mint , DateTimeOffset ceiling , TimeProvider ? timeProvider = null ) ++ AAuth.Server.AuthTokenResponse: public static IResult Create ( string token , DateTimeOffset ceiling , TimeProvider ? timeProvider = null ) ++ AAuth.Server.AuthTokenResponse: public static IResult Expired ( ) ++ AAuth.Server.AuthTokenResponse: public static async Task < IResult > CreateTrackedAsync ( Func < string > mint , DateTimeOffset ceiling , IJtiStore inventory , IReadOnlyCollection < TokenKey > sources , TimeProvider ? timeProvider = null , CancellationToken cancellationToken = default ) ++ AAuth.Server: public static class AuthTokenResponse +``` + +Public owners: `AAuth.Server.AuthTokenResponse`, `AAuth.Server`. + +### src/AAuth/Server/BrowserConsentSessions.cs + +Concept/decision: [consent](#consent). Source: [BrowserConsentSessions.cs](../../../src/AAuth/Server/BrowserConsentSessions.cs). + +```diff ++ AAuth.Server.BrowserConsentDecision: public Task < IResult > ApplyAsync ( HttpContext context , Func < IResult > mutation ) ++ AAuth.Server.BrowserConsentDecision: public async Task < IResult > ApplyAsync ( HttpContext context , Func < Task < IResult > > mutation ) ++ AAuth.Server.BrowserConsentDecision: public string Id ++ AAuth.Server.BrowserConsentSessions: public BrowserConsentSessions ( string cookieName , string ? isolatedDemoIdentity = null , Func < HttpContext , BrowserPendingRequest , BrowserConsentIdentity , bool > ? authorizePerson = null , Func < HttpContext , bool > ? isolatedDemoAccess = null ) ++ AAuth.Server.BrowserConsentSessions: public async Task < ( BrowserConsentDecision ? Decision , IResult ? Error ) > DecideAsync ( HttpContext context , bool externalLogin = false , string ? externalState = null ) ++ AAuth.Server.BrowserConsentSessions: public async Task < ( string ? Id , string ? Decision , IResult ? Error ) > EnterAsync ( HttpContext context , Func < string , BrowserPendingRequest ? > lookup , bool externalLogin = false ) ++ AAuth.Server.BrowserConsentSessions: public string ? DemoIdentity { get ; } ++ AAuth.Server.BrowserConsentSessions: public string Fields ( HttpContext context , string decision ) ++ AAuth.Server.BrowserInteraction: public string Code { get ; private set ; } = InteractionCode . Generate ( 26 ) ++ AAuth.Server.BrowserInteraction: public void Renew ( ) ++ AAuth.Server: public sealed class BrowserConsentDecision ++ AAuth.Server: public sealed class BrowserConsentSessions ++ AAuth.Server: public sealed class BrowserInteraction ++ AAuth.Server: public sealed record BrowserConsentIdentity ( string AuthenticationType , string Issuer , string Subject ) ++ AAuth.Server: public sealed record BrowserPendingRequest ( string Id , DateTimeOffset ExpiresAt , BrowserInteraction Browser , DeferredState Lifecycle ) +``` + +Public owners: `AAuth.Server.BrowserConsentDecision`, `AAuth.Server.BrowserConsentSessions`, `AAuth.Server.BrowserInteraction`, `AAuth.Server`. + +### src/AAuth/Server/CallChaining/CallChainingHandler.cs + +Concept/decision: [governance](#governance). Source: [CallChainingHandler.cs](../../../src/AAuth/Server/CallChaining/CallChainingHandler.cs). + +```diff +- AAuth.Server.CallChaining.CallChainingHandler: public async Task < string > ExchangeForDownstreamAsync ( string upstreamAuthToken , string resourceToken , Func < Interaction , CancellationToken , Task > ? onInteractionRequired = null , DeferredPollerOptions ? pollerOptions = null , CancellationToken cancellationToken = default ) ++ AAuth.Server.CallChaining.CallChainingHandler: public async Task < string > ExchangeForDownstreamAsync ( string upstreamAuthToken , string resourceToken , Func < Interaction , CancellationToken , Task > ? onInteractionRequired = null , DeferredPollerOptions ? pollerOptions = null , CancellationToken cancellationToken = default , string ? account = null ) +``` + +Public owners: `AAuth.Server.CallChaining.CallChainingHandler`, `AAuth.Server.CallChaining`. + +### src/AAuth/Server/CallChaining/CallChainingRouter.cs + +Concept/decision: [governance](#governance). Source: [CallChainingRouter.cs](../../../src/AAuth/Server/CallChaining/CallChainingRouter.cs). + +```diff +- AAuth.Server.CallChaining.CallChainingRouter: public static string ResolveDownstreamServer ( string upstreamAuthToken ) ++ AAuth.Server.CallChaining.CallChainingRouter: public static string ResolveDownstreamServer ( string upstreamAuthToken , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Server.CallChaining.CallChainingRouter`, `AAuth.Server.CallChaining`. + +### src/AAuth/Server/Challenge/AAuthChallengeMiddleware.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthChallengeMiddleware.cs](../../../src/AAuth/Server/Challenge/AAuthChallengeMiddleware.cs). + +Public signatures unchanged (3); behavior reviewed under server-contracts. + +Public owners: `AAuth.Server.Challenge.AAuthChallengeMiddleware`, `AAuth.Server.Challenge`. + +### src/AAuth/Server/Challenge/ChallengeOptions.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [ChallengeOptions.cs](../../../src/AAuth/Server/Challenge/ChallengeOptions.cs). + +```diff +- AAuth.Server.Challenge.ChallengeOptions: public AAuthKey ? ResourceSigningKey { get ; init ; } ++ AAuth.Server.Challenge.ChallengeOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Challenge.ChallengeOptions: public IAAuthKey ? ResourceSigningKey { get ; init ; } ++ AAuth.Server.Challenge.ChallengeOptions: public IReadOnlyDictionary < string , string > ? ScopeDescriptions { get ; init ; } ++ AAuth.Server.Challenge.ChallengeOptions: public System . Func < Microsoft . AspNetCore . Http . HttpContext , string ? > ? RequestedAccount { get ; init ; } +``` + +Public owners: `AAuth.Server.Challenge.ChallengeOptions`, `AAuth.Server.Challenge`. + +### src/AAuth/Server/DeferredState.cs + +Concept/decision: [consent](#consent). Source: [DeferredState.cs](../../../src/AAuth/Server/DeferredState.cs). + +```diff ++ AAuth.Server.DeferredState: public SemaphoreSlim Gate { get ; } = new ( 1 , 1 ) ++ AAuth.Server.DeferredState: public async Task < IResult > ExecuteAsync ( HttpContext context , DateTimeOffset expiry , TimeProvider timeProvider , Func < Task < IResult > > operation ) ++ AAuth.Server.DeferredState: public bool Cancelled { get ; private set ; } ++ AAuth.Server.DeferredState: public bool Delivered { get ; private set ; } ++ AAuth.Server.DeferredState: public bool InvalidCode { get ; set ; } ++ AAuth.Server.DeferredState: public static IResult Missing ( string id ) ++ AAuth.Server.DeferredState: public void Cancel ( ) ++ AAuth.Server: public sealed class DeferredState +``` + +Public owners: `AAuth.Server.DeferredState`, `AAuth.Server`. + +### src/AAuth/Server/Endpoints/AAuthEndpointExtensions.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthEndpointExtensions.cs](../../../src/AAuth/Server/Endpoints/AAuthEndpointExtensions.cs). + +```diff ++ Microsoft.AspNetCore.Builder.AAuthEndpointExtensions: public static RouteHandlerBuilder RequireGenericSignature ( this RouteHandlerBuilder builder , bool identified = false ) +``` + +Public owners: `Microsoft.AspNetCore.Builder.AAuthEndpointExtensions`, `Microsoft.AspNetCore.Builder`. + +### src/AAuth/Server/Endpoints/AAuthEndpointRequirement.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthEndpointRequirement.cs](../../../src/AAuth/Server/Endpoints/AAuthEndpointRequirement.cs). + +```diff +- AAuth.Server.Endpoints.AAuthServerOptions: public AAuthKey ? ResourceSigningKey { get ; set ; } +- AAuth.Server.Endpoints.AAuthServerOptions: public bool RequireIssuerVerification { get ; set ; } = true ++ AAuth.Server.Endpoints.AAuthEndpointRequirement: public IReadOnlyList < string > AcceptedSchemes { get ; init ; } = [ "jwt" ] ++ AAuth.Server.Endpoints.AAuthServerOptions: public IAAuthKey ? ResourceSigningKey { get ; set ; } +``` + +Public owners: `AAuth.Server.Endpoints.AAuthEndpointRequirement`, `AAuth.Server.Endpoints.AAuthServerOptions`, `AAuth.Server.Endpoints`. + +### src/AAuth/Server/Governance/AAuthGovernancePipelineOptions.cs + +Concept/decision: [governance](#governance). Source: [AAuthGovernancePipelineOptions.cs](../../../src/AAuth/Server/Governance/AAuthGovernancePipelineOptions.cs). + +```diff ++ AAuth.Server.Governance.AAuthGovernancePipelineOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production +``` + +Public owners: `AAuth.Server.Governance.AAuthGovernancePipelineOptions`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/GovernanceEndpoints.cs + +Concept/decision: [governance](#governance). Source: [GovernanceEndpoints.cs](../../../src/AAuth/Server/Governance/GovernanceEndpoints.cs). + +```diff +- AAuth.Server.Governance.GovernanceEndpoints: public static AuditRecord ParseAudit ( JsonObject body ) +- AAuth.Server.Governance.GovernanceEndpoints: public static InteractionRequest ParseInteraction ( JsonObject body ) +- AAuth.Server.Governance.GovernanceEndpoints: public static PermissionRequest ParsePermission ( JsonObject body ) ++ AAuth.Server.Governance.GovernanceEndpoints: public static AuditRecord ParseAudit ( JsonObject body , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Server.Governance.GovernanceEndpoints: public static IResult ? Authorize ( HttpContext context , MissionClaim ? reference , StoredMission ? mission ) ++ AAuth.Server.Governance.GovernanceEndpoints: public static InteractionRequest ParseInteraction ( JsonObject body , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Server.Governance.GovernanceEndpoints: public static PermissionRequest ParsePermission ( JsonObject body , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Server.Governance.GovernanceEndpoints`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/IDeferredConsentStore.cs + +Concept/decision: [consent](#consent). Source: [IDeferredConsentStore.cs](../../../src/AAuth/Server/Governance/IDeferredConsentStore.cs). + +```diff ++ AAuth.Server.Governance.DeferredConsent: public DateTimeOffset ExpiresAt { get ; init ; } = DateTimeOffset . UtcNow . AddMinutes ( 10 ) ++ AAuth.Server.Governance.DeferredConsent: public DeferredState Lifecycle { get ; } = new ( ) ++ AAuth.Server.Governance.DeferredConsent: public string ? OwnerIssuer { get ; init ; } ++ AAuth.Server.Governance.DeferredConsent: public string ? OwnerKeyThumbprint { get ; init ; } ++ AAuth.Server.Governance.DeferredConsent: public string Code { get ; } = AAuth . Headers . InteractionCode . Generate ( 26 ) ++ AAuth.Server.Governance.IDeferredConsentStore: Task < DeferredConsent ? > GetByCodeAsync ( string code , CancellationToken ct = default ) +``` + +Public owners: `AAuth.Server.Governance.DeferredConsentKind`, `AAuth.Server.Governance.DeferredConsent`, `AAuth.Server.Governance.IDeferredConsentStore`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/IMissionLog.cs + +Concept/decision: [governance](#governance). Source: [IMissionLog.cs](../../../src/AAuth/Server/Governance/IMissionLog.cs). + +```diff +- AAuth.Server.Governance.IMissionLog: Task < bool > HasPriorConsentAsync ( string s256 , string resource , string scope , CancellationToken ct = default ) ++ AAuth.Server.Governance.IMissionLog: Task < bool > HasPriorConsentAsync ( string s256 , string resource , string scope , CancellationToken ct = default , string ? account = null , string ? agentId = null , string ? agentKeyThumbprint = null ) ++ AAuth.Server.Governance.MissionLogEntry: public string ? Account { get ; init ; } ++ AAuth.Server.Governance.MissionLogEntry: public string ? AgentId { get ; init ; } ++ AAuth.Server.Governance.MissionLogEntry: public string ? AgentKeyThumbprint { get ; init ; } +``` + +Public owners: `AAuth.Server.Governance.IMissionLog`, `AAuth.Server.Governance.MissionLogEntryKind`, `AAuth.Server.Governance.MissionLogEntry`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/IMissionTokenConsent.cs + +Concept/decision: [consent](#consent). Source: [IMissionTokenConsent.cs](../../../src/AAuth/Server/Governance/IMissionTokenConsent.cs). + +```diff ++ AAuth.Server.Governance.MissionTokenConsentContext: public StoredMission ? ValidatedApproval { get ; internal init ; } ++ AAuth.Server.Governance.MissionTokenConsentContext: public System . Text . Json . Nodes . JsonObject ? ResourceContext { get ; init ; } ++ AAuth.Server.Governance.MissionTokenConsentContext: public UpstreamTokenValidationResult ? UpstreamAuthorization { get ; init ; } ++ AAuth.Server.Governance.MissionTokenConsentContext: public string ? Account { get ; init ; } ++ AAuth.Server.Governance.MissionTokenConsentContext: public string ? AgentKeyThumbprint { get ; init ; } ++ AAuth.Server.Governance.MissionTokenConsentContext: public string ? ConsentAgentId { get ; init ; } +``` + +Public owners: `AAuth.Server.Governance.IMissionTokenConsent`, `AAuth.Server.Governance.MissionTokenConsentContext`, `AAuth.Server.Governance.MissionTokenConsentDecision`, `AAuth.Server.Governance.MissionTokenConsentKind`, `AAuth.Server.Governance.MissionTokenConsentStage`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/InMemoryDeferredConsentStore.cs + +Concept/decision: [consent](#consent). Source: [InMemoryDeferredConsentStore.cs](../../../src/AAuth/Server/Governance/InMemoryDeferredConsentStore.cs). + +```diff +- AAuth.Server.Governance.InMemoryDeferredConsentStore: public Task ResolveAsync ( string id , bool approved , CancellationToken ct = default ) ++ AAuth.Server.Governance.InMemoryDeferredConsentStore: public Task < DeferredConsent ? > GetByCodeAsync ( string code , CancellationToken ct = default ) ++ AAuth.Server.Governance.InMemoryDeferredConsentStore: public async Task ResolveAsync ( string id , bool approved , CancellationToken ct = default ) +``` + +Public owners: `AAuth.Server.Governance.InMemoryDeferredConsentStore`, `AAuth.Server.Governance`. + +### src/AAuth/Server/Governance/InMemoryMissionLog.cs + +Concept/decision: [governance](#governance). Source: [InMemoryMissionLog.cs](../../../src/AAuth/Server/Governance/InMemoryMissionLog.cs). + +```diff +- AAuth.Server.Governance.InMemoryMissionLog: public Task < bool > HasPriorConsentAsync ( string s256 , string resource , string scope , CancellationToken ct = default ) ++ AAuth.Server.Governance.InMemoryMissionLog: public Task < bool > HasPriorConsentAsync ( string s256 , string resource , string scope , CancellationToken ct = default , string ? account = null , string ? agentId = null , string ? agentKeyThumbprint = null ) +``` + +Public owners: `AAuth.Server.Governance.InMemoryMissionLog`, `AAuth.Server.Governance`. + +### src/AAuth/Server/IJtiStore.cs + +Concept/decision: [revocation](#revocation). Source: [IJtiStore.cs](../../../src/AAuth/Server/IJtiStore.cs). + +```diff +- AAuth.Server.IJtiStore: Task < bool > IsRevokedAsync ( string jti , CancellationToken ct = default ) +- AAuth.Server.IJtiStore: Task < bool > TryRecordAsync ( string jti , DateTimeOffset expiration , CancellationToken ct = default ) +- AAuth.Server.IJtiStore: Task RevokeAsync ( string jti , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < IReadOnlyList < TokenGrant > > GetGrantsAsync ( TokenKey source , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < bool > IsRevokedAsync ( TokenKey token , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < bool > RegisterAsync ( TokenKey token , DateTimeOffset expiration , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < bool > RegisterGrantAsync ( IReadOnlyCollection < TokenKey > sources , TokenGrant grant , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < bool > RevokeAsync ( TokenKey token , CancellationToken ct = default ) ++ AAuth.Server.IJtiStore: Task < bool > TryRecordRequestAsync ( string requestKey , DateTimeOffset expiration , CancellationToken ct = default ) +``` + +Public owners: `AAuth.Server.IJtiStore`, `AAuth.Server`. + +### src/AAuth/Server/IOpaqueTokenStore.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [IOpaqueTokenStore.cs](../../../src/AAuth/Server/IOpaqueTokenStore.cs). + +```diff ++ AAuth.Server.OpaqueTokenInfo: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Server.IOpaqueTokenStore`, `AAuth.Server.InMemoryOpaqueTokenStore`, `AAuth.Server.OpaqueTokenInfo`, `AAuth.Server`. + +### src/AAuth/Server/InMemoryJtiStore.cs + +Concept/decision: [revocation](#revocation). Source: [InMemoryJtiStore.cs](../../../src/AAuth/Server/InMemoryJtiStore.cs). + +```diff +- AAuth.Server.InMemoryJtiStore: public Task < bool > IsRevokedAsync ( string jti , CancellationToken ct = default ) +- AAuth.Server.InMemoryJtiStore: public Task < bool > TryRecordAsync ( string jti , DateTimeOffset expiration , CancellationToken ct = default ) +- AAuth.Server.InMemoryJtiStore: public Task RevokeAsync ( string jti , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public InMemoryJtiStore ( TimeProvider ? timeProvider = null , int capacity = 100_000 , TimeSpan ? retention = null ) ++ AAuth.Server.InMemoryJtiStore: public Task < IReadOnlyList < TokenGrant > > GetGrantsAsync ( TokenKey source , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public Task < bool > IsRevokedAsync ( TokenKey token , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public Task < bool > RegisterAsync ( TokenKey token , DateTimeOffset expiration , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public Task < bool > RegisterGrantAsync ( IReadOnlyCollection < TokenKey > sources , TokenGrant grant , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public Task < bool > RevokeAsync ( TokenKey token , CancellationToken ct = default ) ++ AAuth.Server.InMemoryJtiStore: public Task < bool > TryRecordRequestAsync ( string requestKey , DateTimeOffset expiration , CancellationToken ct = default ) +``` + +Public owners: `AAuth.Server.InMemoryJtiStore`, `AAuth.Server`. + +### src/AAuth/Server/Metadata/AAuthAccessServerMetadataOptions.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [AAuthAccessServerMetadataOptions.cs](../../../src/AAuth/Server/Metadata/AAuthAccessServerMetadataOptions.cs). + +```diff +- AAuth.Server.Metadata.AAuthAccessServerMetadataOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } ++ AAuth.Server.Metadata.AAuthAccessServerMetadataOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Metadata.AAuthAccessServerMetadataOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } +``` + +Public owners: `AAuth.Server.Metadata.AAuthAccessServerMetadataOptions`, `AAuth.Server.Metadata`. + +### src/AAuth/Server/Metadata/AAuthAgentMetadataOptions.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthAgentMetadataOptions.cs](../../../src/AAuth/Server/Metadata/AAuthAgentMetadataOptions.cs). + +```diff +- AAuth.Server.Metadata.AAuthAgentMetadataOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } ++ AAuth.Server.Metadata.AAuthAgentMetadataOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Metadata.AAuthAgentMetadataOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } +``` + +Public owners: `AAuth.Server.Metadata.AAuthAgentMetadataOptions`, `AAuth.Server.Metadata`. + +### src/AAuth/Server/Metadata/AAuthPersonServerMetadataOptions.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [AAuthPersonServerMetadataOptions.cs](../../../src/AAuth/Server/Metadata/AAuthPersonServerMetadataOptions.cs). + +```diff +- AAuth.Server.Metadata.AAuthPersonServerMetadataOptions: public required IReadOnlyDictionary < string , AAuthKey > SigningKeys { get ; init ; } ++ AAuth.Server.Metadata.AAuthPersonServerMetadataOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Metadata.AAuthPersonServerMetadataOptions: public required IReadOnlyDictionary < string , IAAuthKey > SigningKeys { get ; init ; } +``` + +Public owners: `AAuth.Server.Metadata.AAuthPersonServerMetadataOptions`, `AAuth.Server.Metadata`. + +### src/AAuth/Server/Metadata/WellKnownEndpoints.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [WellKnownEndpoints.cs](../../../src/AAuth/Server/Metadata/WellKnownEndpoints.cs). + +```diff +- AAuth.Server.Metadata.AAuthResourceMetadataOptions: public IReadOnlyDictionary < string , AAuthKey > ? SigningKeys { get ; init ; } ++ AAuth.Server.Metadata.AAuthResourceMetadataOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Metadata.AAuthResourceMetadataOptions: public IReadOnlyDictionary < string , IAAuthKey > ? SigningKeys { get ; init ; } +``` + +Public owners: `AAuth.Server.Metadata.AAuthResourceMetadataOptions`, `AAuth.Server.Metadata.WellKnownEndpoints`, `AAuth.Server.Metadata`. + +### src/AAuth/Server/ResourceManaged/AAuthInteractionEndpointExtensions.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [AAuthInteractionEndpointExtensions.cs](../../../src/AAuth/Server/ResourceManaged/AAuthInteractionEndpointExtensions.cs). + +Public signatures unchanged (2); behavior reviewed under resource-managed. + +Public owners: `Microsoft.AspNetCore.Builder.AAuthInteractionEndpointExtensions`, `Microsoft.AspNetCore.Builder`. + +### src/AAuth/Server/ResourceManaged/AAuthResourceManagedHttpContextExtensions.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [AAuthResourceManagedHttpContextExtensions.cs](../../../src/AAuth/Server/ResourceManaged/AAuthResourceManagedHttpContextExtensions.cs). + +```diff +- AAuth.Server.AAuthResourceManagedHttpContextExtensions: public static IResult RequireAAuthInteraction ( this HttpContext context , string scope ) ++ AAuth.Server.AAuthResourceManagedHttpContextExtensions: public static IResult RequireAAuthInteraction ( this HttpContext context , string scope , string ? account = null ) +``` + +Public owners: `AAuth.Server.AAuthResourceManagedHttpContextExtensions`, `AAuth.Server`. + +### src/AAuth/Server/ResourceManaged/IInteractionPendingStore.cs + +Concept/decision: [resource-managed](#resource-managed). Source: [IInteractionPendingStore.cs](../../../src/AAuth/Server/ResourceManaged/IInteractionPendingStore.cs). + +```diff +- AAuth.Server.IInteractionPendingStore: InteractionPendingEntry Park ( string scope , string agentJkt , TimeSpan ttl ) +- AAuth.Server.InMemoryInteractionPendingStore: public InteractionPendingEntry Park ( string scope , string agentJkt , TimeSpan ttl ) ++ AAuth.Server.IInteractionPendingStore: InteractionPendingEntry Park ( string scope , string agentJkt , TimeSpan ttl , string ? account = null ) ++ AAuth.Server.InMemoryInteractionPendingStore: public InteractionPendingEntry Park ( string scope , string agentJkt , TimeSpan ttl , string ? account = null ) ++ AAuth.Server.InteractionPendingEntry: public BrowserInteraction Browser { get ; init ; } = new ( ) ++ AAuth.Server.InteractionPendingEntry: public DeferredState Lifecycle { get ; } = new ( ) ++ AAuth.Server.InteractionPendingEntry: public bool Denied { get ; set ; } ++ AAuth.Server.InteractionPendingEntry: public string ? Account { get ; init ; } ++ AAuth.Server.InteractionPendingEntry: public string ? OwnerAgent { get ; set ; } ++ AAuth.Server.InteractionPendingEntry: public string ? OwnerIssuer { get ; set ; } +``` + +Public owners: `AAuth.Server.IInteractionPendingStore`, `AAuth.Server.InMemoryInteractionPendingStore`, `AAuth.Server.InteractionPendingEntry`, `AAuth.Server`. + +### src/AAuth/Server/RevocationClient.cs + +Concept/decision: [revocation](#revocation). Source: [RevocationClient.cs](../../../src/AAuth/Server/RevocationClient.cs). + +```diff ++ AAuth.Server.RevocationClient: public RevocationClient ( HttpClient signedHttp ) ++ AAuth.Server.RevocationClient: public async Task < HttpStatusCode > RevokeAsync ( Uri endpoint , TokenKey token , CancellationToken cancellationToken = default ) ++ AAuth.Server: public sealed class RevocationClient +``` + +Public owners: `AAuth.Server.RevocationClient`, `AAuth.Server`. + +### src/AAuth/Server/RevocationEndpoint.cs + +Concept/decision: [revocation](#revocation). Source: [RevocationEndpoint.cs](../../../src/AAuth/Server/RevocationEndpoint.cs). + +```diff ++ AAuth.Server.RevocationEndpoint: public static IJtiStore MapAAuthIssuerRevocation ( this WebApplication app , string issuer , string dwk , AAuth . Crypto . IAAuthKey signingKey , string signingKid , string path , AAuth . Discovery . AAuthEgressPolicy egressPolicy , TimeProvider clock , Action < AAuthRevocationOptions > ? configure ) +``` + +Public owners: `AAuth.Server.RevocationEndpoint`, `AAuth.Server`. + +### src/AAuth/Server/TokenGrant.cs + +Concept/decision: [revocation](#revocation). Source: [TokenGrant.cs](../../../src/AAuth/Server/TokenGrant.cs). + +```diff ++ AAuth.Server: public sealed record TokenGrant ( TokenKey Token , string Resource , DateTimeOffset ExpiresAt ) +``` + +Public owners: `AAuth.Server`. + +### src/AAuth/Server/TokenKey.cs + +Concept/decision: [revocation](#revocation). Source: [TokenKey.cs](../../../src/AAuth/Server/TokenKey.cs). + +```diff ++ AAuth.Server.TokenKey: public TokenKey ( string issuer , string tokenId ) ++ AAuth.Server.TokenKey: public string Issuer { get ; } ++ AAuth.Server.TokenKey: public string TokenId { get ; } ++ AAuth.Server: public sealed record TokenKey +``` + +Public owners: `AAuth.Server.TokenKey`, `AAuth.Server`. + +### src/AAuth/Server/TokenRegistration.cs + +Concept/decision: [revocation](#revocation). Source: [TokenRegistration.cs](../../../src/AAuth/Server/TokenRegistration.cs). + +```diff ++ AAuth.Server.TokenRegistration: public static TokenRegistration FromVerified ( TokenVerifier . VerifiedToken token ) ++ AAuth.Server.TokenRegistration: public static async Task < IReadOnlyList < TokenKey > > RegisterAsync ( IJtiStore inventory , IReadOnlyCollection < TokenRegistration > tokens , CancellationToken cancellationToken = default ) ++ AAuth.Server: public sealed record TokenRegistration ( TokenKey Token , DateTimeOffset ExpiresAt ) +``` + +Public owners: `AAuth.Server.TokenRegistration`, `AAuth.Server`. + +### src/AAuth/Server/TokenRequestBody.cs + +Concept/decision: [server-contracts](#server-contracts). Source: [TokenRequestBody.cs](../../../src/AAuth/Server/TokenRequestBody.cs). + +```diff ++ AAuth.Server.TokenRequestBody: public static async Task < JsonObject > ReadAsync ( HttpRequest request , TokenVerifier verifier ) ++ AAuth.Server: public static class TokenRequestBody +``` + +Public owners: `AAuth.Server.TokenRequestBody`, `AAuth.Server`. + +### src/AAuth/Server/Verification/AAuthAuthenticationHandler.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthAuthenticationHandler.cs](../../../src/AAuth/Server/Verification/AAuthAuthenticationHandler.cs). + +```diff ++ AAuth.Server.Verification.AAuthAuthenticationHandler: public const string AccountClaimType = "aauth:account" ; +``` + +Public owners: `AAuth.Server.Verification.AAuthAuthenticationHandler`, `AAuth.Server.Verification`. + +### src/AAuth/Server/Verification/AAuthHttpContextExtensions.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthHttpContextExtensions.cs](../../../src/AAuth/Server/Verification/AAuthHttpContextExtensions.cs). + +```diff +- AAuth.Server.Verification.AAuthHttpContextExtensions: public static IResult InteractionRequiredAAuth ( this HttpContext context , string interactionUrl , string code , string pendingLocation ) +- AAuth.Server.Verification.AAuthHttpContextExtensions: public static async Task < OpaqueTokenInfo ? > ResolveAAuthAccessAsync ( this HttpContext context , IOpaqueTokenStore store , CancellationToken cancellationToken = default ) ++ AAuth.Server.Verification.AAuthHttpContextExtensions: public static IResult InteractionRequiredAAuth ( this HttpContext context , string interactionUrl , string code , string pendingLocation , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Server.Verification.AAuthHttpContextExtensions: public static async Task < OpaqueTokenInfo ? > ResolveAAuthAccessAsync ( this HttpContext context , IOpaqueTokenStore store , CancellationToken cancellationToken = default , string ? expectedAccount = null ) +``` + +Public owners: `AAuth.Server.Verification.AAuthHttpContextExtensions`, `AAuth.Server.Verification`. + +### src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthVerificationMiddleware.cs](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs). + +```diff ++ AAuth.Server.Verification.AAuthVerificationMiddleware: public const string TokenStoreItemKey = "AAuth.TokenInventory" ; +``` + +Public owners: `AAuth.Server.Verification.AAuthVerificationMiddleware`, `AAuth.Server.Verification.VerificationResult`, `AAuth.Server.Verification`. + +### src/AAuth/Server/Verification/AAuthVerificationOptions.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthVerificationOptions.cs](../../../src/AAuth/Server/Verification/AAuthVerificationOptions.cs). + +```diff +- AAuth.Server.Verification.AAuthVerificationOptions: public bool RequireIssuerVerification { get ; init ; } = true +- AAuth.Server.Verification.AAuthVerificationOptions: public static AAuthVerificationOptions SignatureOnly ( Func < DateTimeOffset > ? clock = null ) ++ AAuth.Server.Verification.AAuthVerificationOptions: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; set ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Server.Verification.AAuthVerificationOptions: public Func < Microsoft . AspNetCore . Http . HttpContext , string ? > ? ExpectedAccount { get ; init ; } ++ AAuth.Server.Verification.AAuthVerificationOptions: public IReadOnlyCollection < string > RequiredComponents { get ; init ; } = [ ] ++ AAuth.Server.Verification.AAuthVerificationOptions: public IReadOnlyList < string > AcceptedSchemes { get ; init ; } = [ "jwt" ] ++ AAuth.Server.Verification.AAuthVerificationOptions: public bool GenericSignatureKeys { get ; init ; } ++ AAuth.Server.Verification.AAuthVerificationOptions: public static AAuthVerificationOptions Generic ( Func < DateTimeOffset > ? clock = null ) ++ AAuth.Server.Verification.AAuthVerificationOptions: public string SignatureLabel { get ; init ; } = "sig" +``` + +Public owners: `AAuth.Server.Verification.AAuthVerificationOptions`, `AAuth.Server.Verification`. + +### src/AAuth/Server/Verification/AAuthVerificationResult.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthVerificationResult.cs](../../../src/AAuth/Server/Verification/AAuthVerificationResult.cs). + +```diff ++ AAuth.Server.Verification.AAuthVerificationResult: public DateTimeOffset ? ReplayExpiresAt { get ; init ; } ++ AAuth.Server.Verification.AAuthVerificationResult: public bool AccountVerified { get ; init ; } ++ AAuth.Server.Verification.AAuthVerificationResult: public string ? Account { get ; init ; } ++ AAuth.Server.Verification.AAuthVerificationResult: public string ? ReplayIdentity { get ; init ; } +``` + +Public owners: `AAuth.Server.Verification.AAuthVerificationResult`, `AAuth.Server.Verification`. + +### src/AAuth/Server/Verification/AAuthVerifiedAssertion.cs + +Concept/decision: [signatures](#signatures). Source: [AAuthVerifiedAssertion.cs](../../../src/AAuth/Server/Verification/AAuthVerifiedAssertion.cs). + +```diff ++ AAuth.Server.Verification: public sealed record AAuthVerifiedAssertion ( string CompactToken , TokenVerifier . VerifiedToken Token , IAAuthKey HttpSigningKey ) +``` + +Public owners: `AAuth.Server.Verification`. + +### src/AAuth/Tokens/AccountBinding.cs + +Concept/decision: [tokens](#tokens). Source: [AccountBinding.cs](../../../src/AAuth/Tokens/AccountBinding.cs). + +```diff ++ AAuth.Tokens.AccountBinding: public static bool IsValid ( string ? account ) ++ AAuth.Tokens.AccountBinding: public static bool Matches ( string ? expected , string ? actual ) ++ AAuth.Tokens.AccountBinding: public static bool TryRead ( JsonObject payload , out string ? account ) ++ AAuth.Tokens.AccountBinding: public static string ? Read ( JsonObject ? payload ) ++ AAuth.Tokens.AccountBinding: public static void Validate ( string ? account ) ++ AAuth.Tokens.AccountExpectation: public AccountExpectation ( string ? account ) ++ AAuth.Tokens.AccountExpectation: public string ? Account { get ; } ++ AAuth.Tokens: public sealed record AccountExpectation ++ AAuth.Tokens: public static class AccountBinding +``` + +Public owners: `AAuth.Tokens.AccountBinding`, `AAuth.Tokens.AccountExpectation`, `AAuth.Tokens`. + +### src/AAuth/Tokens/ActChainBuilder.cs + +Concept/decision: [tokens](#tokens). Source: [ActChainBuilder.cs](../../../src/AAuth/Tokens/ActChainBuilder.cs). + +```diff +- AAuth.Tokens.ActChainBuilder: public static JsonObject BuildNestedAct ( string upstreamAgentId , JsonObject ? upstreamChain = null ) +- AAuth.Tokens.ActChainBuilder: public static bool ValidateChain ( JsonObject act , int maxDepth = 10 ) ++ AAuth.Tokens.ActChainBuilder: public static JsonObject BuildNestedAct ( string upstreamAgentId , JsonObject ? upstreamChain = null , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Tokens.ActChainBuilder: public static bool ValidateChain ( JsonObject act , int maxDepth = 10 , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Tokens.ActChainBuilder`, `AAuth.Tokens`. + +### src/AAuth/Tokens/ActChainReader.cs + +Concept/decision: [tokens](#tokens). Source: [ActChainReader.cs](../../../src/AAuth/Tokens/ActChainReader.cs). + +```diff +- AAuth.Tokens.ActChainReader: public static IReadOnlyList < string > GetDelegationChain ( JsonObject payload , int maxDepth = 10 ) +- AAuth.Tokens.ActChainReader: public static int GetChainDepth ( JsonObject payload , int maxDepth = 10 ) +- AAuth.Tokens.ActChainReader: public static string ? GetImmediateActor ( JsonObject payload ) +- AAuth.Tokens.ActChainReader: public static string ? GetOriginalActor ( JsonObject payload , int maxDepth = 10 ) ++ AAuth.Tokens.ActChainReader: public static IReadOnlyList < string > GetDelegationChain ( JsonObject payload , int maxDepth = 10 , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Tokens.ActChainReader: public static int GetChainDepth ( JsonObject payload , int maxDepth = 10 , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Tokens.ActChainReader: public static string ? GetImmediateActor ( JsonObject payload , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Tokens.ActChainReader: public static string ? GetOriginalActor ( JsonObject payload , int maxDepth = 10 , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Tokens.ActChainReader`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AgentAuthTokenValidator.cs + +Concept/decision: [tokens](#tokens). Source: [AgentAuthTokenValidator.cs](../../../src/AAuth/Tokens/AgentAuthTokenValidator.cs). + +```diff ++ AAuth.Tokens.AgentAuthTokenValidator: public static void Validate ( string authToken , string resourceToken , IAAuthKey signingKey , string agentToken , string ? subagentToken = null , string ? upstreamToken = null , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) ++ AAuth.Tokens: public static class AgentAuthTokenValidator +``` + +Public owners: `AAuth.Tokens.AgentAuthTokenValidator`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AgentIssuanceContext.cs + +Concept/decision: [tokens](#tokens). Source: [AgentIssuanceContext.cs](../../../src/AAuth/Tokens/AgentIssuanceContext.cs). + +```diff ++ AAuth.Tokens.AgentIssuanceContext: public IReadOnlyList < TokenRegistration > SourceTokens { get ; init ; } = [ ] ++ AAuth.Tokens.AgentIssuanceContext: public JsonObject ? Act { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public UpstreamTokenValidationResult ? Upstream { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public required DateTimeOffset AgentTokenExpiresAt { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public required DateTimeOffset ExpiresAt { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public required IAAuthKey ConfirmationKey { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public required string AgentId { get ; init ; } ++ AAuth.Tokens.AgentIssuanceContext: public static async Task < AgentIssuanceContext > VerifyAsync ( string agentToken , string ? subagentToken , string ? upstreamToken , TokenVerifier verifier , MetadataClient metadata , JwksClient jwks , Func < string , bool > isTrustedUpstreamIssuer , CancellationToken cancellationToken = default ) ++ AAuth.Tokens.AgentIssuanceContext: public void ValidateResourceContext ( JsonObject resource , string ? governingPersonServer = null ) ++ AAuth.Tokens: public sealed record AgentIssuanceContext +``` + +Public owners: `AAuth.Tokens.AgentIssuanceContext`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AgentTokenBuilder.cs + +Concept/decision: [tokens](#tokens). Source: [AgentTokenBuilder.cs](../../../src/AAuth/Tokens/AgentTokenBuilder.cs). + +```diff +- AAuth.Tokens.AgentTokenBuilder: public AAuthKey ? ConfirmationKey { get ; init ; } +- AAuth.Tokens.AgentTokenBuilder: public required AAuthKey Key { get ; init ; } ++ AAuth.Tokens.AgentTokenBuilder: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Tokens.AgentTokenBuilder: public IAAuthKey ? ConfirmationKey { get ; init ; } ++ AAuth.Tokens.AgentTokenBuilder: public required IAAuthKey Key { get ; init ; } +``` + +Public owners: `AAuth.Tokens.AgentTokenBuilder`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AuthTokenBuilder.cs + +Concept/decision: [tokens](#tokens). Source: [AuthTokenBuilder.cs](../../../src/AAuth/Tokens/AuthTokenBuilder.cs). + +```diff ++ AAuth.Tokens.AuthTokenBuilder: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Tokens.AuthTokenBuilder: public DateTimeOffset ? AuthorizationExpiresAt { get ; init ; } ++ AAuth.Tokens.AuthTokenBuilder: public TimeProvider TimeProvider { get ; init ; } = TimeProvider . System ++ AAuth.Tokens.AuthTokenBuilder: public required DateTimeOffset AgentTokenExpiresAt { get ; init ; } ++ AAuth.Tokens.AuthTokenBuilder: public static bool IsIdentityClaimAllowed ( string name ) ++ AAuth.Tokens.AuthTokenBuilder: public static bool IsReservedClaim ( string name ) ++ AAuth.Tokens.AuthTokenBuilder: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Tokens.AuthTokenBuilder`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AuthTokenExpiredException.cs + +Concept/decision: [tokens](#tokens). Source: [AuthTokenExpiredException.cs](../../../src/AAuth/Tokens/AuthTokenExpiredException.cs). + +```diff ++ AAuth.Tokens.AuthTokenExpiredException: public AuthTokenExpiredException ( ) ++ AAuth.Tokens: public sealed class AuthTokenExpiredException : InvalidOperationException +``` + +Public owners: `AAuth.Tokens.AuthTokenExpiredException`, `AAuth.Tokens`. + +### src/AAuth/Tokens/AuthTokenResponseValidator.cs + +Concept/decision: [tokens](#tokens). Source: [AuthTokenResponseValidator.cs](../../../src/AAuth/Tokens/AuthTokenResponseValidator.cs). + +```diff +- AAuth.Tokens.AuthTokenResponseValidator: public async Task < AuthTokenDeliveryResult > ValidateAsync ( string authToken , string expectedIssuer , string expectedAudience , string expectedAgentId , IAAuthKey agentKey , JsonObject ? expectedActContext = null , string ? requestedScope = null , CancellationToken ct = default ) ++ AAuth.Tokens.AuthTokenResponseValidator: public async Task < AuthTokenDeliveryResult > ValidateAsync ( string authToken , string expectedIssuer , string expectedAudience , string expectedAgentId , IAAuthKey agentKey , JsonObject ? expectedActContext = null , string ? requestedScope = null , CancellationToken ct = default , string ? expectedAccount = null ) ++ AAuth.Tokens.AuthTokenResponseValidator: public static bool ActChainsMatch ( JsonObject ? actual , JsonObject ? expected , AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Tokens.AuthTokenDeliveryResult`, `AAuth.Tokens.AuthTokenResponseValidator`, `AAuth.Tokens`. + +### src/AAuth/Tokens/MissionClaim.cs + +Concept/decision: [tokens](#tokens). Source: [MissionClaim.cs](../../../src/AAuth/Tokens/MissionClaim.cs). + +```diff +- AAuth.Tokens.MissionClaim: public static MissionClaim ? FromPayload ( JsonObject ? payload ) ++ AAuth.Tokens.MissionClaim: public static MissionClaim ? FromPayload ( JsonObject ? payload , AAuth . Discovery . AAuthEgressPolicy ? policy = null ) +``` + +Public owners: `AAuth.Tokens.MissionClaim`, `AAuth.Tokens`. + +### src/AAuth/Tokens/ResourceTokenBuilder.cs + +Concept/decision: [tokens](#tokens). Source: [ResourceTokenBuilder.cs](../../../src/AAuth/Tokens/ResourceTokenBuilder.cs). + +```diff +- AAuth.Tokens.ResourceTokenBuilder: public required AAuthKey Key { get ; init ; } ++ AAuth.Tokens.ResourceTokenBuilder: public AAuth . Discovery . AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuth . Discovery . AAuthEgressPolicy . Production ++ AAuth.Tokens.ResourceTokenBuilder: public AAuth . Headers . Interaction ? Interaction { get ; init ; } ++ AAuth.Tokens.ResourceTokenBuilder: public IReadOnlyCollection < string > ? PersonServerScopesSupported { get ; init ; } ++ AAuth.Tokens.ResourceTokenBuilder: public IReadOnlyDictionary < string , string > ? ScopeDescriptions { get ; init ; } ++ AAuth.Tokens.ResourceTokenBuilder: public required IAAuthKey Key { get ; init ; } ++ AAuth.Tokens.ResourceTokenBuilder: public static void ValidateScopes ( string ? scope , IReadOnlyDictionary < string , string > ? resourceScopes , IReadOnlyCollection < string > ? personServerScopes ) ++ AAuth.Tokens.ResourceTokenBuilder: public string ? Account { get ; init ; } +``` + +Public owners: `AAuth.Tokens.ResourceTokenBuilder`, `AAuth.Tokens`. + +### src/AAuth/Tokens/TokenVerifier.cs + +Concept/decision: [tokens](#tokens). Source: [TokenVerifier.cs](../../../src/AAuth/Tokens/TokenVerifier.cs). + +```diff +- AAuth.Tokens.TokenVerifier: public VerifiedToken VerifyAuthToken ( string jwt , IAAuthKey issuerKey , string expectedAudience , IAAuthKey httpSignatureKey , string expectedAgentId , string ? expectedDwk = null , string ? expectedMaxScope = null ) +- AAuth.Tokens.TokenVerifier: public async Task < VerifiedToken > VerifyAuthTokenWithJwksAsync ( string jwt , MetadataClient metadata , JwksClient jwks , string expectedAudience , IAAuthKey httpSignatureKey , string expectedAgentId , string ? expectedMaxScope = null , CancellationToken cancellationToken = default ) ++ AAuth.Tokens.TokenCredential: Agent ++ AAuth.Tokens.TokenCredential: Resource ++ AAuth.Tokens.TokenCredential: Subagent ++ AAuth.Tokens.TokenCredential: Upstream ++ AAuth.Tokens.TokenVerificationException: public AAuth . Errors . SignatureErrorCode Code { get ; } ++ AAuth.Tokens.TokenVerificationException: public TokenCredential ? Credential { get ; init ; } ++ AAuth.Tokens.TokenVerificationException: public TokenVerificationException ( AAuth . Errors . SignatureErrorCode code , string message , Exception ? inner = null ) ++ AAuth.Tokens.TokenVerifier.VerifiedToken: public AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuthEgressPolicy . Production ++ AAuth.Tokens.TokenVerifier.VerifiedToken: public DateTimeOffset ExpiresAt { get ; } = ReadExpiration ( Payload ) ++ AAuth.Tokens.TokenVerifier.VerifiedToken: public string ? Account ++ AAuth.Tokens.TokenVerifier: public AAuthEgressPolicy EgressPolicy { get ; init ; } = AAuthEgressPolicy . Production ++ AAuth.Tokens.TokenVerifier: public VerifiedToken VerifyAuthToken ( string jwt , IAAuthKey issuerKey , string expectedAudience , IAAuthKey httpSignatureKey , string expectedAgentId , string ? expectedDwk = null , string ? expectedMaxScope = null , AccountExpectation ? accountExpectation = null ) ++ AAuth.Tokens.TokenVerifier: public async Task < VerifiedToken > VerifyAuthTokenWithJwksAsync ( string jwt , MetadataClient metadata , JwksClient jwks , string expectedAudience , IAAuthKey httpSignatureKey , string expectedAgentId , string ? expectedMaxScope = null , CancellationToken cancellationToken = default , AccountExpectation ? accountExpectation = null ) ++ AAuth.Tokens: public enum TokenCredential +``` + +Public owners: `AAuth.Tokens.TokenCredential`, `AAuth.Tokens.TokenVerificationException`, `AAuth.Tokens.TokenVerifier.VerifiedToken`, `AAuth.Tokens.TokenVerifier`, `AAuth.Tokens`. + +### src/AAuth/Tokens/UpstreamTokenValidator.cs + +Concept/decision: [tokens](#tokens). Source: [UpstreamTokenValidator.cs](../../../src/AAuth/Tokens/UpstreamTokenValidator.cs). + +```diff ++ AAuth.Tokens.UpstreamTokenValidationResult: public AAuth . Errors . SignatureErrorCode FailureCode { get ; init ; } = AAuth . Errors . SignatureErrorCode . InvalidJwt ++ AAuth.Tokens.UpstreamTokenValidationResult: public DateTimeOffset ? ExpiresAt { get ; init ; } ++ AAuth.Tokens.UpstreamTokenValidationResult: public MissionClaim ? Mission { get ; init ; } ++ AAuth.Tokens.UpstreamTokenValidationResult: public TokenVerifier . VerifiedToken ? Verified { get ; init ; } ++ AAuth.Tokens.UpstreamTokenValidationResult: public string ? Account +``` + +Public owners: `AAuth.Tokens.UpstreamTokenValidationResult`, `AAuth.Tokens.UpstreamTokenValidator`, `AAuth.Tokens`. diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/capability-scenarios.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/capability-scenarios.md new file mode 100644 index 00000000..73563ab9 --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/capability-scenarios.md @@ -0,0 +1,156 @@ +--- +description: Phase 12 migration capability coverage, runnable scenarios and explicit evidence limits. +--- + +# Capability Scenarios + +Baseline: ba768f1. Cross-checked against [api-surface-map.md](api-surface-map.md), +the Phase 1-11 findings, current sample routes and the browser specs below. +An API declaration is not automatically a new end-user workflow. Mandatory +validation, transport contracts and typed codecs have negative tests; protocol +workflows have executable pages in both apps. Native gRPC, SOAP and GraphQL +applications are not claimed by a codec test or by an HTTP gateway. + +## Runnable Workflows + +Both apps use the existing Playwright projects. Links below identify the actual +page or flow implementation; spec paths identify assertions, not inferred +coverage from unrelated successful requests. + +| Capability | Flow | GuidedTour entry | SampleApp entry | Resource purpose | Playwright evidence and limits | +|---|---|---|---|---|---| +| Resource-initiated interaction before PS consent | Document Release | [/documents](../../../samples/GuidedTour/Components/Pages/Documents.razor) | [/documents](../../../samples/SampleApp/Components/Pages/Documents.razor) | Work document release, not external OAuth simulation | [shared Documents specs](../../../tests/e2e/helpers/documents.ts): real AP enrollment, signed challenge/poll/download, session/CSRF continuation, ordinary-consent bypass rejection, resource success/denial, account/scope preservation and reset/layout | +| Signed enrollment, provider-assigned agent identity | Existing setup; new Wallet setup | [/wallet-protocol](../../../samples/GuidedTour/Components/Pages/WalletProtocol.razor), step 1 | [/wallet-protocol](../../../samples/SampleApp/Components/Pages/WalletProtocol.razor), step 1 | AP provisions an agent, not a resource authorization party | [shared Wallet specs](../../../tests/e2e/helpers/wallet-protocol.ts) execute enrollment again after reset; [bootstrap](../../../samples/GuidedTour/playwright-tests/bootstrap.spec.ts) covers the tour ceremony | +| Self-issued agent JWT and PS authorization | Existing Autonomous / Calendar | [TourSession](../../../samples/GuidedTour/TourSession.cs), Autonomous selector | [/calendar](../../../samples/SampleApp/Components/Pages/Jwt.razor) | Calendar reads a person's events | [autonomous](../../../samples/GuidedTour/playwright-tests/autonomous.spec.ts), [jwt](../../../samples/SampleApp/playwright-tests/jwt.spec.ts): signed resource challenge, PS grant, resource response | +| Agent JWT plus opaque resource-managed access | Existing Inbox | [TourSession](../../../samples/GuidedTour/TourSession.cs), ResourceManaged selector | [/inbox](../../../samples/SampleApp/Components/Pages/Inbox.razor) | Inbox imports trip confirmations | [resource-managed](../../../samples/GuidedTour/playwright-tests/resource-managed.spec.ts), [inbox](../../../samples/SampleApp/playwright-tests/inbox.spec.ts): AP/local setup, authenticated consent, opaque credential and replay; no PS/AS resource exchange | +| Generic hwk, jkt-jwt and direct jwks signing | Existing generic Profile flows | [TourSession](../../../samples/GuidedTour/TourSession.cs), identity selectors | [Hwk](../../../samples/SampleApp/Components/Pages/Hwk.razor), [JktJwt](../../../samples/SampleApp/Components/Pages/JktJwt.razor), [JwksUri](../../../samples/SampleApp/Components/Pages/JwksUri.razor) | Profile exposes travel preferences using explicitly generic Signature Keys | [identity](../../../samples/GuidedTour/playwright-tests/identity.spec.ts), [hwk](../../../samples/SampleApp/playwright-tests/hwk.spec.ts), [jkt-jwt](../../../samples/SampleApp/playwright-tests/jkt-jwt.spec.ts), [jwks-uri](../../../samples/SampleApp/playwright-tests/jwks-uri.spec.ts); not described as AAuth resource modes | +| Authenticated deferred consent | Existing Deferred | [TourSession](../../../samples/GuidedTour/TourSession.cs), Deferred selector | [/calendar-deferred](../../../samples/SampleApp/Components/Pages/Deferred.razor) | Calendar consent | [deferred tour](../../../samples/GuidedTour/playwright-tests/deferred.spec.ts), [deferred app](../../../samples/SampleApp/playwright-tests/deferred.spec.ts): 202, authenticated session/CSRF, approval/poll transitions | +| Four-party authorization and claims policy | Existing Federated | [TourSession](../../../samples/GuidedTour/TourSession.cs), Federated selector | [/wallet](../../../samples/SampleApp/Components/Pages/Federated.razor) | Wallet delegates policy to its AS | [federated tour](../../../samples/GuidedTour/playwright-tests/federated.spec.ts), [federated app](../../../samples/SampleApp/playwright-tests/federated.spec.ts), [live Keycloak](../../../samples/SampleApp/playwright-tests/federated-deferred.spec.ts): issuer, directed identity and consent. Claims push is also covered by actual AS endpoint tests, not inferred from every browser grant | +| Mission creation, permissions, audit and completion | Existing mission flows | [TourSession](../../../samples/GuidedTour/TourSession.cs), Mission selector | [/trips](../../../samples/SampleApp/Components/Pages/Mission.razor) | Trips is mission-aware travel planning | [mission tour](../../../samples/GuidedTour/playwright-tests/mission.spec.ts), [mission app](../../../samples/SampleApp/playwright-tests/mission.spec.ts); foreign/unknown/terminated cases are HTTP regressions, not artificial UI controls | +| PS clarification and mission call chaining | Existing mission chain | [TourSession](../../../samples/GuidedTour/TourSession.cs), MissionCallChain selector | [/mission-call-chain](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor) | Concierge orchestrates Trips under a mission | [mission-chain tour](../../../samples/GuidedTour/playwright-tests/mission-call-chain.spec.ts), [mission-chain app](../../../samples/SampleApp/playwright-tests/mission-call-chain.spec.ts): question, answer, actor/mission propagation | +| PS-routed and interaction-chained calls | Existing CallChain | [TourSession](../../../samples/GuidedTour/TourSession.cs), CallChain selector | [/call-chain](../../../samples/SampleApp/Components/Pages/CallChain.razor) | Concierge orchestrates Calendar access | [call-chain tour](../../../samples/GuidedTour/playwright-tests/call-chain.spec.ts), [call-chain app](../../../samples/SampleApp/playwright-tests/call-chain.spec.ts), [deferred chain](../../../samples/SampleApp/playwright-tests/call-chain-deferred.spec.ts): downstream consent and resource result | +| Parent-mediated child and combined upstream delegation | Existing SubAgent | [TourSession](../../../samples/GuidedTour/TourSession.cs), SubAgent selector | [/sub-agent](../../../samples/SampleApp/Components/Pages/SubAgent.razor) | Wallet read delegated through distinct parent/worker keys | Both [tour](../../../samples/GuidedTour/playwright-tests/sub-agent.spec.ts) and [app](../../../samples/SampleApp/playwright-tests/sub-agent.spec.ts) execute [FederatedWorkerScenario](../../../samples/FederatedWorkerScenario.cs), including parent-key rejection | +| Account selection and account-bound R3 approval | Existing RichRequests / Bookings | [TourSession](../../../samples/GuidedTour/TourSession.cs), RichRequests selector | [/bookings](../../../samples/SampleApp/Components/Pages/Bookings.razor) | Bookings owns personal/work reservation accounts | [richrequests](../../../samples/GuidedTour/playwright-tests/richrequests.spec.ts), [bookings](../../../samples/SampleApp/playwright-tests/bookings.spec.ts): actual account claims, selected account and per-call consent | +| R3 unconditional and conditional operations, proposal integrity | Existing RichRequests / Bookings | Same RichRequests entry | Same Bookings entry | Search, hold and confirm a reservation | Same two specs check numbered flow and proposal consent; byte/parameter tampering and audit failure have [resource HTTP tests](../../../tests/AAuth.R3.Tests/ResourceR3Tests.cs) | +| Events public registration | Existing Events public channel | [/events](../../../samples/GuidedTour/Components/Pages/Events.razor) | [/events](../../../samples/SampleApp/Components/Pages/Events.razor) | Bookings announces availability | [shared Events specs](../../../tests/e2e/helpers/events.ts): discover AsyncAPI/AP metadata, subscribe JWT, HTTP 202 delivery, agent receipt and duplicate ignored | +| Events protected registration and account context | Existing Events protected work account | Same Events page | Same Events page | Account-authorized reservation notifications | Same Events specs: real PS consent/ticket, work account, durable receipt/ack and payload; recurring delivery ambiguity remains explicit | +| AS clarification, PS relay, answer and cancellation | **New Wallet Clarification** | [/wallet-protocol](../../../samples/GuidedTour/Components/Pages/WalletProtocol.razor), AS clarification option | [/wallet-protocol](../../../samples/SampleApp/Components/Pages/WalletProtocol.razor), same option | Wallet review requires a travel justification before normal AS policy | Both [tour spec](../../../samples/GuidedTour/playwright-tests/wallet-protocol.spec.ts) and [app spec](../../../samples/SampleApp/playwright-tests/wallet-protocol.spec.ts) invoke shared tests: real clarification_response, wallet.review grant, rejected charge; separate DELETE cancellation/reset case | +| No-mission direct-AS chaining | **New Wallet DirectAs** | Same page, Direct AS chaining option | Same page and option | Concierge reads Wallet on an existing AS grant | Shared Wallet spec: AS-issued upstream with no mission, AS-issued downstream, Concierge agent and actor chain, 401 when upstream grant is presented directly to Wallet, repeated call. The capture sees resource requests, not the builder's separate exchange channel; direct-AS body validation belongs to HTTP endpoint tests | +| Issuer-qualified token revocation and recovery | **New Wallet Revocation** | Same page, Issuer-qualified revocation option | Same page and option | Owner withdraws an issued Wallet grant through the PS | Shared Wallet spec: agent revoker 403, signed PS withdrawal twice with HTTP 200, revoked resource call 401, fresh grant with different jti and recovered read | +| Service-qualified OpenAPI gateway operations | **New Catalog Gateway** | [/catalog-gateway](../../../samples/GuidedTour/Components/Pages/Catalog.razor) | [/catalog-gateway](../../../samples/SampleApp/Components/Pages/Catalog.razor) | Read two travel catalogs, each with operationId list | Both [tour spec](../../../samples/GuidedTour/playwright-tests/catalog.spec.ts) and [app spec](../../../samples/SampleApp/playwright-tests/catalog.spec.ts) invoke [shared assertions](../../../tests/e2e/helpers/catalog.ts): actual definitions, selected service, sibling 403, reauthorization and recovery for both service selections | + +## Internal Contracts And Exclusions + +These rows are not substitutes for missing end-user workflows. They classify +low-level API changes from the public delta and the explicitly excluded optional +capabilities. Their evidence is executable SDK/host tests, not new UI. + +| API-map group / capability | Disposition | Evidence | +|---|---|---| +| Problem details and typed errors | Shared wire correction; all live flows consume it | [problem-details tests](../../../tests/AAuth.Tests/Server/AAuthProblemDetailsTests.cs), endpoint error assertions | +| Verified issuance ceiling, reserved claims and narrowed delivery | Internal token security contract | [IssuanceBoundsTests](../../../tests/AAuth.Conformance/AuthTokens/IssuanceBoundsTests.cs), [AuthTokenDeliveryTests](../../../tests/AAuth.Conformance/AuthTokens/AuthTokenDeliveryTests.cs) | +| Six carrier codecs, fully specified algorithms and selected labels | Generic carrier support plus AAuth profile restrictions | [SignatureV10WireTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10WireTests.cs), [SignatureV10AdversarialTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10AdversarialTests.cs); Events is the actual self-jwt workflow | +| Discovery admission, caches and injected transports | Internal security and deployment contract | [EgressTransportTests](../../../tests/AAuth.Tests/Discovery/EgressTransportTests.cs), [DiscoveryCacheSecurityTests](../../../tests/AAuth.Tests/Discovery/DiscoveryCacheSecurityTests.cs) | +| All eight typed R3 vocabularies | Model and enforcement support, not eight native transport implementations | [R3VocabularyTests](../../../tests/AAuth.R3.Tests/R3VocabularyTests.cs): Shapes_RoundTripDocumentRequestClaimsAndProposal, AllVocabularies_MatchReorderedObjectsAndBindConditionalRetries, OptionalMembers_ArePartOfIdentity, OData_MultiMethodGrantCoversIndividualCallWithoutWidening. Runnable protocol integrations are OpenAPI, OpenAPI Gateway and AsyncAPI; native MCP/gRPC/GraphQL/SOAP/OData sample services are not claimed | +| Consent owner/key/account binding, tombstones and atomic delivery | Internal enforcement of every applicable live consent flow | [BrowserConsentSessionTests](../../../tests/AAuth.Tests/Server/BrowserConsentSessionTests.cs), [GovernanceDeferredConsentMapperTests](../../../tests/AAuth.Conformance/Missions/GovernanceDeferredConsentMapperTests.cs), signed [MissionAgentFlowTests](../../../tests/AAuth.Tests/Integration/MissionAgentFlowTests.cs) | +| Fluent composition and ownership | Existing builders retained; low-level fixed token usage only for explicit steps | [ClientCompositionTests](../../../tests/AAuth.Tests/HttpSig/ClientCompositionTests.cs), [SnippetCompilationTests](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| Persistent provider contracts | Operator responsibility; configured SQLite implementations tested | [Events persistence](../../../tests/AAuth.Events.Tests/EventPersistenceTests.cs), [R3 audit persistence](../../../tests/AAuth.R3.Tests/R3SqliteAuditTests.cs); arbitrary injected implementations are not certified | +| X.509 and cached Signature Keys | Unsupported optional, Phase 0 Q1 | Unsupported-scheme tests; no compatibility parser or fake UI | +| Platform-native attestation and AP-agent push transports | Extension points / deployment choices | Bootstrap software keys and polling are real; hardware assurance and mobile push are not claimed | +| Payment settlement | External protocol, not an AAuth payment implementation | Payment requirement/cancellation tests exercise response handling; no fake settlement UI | + +## Resource Decisions + +- Wallet remains a travel wallet: review and revocation concern its own grants. +- Concierge remains a travel intermediary: the direct-AS wallet read is another + travel orchestration path, with the existing WithCallChaining builder. +- Bookings remains reservations, including reservation events and accounts. +- Catalog is the Phase 12 resource process, at localhost:5006. It reads travel + catalogs and demonstrates service-qualified authorization with colliding + operation names. It contains no payments, Events or unrelated endpoints. +- Documents is the final authorization-repair resource at localhost:5007. It + owns one document-release permission and requires that permission as well as + the PS grant on download. It does not extend Catalog or fabricate OAuth. +- CapabilitySupport is a shared Razor library, not a server. It prevents the two + apps' runtime steps/snippets from diverging and uses the existing SDK clients. + +Catalog is registered once in AAuth.slnx, Makefile resources/demo and the shared +Playwright webServer array. SampleEgress admits only its explicit loopback origin. +CI already discovers the app-local specs through the shared Playwright projects. +Reset creates a fresh agent/session; Catalog domain data and definitions are +immutable, so no unauthenticated reset endpoint or external database is needed. + +## Verification Record + +### Final Authorization Repairs + +Full fresh-service stub suite: 71 passed, one existing live-only skip. Full live +Keycloak suite: 72 passed, no skips. Both use retries=0, with zero unexpected or +flaky results. The four added Documents cases execute actual resource permission +and denial in both apps; all 68 baseline live cases remain. Reports: +/tmp/aauth-final-stub.json and /tmp/aauth-final-live.json. CSS-only follow-up +passes the same four Documents cases with final screenshots in +/tmp/aauth-final-documents-layout3-results/. The timeout attempts and memory +recovery are retained in the implementation log. + +Full Release: 2160 passed, zero failed/skipped. Documentation inventory: 169 +files, 617 blocks, 261 exact compiled C# blocks; 80 docs checks pass. API map: +197 changed public-source files, +777/-149 declarations, zero unmapped files, +verified current. These supersede the earlier counts below, not their recorded +evidence limitations. Independent Phase 14/15 gates remain open. + +### Phase 13 documentation alignment + +The [docs surface map](docs-surface-map.md) now covers both primary apps and +shared scenario sources, including raw/multiline/single-line C# strings, quoted +Markdown fences, inline Razor code, dynamic payloads and shell/JSON/HTTP examples. +Wallet's guide follows its actual 5/6/8 steps; Catalog follows five steps and +the destinations/experiences service labels. Both guides link the existing shared +Playwright wrappers, not a second test harness. Catalog has a single-purpose +resource README, and both app READMEs/indexes expose the new routes. + +Final Phase 13 full fresh-service results: 67 stub passes plus one live-only +skip, and 68 live-Keycloak passes, zero unexpected/flaky results, retries=0. +Reports: /tmp/aauth-phase13-stub-release.json and +/tmp/aauth-phase13-live-release.json. Initial display/timing failures and the +14-case focused recovery run remain in the log. Final Release passes 2128 tests; +80 documentation test cases include 261 exact compiled blocks and separately +classified excerpts/templates/displays. These supersede the representative +21-template boundary below, which records the earlier Phase 12 checkpoint. + +### Phase 12 checkpoint + +Final policy-mode matrix: all 68 live cases pass (38 GuidedTour, 30 SampleApp), +and stub mode passes 67 with the one existing live-only skip. Both runs use +fresh services, isolated settings and retries=0, with no failures/flaky results. +The four new scenarios, Catalog's two service selections, worker attribution, +callbacks and reset/layout assertions are included in both full runs. Reports: +/tmp/aauth-phase12-repairs-live-final.json and +/tmp/aauth-phase12-repairs-stub-final.json. Exact snippet compilation passes 21 +templates. The make demo entry point also starts both apps and Catalog on fresh +settings; final readiness endpoints return 200. + +The adversarial repair pass retains all four new selectable scenarios and +Catalog's single resource purpose. Wallet recovery now labels its fresh-grant +consent callback in the numbered step, sequence row and exact compiled snippet. +The shared Keycloak driver waits for the actual AS callback outcome; successful +popup completion still does not replace signed token/resource assertions. +Existing AS approval/denial and parent/worker tests now execute both policy modes +without owner-excluding worker coverage. Five focused live AS/worker cases and +four live Catalog cases pass with fresh settings and retries=0. The earlier +full-live failures and replacement full-suite evidence remain in the log. + +Initial Wallet browser run: four passed, four failed. Repairs and reasons are +recorded in [implementation-log.md](implementation-log.md), not hidden by retries. +The second run passed six cases; two direct-AS assertions overclaimed the capture +surface. Corrected observable assertions then passed both direct-AS cases. +Catalog fresh-service run passed all four cases. These focused runs establish +12 new browser cases for four selectable scenarios across the two apps, including +two cancellation cases and both catalog service selections. Full final browser +and policy-mode counts belong in the final gate entry, not these earlier results. + +Every new flow checks its numbered list, sequence row count, corresponding C# +snippet, navigation, reset/re-enrollment and desktop/narrow layout. New snippets +are compiled exactly alongside the original 17 templates. Screenshots exposed +and drove a contrast repair in the dark GuidedTour host. Phase 13's repository-wide +documentation and snippet sweep remains separate. \ No newline at end of file diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/conformance-ledger.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/conformance-ledger.md new file mode 100644 index 00000000..8c0bad1f --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/conformance-ledger.md @@ -0,0 +1,398 @@ +--- +description: Section-oriented v10 conformance evidence and explicit implementation, optional and deployment dispositions. +--- + +# Conformance Ledger + +## Final Status + +Closed 2026-09-09 for the approved migration scope. This supersedes the numbered +repair checkpoints below without rewriting their historical evidence. Final +Release: 2913 tests, zero failed/skipped; explicit core/conformance/R3/Events +and 105 documentation/source/link checks pass, with a clean build. API inventory: +201 changed public-source files, +810/-162 declarations, zero unmapped; +documentation inventory remains 169 files and 629 classified blocks. + +The final runtime browser reports contain 71 stub passes plus the expected +live-only skip and 72 live Keycloak passes, no failures or flaky results. +Subsequent edits only correct docs/XML and add two documentation regressions. +Fresh independent reviewers report zero remaining confirmed findings in their +respective signing/discovery/API, authorization/claims, R3/Events/storage and +sample/docs scopes after repair cycles. This is bounded acceptance, not a +certification of arbitrary injected contracts or unexercised external systems. + +Both apps' capability scenarios, numbered steps, sequence displays, snippets and +their Playwright coverage were reviewed; saved desktop/mobile captures were +inspected. The [implementation log](implementation-log.md) records exact gate +artifacts and the premature worker-push deviation. External full authorization +returned `person_token_required` and is not a passing interoperability result. +The optional, ambiguous and deployment-owned dispositions below remain in force. + +Pinned sources are the immutable v10 protocol, Signature Keys draft 08, R3 and +Events snapshots. References below use canonical source lines and section names. +This is an area/requirement ledger, not a certification of arbitrary applications +that inject their own policies, stores, renderers or transports. A passing suite +does not prove every branch of a compound normative sentence independently. + +Disposition vocabulary: + +- **Implemented**: the owning code and named tests exercise the stated contract. +- **Policy**: SDK mechanics are implemented; the stated decision or operational + guarantee belongs to the host/operator and is not silently assumed. +- **Optional unsupported**: capability is not enabled, so its conditional + requirements are not claimed as implemented. +- **Ambiguous**: pinned text conflicts; the logged interpretation is explicit. +- **Inapplicable**: registration, rationale, historical text or a non-runtime role. + +The normative sweep includes positive MUST/REQUIRED, negative MUST NOT/reject, +SHOULD recommendations, and conditional optional features. Document history, +examples with placeholders, appendices labeled non-normative and IANA expert +procedures are not executable protocol requirements. Lines in those areas must +not be mistaken for a current runtime contract. + +## Protocol + +| Requirement / canonical area | Owning code | Tests and disposition | +|---|---|---| +| [Terminology L203](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L203), Markdown sanitization L226 | [PS consent rendering](../../../samples/MockPersonServer/Program.cs), [PayloadInspector](../../../samples/GuidedTour/Components/PayloadInspector.razor), Razor pages | Implemented for shipped renderers: MissionConsent_RendersUntrustedMarkdownAsEncodedText in [MissionAgentFlowTests](../../../tests/AAuth.Tests/Integration/MissionAgentFlowTests.cs); arbitrary host Markdown renderers remain Policy | +| [Access modes L237](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L237), identity/resource-managed/PS/federated roles | [AAuthClientBuilder](../../../src/AAuth/AAuthClientBuilder.cs), [resource endpoints](../../../src/AAuth/Server/Endpoints/) | Implemented: [SigningModeEndToEndTests](../../../tests/AAuth.Conformance/HttpSignatures/SigningModeEndToEndTests.cs), [ResourceManagedFlowTests](../../../tests/AAuth.Conformance/ResourceTokens/ResourceManagedFlowTests.cs); app topology in [capability matrix](capability-scenarios.md) | +| [Roles and policy evaluation L400](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L400) | [IAccessPolicy](../../../src/AAuth/Access/IAccessPolicy.cs), [Person endpoints](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs) | Policy: verified claims are not an authorization decision; deny/consent-needed tested in [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs) | +| [Agent identifiers L544](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L544) | [Identifiers](../../../src/AAuth/Identifiers/) | Implemented: [AgentIdTests](../../../tests/AAuth.Conformance/Identifiers/AgentIdTests.cs), invalid names and byte-sensitive comparison | +| [Agent acquisition/structure L566](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L566), required claims and cnf | [AgentTokenBuilder](../../../src/AAuth/Tokens/AgentTokenBuilder.cs), [TokenVerifier](../../../src/AAuth/Tokens/TokenVerifier.cs) | Implemented: [AgentTokenStructureTests](../../../tests/AAuth.Conformance/AgentTokens/AgentTokenStructureTests.cs), [AgentTokenVerificationTests](../../../tests/AAuth.Conformance/AgentTokens/AgentTokenVerificationTests.cs); AP issuance/account identity is Policy | +| [Agent verification L609](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L609), signature before identity trust | [AAuthVerificationMiddleware](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs) | Implemented: [VerificationMiddlewareTests](../../../tests/AAuth.Conformance/HttpSignatures/VerificationMiddlewareTests.cs), forged issuer/PoP negative tests | +| [Authorization request/response L640](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L640), account/scope definitions, with/without resource token | [Challenge middleware](../../../src/AAuth/Server/Challenge/), [ResourceTokenBuilder](../../../src/AAuth/Tokens/ResourceTokenBuilder.cs) | Implemented: [ChallengeMiddlewareTests](../../../tests/AAuth.Conformance/HttpSignatures/ChallengeMiddlewareTests.cs), [ScopeVocabularyTests](../../../tests/AAuth.Conformance/ResourceTokens/ScopeVocabularyTests.cs) | +| [Agent-token requirement L748](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L748), no generic carrier substitution | [AAuthClientBuilder](../../../src/AAuth/AAuthClientBuilder.cs), resource verification | Implemented: [ClientCompositionTests](../../../tests/AAuth.Tests/HttpSig/ClientCompositionTests.cs), actual Inbox flows; HWK demonstrations explicitly generic | +| [AAuth-Access L761](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L761), opaque grammar, covered authorization | [ResourceManaged](../../../src/AAuth/Server/ResourceManaged/), [AAuthSigningHandler](../../../src/AAuth/HttpSig/AAuthSigningHandler.cs) | Implemented: [AAuthAccessTokenGrammarTests](../../../tests/AAuth.Conformance/ResourceTokens/AAuthAccessTokenGrammarTests.cs), [AAuthAccessSignedComponentTests](../../../tests/AAuth.Conformance/HttpSignatures/AAuthAccessSignedComponentTests.cs) | +| [Resource-managed authorization L781](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L781), agent/key/account binding | [ResourceManaged](../../../src/AAuth/Server/ResourceManaged/) | Implemented: [ResourceManagedFlowTests](../../../tests/AAuth.Conformance/ResourceTokens/ResourceManagedFlowTests.cs), [OpaqueTokenStoreTests](../../../tests/AAuth.Conformance/ResourceTokens/OpaqueTokenStoreTests.cs), account-aware store tests | +| [Resource-token structure L818](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L818), iss/aud/agent/cnf/scope/mission/account | [ResourceTokenBuilder](../../../src/AAuth/Tokens/ResourceTokenBuilder.cs) | Implemented: [ResourceTokenStructureTests](../../../tests/AAuth.Conformance/ResourceTokens/ResourceTokenStructureTests.cs), [AccountBindingTests](../../../tests/AAuth.Tests/Tokens/AccountBindingTests.cs) | +| [Resource and challenge verification L849](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L849), expiry, request/key/issuer binding | [TokenVerifier](../../../src/AAuth/Tokens/TokenVerifier.cs), [ChallengeHandler](../../../src/AAuth/Agent/ChallengeHandler.cs) | Implemented: resource-token and [TokenVerifierTests](../../../tests/AAuth.Tests/Tokens/TokenVerifierTests.cs); expired resource replacement is not a fresh unbounded grant | +| [PS token request L895](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L895), independent concurrent pending requests | [Person endpoints](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs) | Implemented: [PersonServerMapperTests](../../../tests/AAuth.Conformance/Person/PersonServerMapperTests.cs), owner/key checks and separate request state; user interaction scheduling is Policy | +| [PS response L930](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L930), consent before claims/grant delivery | Person endpoints and [AccessServerClient](../../../src/AAuth/Access/AccessServerClient.cs) | Implemented: PsDenialPreventsGrantWithoutAsClaimsRequest, FailedClaimsConsentNeverBecomesClaims, FederatedMissionGatePrecedesIdentityAndAccessServer in [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs) | +| [Resource-initiated interaction L961](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L961), resource before PS consent L965, abandon on callback error L973 | [PersonResourceInteraction](../../../src/AAuth/Person/PersonResourceInteraction.cs), Person endpoints and configured BrowserConsentSessions | Implemented: PersonServerMapperTests callback state/browser/context/replay/error matrix; DeferredFederationTests success/denial before AS policy; [both Documents browsers](../../../tests/e2e/helpers/documents.ts) exercise permission, PS consent and signed download. Resource OAuth validation and browser-network controls remain host responsibilities | +| [Callback errors L995](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L995) | [Errors](../../../src/AAuth/Errors/), interaction clients | Implemented: [InteractionCallbackErrorTests](../../../tests/AAuth.Conformance/Errors/InteractionCallbackErrorTests.cs); callbacks do not substitute for signed terminal polling | +| [Clarification L1013](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1013), explicit response/update/cancel actions L1046 | [ClarificationExchange](../../../src/AAuth/Agent/ClarificationExchange.cs), PS/AS endpoints | Implemented: [ClarificationChatTests](../../../tests/AAuth.Conformance/Missions/ClarificationChatTests.cs), [PersonServerMapperTests](../../../tests/AAuth.Conformance/Person/PersonServerMapperTests.cs), [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs); missing/mismatched action, foreign replacement and narrowed scope tested | +| [Clarification limits L1116](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1116) | ClarificationExchange, [DeferredExchange](../../../src/AAuth/Agent/DeferredExchange.cs) | Implemented bounded rounds/deadline: AsEnforcesClarificationRoundLimit and ClarificationDeadlineTerminatesBothPendingRequests; real AS answer and DELETE browser flows in both apps | +| [Permission L1128](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1128), signed agent and mission association | [GovernanceEndpoints.Authorize](../../../src/AAuth/Server/Governance/GovernanceEndpoints.cs), [mapper](../../../src/AAuth/DependencyInjection/AAuthGovernanceApplicationBuilderExtensions.cs), sample PS | Implemented: [GovernanceEndpointMapperTests](../../../tests/AAuth.Conformance/Missions/GovernanceEndpointMapperTests.cs), signed [MissionAgentFlowTests](../../../tests/AAuth.Tests/Integration/MissionAgentFlowTests.cs); unknown/foreign/approver/terminated failures have no policy/log side effects | +| [Audit L1184](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1184), required mission and 201 acknowledgement | Governance parsers/authorization, sample audit sink | Implemented: same signed boundary tests plus [GovernanceServerTests](../../../tests/AAuth.Conformance/Missions/GovernanceServerTests.cs); durable mission log retention is Policy | +| [Interaction L1242](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1242), relay/question/payment/completion, final poll authority | Governance mapper, [InteractionClient](../../../src/AAuth/Agent/Governance/InteractionClient.cs) | Implemented: [GovernanceDeferredConsentMapperTests](../../../tests/AAuth.Conformance/Missions/GovernanceDeferredConsentMapperTests.cs), [InteractionChainingTests](../../../tests/AAuth.Tests/Agent/InteractionChainingTests.cs); payment settlement/user-channel delivery is Policy | +| [Reauthorization L1338](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1338), agent expiry limits and renewed consent | PS/AS minting, [AuthTokenBuilder](../../../src/AAuth/Tokens/AuthTokenBuilder.cs) | Implemented: [IssuanceBoundsTests](../../../tests/AAuth.Conformance/AuthTokens/IssuanceBoundsTests.cs); Wallet fresh-grant recovery browser cases | +| [Mission creation/approval L1350](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1350), exact bytes/hash L1428 | [Mission](../../../src/AAuth/Agent/Mission.cs), governance builder/store | Implemented: [MissionS256Tests](../../../tests/AAuth.Conformance/Missions/MissionS256Tests.cs), [MissionModelTests](../../../tests/AAuth.Conformance/Missions/MissionModelTests.cs), HTTP mission approvals | +| [Mission log/completion/status L1432](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1432), permanently terminated L1449/L1455 | Governance mapper and PS state gates | Implemented terminal rejection: [MissionTerminatedTests](../../../tests/AAuth.Conformance/Missions/MissionTerminatedTests.cs), new signed three-endpoint tests and deferred completion tests. Production store permanence/retention is Policy | +| [Mission presentation L1488](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1488), no dereference L1490 and exact reference echo | [Mission header](../../../src/AAuth/Agent/Mission.cs), challenge/chain handlers | Implemented reference-only data flow: [MissionReferenceValidationTests](../../../tests/AAuth.Conformance/Missions/MissionReferenceValidationTests.cs), [MissionHeaderSeamTests](../../../tests/AAuth.Conformance/Missions/MissionHeaderSeamTests.cs), [MissionSignedComponentTests](../../../tests/AAuth.Conformance/HttpSignatures/MissionSignedComponentTests.cs). Resource/AS have no mission-fetch implementation; no arbitrary application callback guarantee | +| [PS-to-AS request L1503](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1503), child/upstream propagation and signing | [AccessServerClient](../../../src/AAuth/Access/AccessServerClient.cs), [AgentIssuanceContext](../../../src/AAuth/Tokens/AgentIssuanceContext.cs) | Implemented: [AccessServerClientTests](../../../tests/AAuth.Tests/AccessServerClientTests.cs), [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs). Q2 uses normative Signature Keys jwks_uri discovery, not stale protocol example syntax | +| [AS response/delivery L1531](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1531), claims composition L1581 | AS endpoints, [AuthTokenResponseValidator](../../../src/AAuth/Tokens/AuthTokenResponseValidator.cs) | Implemented: [AuthTokenDeliveryTests](../../../tests/AAuth.Conformance/AuthTokens/AuthTokenDeliveryTests.cs), [MockAccessServerTests](../../../tests/AAuth.Tests/Integration/MockAccessServerTests.cs); reserved claim requests/pushes rejected | +| [Signed requested claims L1599](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1599) (#requirement-claims), [clarification action L1054](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1054) (#agent-response-to-clarification) | [TokenRequestBody](../../../src/AAuth/Server/TokenRequestBody.cs), [AS pending dispatch](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs) | Implemented, 2026-09-09 final repair: ClaimsPushPreservesRequestedCredentialNamedIdentity in [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs) preserves policy-requested credential-like names and action values through signed HTTP issuance; trusted pending state controls dispatch. Raw duplicate/nested-duplicate and reserved/typed-identity failures leave policy and pending state unchanged; initial and updated-request malformed credential matrices retained | +| [Federation trust L1601](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1601), PS-AS collapse L1679 | Explicit configured trust and policy interfaces | Policy: configured trust/pairwise identity, no issuer-to-policy inference; [MockPersonServerFederationTests](../../../tests/AAuth.Tests/Integration/MockPersonServerFederationTests.cs). Organization visibility and directory policy require host integration | +| [Auth-token structure L1690](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1690), optional/reserved claims and expiry ceilings | AuthTokenBuilder, TokenVerifier | Implemented: [AuthTokenStructureTests](../../../tests/AAuth.Conformance/AuthTokens/AuthTokenStructureTests.cs), [IssuanceBoundsTests](../../../tests/AAuth.Conformance/AuthTokens/IssuanceBoundsTests.cs) | +| [Auth verification L1736](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1736), request binding and response validation | TokenVerifier, [AgentAuthTokenValidator](../../../src/AAuth/Tokens/AgentAuthTokenValidator.cs) | Implemented: [AuthTokenVerificationTests](../../../tests/AAuth.Conformance/AuthTokens/AuthTokenVerificationTests.cs), [ScopeNarrowingTests](../../../tests/AAuth.Conformance/AuthTokens/ScopeNarrowingTests.cs); optional sub is not manufactured by sample direct-AS policy | +| [Upstream verification L1766](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1766), AS/PS route L1784, directed sub L1800 | [UpstreamTokenValidator](../../../src/AAuth/Tokens/UpstreamTokenValidator.cs), [CallChainingRouter](../../../src/AAuth/Server/CallChaining/CallChainingRouter.cs) | Implemented: [UpstreamTokenValidationTests](../../../tests/AAuth.Conformance/AuthTokens/UpstreamTokenValidationTests.cs), DirectAsChainingUsesAccessMetadataAndAgentCarrier / RejectsUnboundAuthorization in DeferredFederationTests; distinct intermediary key and audience are preserved | +| [Interaction chaining L1819](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1819) | Concierge and shared interaction helpers | Implemented representative flows: [InteractionChainingTests](../../../tests/AAuth.Tests/Agent/InteractionChainingTests.cs), call-chain deferred browsers. Intermediary-owned pending storage requires its own ownership/retention controls; see review limits below | +| [Sub-agents L1825](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1825), single depth and parent authorization L1859 | AgentIssuanceContext, agent identifiers and token builders | Implemented: [PersonServerMapperTests](../../../tests/AAuth.Conformance/Person/PersonServerMapperTests.cs), four-party [FederatedWorkerScenario](../../../samples/FederatedWorkerScenario.cs) and both sub-agent browser specs | +| [Delegation chain L1874](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1874), actor nesting/no person identifiers | [ActChainBuilder](../../../src/AAuth/Tokens/ActChainBuilder.cs), [ActChainReader](../../../src/AAuth/Tokens/ActChainReader.cs) | Implemented: [ActChainBuilderTests](../../../tests/AAuth.Conformance/AuthTokens/ActChainBuilderTests.cs), [ActChainReaderTests](../../../tests/AAuth.Conformance/AuthTokens/ActChainReaderTests.cs) | +| [Third-party login L1928](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1928), conditional ps/start_path validation L2000 | Metadata field only | Optional unsupported by sample hosts. No login_endpoint flow is advertised/implemented by the migration; hosts enabling their own endpoint must validate PS discovery and same-origin relative start_path. Metadata serialization tests do not establish login conformance | +| [Capabilities L2010](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2010), ignore unknown/no assumed capabilities | [AAuthCapabilitiesHeader](../../../src/AAuth/Agent/AAuthCapabilitiesHeader.cs), exchange options | Implemented: [CapabilitiesHeaderTests](../../../tests/AAuth.Conformance/HttpSignatures/CapabilitiesHeaderTests.cs), client callback/capability tests | +| [Scopes L2034](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2034), identity scopes and account L2051 | Scope validation and [AccountBinding](../../../src/AAuth/Tokens/AccountBinding.cs) | Implemented: [ScopeVocabularyTests](../../../tests/AAuth.Conformance/ResourceTokens/ScopeVocabularyTests.cs), [AccountBindingTests](../../../tests/AAuth.Tests/Tokens/AccountBindingTests.cs), two-account Bookings/Events browsers | +| [Requirement responses L2061](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2061), code format L2124 and relay L2144 | Header parsers, [BrowserConsentSessions](../../../src/AAuth/Server/BrowserConsentSessions.cs) | Implemented: [InteractionCodeTests](../../../tests/AAuth.Tests/Headers/InteractionCodeTests.cs), [BrowserConsentSessionTests](../../../tests/AAuth.Tests/Server/BrowserConsentSessionTests.cs); code is not an approval credential | +| [Deferred responses L2206](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2206), GET/pending/terminal state L2258 | [DeferredState](../../../src/AAuth/Server/DeferredState.cs), [DeferredPoller](../../../src/AAuth/Agent/DeferredPoller.cs) | Implemented: [DeferredStateTests](../../../tests/AAuth.Tests/Server/DeferredStateTests.cs), new governance owner/cancel/first-decision/concurrency tests; injected stores need atomic contracts | +| [Error format L2302](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2302), error controls behavior, detail only | [AAuthProblemDetails](../../../src/AAuth/Server/AAuthProblemDetails.cs), typed clients | Implemented: [AAuthProblemDetailsTests](../../../tests/AAuth.Tests/Server/AAuthProblemDetailsTests.cs), [TokenErrorTests](../../../tests/AAuth.Conformance/Errors/TokenErrorTests.cs); no stale-error production rewrite performed in Phase 12 | +| [Polling errors L2336](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2336), slow_down and Retry-After | DeferredPoller / DeferredExchange | Implemented: [PollingErrorTests](../../../tests/AAuth.Conformance/Errors/PollingErrorTests.cs), [DeferredPollerTests](../../../tests/AAuth.Tests/Agent/DeferredPollerTests.cs), AccessServerClientTests mixed claims/clarification/new interactions; payment settlement remains external | +| [Revocation L2359](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2359), issuer-qualified identity/cascade/trusted revoker | [RevocationEndpoint](../../../src/AAuth/Server/RevocationEndpoint.cs), [RevocationClient](../../../src/AAuth/Server/RevocationClient.cs), IJtiStore | Implemented: [JtiStoreAndRevocationTests](../../../tests/AAuth.Conformance/Discovery/JtiStoreAndRevocationTests.cs), [RevocationLifecycleTests](../../../tests/AAuth.Conformance/Discovery/RevocationLifecycleTests.cs), both Wallet browser flows. Production persistence and cascade retry scheduling are Policy | +| [Algorithms/carriers L2403](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2403), jwt for AAuth L2418 | Crypto factories and verification policy | Implemented Ed25519/ES256 and six generic carriers; negative polymorphic/private/symmetric/unknown tests in [SignatureV10AdversarialTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10AdversarialTests.cs) | +| [Covered components L2434](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2434), created/alg/keyid L2461 | Signer/verifier and structured fields | Implemented: [CoveredComponentsTests](../../../tests/AAuth.Conformance/HttpSignatures/CoveredComponentsTests.cs), [SignatureV10WireTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10WireTests.cs); content-digest only where required, no universal invented mandate | +| [Verification/status L2471](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2471), unsupported negotiation and no signature headers on 403 | Verification middleware and typed errors | Implemented: [SignatureErrorTests](../../../tests/AAuth.Conformance/Errors/SignatureErrorTests.cs), [VerificationMiddlewareTests](../../../tests/AAuth.Conformance/HttpSignatures/VerificationMiddlewareTests.cs), new governance 403 assertions | +| [Freshness/replay L2503](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2503), honor expires, no nonce mechanism | Signer/verifier and short-lived signature replay store | Implemented: [ReplayDetectionMiddlewareTests](../../../tests/AAuth.Conformance/HttpSignatures/ReplayDetectionMiddlewareTests.cs), wire/adversarial tests. Wallet idempotent retries wait for a new created second; no nonce extension remains | +| [Discovery/cache L2509](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2509), identifiers/URLs L2523 | [Discovery](../../../src/AAuth/Discovery/), ServerId/AAuthUrl | Implemented: [IssuerDiscoverySecurityTests](../../../tests/AAuth.Tests/Discovery/IssuerDiscoverySecurityTests.cs), [DiscoveryCacheSecurityTests](../../../tests/AAuth.Tests/Discovery/DiscoveryCacheSecurityTests.cs), [EgressTransportTests](../../../tests/AAuth.Tests/Discovery/EgressTransportTests.cs) | +| [Metadata L2564](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2564), AP/PS/AS/resource fields | [Metadata endpoints](../../../src/AAuth/Server/Metadata/), MetadataClient | Implemented: [AllRolesWellKnownMetadataTests](../../../tests/AAuth.Conformance/Discovery/AllRolesWellKnownMetadataTests.cs), [ResourceAccessModeMetadataTests](../../../tests/AAuth.Conformance/Discovery/ResourceAccessModeMetadataTests.cs); issuer_missing/mismatch distinguished | +| [Security L2809](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2809), PoP/token/pending/input/approval/person binding | Verification, consent, egress and sample policies above | Implemented tested mechanics; Policy for secure key storage, authenticated user directory, deployment isolation, retention and monitoring. [KeycloakDiagnosticSecurityTests](../../../tests/AAuth.Tests/Integration/KeycloakDiagnosticSecurityTests.cs) prove IdP bodies are not leaked; [ActivityDiagnosticsTests](../../../tests/AAuth.Conformance/Observability/ActivityDiagnosticsTests.cs) excludes token material | +| [TLS L2892](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2892), audit after rotation L2896, privacy L2908 | Production egress defaults, explicit SampleEgress, typed audit stores | Policy: samples use admitted loopback HTTP only; production TLS, key custody, archival keys, privacy/retention and external interoperability require operator validation. No resource/AS mission body fetch path is added | +| [IANA L2924](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2924), history/rationale | Constants and metadata values | Inapplicable registration/expert procedures; wire constants tested. Historical/non-normative examples do not override active requirements | + +## Final Authorization Repair Evidence + +These focused regressions supplement the protocol rows; they do not mark the +independent Phase 14 review complete. + +### Remaining Credential and Reference Repairs + +The 2637-test checkpoint below is historical. The remaining repairs pass 2859 +Release tests, 96 snippet/source-semantic checks, 71 full stub browsers plus +one live-only skip, and 72 full live browsers, retries=0. Fresh independent +review remains pending; no Phase 14/15 closure is implied. + +| Canonical requirement | Repair and disposition | +|---|---| +| [Protocol L2316](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2316), #token-endpoint-error-codes | Implemented: [TokenRequestBody](../../../src/AAuth/Server/TokenRequestBody.cs#L12) uses strict duplicate-rejecting JSON/JWT structural reads for initial, pending replacement and claims paths. [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs#L61) and [R3 endpoint tests](../../../tests/AAuth.R3.Tests/AccessEndpointR3Tests.cs#L47) cover credential shapes, missing claims, base64, signatures and expired parent/child/upstream context before policy/audit/document fetch. | +| [Protocol L2298](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2298), #error-responses | Implemented: [TokenFailure](../../../src/AAuth/Server/AAuthProblemDetails.cs#L9) preserves typed 400 token errors; expired agent/resource codes are distinct, upstream failures retain invalid_upstream_token, and genuine carrier failure remains 401 with Signature-Error. | +| [Protocol L614](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L614), Agent Token Verification; [L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517), #jwks-discovery | Resolved documentation: [signing-mode matrix](../../../docs/signing-modes/overview.md#L103) shows cached issuer JWKS discovery and separates embedded cnf.jwk from issuer verification. | +| [Protocol L2734](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2734), Resource Metadata | Resolved documentation: [configuration](../../../docs/reference/configuration.md#L203) and [DI](../../../docs/reference/dependency-injection.md#L361) distinguish nullable metadata keys and conditional issuance/signing requirements. [Whole-table checks](../../../tests/AAuth.Tests/Api/DocumentationApiExcerpts.cs#L66) validate source names, types and nullability across both reference pages. | + +### Final Focused Input and State Repairs + +Final implementation checkpoint: 2637 Release tests and a clean Release build; +93 snippet/source-semantic cases; 71 full stub browser passes plus one live-only +skip, and 72 full live Keycloak passes, retries=0. Host-only sample identities, +explicit development issuer mappings and both real worker scenarios are included. +Earlier failed reports, including an unattributed live clarification timeout, +remain in the append-only log. Independent Phase 14 review remains pending. + +| Source and disposition | Repair and executable evidence | +|---|---| +| [Signature Keys invalid_jwt L2086](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2086), section 5.4.11 | Local strict policy rejects all duplicate raw JWT names, including equal values and nested objects/arrays. `DuplicateRawMembersRejectBeforeDiscovery` independently signs raw compact input; direct/JWKS verification, naming/carrier parsing and HTTP middleware return typed invalid_jwt with zero discovery calls or trusted context. | +| [Agent identifiers L546](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L546), #agent-identifiers; [server identifiers L2529](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2529), #server-identifiers | `InvalidActorDomainsRejectAtEveryDepth` and `ActorDomainsUseExplicitPolicyWithoutSameProviderRequirement` cover immediate/nested actors, URI suffixes, blank/Unicode domains, ACE and distinct APs. HTTP/HTTPS development origins never admit actor ports. Builder, reader, token verifier and issuance/response contexts use the same explicit policy. | +| SDK source/refresh lifetime and binding contract, not a new normative wire requirement | `RefreshPipelinePreservesCurrentToken` covers eight fixed/factory and challenge/no-challenge cases; `CancellationDuringRefreshDoesNotPublishToken` rejects post-cancellation publication. `CachedCarrierTracksRefreshedSourceAndRequestBindings` checks source, key, account and mission cache isolation. | +| [R3 proposal parameters L562](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L562), #proposal-document | Explicit null is a concrete inline JSON value, distinct from missing parameter, null container and digest representation. `ExplicitNullParameterRoundTripsAndBindsExactRetry` and `TokenEndpoint_ProposalParametersRequireObject` prove policy receives null, deferred minting works, and exact retry rejects missing/non-null/digest substitutions. Duplicate object names reject before node materialization. | +| Optional provisioning boundary | `BootstrapEnrollmentHasConcreteKeyBoundaryButEnrolledRefreshDoesNot` records the existing concrete Ed25519 bootstrap convenience limit. Actual AP ES256 enrollment/publication remains covered by `ActualAgentProviderPublishesEnrolledEs256KeyAfterRestart`; no broad fluent ES256 enrollment claim is made. | + +| Requirement | Repair and executable evidence | +|---|---| +| [Resource verification L859](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L859) | Initial and replacement AS resource tokens bind approver to the authenticated PS; collapsed/local PS verification also supplies its issuer. MissionApproverMustBeAuthenticatedPs and CollapsedPersonServerRejectsForeignApproverBeforeConsent reject before policy | +| [Mission approval L1416](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1416), [chaining L1788](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1788) | ValidateMissionAsync rejects unknown/foreign-owner/foreign-approver records before policy or resource interaction, retaining verified parent and upstream delegation. Clarification_UpstreamMissionCannotBeStrippedOrChanged preserves original state and termination checks | +| [Parent consent L1827](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1827) | Mission_ParentConsentIdentitySurvivesClarification preserves consenting parent identity while worker agent/cnf remain bound to the worker | +| [Revocation L2390](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2390) | ThreeGenerationsRevokeAndNotifyAllLocalDescendants checks actual descendant rejection/notifications; TrackedIssuanceTests rejects cycles and concurrent extension of revoked ancestry. Local guarantees only; arbitrary stores and remote retry scheduling remain host contracts | +| [Privacy L2695](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2695) | UnstructuredErrorsDoNotEnterExceptionDiagnostics and UnstructuredFederationErrorsNeverReachPersonLogs reject sentinel tokens, PII and forged log lines in exceptions and captured PS warnings | + +## Signature Keys + +| Requirement / canonical area | Owning code | Tests and disposition | +|---|---|---| +| [Section 3 L341](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L341), structured dictionary, labels/multiple signatures L430/L437 | [SignatureKeyHeader](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs), [SignatureKeyParser](../../../src/AAuth/HttpSig/SignatureKeyParser.cs), verifier | Implemented using StructuredFieldValues; [SignatureV10WireTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10WireTests.cs), [SignatureV10AdversarialTests](../../../tests/AAuth.Tests/HttpSig/SignatureV10AdversarialTests.cs) cover selected labels, escaping/types and malformed fields | +| [3.3 L462](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L462), alg/key consistency, public-only and unsupported distinction | [Crypto](../../../src/AAuth/Crypto/) | Implemented Ed25519 and ES256; [EcdsaKeyTests](../../../tests/AAuth.Conformance/HttpSignatures/EcdsaKeyTests.cs), adversarial key matrix. Other algorithms are unsupported, not silently substituted | +| [3.4 hwk L630](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L630) | HWK header/provider/parser | Implemented standard JWK members; [SignatureKeySchemesTests](../../../tests/AAuth.Conformance/HttpSignatures/SignatureKeySchemesTests.cs), wire vectors; legacy embedded-jwk shape rejected | +| [3.5 jkt-jwt L705](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L705), validation L891 | Naming JWT validation and key binding | Implemented: [NamingJwtValidationTests](../../../tests/AAuth.Conformance/HttpSignatures/NamingJwtValidationTests.cs), [JktJwtAndEcdsaTests](../../../tests/AAuth.Conformance/HttpSignatures/JktJwtAndEcdsaTests.cs); iat/exp/type/header-key/thumbprint/ephemeral binding | +| [3.6 jwks_uri L957](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L957), exact issuer and metadata discovery | Resolver, MetadataClient/JwksClient | Implemented id/dwk/kid; wire tests, missing/mismatched issuer, egress/cache tests; not a direct key URL alias | +| [3.7 jwks L1021](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1021) | Direct JWKS provider/resolver | Implemented url/kid; direct Profile browser plus wire tests; generic identity, not an AAuth mode | +| [3.8 jwt L1091](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1091), validation L1160 | DefaultSignatureKeyResolver, registered token verifiers | Implemented admitted key resolution plus explicit token-type validation; forged issuer with valid PoP rejected; unknown typ fails closed | +| [3.9 self-jwt L1222](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1222), absent cnf L1307 and same key | Shared resolver and Events verifier | Implemented: wire tests and [EventHttpTests](../../../tests/AAuth.Events.Tests/EventHttpTests.cs); real Events delivery in both apps | +| [3.10 x509 L1370](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1370), [3.11 cached L1429](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1429) | Unsupported scheme dispatch | Optional unsupported per Q1. No certificate-chain, revocation-cache or cached-assertion implementation claimed | +| Accept-Signature negotiation / Signature-Error (sections 4-5) | [SignatureError](../../../src/AAuth/Errors/SignatureError.cs), middleware | Implemented: [SignatureErrorTests](../../../tests/AAuth.Conformance/Errors/SignatureErrorTests.cs); AAuth 401 vs generic policy distinguished, 403 has no authentication negotiation | +| Signature-Key-Cache (section 6) | No cache-carrier feature | Optional unsupported with cached scheme; mandatory ordinary metadata/JWKS caching remains implemented separately | +| [7.1 key validation L2257](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2257), [7.2 caching L2283](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2283) | Crypto and discovery caches | Implemented key/public-material checks and bounded synchronized fetch floor; discovery and crypto tests | +| [7.3 risks L2327](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2327), egress, redirects, DNS and actual connection | AAuthEgressPolicy/AAuthHttpTransport | Implemented for SDK transport: EgressTransportTests real socket/private/redirect/mixed-DNS/oversize/timeout checks. Injected transport obligations are Policy | +| [7.4 algorithms L2425](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2425), [7.5 symmetric prohibition L2485](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2485) | KeyFactory and verifier algorithm admission | Implemented negative matrix; optional post-quantum algorithms not advertised | +| [7.6 cache identity L2504](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2504), [7.7 sizes L2581](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2581), [7.8 integrity L2603](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2603) | Bounded parsing/HTTP; required signature-key coverage | Implemented required coverage; cached/PQ-specific requirements Optional unsupported; host proxy/header-size configuration is Policy | +| Privacy, registry and expert procedures | Public key identity and deployment policy | Policy for correlation/privacy; Inapplicable registry administration. No universal anonymity claim | + +## R3 + +| Requirement / canonical area | Owning code | Tests and disposition | +|---|---|---| +| [Metadata L93](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L93), identifier scope L109 | [R3Metadata](../../../src/AAuth.R3/R3Metadata.cs) | Implemented: [R3VocabularyTests](../../../tests/AAuth.R3.Tests/R3VocabularyTests.cs), actual Catalog gateway definitions and sibling-service rejection browsers | +| [Eight vocabularies L115](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L115), MCP L121/OpenAPI L139/gateway L157/gRPC L194/GraphQL L212/AsyncAPI L231/WSDL L250/OData L268 | [R3Operation](../../../src/AAuth.R3/Model/R3Operation.cs), [R3VocabularySchemas](../../../src/AAuth.R3/Model/R3VocabularySchemas.cs), [R3OperationIdentity](../../../src/AAuth.R3/Model/R3OperationIdentity.cs) | Implemented typed shape/qualifier/directional subset semantics: all-vocabulary roundtrips, malformed identifiers, qualifier-preserving conditional retries and OData method narrowing. Native protocol hosting/discovery is a host responsibility; sample integrations are OpenAPI/gateway/AsyncAPI | +| [Authorization L287](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L287), operations spanning definitions L333 | R3Operations, R3Request, R3Metadata | Implemented: [AgentR3RequestTests](../../../tests/AAuth.R3.Tests/AgentR3RequestTests.cs), vocabulary collision and metadata tests | +| [Document L346](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L346), fields/account L370, content addressing L389 | R3Document/R3Hash/proposal store | Implemented exact bytes: [R3HashTests](../../../tests/AAuth.R3.Tests/R3HashTests.cs), [R3ModelTests](../../../tests/AAuth.R3.Tests/R3ModelTests.cs), stored-buffer isolation | +| [Resource token extensions L400](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L400), pointer/hash/account/agent | R3Challenge and token verification | Implemented: [TokenClaimTests](../../../tests/AAuth.R3.Tests/TokenClaimTests.cs), [ResourceR3Tests](../../../tests/AAuth.R3.Tests/ResourceR3Tests.cs) | +| [Processing L444](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L444), AS fetch/audit L453, cache L464 | R3FetchClient, R3AccessTokenEndpoint | Implemented hash/issuer/admission checks and audit-before-release; [AccessEndpointR3Tests](../../../tests/AAuth.R3.Tests/AccessEndpointR3Tests.cs). PS-reader permission is Ambiguous Q4, explicitly configured, not generic issuer trust | +| [Auth extensions L469](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L469), granted/conditional narrowing | R3Grant/claim reader/AS validation | Implemented: TokenClaimTests, AccessEndpointR3Tests; empty grants valid but empty requests rejected | +| [Enforcement L538](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L538), per-call proposals L550 | [R3Enforcement](../../../src/AAuth.R3/R3Enforcement.cs), proposal store | Implemented: ResourceR3Tests, R3VocabularyTests; wrong service/vocabulary/parameters/hash/account and missing vs empty parameters rejected | +| [Sensitive payloads L592](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L592) | R3Parameter/R3PresentedParameters | Implemented digest and exact byte checks, excerpt/display does not authorize content; caller data minimization is Policy | +| [Reader restriction L600](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L600), endpoint access L606, hashes L610 | R3DocumentReaderPolicy/R3DocumentEndpoint | Implemented verified designated-AS role plus explicit Q4 PS evaluation role; forged role/key tests. Ambiguous source readership statements remain logged | +| [Audit L614](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L614), authoritative operations L618, grants L622 | AS audit sink; resource R3Metadata/enforcement | Implemented sample SQLite write-before-release and resource authority: [R3SqliteAuditTests](../../../tests/AAuth.R3.Tests/R3SqliteAuditTests.cs), [BookingsPolicyTests](../../../tests/AAuth.R3.Tests/BookingsPolicyTests.cs). Injected durable stores and native definitions remain Policy | +| [IANA L626](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L626), experts/history/rationale | Vocabulary constants | Inapplicable registration/expert procedures; codec namespace validation tested | + +## Events + +| Requirement / canonical area | Owning code | Tests and disposition | +|---|---|---| +| [AP metadata L196](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L196), optional event endpoint | [EventsProtocol](../../../src/AAuth.Events/EventsProtocol.cs), MockAgentProvider | Implemented discovery; no endpoint means Events unsupported at that AP. Events browser discovery assertions | +| [Subscribe structure L212](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L212), required claims, alg, audience, expiry and positive max_uses | SubscribeTokenBuilder / EventsTokens | Implemented: [SubscribeTokenTests](../../../tests/AAuth.Events.Tests/SubscribeTokenTests.cs), [EventsTokenTests](../../../tests/AAuth.Events.Tests/EventsTokenTests.cs), malformed/foreign issuer/subject/key cases | +| [Presentation L254](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L254), verification L275 and context L288 | EventsProtocol/EventsSignatureTokenVerifier/receiver | Implemented jwt subscribe carrier and authenticated context; [EventHttpTests](../../../tests/AAuth.Events.Tests/EventHttpTests.cs), both public/protected browser flows | +| [Public registration L294](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L294), protected tickets L298 | BookingsEvents/SqliteEventStore | Implemented owner/key/account-bound registration, consume-once tickets, idempotent registration: EventHttpTests and [EventPersistenceTests](../../../tests/AAuth.Events.Tests/EventPersistenceTests.cs) | +| [Event structure L349](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L349), absent cnf L368 and no event-specific claims | EventTokenBuilder/EventsTokens | Implemented self-jwt structure/alg/aud/eid/expiry and payload separation: EventsTokenTests/EventHttpTests | +| [Delivery L385](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L385), same signer and body integrity | EventsProtocol / AP delivery endpoint | Implemented actual signed HTTP and raw body forwarding; malformed/signature/issuer failures tested. Ambiguous Q5 privacy wording is not used to invent a payload wrapper | +| [AP validation L411](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L411), atomic quota L421 and durable-before-202 L424 | Events endpoints and configured SqliteEventStore | Implemented for sample backend: EventHttpTests/EventPersistenceTests, competing quota, failed write, restart, receipt retry, unknown/expired eid and wrong aud/resource | +| [Remaining uses L424](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L424), unlimited subscription response | Same AP/store | Implemented bounded integer or empty unlimited response; quota is not inferred from token expiry alone | +| [AP-to-agent L439](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L439), final verification L445 and deduplication L454 | EventReceiver and durable context/receipt store | Implemented agent issuer/audience/expiry/context checks and issuer/eid deduplication. AP transport is Policy: sample uses authenticated bounded polling/ack, not standardized push | +| [Discovery L458](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L458), AsyncAPI security L491 | BookingsEvents AsyncAPI document | Implemented actual document and aauth-subscribe scheme; both app specs inspect it | +| [Security L583](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L583), replay/tickets/intermediary/enumeration | Events verifier, stores and AP enrollment ownership | Implemented sample protections: [EnrollmentHttpTests](../../../tests/AAuth.Events.Tests/EnrollmentHttpTests.cs), EventHttpTests/EventPersistenceTests. TLS/key custody/storage ACL/rate policy are deployment responsibilities | +| [Privacy L617](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L617), content L623 | Namespace assignment and raw payload delivery | Ambiguous recurring eid/dedup semantics: sample is single-shot, literal dedup; no new per-event jti. Payload minimization is resource policy, AP is not confidential from payload by design | +| [IANA L627](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L627), history and non-normative delivery examples | Token/vocabulary constants | Inapplicable registry administration and platform examples; no cloud/mobile delivery claim | + +## Injected Contracts And Review Limits + +- IMissionStore/IMissionLog/IDeferredConsentStore are development in-memory + defaults. Production stores must preserve owner context, exact mission bytes, + monotonic decisions/termination, shared atomicity and terminal retention. + DeferredState serializes a shared in-process entry; it cannot serialize two + independent objects loaded by a custom distributed provider. That provider + must supply transactional compare-and-set behavior and equivalent retention. +- Events acceptance requires durable event+quota+receipt state before 202. The + configured SQLite provider has restart/concurrency/failure tests. Arbitrary + implementations of the interfaces are not certified by those tests. +- R3 audit sinks must commit before release. Sample SQLite tests cover actual + persistence; a callback returning success before a durable write violates its + contract even though the SDK cannot inspect its implementation. +- Injected HttpClient/HttpMessageHandler and R3 fetch callbacks explicitly declare + their transport contract. AttachPolicy is not a socket sandbox. Production + callers must enforce URL, DNS, connected-address, redirect, timeout and size + admission; InProcessOnly is a test contract, not a production bypass. +- Policy callbacks must use authenticated principal context and correct directed + identifiers. The SDK cannot prove a tenant directory, account mapping or human + identity assertion supplied by a host. Stub consent is isolated demo behavior; + Keycloak mode must never use stub approve/deny as an authorization fallback. +- The reusable governance mapper and sample PS reject unknown/foreign mission + actions and recheck mission status before deferred delivery. Concierge pending + entries now require the exact verified upstream grant, retain terminal state, + expire with that grant and serialize delivery/cancellation. Six signed-host + cases in [ConciergePendingSecurityTests](../../../tests/AAuth.Tests/Integration/ConciergePendingSecurityTests.cs) + reject foreign agent/key/grant GET and DELETE, then prove owner cancellation + and terminal replay. The new direct-AS route creates no intermediary pending entry. +- Live external HTTPS interop and production storage deployments are not covered + by local browser/tests. Optional X.509/cached, third-party login hosting and + native platform transports remain explicitly unsupported or application-owned. + +## Verification + +### Phase 13 local interop and documentation + +The five informational interop surfaces run locally through the existing +sample/test harness; they are not five external interoperability passes: + +| Surface | Executed local evidence | External disposition | +|---|---|---| +| S1 mission approval and exact blob hash | GovernanceClientTests approval/header/body/PS binding and S256 mismatch; both mission browsers | Not exercised against an external PS | +| S2 signed mission presentation and challenge echo | MissionHeaderSeamTests, MissionSignedComponentTests, MissionReferenceValidationTests; both mission/call-chain browsers | Not exercised externally | +| S3 resource issuance and issuer discovery | ResourceTokenStructureTests, ResourceTokenVerificationTests, AllRolesWellKnownMetadataTests; captured resource challenges in both apps | External whoami responded with its live person-token requirement, not the pinned auth-token challenge | +| S4 auth issuance, audience and proof binding | AuthTokenVerificationTests, AuthTokenDeliveryTests, both stub/live federated and mission browser flows | LiveWhoAmITest full authorization returned 401 person_token_required; incomplete | +| S5 distinct-key four-party parent/worker | FederatedWorkerScenario in both sub-agent browser specs, including parent-key rejection and child/act assertions; PS/AS endpoint regressions | Not exercised externally | + +LiveWhoAmITest reached whoami through its normal public metadata tunnel. +Unsigned 401 and agent-JWT identity 200 were observed; full external authorization +was not established. Its zero process exit did not override the 401 wire result. +No person consent was approved and no legacy person-token compatibility was added. + +The current [docs surface map](docs-surface-map.md) records exact file/block +hashes, validation classes and source/test links. It supersedes the earlier +representative 21-template limit for documentation inventory, without relabeling +external/platform templates or dynamic displays as compiled signed requests. +That Phase 13 checkpoint recorded 196 files, +761/-149 declarations and zero +unmapped files. It is historical, not the current Phase 14 API count: the review +repairs change challenge verification dependencies and sample instructional +surfaces. The generated API/docs maps and current repair checkpoint below govern +the updated worktree; freshness must be checked after the final edits. + +### Phase 14 focused review repair checkpoint + +Resource challenge verification now precedes exchange and binds the original +origin, presented token, signing key, account and mission. The 70-test focused +challenge gate passes, including invalid-signature/cross-origin rejection without +PS calls or consent, mutable-holder isolation, routing and Calendar consent. +Canonical challenge ordering: [L868](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L868). + +R3 AS issuance now checks mission approver against the authenticated PS and +validates upstream mission retention before document/policy/audit work. Verified +mission survives immediate and deferred AS delivery through the real PS federation +client. The endpoint suite passes 94/94. The actual AP endpoint publishes ES256 +correctly before and after registry restart; enrollment suite passes 11/11. + +Four documentation checks cover constructor tables, actual signing-key selection, +mandatory recipient context and generic routes; ten exact Documents/Events step +templates compile. Both shared browser helpers cover step/diagram/snippet +association and full reset/reexecution. The repaired Release gate passes 2234 +tests (1059 core, 878 conformance, 222 R3, 75 Events), with zero failures/skips. +Release and make builds have zero warnings/errors. Fresh stub browsers pass +71 with the existing live-only skip; fresh live Keycloak passes all 72, with +zero retries, failures or flaky results in either mode. Desktop/mobile captures +cover both apps, diagrams and associated snippets. Current API inventory is +198 files, +790/-152 declarations and zero unmapped; docs inventory is 169 files, +629 blocks, including 272 exact C# blocks. Final non-writing freshness checks +are recorded in the implementation log. Phases 14 and 15 remain open for fresh +independent review; local Keycloak does not establish external interop. + +### Phase 14 final mandatory-claim and PS-role repair coverage + +The append-only implementation log records the final confirmed-review repair +matrix and exact profile assumptions. Independently signed malformed JWTs cover +the required agent/resource/auth claims at direct verification and JWKS entry +points, with matching agent/auth middleware cases before trusted context. The +central checker covers typed values, optional PS/parent identifiers, nested +mission/actor fields, NumericDate bounds and auth lifetime. Required absence and +explicit null both fail. Generic JWT iat/jti presence stays optional and the +registered verifier hook is exercised, not bypassed by a builder-only assertion. + +Core AS token/pending gates now require the verified person-server metadata role +before issuer trust or access policy. Distinct/shared collocated role keys and +wrong-key PS-role spoofing are covered across issuance, poll and claims push, +including no policy side effects and legitimate recovery. Direct agent-JWT +chaining remains covered separately. Named provider parameters are compiled; +mission-recipient XML and Profile generic-admission comments are source-checked. +The 2234/198/629 checkpoint above is historical. Final verified checkpoint: + +| Gate | Final Result | +|---|---| +| Release solution build | Zero warnings/errors | +| Release solution tests | 2596 passed: 1421 core, 878 conformance, 222 R3, 75 Events; zero failures/skips; +362 from 2234 | +| Full fresh stub browsers | 71 passed, one existing live-only skip; zero retries/unexpected/flaky | +| Full fresh live Keycloak browsers | 72 passed: 40 tour, 32 app; zero skips/retries/unexpected/flaky | +| Snippets and source semantics | 92 passed; named constructor arguments and recipient/Profile guidance checked | +| API inventory | 198 changed public-source files; +790/-152 declarations; zero unmapped; non-writing freshness passes | +| Documentation inventory | 169 files, 629 blocks, 272 exact C# compilations; final non-writing freshness passes | +| Browser TypeScript and scoped whitespace | Pass | + +The latest reports and reproducible runner use the prefix +/tmp/aauth-phase14-final-remaining-; tests.log, final-trx/, stub.json and +live.json contain the authoritative final counts. The implementation log retains +failed runs, fixture repairs and spec/profile decisions. Independent review and +Phase 15 remain pending; local Keycloak is not external AAuth interoperability. + +### Phase 12 adversarial repair evidence + +The eight owner-supplied findings were independently checked in the current +worktree. Findings 1-3 already contained production repairs; mapped-route tests +now include unauthenticated/foreign GET and DELETE, changed ownership, terminated +permission delivery without log append, and terminal PS interaction denial. +[GovernancePendingSignatureTests](../../../tests/AAuth.Conformance/Missions/GovernancePendingSignatureTests.cs) +adds eight actual signed HTTP cases, not injected verification features. + +The mission approval and lifecycle rows now include +[GovernanceClientTests](../../../tests/AAuth.Conformance/Missions/GovernanceClientTests.cs) +and [GovernanceFacadeTests](../../../tests/AAuth.Conformance/Missions/GovernanceFacadeTests.cs): +header/body/bound-PS agreement, missing approver rejection, exact bytes, completion, +terminal errors/callbacks and no further pre-approved or network actions. +References: #mission-approval L1430 and #mission-status-errors L1469. + +The deferred/polling rows now include +[DeferredExchangeTests](../../../tests/AAuth.Tests/Agent/DeferredExchangeTests.cs) +and [DeferredTimingTests](../../../tests/AAuth.Tests/Agent/DeferredTimingTests.cs): +approval without a user callback, bare 202, changed interaction URL/code, initial +Retry-After delta/date, persistent five-second linear backoff, default/past dates, +503, bounded timeout and cancellation. The new timing tests use injected clock +and delay, not sleeps. References: approval L2202 and polling L2262. + +Live revocation recovery is no longer inferred from stub coverage: the retained +callback trace exposed an invisible completion title, repaired with encoded +visible outcome text. Both apps' focused live recovery cases pass with fresh +settings and zero retries in /tmp/aauth-phase12-repairs-keycloak.json. Original +failures, HTTP regressions and final full-suite gates are retained in the +append-only implementation log. Catalog and parent/worker attribution are unchanged. + +### Historical Phase 12 gates + +Final repair gate: 2069/2069 Release tests (965 core, 827 conformance, 206 R3, +71 Events), zero failures/skips; Release build zero warnings/errors; 21 exact +snippet templates; TypeScript typecheck and scoped whitespace check pass. +All 68 live-Keycloak browser cases pass (38 tour, 30 app) with zero skips; +stub mode passes 67 with the one existing live-only skip. Both full suites use +fresh services, isolated settings, retries=0 and retained traces, with zero +unexpected/flaky results. Final reports are +/tmp/aauth-phase12-repairs-live-final.json and +/tmp/aauth-phase12-repairs-stub-final.json. Original failed/interrupted reports +remain recorded in the implementation log; none are silently replaced as passes. + +The eight supplied findings and live callback/recovery gate have no remaining +open in-scope finding. The clarification POST/DELETE path preserves terminal +mission errors, and virtual timers prove non-cooperative callback/request bounds. +Catalog and parent/worker scenarios pass in both final full suites. These results +do not certify arbitrary injected stores/policies or remove the deployment and +optional-feature dispositions above. Phase 13/14 remain separate gates. + +Initial full Release run was blocked by a duplicate solution project registration; +the duplicate was removed and the repeated suite passed 2005 tests, zero failures +or skips (928 core, 800 conformance, 206 R3, 71 Events). Four exact new snippet +cases bring template coverage from 17 to 21. Seven activity tests verify no token +material in diagnostics. Two IdP error-body tests reproduced disclosure and pass +after removing response bodies; real consent HTML encoding also passes. + +These are intermediate executed results. Final full Release/build, both browser +projects, live Keycloak, catalog lifecycle and ledger checks are recorded in the +final implementation-log entry. Phase 13 remains open. No vendor bytes, branch +or commits were changed by this phase. \ No newline at end of file diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/docs-surface-map.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/docs-surface-map.md new file mode 100644 index 00000000..5d4386d2 --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/docs-surface-map.md @@ -0,0 +1,960 @@ +--- +description: Exhaustive active documentation and primary-app display inventory with exact validation classifications. +--- + +# Documentation Surface Map + +Phase 13 inventories root/package/sample Markdown, every docs family, both +primary apps' C# and Razor source, shared CapabilitySupport/EventSupport displays, +and both app-local Playwright suites. Historical snapshots/plans are not rewritten. +The companion [capability map](capability-scenarios.md) identifies each runnable +flow, resource purpose, shared browser wrapper and meaningful negative assertion. +The [API map](api-surface-map.md) and [conformance ledger](conformance-ledger.md) +remain the source-to-behavior references, not substitutes for snippet validation. + +## Validation Classes + +Each discovered block below has its own source location, content hash and result. +Exact C# compilation uses the existing Roslyn `SnippetCompilationTests` harness. +Its typed context supplies prior-step variables and explicitly application-owned +callbacks, not substitute SDK types or compatibility APIs. Compilation does not +execute network requests. API excerpts check declared SDK member names, method +parameter/return types, property types and sealed modifiers against source; they +are not counted as compiled programs or a complete public API listing. + +Five external integration templates remain intentionally illustrative: Azure +Secrets storage, OpenTelemetry registration, and three platform-adapter examples. +Their syntax is checked; their external packages, hardware and platform ceremony +are not executed. Platform attestation is not claimed as a sample implementation. +Endpoint names, opaque tokens, signatures, local +handles and deployment configuration values shown as placeholders are not usable +credentials. JSON fragments parse with explicit enclosing-object context. + +Dynamic Razor displays are bindings to runtime capture/results, not static +templates. The listed browser wrappers check their actual scenario outputs; +crypto/endpoint tests establish validation of token bytes, not the highlighter. +SQL literals belong to the sample persistence implementation and its Events +HTTP/SQLite tests. Shell blocks receive syntax and Make-target checks; provisioning and +external side effects are not run by a documentation test. + +Static HTTP examples parse their displayed JSON bodies and requirement headers; +Location examples must be absolute. Placeholder signature/token bytes cannot +establish cryptographic validity. Comments-only C# blocks are narrative, not +counted as compiled programs. Quoted Markdown fences and standalone inline Razor +code labels are included, with labels counted separately from executable blocks. + +## Findings and Alignment + +- Root/package/getting-started now teach an agent JWT path, with generic HWK + examples retained and explicitly separated from AAuth access modes. +- All tour constants, single-line step assignments, Razor C# displays and shared + Wallet/Catalog/Events templates are inventoried. Fixes include removed builder + APIs, immutable mission inputs, keystore methods and authenticated federation. +- Mission client paths agree with Trips. Permission execution and checks remain + local decisions, not invented HTTP requests. The Concierge poll example retains + exact owner authorization, expiry, atomic delivery/cancel and terminal state. +- Wallet and Catalog guides document actual steps, policy/consent callbacks, + rejection/recovery and resource purpose, and link both apps' existing wrappers. +- The Document Release guide and resource README cover the real resource-first + permission flow, browser callback boundary, PS consent and signed download. + Both new app pages and shared session are included in the generated inventory; + the capability map links their success/denial browser assertions. +- Token workflow text distinguishes empty JSON refresh bodies, absolute pending + URLs, verified issuance ceilings, account binding and directed identities. +- Source snapshots are immutable. Phase 0's missing pre-edit baseline remains a + historical evidence gap; Phases 14 and 15 remain independent open gates. + +## Reproduction + +Context-aware final repair checkpoint (2026-09-09): overview replay guidance +separates per-request freshness, optional signature replay caching for all +schemes, and issuer+jti revocation. Configuration, DI, resource-metadata examples +and source XML distinguish the resource proactive endpoint from the PS/AS token +recipient. Token-issuance describes IAAuthKey with Ed25519/ES256 support; its +13 PS options rows join the existing 136 source-checked reference rows. +All 102 snippet/source-semantic checks plus the link check pass (103 total). +Inventory remains 169 files/629 blocks, including 272 exact compiled C# blocks. +Full Release passes 2911 tests with zero warnings/errors. Fresh browsers pass +71 stub plus one live-only skip and 72 live, with zero retries, unexpected/flaky +outcomes or global errors. Phase 14/15 and independent review remain open. + +Remaining-repair checkpoint (2026-09-09): Agent Token discovery includes cached +issuer JWKS while `cnf.jwk` remains the embedded confirmation key. Resource key +tables use IAAuthKey, nullable metadata keys, and conditional issuance/signing +requirements. The complete property/constructor-parameter tables in both +reference pages are compared with source names, types and nullability; that +check also found the nullable MetadataClient transport parameter. Its default +cache lifetime is five minutes. All 96 snippet/source-semantic checks pass; +169 files/629 blocks include 272 exact compiled C# blocks. Release passes 2859 +tests; fresh full browsers pass 71 stub plus one live-only skip and 72 live, +with zero retries, unexpected/flaky outcomes or global errors. These are repair +gates, not a fresh independent review or Phase 14/15 closure. + +Final focused repair checkpoint (2026-09-09): getting-started and AP source +documentation distinguish the per-agent JWKS selector from the issuer JWT kid; +DI credential requirements apply only to AddAAuthAgent. Bootstrap documentation +states the concrete Ed25519 convenience limit without excluding algorithm-neutral +single-key refresh. Sample configuration, browser consent mappings, expected +actors and the displayed worker validator use host-only agent identities with +explicit development policy. All 93 snippet/source-semantic cases pass; the +inventory remains 169 files/629 blocks, with 272 exact compiled C# blocks. +Final Release passes 2637 tests. Fresh full browsers pass 71 stub plus one +live-only skip and 72 live Keycloak, with zero retries/unexpected/flaky results. +Earlier failed browser reports remain in the append-only log. Phase 14/15 +are not closed by this implementation checkpoint. + +Phase 14 repair checkpoint: 169 files and 629 blocks, including 272 exact C# +compilation blocks and ten Documents/Events step templates checked independently. +Provider-table constructor declarations also compile; semantic checks require +the naming JWT's ephemeral HTTP key, authenticated PS approver context, generic +Profile routes and explicit DI credentials. Both apps' shared walkthrough helpers +check numbered step/diagram/code association and full reset/reexecution, with +desktop/mobile visual evidence. Fresh full browser gates pass 71 stub plus one +live-only skip and 72 live-Keycloak cases, with zero retries or flaky results. +The generated appendix below reflects the actual repaired sources; Phases 14 and +15 remain open for fresh independent review. + +Run `dotnet test tests/AAuth.Tests -c Release --filter FullyQualifiedName~SnippetCompilationTests`. +`Documentation_FrozenSurface` emits a detailed temporary report. Set +`AAUTH_UPDATE_DOCS_INVENTORY=1` only after successful checks to regenerate the +appendix, then rerun without it to verify freshness. The inventory includes every +file even when it has zero snippets; a file hash detects prose/navigation changes. + + + +## Complete Inventory + +174 files; 638 blocks. Counts by validation class: + +- 33: API excerpt: source member/type/sealed checks; not executable +- 1: C# comment-only narrative: reviewed against the associated scenario; no executable statements +- 39: Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests +- 272: Exact C# compiled with typed prior-step/host inputs +- 1: External template: Azure.Security.KeyVault.Secrets/Azure.Core required; exportable Ed25519 secrets, not HSM signing; syntax checked only. +- 1: External template: OpenTelemetry.Extensions.Hosting and Instrumentation.AspNetCore required; syntax checked, exporter not executed. +- 3: Illustrative platform adapter: IWebAuthnService/DeviceCheck are host placeholders; IPlatformAttestor signature checked separately; no hardware or AP challenge/retry claim. +- 15: Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request +- 167: Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program +- 1: JSON member fragment parsed inside an explicit object +- 4: JSON parsed; displayed identifiers/claims are illustrative +- 28: Sequence/flow source checked; actors/order reviewed against mapped scenario +- 69: Shell syntax checked; side-effect commands not executed +- 4: SQL runtime literal: sample build and Events HTTP/persistence tests + +| File | SHA-256 | Blocks | Check | +|---|---|---|---| +| [docs/advanced/clarification-chat.md](../../../docs/advanced/clarification-chat.md) | `8fb75140b612a8790e319cb4a2a1288b6b83b273361c5882e638bdbdbef8f94b` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/error-handling.md](../../../docs/advanced/error-handling.md) | `7105cf477c01509498d5352f5c0c2f15f020f9ca55036bd6ff367be213d2b930` | 17 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/interaction-chaining.md](../../../docs/advanced/interaction-chaining.md) | `e60329aaeb4a139f2d19e762cfa8c16cd30c4d9dceb915024613fc59f30daea6` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/key-management.md](../../../docs/advanced/key-management.md) | `c8a861597a74b847195ec424751587b7fe4a5d80eb985806192d50d9d1db5f24` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/mission-governance-clients.md](../../../docs/advanced/mission-governance-clients.md) | `af3165c565ebba55edff538d31737ceac1b71c893aff67374c28367d9ac98cc8` | 8 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/missions.md](../../../docs/advanced/missions.md) | `01af762ef8af16119816fba4e8f30330e935d4204604382a90ae8dbfcf5b576b` | 9 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/observability.md](../../../docs/advanced/observability.md) | `1e23c64617024dfe55bcf5e0bf25abf53633e46c5a522058a1556711b85ccdc5` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/advanced/platform-attestation.md](../../../docs/advanced/platform-attestation.md) | `c732fe35312dbece719f4278bbfbf8a1a7c50823332f31e6f2429268768fb9f5` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/concepts.md](../../../docs/concepts.md) | `e227e1ada7ba7ce69067feed83e65badc7e839da44ed435d95fa163ac4a36d6f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/getting-started.md](../../../docs/getting-started.md) | `1f4ed68e0c1cc0a59aa4e38c35c6cccc9372108d1d5bd79f03be6758f0e3bf7b` | 22 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/glossary.md](../../../docs/glossary.md) | `361008535bb199529cce2dfb7ea0f92de68d3a19b1c25f649ce58badb1a3e359` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/README.md](../../../docs/README.md) | `9e70ae701ac1caed7bd1be3798f3ff3e0404c7bc1858b14789f170dd38191796` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/reference/configuration.md](../../../docs/reference/configuration.md) | `bcd99736b81f94a9b0495b8131226c6f634e5990c60096f599cd538b7c907d2a` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/reference/dependency-injection.md](../../../docs/reference/dependency-injection.md) | `fb06b2602f241d85cccf62d2ac487ae632e92cd26422766cabcb401f0b012802` | 21 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/authn-authz.md](../../../docs/server/authn-authz.md) | `5f2ee4a41de421e6f9a34b5a116a20674aada705e2f3ea10e9c68cc20e053ad3` | 9 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/authorization-policies.md](../../../docs/server/authorization-policies.md) | `ae2f6ec9db8ebfac59aa9d50413705e8e3372cbdfa3cc2e8de819364b428982d` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/challenge-middleware.md](../../../docs/server/challenge-middleware.md) | `de74e6a136591432bc0fd6dd1513aec6b910e9f32e2dd885fec1c7cbd8319ecf` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/mission-governance.md](../../../docs/server/mission-governance.md) | `17830cf6d0ec0a8796c33836c4eede3a15ad438f6b8e2264aa35e8f5f2c7444e` | 11 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/multi-scheme-verification.md](../../../docs/server/multi-scheme-verification.md) | `72930aa707c23dd6093f13b5010c624614082b0fc1eb5365eec530eb7d483f36` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/replay-detection.md](../../../docs/server/replay-detection.md) | `d9df5332e730a02db7a96fbaa8196ba1b39fbd5cf31ffeeea63ce5f18a0f0acc` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/resource-metadata.md](../../../docs/server/resource-metadata.md) | `927d55bafc9297fb6ce643d6d4ca6c24bbb657642c806607fe76adff20ef1440` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/token-issuance.md](../../../docs/server/token-issuance.md) | `c5be8c30bc99526fa7a470dfc8bbedb065965c786fdc581f7d51c262fec9746c` | 10 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/server/verification-middleware.md](../../../docs/server/verification-middleware.md) | `01f7c20971d7da923c463677dfd434b7346446b7a941088d66535f990c3105fe` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/signing-modes/agent-identity-jwks-uri.md](../../../docs/signing-modes/agent-identity-jwks-uri.md) | `cc35de406dae7e253292c846ab811e39cb0d588ce95ff2a746baf13199aa6d0b` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/signing-modes/agent-token-jwt.md](../../../docs/signing-modes/agent-token-jwt.md) | `f9faa98a9789e7a01b4c4900d09d41bec8e738db9351517f846d709e69c60749` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/signing-modes/key-rotation-jkt-jwt.md](../../../docs/signing-modes/key-rotation-jkt-jwt.md) | `2b614a442506f64b32df28862e7819b378021c90a21285cff78315f71fca5bb4` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/signing-modes/overview.md](../../../docs/signing-modes/overview.md) | `a57c592b04b26423a9c83ea840a2c62340e13e30f4b1c3a8c4b4962fb1714ddc` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/signing-modes/pseudonymous-hwk.md](../../../docs/signing-modes/pseudonymous-hwk.md) | `fca5591d10ee11a6d71b1e477da728f93f053138fae1d15b81e6cbaa05013a66` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/bootstrap-enrollment.md](../../../docs/workflows/bootstrap-enrollment.md) | `91eaabf3c0cc9985e549bfaa49a3d8422647570c64fcd15dd587105a00713922` | 13 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/call-chaining.md](../../../docs/workflows/call-chaining.md) | `2d27d68cadce792347ab7a2238284b9ce27d37c90a7d8eea5f9c40b26631e7a4` | 15 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/catalog-gateway.md](../../../docs/workflows/catalog-gateway.md) | `c00a9f3fce52700e52d0b72b1f7d04a1e04ad362e019443072454faf0c8def13` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/deferred-consent.md](../../../docs/workflows/deferred-consent.md) | `3243412d5e8456f36c663aa9694fe62d89cf3aeac763a92af84a6200898711de` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/document-release.md](../../../docs/workflows/document-release.md) | `447f40f072d46c108d42f39be0aeb5b935f3c4831e0d25197ae36e19e29429b0` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/events.md](../../../docs/workflows/events.md) | `d2dafcd0232d0598813f86426c19e69c134c369b8e4fcbbb27df1e63b9c430f9` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/federated-access.md](../../../docs/workflows/federated-access.md) | `0fd3290d9b9e83bce461deb281bda333fdab258b448253533d82e451520774a8` | 8 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/identity-based-access.md](../../../docs/workflows/identity-based-access.md) | `00dd710d62f8246947557a21c869f5e12b0ad7751e9ec1df1a19f64f50b45351` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/mission-governed-access.md](../../../docs/workflows/mission-governed-access.md) | `a95d1fdf8b249e713b6c7008a5ed6a9cf2b365862bc87b0b1fc133fc735bdabd` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/ps-asserted-access.md](../../../docs/workflows/ps-asserted-access.md) | `0fccb4466129a83fb6a2244c7f00183039bc1512c4171f1bc96eb093ae7cc812` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/resource-managed-access.md](../../../docs/workflows/resource-managed-access.md) | `40c6e59cc12817568da1da454109676146d3b2560216e364655d868f1f0d976c` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/rich-resource-requests.md](../../../docs/workflows/rich-resource-requests.md) | `26577f38824ddc7b324de8c56f766b58ec50d26b04571231ab943a0f036f5213` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [docs/workflows/wallet-protocol.md](../../../docs/workflows/wallet-protocol.md) | `c484f1e9ec9eeb000fbb0237af7c71bb3bb8a4e7493468ef2982a43c4f0b66ee` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [README.md](../../../README.md) | `8fc35fc29263734bedd5ba3965d59447a237cfffba48a709c5f5bedc3c29ea5a` | 9 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/AgentConsole/README.md](../../../samples/AgentConsole/README.md) | `67e7bc72a1cfd602dbafee19fb8d778217c7bc5556993358a1c39118d327c2d3` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/CatalogDemoSession.cs](../../../samples/CapabilitySupport/CatalogDemoSession.cs) | `7d85876514e7507734ac709e0a248f667ebc953556f376fb257ccb769e896072` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/CatalogWalkthrough.razor](../../../samples/CapabilitySupport/CatalogWalkthrough.razor) | `b3b78e119e4162d6c5b8d276d6c1db1872d7dc26c93637ea0688649cddbbf307` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/DocumentDemoSession.cs](../../../samples/CapabilitySupport/DocumentDemoSession.cs) | `5f7da17a59bc6107480eda61abf1f31b0a5db496d1172d8cdb9e43f7bef52b69` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/DocumentWalkthrough.razor](../../../samples/CapabilitySupport/DocumentWalkthrough.razor) | `73de8c7f2b04df2de4768a0f174f8b51cb8977a5e30f64363f94b384725c3101` | 8 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/ScenarioWireHandler.cs](../../../samples/CapabilitySupport/ScenarioWireHandler.cs) | `586314556b765dd1a2e3570f555c9fd2191d18410c4b3d4e3736dd67049f3224` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/WalletDemoSession.cs](../../../samples/CapabilitySupport/WalletDemoSession.cs) | `7c089a34716fe5b2b117f742dbc72a41b65ef490edbc4833e4fc567868594d30` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/WalletScenarioCode.cs](../../../samples/CapabilitySupport/WalletScenarioCode.cs) | `0fb481aa830d572831f73fb9efcbc147adfc502d14b5969731fb107fac685a18` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/CapabilitySupport/WalletWalkthrough.razor](../../../samples/CapabilitySupport/WalletWalkthrough.razor) | `fdd8dc0e39187665385f0cdcc376905d92c25a5296b2a7daeac5976d054c93ff` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/Concierge/README.md](../../../samples/Concierge/README.md) | `d79d5bfb6eb4335dd72ccfe127f337ea0dd44f128238544336d5891b14670f1e` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventAgent/README.md](../../../samples/EventAgent/README.md) | `c6847d346574a0d6202f3484395db4be0c76c0c481a9bda155456bba5d85d34d` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/BookingsEvents.cs](../../../samples/EventSupport/BookingsEvents.cs) | `44bb15e27de374b4b82203810597478f7b06f2921dcb07e53c379099a37421a3` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/EventDemoCode.cs](../../../samples/EventSupport/EventDemoCode.cs) | `3b0579e1a24734977574104d8fc414576bb085c3c20d3df4baed6e1d7fde176d` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/EventDemoSession.cs](../../../samples/EventSupport/EventDemoSession.cs) | `8649d054f6819aa36018fb6d543fa3bf36ba81de38a2b85d128ec1c103746ad8` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/EventWalkthrough.razor](../../../samples/EventSupport/EventWalkthrough.razor) | `5e55267c3a00cc24e3ea3a0c8e0880a171b9c994b66785bbfda42adb57671d70` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/LocalEventProvider.cs](../../../samples/EventSupport/LocalEventProvider.cs) | `4a6450156bc911f67679e36f7c8e515ffe2b00109655562654cec7cd3d77f647` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/ProtocolSequence.razor](../../../samples/EventSupport/ProtocolSequence.razor) | `41febd2c9576b22c3446c2e0cd35ed40c3e5950a458348d704fcf9e5d5e30760` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/ProtocolSequenceModel.cs](../../../samples/EventSupport/ProtocolSequenceModel.cs) | `cbf3f5139661c5a9883d0e5596b5da42ce8ae3f589d2553e8429e136ac5409ad` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/SampleAgentEnrollment.cs](../../../samples/EventSupport/SampleAgentEnrollment.cs) | `91cedfc3c16c3eec85104f24af367a8e63a22ba327827ee42161262351e9d27b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/SampleAgentRegistry.cs](../../../samples/EventSupport/SampleAgentRegistry.cs) | `754f5f423e54bff18ffda08262344993c742b2a22d09674b328e7ef54a5d7378` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/SqliteEventStore.cs](../../../samples/EventSupport/SqliteEventStore.cs) | `8feda47df0586300908f79e2af661c8174e12991f42bac62316927c3d56acc0a` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/EventSupport/SyntaxHighlight.razor](../../../samples/EventSupport/SyntaxHighlight.razor) | `16bf52954ed8bc0bff367e5a4cee00d34f4ce17cc6af73a1046666c73b1f93f1` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/CapturingMessageHandler.cs](../../../samples/GuidedTour/CapturingMessageHandler.cs) | `40aca54715d8880cb6a9236d1ef2b6414e72bb6c618af64a7493ff5f03f43b4e` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/CodeSnippets.cs](../../../samples/GuidedTour/CodeSnippets.cs) | `ff4d96d0e9b8f5cf58beba47bb15c3ed4dfcf72651ac8c6ba740489aeed10ea3` | 42 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/_Imports.razor](../../../samples/GuidedTour/Components/_Imports.razor) | `ff71bc5b618f275846e5fc70ad99cd64d493b8bf198d6b604d7105764bbd08a0` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/App.razor](../../../samples/GuidedTour/Components/App.razor) | `848293d6fb5463468a75591d228c60beb0b52c8c187d2fa9882d393d77f4b143` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/CapabilityTourChrome.razor](../../../samples/GuidedTour/Components/CapabilityTourChrome.razor) | `53bb329bec371f05041a298da8d6f30bb41af8597553f04de66bcc6e6f1ec724` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/EntityHighlighter.cs](../../../samples/GuidedTour/Components/EntityHighlighter.cs) | `44dbe8b987a09db2021e280d3156ac5fb1b59a30854adc611f3f153d509ab829` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/Catalog.razor](../../../samples/GuidedTour/Components/Pages/Catalog.razor) | `3d9fdad1a7512894272e75a106ba55030e8f5c8644e7d0b726b8954dd0c7c8ce` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/Documents.razor](../../../samples/GuidedTour/Components/Pages/Documents.razor) | `744149b225526a8f806399051240443a71157683b6ad2551d5b756f940fdc556` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/Events.razor](../../../samples/GuidedTour/Components/Pages/Events.razor) | `f3f07f0d9131eb86df9e44f4bd1e119e4522cc3860ae69e58c06cde379e1155f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/Home.razor](../../../samples/GuidedTour/Components/Pages/Home.razor) | `bee24377f084f32c3a66cbfc049713426a10d6b408642a103d510c1aee96b49a` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/Tour.razor](../../../samples/GuidedTour/Components/Pages/Tour.razor) | `58d5f5a01d6f2762142640daa2cd22b7c81b02d1c73909a8323a357c3c4a5b41` | 57 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Pages/WalletProtocol.razor](../../../samples/GuidedTour/Components/Pages/WalletProtocol.razor) | `72a60740d408462058f083fe8236295db819250ccc0c0ba6114b7fd275259f32` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/PayloadInspector.razor](../../../samples/GuidedTour/Components/PayloadInspector.razor) | `2e6ab9e26b36346663fb7db0775ed7ceaecbc89f2704c444741fa6ab10b936a6` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/Routes.razor](../../../samples/GuidedTour/Components/Routes.razor) | `80766f20fb8e8e3e09e281d2679bbeb6129eb3056e5086f66380dbcdacc78e33` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/SequenceDiagram.razor](../../../samples/GuidedTour/Components/SequenceDiagram.razor) | `4cf2a89400d5c634b45039a319d8cab18c08eb57e4d82a12bd8339bc9f42b700` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/StepList.razor](../../../samples/GuidedTour/Components/StepList.razor) | `285749e182252337b9d9b4ec67d21976a23e6f3de4ec607beb8790888654b66c` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/TokenView.razor](../../../samples/GuidedTour/Components/TokenView.razor) | `8368f2a33c1f65c6ceecc6945ab689a13a59dc26bfcf8ffc6bc2754d88e4f1ac` | 4 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Components/TourFlowSelect.razor](../../../samples/GuidedTour/Components/TourFlowSelect.razor) | `4affbff8695448d9e22c79917ff02504ec5c6b125b7092aca01945e8df2110e9` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/actor-bar-visual.spec.ts](../../../samples/GuidedTour/playwright-tests/actor-bar-visual.spec.ts) | `35d1b48e2796ffaa3ce433179742365b877314123330503fd4d98690a765c4a1` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/autonomous.spec.ts](../../../samples/GuidedTour/playwright-tests/autonomous.spec.ts) | `1e9aba8bfb9e6e1bb8141bc3d826dcaceb83f1e8f4e06641fd642163a02687e0` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/bootstrap.spec.ts](../../../samples/GuidedTour/playwright-tests/bootstrap.spec.ts) | `f2d43ca1e8fca415049ff08d0c0c834bc75aaf7dee7954e0d0edbd438964fc09` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/call-chain.spec.ts](../../../samples/GuidedTour/playwright-tests/call-chain.spec.ts) | `09be9c5e465e5ed02e6033e47dba44fa657a8a8711cf0a817775f0555ac90249` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/catalog.spec.ts](../../../samples/GuidedTour/playwright-tests/catalog.spec.ts) | `a8aa5cbfe3fe167a71d37a9f3b999fdc3d57b993e5f99ddb10669942372dadb6` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/deferred.spec.ts](../../../samples/GuidedTour/playwright-tests/deferred.spec.ts) | `c444c71b4c242b769e5f846a791918ea100107b5aa55d1c277925fc6ad00bacc` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/documents.spec.ts](../../../samples/GuidedTour/playwright-tests/documents.spec.ts) | `18ac07458d76047bae73270f6e2d3f3a7b5b8d0d9784eaa834c6fd00035ed2cc` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/events.spec.ts](../../../samples/GuidedTour/playwright-tests/events.spec.ts) | `a0eece5b0bcb3d5820d7af9916b634f88fc4111ff5e9d147a9639b50f400d04b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/federated.spec.ts](../../../samples/GuidedTour/playwright-tests/federated.spec.ts) | `f4bf46db2670e3d5eca826cbc891887a1dc609ddf62d46220b3f2cdef17be0ca` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/home.spec.ts](../../../samples/GuidedTour/playwright-tests/home.spec.ts) | `7c0db15db2be68c4da43a16d3cccf293cc94ea785273c8435de54c61e2f2596c` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/identity.spec.ts](../../../samples/GuidedTour/playwright-tests/identity.spec.ts) | `82ba07636aff6093e48dad8249f1de905ad96321edcb582c46c52ae56f5976e0` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/mission-call-chain.spec.ts](../../../samples/GuidedTour/playwright-tests/mission-call-chain.spec.ts) | `c5887feac45c712831af948594f8a56f4be0695450624e077fcbaf9d15a34430` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/mission.spec.ts](../../../samples/GuidedTour/playwright-tests/mission.spec.ts) | `51e4f4c5bbfa498a335bf6fd6facff776be090ff36d90eccc16607b4f3590f1e` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/picker.spec.ts](../../../samples/GuidedTour/playwright-tests/picker.spec.ts) | `1d974f2a04d2d29148d7b5b2f810cb9ecf1486ce764828e91b175f5e77dd39d2` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/reset.spec.ts](../../../samples/GuidedTour/playwright-tests/reset.spec.ts) | `2df49e83ac2b8fe95f46f726d2441905b4ea65cbaeff63cd3af09a72500fc3e7` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/resource-managed.spec.ts](../../../samples/GuidedTour/playwright-tests/resource-managed.spec.ts) | `18b77308571ccfde2d9dd9ed3fbb5b7ca5bd203952bc403e072d335aaeff2ccb` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/richrequests.spec.ts](../../../samples/GuidedTour/playwright-tests/richrequests.spec.ts) | `34cbd5ca6894ed0d85d5553a501ee3d1274e236ba43be15a63087246e8f26d98` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/smoke.spec.ts](../../../samples/GuidedTour/playwright-tests/smoke.spec.ts) | `54f5fd40ac010fc12ddf379c8e2711a73c600155a5189909248da6ea53e7226f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/sub-agent.spec.ts](../../../samples/GuidedTour/playwright-tests/sub-agent.spec.ts) | `7f3d9c6675e4e9a0ba8ba90204dd20f1b1bc1f9cb3d57ba2314e48394e50da48` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/playwright-tests/wallet-protocol.spec.ts](../../../samples/GuidedTour/playwright-tests/wallet-protocol.spec.ts) | `72feebcce6d52c060d9d837a461779cdbf05147f30d57120d49d54bacf7ffadb` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/Program.cs](../../../samples/GuidedTour/Program.cs) | `7e202e86234895cba29c3724db1aadcb9a6ba1ed4a2a7d7aed51c9280cdafbc1` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/README.md](../../../samples/GuidedTour/README.md) | `07682d4fbd99fe233f341a68c9285262899216baa266fc0af1f862a60aeaf7df` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/StepRecord.cs](../../../samples/GuidedTour/StepRecord.cs) | `235fb340a44b5e51e9923b4f1f8049cf496b14b1f5abd128fccdd262a0025fc5` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/TourOptions.cs](../../../samples/GuidedTour/TourOptions.cs) | `48a622fbd14e70eca05efd113ba4054a556aae778a1698ff4af42e58e626017c` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/GuidedTour/TourSession.cs](../../../samples/GuidedTour/TourSession.cs) | `87562c1a8d7f7a1dd7d218bf5f626b6bf8e669c33b3cd62d177571431931994f` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MissionAgent/README.md](../../../samples/MissionAgent/README.md) | `e74b1ef424c48cc1455f8a9a21177347e76dd9a29edc4941b6658a9657d24b78` | 9 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockAccessServers/Federated/README.md](../../../samples/MockAccessServers/Federated/README.md) | `98de1a8e5f02905229f447409fa333356ceaaedc6fa720158eb666997fa2568f` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockAccessServers/README.md](../../../samples/MockAccessServers/README.md) | `d8ed18067fa622f87bc32d5ee75f5a40341bae6d58513a5e9ae06ef8e1637aca` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockAgentProvider/README.md](../../../samples/MockAgentProvider/README.md) | `ef1bddcaf9a7c65623f6c68b86bea89fee9c2f69e2bfbc5013489623ecd780a8` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockPersonServer/README.md](../../../samples/MockPersonServer/README.md) | `80b6124bff77cadcb3bec2f46e7aee2c898034b7cce23d7bc64c7d9ca8b531a6` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Bookings/README.md](../../../samples/MockResourceServers/Bookings/README.md) | `c0a3edb6b2040da9e2cd14b51408dd98c39371da09d4e2ebf88959c95396640b` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Calendar/README.md](../../../samples/MockResourceServers/Calendar/README.md) | `b76a58d4f22fc583d7b9fcb8b20a8c0f145ee01301f02c888adaa07df9e6ab5e` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Catalog/README.md](../../../samples/MockResourceServers/Catalog/README.md) | `6097a897334dcf3fd68fadb6d3783646df8e39b92b5b28ea438520cbb58b6c96` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Documents/README.md](../../../samples/MockResourceServers/Documents/README.md) | `786d6f9f717c94935cba36bb598f6f1625714928943ec61ddecebbf6c96711bc` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Inbox/README.md](../../../samples/MockResourceServers/Inbox/README.md) | `fc04b4b88278971c8255b34d19d82fab15bf52e2776297631dd83b3e0c78a01d` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Profile/README.md](../../../samples/MockResourceServers/Profile/README.md) | `b7d1a625a8d733b9be42dc018b114a926e78667f13a603e1926684c23865003d` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/README.md](../../../samples/MockResourceServers/README.md) | `44227cf793a83e71b23981f547c4254d272f6d04272986fcc0db0da25432130e` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Trips/README.md](../../../samples/MockResourceServers/Trips/README.md) | `f56f07a80a7ee625890a235fdb8c9dc2be923eceb7d0fa9a0d73174be7c138b5` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/MockResourceServers/Wallet/README.md](../../../samples/MockResourceServers/Wallet/README.md) | `775677d1926810f9bb3d05b1c467778fb01284c6d94adb9b3d83d0b349bef121` | 2 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/README.md](../../../samples/README.md) | `693d7dc4a321f5f537c089e0e58c1d57e622dad72650706e3259e21893a605c2` | 25 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/_Imports.razor](../../../samples/SampleApp/Components/_Imports.razor) | `823cdc26fef5242268ac5c9dc8cdf4401845d6b04dfc56291e6cdf69c0e320ee` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/App.razor](../../../samples/SampleApp/Components/App.razor) | `e28bc9f11a4329d2689a64520db6550c34aaf9c042c478ef46b88398fe6e707a` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/ConsentProgress.razor](../../../samples/SampleApp/Components/ConsentProgress.razor) | `c1c9896ad52e8cae388cce2a7e58271d5e9549ef352c1f4f26c1e36fe52614d6` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Layout/MainLayout.razor](../../../samples/SampleApp/Components/Layout/MainLayout.razor) | `9612f8b0086834d92cd7d8e4765febd14baf89f5b7aa8f2661fcd1b380296439` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Layout/NavMenu.razor](../../../samples/SampleApp/Components/Layout/NavMenu.razor) | `87b699c2009feacbe2498f4656baefdc41beca4601c2e084723c67c197195e4b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Layout/ReconnectModal.razor](../../../samples/SampleApp/Components/Layout/ReconnectModal.razor) | `e1c8308c1ec6656c8f5cd50df3f1879b614e43109ad6b1e23ab26d6f1007c6db` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Bookings.razor](../../../samples/SampleApp/Components/Pages/Bookings.razor) | `71ffe8f544b9fce58cee89b99a3726c2833cd97f1a53f4b2992c6cef1fc614c8` | 17 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/CallChain.razor](../../../samples/SampleApp/Components/Pages/CallChain.razor) | `e73d01df62389a1c4aab67c5ca651ba6c9b880800b1101cd0024b185a38b61fe` | 15 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Catalog.razor](../../../samples/SampleApp/Components/Pages/Catalog.razor) | `b754e2daadfb6aa9d49724a71c2701a1ddec5cfd32ab84b89a52f8aa9fc24f64` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Deferred.razor](../../../samples/SampleApp/Components/Pages/Deferred.razor) | `ec42004963663a54e44055788c12d0a0b4aba01d0f4839288f98c1b0828d745b` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Documents.razor](../../../samples/SampleApp/Components/Pages/Documents.razor) | `90cd5ab588129406dc71283dbf1be755282a00c51f605227c881a8602d339657` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Error.razor](../../../samples/SampleApp/Components/Pages/Error.razor) | `e77473780e53f2ba6d42105b745d3eca7cdbdaec1d407bc46a8ce9338b43eb29` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Events.razor](../../../samples/SampleApp/Components/Pages/Events.razor) | `43f097f6378cdcb0391480a8a7ccfc0ce028449bc7372b635ed96fd19f700adc` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Federated.razor](../../../samples/SampleApp/Components/Pages/Federated.razor) | `ea4e67e3f25d9f43ee197061760222400787dc1fc127ce96ddb31849883ba39c` | 15 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Home.razor](../../../samples/SampleApp/Components/Pages/Home.razor) | `e8b008ca3f68fd7be620e963ce7591634a7086719a719b3aee1315f0660cf942` | 24 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Hwk.razor](../../../samples/SampleApp/Components/Pages/Hwk.razor) | `a7f633945d56283821c487ae56d78fae5d52972ea0f7efddfdbd04770faef9bf` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Inbox.razor](../../../samples/SampleApp/Components/Pages/Inbox.razor) | `5c02f15ca4c412221b6234246413caa8ee03b0c934fe6d65b9f92a9df4b1623c` | 7 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/JktJwt.razor](../../../samples/SampleApp/Components/Pages/JktJwt.razor) | `1fd10af40f56ae004b5477dd33e051ce205455fd45010a2735702377349bed43` | 10 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/JwksUri.razor](../../../samples/SampleApp/Components/Pages/JwksUri.razor) | `ef65454b63687aee836b2243b693a4366c904b346039da4e5ea0c449e7831ca3` | 5 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Jwt.razor](../../../samples/SampleApp/Components/Pages/Jwt.razor) | `25e7c1ad0768010bc02294efc7c98184f035a7cfbd30d9106cbeed9d6c636900` | 6 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/Mission.razor](../../../samples/SampleApp/Components/Pages/Mission.razor) | `30953b3cd4b03547c53240c7535cd7c715f017d2940eeaf924f9441db8ef6fc5` | 13 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor) | `83f94e951af49407fe369484ccf4335ebe6f86a0362515ec354ced3edf2e7db8` | 11 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/NotFound.razor](../../../samples/SampleApp/Components/Pages/NotFound.razor) | `c267b98a248a516f8ca8c79dd8410d9f09d9ad302466e65c6b9b959b5ffc7cbd` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/SubAgent.razor](../../../samples/SampleApp/Components/Pages/SubAgent.razor) | `da45894b890bd155a711e85e8d80ffc9f9b111f9fb8516efa817ae0e17621f7a` | 12 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Pages/WalletProtocol.razor](../../../samples/SampleApp/Components/Pages/WalletProtocol.razor) | `8c72660eb5c77a059e195c4af2e070283f02c057f51e9f5aa66cd8fa6e52fc8a` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Components/Routes.razor](../../../samples/SampleApp/Components/Routes.razor) | `d8ad5bf563c9a858dc9d74bddb4a437f4347cd1cfce5fc81147d324668100c4e` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/EnrollmentService.cs](../../../samples/SampleApp/EnrollmentService.cs) | `639f347cfc92fe239bf0b6347c7e0382c54307413e991d60c77662a144852f2b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/bookings.spec.ts](../../../samples/SampleApp/playwright-tests/bookings.spec.ts) | `7ae59d7ed823af77e4820f50d6820aecb34364ab1990b99ead4e85b800f0ebf8` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/call-chain-deferred.spec.ts](../../../samples/SampleApp/playwright-tests/call-chain-deferred.spec.ts) | `3de62d30a9fda0a6dd8b54ea4fecf1a0033f879f679caac765d96df46553b59f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/call-chain.spec.ts](../../../samples/SampleApp/playwright-tests/call-chain.spec.ts) | `9f011a4d1c38818274fafeab06e967d9ba8867184469c104f7647d4e1adfb4e9` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/catalog.spec.ts](../../../samples/SampleApp/playwright-tests/catalog.spec.ts) | `a8aa5cbfe3fe167a71d37a9f3b999fdc3d57b993e5f99ddb10669942372dadb6` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/deferred.spec.ts](../../../samples/SampleApp/playwright-tests/deferred.spec.ts) | `1f4f0fc9c2647d47c02c97a45ff206e31df3711409f4b09f5233e53c50423204` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/documents.spec.ts](../../../samples/SampleApp/playwright-tests/documents.spec.ts) | `18ac07458d76047bae73270f6e2d3f3a7b5b8d0d9784eaa834c6fd00035ed2cc` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/events.spec.ts](../../../samples/SampleApp/playwright-tests/events.spec.ts) | `a0eece5b0bcb3d5820d7af9916b634f88fc4111ff5e9d147a9639b50f400d04b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/federated-deferred.spec.ts](../../../samples/SampleApp/playwright-tests/federated-deferred.spec.ts) | `dbd281ad02760c5a3be9d3bc48d17f2335225517bcddfac0edf2f5c54db01bbb` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/federated.spec.ts](../../../samples/SampleApp/playwright-tests/federated.spec.ts) | `fa4b8bcae74cdc78d998b86dc0b1ce563a1d1e04647db1df82cf4b1f02e37231` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/home.spec.ts](../../../samples/SampleApp/playwright-tests/home.spec.ts) | `e12c1b904452433807520bdd4dda5f4f28487e80f95fc6a5d4a94f1a96473b0f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/hwk.spec.ts](../../../samples/SampleApp/playwright-tests/hwk.spec.ts) | `1cec5f9bc0f6b83f7bd14fbaa9700be8f5fba8b12295425061efb2f7dc817bc6` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/inbox.spec.ts](../../../samples/SampleApp/playwright-tests/inbox.spec.ts) | `f0cbea438e6a32ea2eea6656cf25e82c2ff2d0ea43b52cf7e90c7f50ecfd1c5f` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/jkt-jwt.spec.ts](../../../samples/SampleApp/playwright-tests/jkt-jwt.spec.ts) | `b33f16fa5447b2b1fa1839adf377126365db36ffbd3e2d87a51f19076f93161a` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/jwks-uri.spec.ts](../../../samples/SampleApp/playwright-tests/jwks-uri.spec.ts) | `808c40e51b76da1513745b86960c5edd6d572d6273943f7dd16b074de7f18ba7` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/jwt.spec.ts](../../../samples/SampleApp/playwright-tests/jwt.spec.ts) | `412a0910ce91857f301526835b48fdb07d38dcb7182168089292e35b876e7a1d` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/mission-call-chain.spec.ts](../../../samples/SampleApp/playwright-tests/mission-call-chain.spec.ts) | `49e308d5ed334a2092fcaa93b0ecdf51265451dc93d9471db219357c37c84ef7` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/mission.spec.ts](../../../samples/SampleApp/playwright-tests/mission.spec.ts) | `c501386b5a413366f0560503f1f793acf8555db7aaeb0b739996913b2a5b4bfe` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/sub-agent.spec.ts](../../../samples/SampleApp/playwright-tests/sub-agent.spec.ts) | `ad5ee459206a8a5ae18d3a750efd64c2bd4f87a98619d062e0329a2692015fac` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/playwright-tests/wallet-protocol.spec.ts](../../../samples/SampleApp/playwright-tests/wallet-protocol.spec.ts) | `72feebcce6d52c060d9d837a461779cdbf05147f30d57120d49d54bacf7ffadb` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/Program.cs](../../../samples/SampleApp/Program.cs) | `0fb80602f73f4a896dc357cd4a00afeadaba5acbeed996949a3fd9283f739e24` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/README.md](../../../samples/SampleApp/README.md) | `b9c56a48d83f08670a27c7f41942b1d5bfe265cd36dd26a09f58a94d88f3164b` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [samples/SampleApp/SelfIssuedIdentity.cs](../../../samples/SampleApp/SelfIssuedIdentity.cs) | `88edd595b97a4a0110fc3e14e640fe2b4ea3971eb345a5331b42935e2f84c558` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [src/AAuth.Events/README.md](../../../src/AAuth.Events/README.md) | `0da992d1c39c782c4305cca2f524899541c3fe56f9d7294ec8c72c5a7fc8e5a2` | 0 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [src/AAuth.R3/README.md](../../../src/AAuth.R3/README.md) | `a16beb43d4d9f09fe3a7e16b23124c2289cb0f0822c86735ea3a7b902fc8a637` | 1 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | +| [src/AAuth/README.md](../../../src/AAuth/README.md) | `a6ef1a5a99f89a65414c64492b700363a332cbc8faadf58dc6753e4979858268` | 3 | Frozen source; links/patterns; blocks below; capability matrix for runtime/browser evidence | + +| Source Block | Format | SHA-256 | Result | Source and Behavior Evidence | +|---|---|---|---|---| +| [docs/advanced/clarification-chat.md:fence-1](../../../docs/advanced/clarification-chat.md#L31) | csharp | `a4ed80747fcef5395f5f9cfb302f76b08708fd8bb257519412c80aff6ac5f387` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-2](../../../docs/advanced/clarification-chat.md#L48) | csharp | `3d48706ba81dd6793d079ff87bc78ea0e45a4e060a1085b320bd60249ffa8240` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-3](../../../docs/advanced/clarification-chat.md#L71) | csharp | `56a5ded3be3396c90a9ee5bb3ca87ff0619afb1c158869ee236c093b370bcff7` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-4](../../../docs/advanced/clarification-chat.md#L93) | csharp | `09245ab8937e93acd07c41116a7ea334fff2f49159c68ca5af667c020fbe502e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-5](../../../docs/advanced/clarification-chat.md#L113) | csharp | `5ab5ee90d6688193b9ae33605814a11548cd05b26264b5e32f1877dd5254f81e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-6](../../../docs/advanced/clarification-chat.md#L144) | csharp | `0cf257cfa82c7d74333f774a676f6db651632fc19000dd49a90f213c02561867` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/clarification-chat.md:fence-7](../../../docs/advanced/clarification-chat.md#L167) | csharp | `996af329c55564613fa136c5e9c5c5ad9594397241eb5139232d00be3f6d68ae` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-1](../../../docs/advanced/error-handling.md#L18) | csharp | `b90b6b447b0e931a4780a3d16df3de6663f680dc1d1e21ee62754844a215d79e` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-2](../../../docs/advanced/error-handling.md#L36) | csharp | `816fd2096186752170c1b4d66cd805105867ab77e07aed4b5ab080b7bbd8a6d8` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-3](../../../docs/advanced/error-handling.md#L86) | http | `ccbecd7fad970b88c55c4a28c314eefed987d3f3d3664015fd07b1f64bf48ff9` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-4](../../../docs/advanced/error-handling.md#L98) | csharp | `c621e12028e33e14048d8520de1ba16de8a90171ad0f683cec2102e91f5ed649` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-5](../../../docs/advanced/error-handling.md#L117) | csharp | `ebb375166ad668577feb4c7a59af0dfcd44d3046509837154d13e3d814d37e67` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-6](../../../docs/advanced/error-handling.md#L132) | csharp | `841cf2031834dd4de7d47dd02d959a4b57316647e0f783cb4756f6bb46b20482` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-7](../../../docs/advanced/error-handling.md#L142) | csharp | `08ef98685b1db4d634f9f5fa48b275048d15aa02ce908ef5e64da529b9d48683` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-8](../../../docs/advanced/error-handling.md#L167) | csharp | `501ef76775d373fd0e3255fd299f9b35aa070650476a22fd1dd52ab507aec559` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-9](../../../docs/advanced/error-handling.md#L200) | csharp | `cb15e3f3d62c0eab29c03d263e5e220f0f88d4158b42842e54b882d9fb842022` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-10](../../../docs/advanced/error-handling.md#L216) | csharp | `f5a3d6c38b64aee40a2648d1386e553ef636a055b97a8cdff713e9b3f4e0fa05` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-11](../../../docs/advanced/error-handling.md#L234) | csharp | `5a5ccd42790bf4f7b9f633db917b884021350cfdc655daa4592db49b8cc49f83` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-12](../../../docs/advanced/error-handling.md#L246) | csharp | `8906ec5cd5900725d63e1205dde7c4be5e15f077694b5a9a13cddcaa1555fba9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-13](../../../docs/advanced/error-handling.md#L280) | csharp | `82c84a1cf9197eb47887e684511942e52266371354cf78807f643a8bcf319310` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-14](../../../docs/advanced/error-handling.md#L290) | csharp | `ca74fa00f6a3e40e644fb3088a109e7a3997584be540a8d0e61b870dfac16e7e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-15](../../../docs/advanced/error-handling.md#L311) | csharp | `1d857fef0e313b9c8ae9797157cb0cc0f7bef3fae7334d3267fd5a773d7ca9ea` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-16](../../../docs/advanced/error-handling.md#L340) | csharp | `f20b4e55cd9acef5619bdd7b500b1daf34893d76e3a18ed2dc2404127b7bbd80` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/error-handling.md:fence-17](../../../docs/advanced/error-handling.md#L352) | csharp | `69087d67b02e6bffbca2985aa9578940aa1fd60a49359e576c260b7cc71ce79b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-1](../../../docs/advanced/interaction-chaining.md#L29) | mermaid | `284f82b2ee78ef3de7488520e693eaa2abc4386583910d3db3358edbde20207c` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-2](../../../docs/advanced/interaction-chaining.md#L63) | csharp | `7a3019d1d5ebe77cd8b551a9955e4cd845fce68cc8551ba8fbf405f1e6cc2f7a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-3](../../../docs/advanced/interaction-chaining.md#L114) | csharp | `6220ff6f771ec69523c3118b98d95d91458ec12e47a5889f5c63bb6c6fc1ce8b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-4](../../../docs/advanced/interaction-chaining.md#L132) | csharp | `255b5eb76791588321b49a28cfb8a09e6b5c85874677ba37600094b038d97a76` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-5](../../../docs/advanced/interaction-chaining.md#L170) | csharp | `281a2725644aaed47026152611d8795358af274fd6c5cee081a179e1d645f8f0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/interaction-chaining.md:fence-6](../../../docs/advanced/interaction-chaining.md#L198) | csharp | `12ce99401466e0c304088f0ce982ef82aadb97a2df7a2ac2f7edd2b33c2f32a9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-1](../../../docs/advanced/key-management.md#L18) | csharp | `6d741b13f2529d165d75874569c3f000c304ecb9c948153b7f43af837c9082cc` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-2](../../../docs/advanced/key-management.md#L34) | csharp | `6fd5ae59073ba7176ae15702664b8a8436c545c2ebbd0778e4c53f5c9c770a83` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-3](../../../docs/advanced/key-management.md#L44) | csharp | `b0b8acd9af234ff216fee116a9388a52ba3da03bb610d050974c8d6d333aaff5` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-4](../../../docs/advanced/key-management.md#L67) | csharp | `25b46fad5d4d904f30f3969f61036abe22383373aa0cb94b7e586ae57c437f41` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-5](../../../docs/advanced/key-management.md#L90) | | `28c8b0984d9766f2dc943abd90050e9cb47a7d9be5211f102ddc71256c9c0e92` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/key-management.md:fence-6](../../../docs/advanced/key-management.md#L113) | csharp | `51e9b70c02a4467f9fc5033a9050f90ff0899fd75bd8a38a4f1effb5ae48fc4c` | External template: Azure.Security.KeyVault.Secrets/Azure.Core required; exportable Ed25519 secrets, not HSM signing; syntax checked only. | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-1](../../../docs/advanced/mission-governance-clients.md#L31) | csharp | `efdbe174b33afb74f569257eb3d4c8d184bc9ea975fc766084feda203cf031b4` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-2](../../../docs/advanced/mission-governance-clients.md#L44) | csharp | `6f3135e9e2d7ea058beec05e9530df7a7cb123190d71215d855b317337f616d9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-3](../../../docs/advanced/mission-governance-clients.md#L60) | csharp | `a48971348935a3cae7eb7f3508db800130ca1fc4343d0e2e38ea72b8aa60e542` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-4](../../../docs/advanced/mission-governance-clients.md#L94) | csharp | `c45de5a19044c70a10502a5f99d1abeb60354731308355d16488a1c3d05d39c6` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-5](../../../docs/advanced/mission-governance-clients.md#L116) | csharp | `b1417da973f9289c33568cc86ea925de70ae438e7846c915bb92f5e871ef3a91` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-6](../../../docs/advanced/mission-governance-clients.md#L130) | csharp | `028bd539ef3847cb7f3254967acf57da1229a2b561f0ed696803e1eec9c641d9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-7](../../../docs/advanced/mission-governance-clients.md#L144) | csharp | `780705db94fdf70e18c9cf3449ad811a9030213b253986eb2a30021aa5425ff8` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/mission-governance-clients.md:fence-8](../../../docs/advanced/mission-governance-clients.md#L165) | csharp | `1418a3bf2ae5c4b9348579678d017d88dcbef097e81d53247dc318a3c55fe250` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-1](../../../docs/advanced/missions.md#L34) | csharp | `49ed2a5623aca7077ae8d065351f5e7cd0cdf35ac656746b9e23c31e25c8e3f3` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-2](../../../docs/advanced/missions.md#L67) | csharp | `a41e7437fc3cef7a2bea845e0ab792ecdddd72539f71943f7b204e73fe51d897` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-3](../../../docs/advanced/missions.md#L109) | csharp | `3df45ba3c240de9d88f78a10fd51b3efad742540376f042669e5ab1dfa31b48d` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-4](../../../docs/advanced/missions.md#L121) | csharp | `bcf8f493220c24c8b5d94cce0326371d79c1119d04accc0c814f274e151cbf87` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-5](../../../docs/advanced/missions.md#L140) | csharp | `305297811b39b19d80697387c2dec2677362ae9faded0c7958ea2de8ace5e398` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-6](../../../docs/advanced/missions.md#L169) | csharp | `188bc37ad492480035a393e9b43a44a9dcac7064d6674b3ead130f08d4d90eb0` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-7](../../../docs/advanced/missions.md#L181) | mermaid | `bb6f6b28504d3acb217f376b5f16091121e38f8c9b9f5f01679915ed4ad51b2e` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-8](../../../docs/advanced/missions.md#L215) | csharp | `7464f004c9a8ca20c1893193275825e889707abe09198b89dc5b5501759037d5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/missions.md:fence-9](../../../docs/advanced/missions.md#L228) | text | `a88cd455dcef944cb8445c45a877f991b5504ecf69a9e7d2c949cb30fc76daac` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/observability.md:fence-1](../../../docs/advanced/observability.md#L12) | csharp | `580bf5eab70345ad556ffd28294e727760cc4b6bade60b040fd7cc7a491ac0b5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/observability.md:fence-2](../../../docs/advanced/observability.md#L22) | csharp | `3151e23b6f0031bcded6574b4f3da255f5341ca4391e780911527181a1030771` | External template: OpenTelemetry.Extensions.Hosting and Instrumentation.AspNetCore required; syntax checked, exporter not executed. | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/observability.md:fence-3](../../../docs/advanced/observability.md#L59) | csharp | `798d0d42550fbd10cf49abf6ef6e8df5d093a11fc41972897fd8ae980628d0f5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/platform-attestation.md:fence-1](../../../docs/advanced/platform-attestation.md#L17) | csharp | `5f0a5359571fd1461426619bc4d32f13764043fc5e24ee4bc8f15217c827fae1` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/platform-attestation.md:fence-2](../../../docs/advanced/platform-attestation.md#L31) | csharp | `9b313bcd8558ce1251841ebbc6c6b2c2e37b4a3a03c5f019224544b9069fc86b` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/platform-attestation.md:fence-3](../../../docs/advanced/platform-attestation.md#L48) | csharp | `1dc43d75de0eb95c1f32b908f357d85a1d9ad32bfcf60c431d70dfabee7a8158` | Illustrative platform adapter: IWebAuthnService/DeviceCheck are host placeholders; IPlatformAttestor signature checked separately; no hardware or AP challenge/retry claim. | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/platform-attestation.md:fence-4](../../../docs/advanced/platform-attestation.md#L68) | csharp | `9232f368dc3371617c75a4b84ff7f4b80b99c009bb5453b17b9f60fa62792e98` | Illustrative platform adapter: IWebAuthnService/DeviceCheck are host placeholders; IPlatformAttestor signature checked separately; no hardware or AP challenge/retry claim. | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/advanced/platform-attestation.md:fence-5](../../../docs/advanced/platform-attestation.md#L90) | csharp | `2d5f0b4c92a5fe1c59331dce06dace510e5ca73a4a49b73403ba109f6be1cd8e` | Illustrative platform adapter: IWebAuthnService/DeviceCheck are host placeholders; IPlatformAttestor signature checked separately; no hardware or AP challenge/retry claim. | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-1](../../../docs/getting-started.md#L14) | bash | `ef50764cc25e3e18dd0b4c55c31a13f834f879894febe875678dac6074841afa` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-2](../../../docs/getting-started.md#L27) | bash | `0cc8bf77419b3cf5842a01e5350d865905b39fbe124a4b0fc90be9e8e4336218` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-3](../../../docs/getting-started.md#L33) | bash | `e50a89f02b3bad70993b022f4c22f61a62dbe565d12e9bdc6b486b7583a2ea2c` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-4](../../../docs/getting-started.md#L39) | csharp | `fdd60869af1dfb8ab381603e337611198f55a2506ad74889aebebed5316140bb` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-5](../../../docs/getting-started.md#L53) | csharp | `e39ae84ba1b8c3819aef5926b5d5ebd84a1e8fc6cf02948b611202ad115bd63d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-6](../../../docs/getting-started.md#L73) | csharp | `0ea3e6805ef7a90688ffc97b13131d560d567f310360c431021125756b9bcd9a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-7](../../../docs/getting-started.md#L79) | csharp | `5960157c66ffe688cc5ad122ad57230b892b68aa277b6bceefd3f6998ec211c3` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-8](../../../docs/getting-started.md#L160) | mermaid | `baf95089d13daa4036817f12c4e67dcd863eaed958d2018e3844cfa0a96d4292` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-9](../../../docs/getting-started.md#L188) | | `eb01c7967541362e3afb1cecff31a8713c18e716466e0234012e6611606576fa` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-10](../../../docs/getting-started.md#L200) | | `48d6fb39e4dc579ef29f14e50612784f39408696587c2e23011298b2eb5b75d0` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-11](../../../docs/getting-started.md#L211) | | `1f4fbf16c1468961c423dbc74f9c2a8e024dd44802699999395281105cccd70b` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-12](../../../docs/getting-started.md#L247) | | `cd698a34a22c0b50bcb6803b9f9ed6b74ee8c3950951156c11904c9718e68b11` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-13](../../../docs/getting-started.md#L268) | csharp | `9a34bcbff8eb333aedc12cfec84bad279eb1944649999e0a51b417fe5e5efd4b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-14](../../../docs/getting-started.md#L303) | csharp | `bf7e6c927c5099e70d863fdb3abf0d8a59d72cc60487699572fbf4fd5943a8fe` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-15](../../../docs/getting-started.md#L356) | csharp | `815116ab3b876deda6d446d52e32cb017148a92a72e054b51c020e336cb07f99` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-16](../../../docs/getting-started.md#L389) | csharp | `c7e55b35db9cc239045a5b55c3a6ba5da77a3293007945e7db7cbc5edfa733f2` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-17](../../../docs/getting-started.md#L413) | csharp | `5670e98a75b023849a96ab6182395ac705086046f4e89586bf76a998d818015e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-18](../../../docs/getting-started.md#L440) | csharp | `842dfef2e85d1763e1042a9e57be29e8782732e70cc0854bc919efc70de631d2` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-19](../../../docs/getting-started.md#L457) | csharp | `9f60ec93e3b0c797ead5e2aebeb7555457724493f97a3e481fa93976e04dadc5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-20](../../../docs/getting-started.md#L478) | csharp | `3e472b560545dca1df07338fb1f26d953846633f898e4ff6d3b962ec09e0e7b6` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-21](../../../docs/getting-started.md#L488) | csharp | `83299b5e1a81413e1fb64034d4014ed4bb1e6253c6357322d97dee95bdc0494f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/getting-started.md:fence-22](../../../docs/getting-started.md#L500) | csharp | `8835ac263e42b64cc7f701f5265ee0463426e334e5b00393517d9c8f578daa12` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-1](../../../docs/reference/dependency-injection.md#L17) | mermaid | `455bbf63be35823e1a78e6fc393f6639a8ed375c5a8ea02a271cf2e97f926cf9` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-2](../../../docs/reference/dependency-injection.md#L38) | csharp | `20ca3d8586178c959b0dfaa8577c654676c9b22af197367cc7a2e007287af1cf` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-3](../../../docs/reference/dependency-injection.md#L52) | csharp | `021e28bc6431dfd94d6ffc078e3ba0aa2a18f598dde147c3f37daf8e4cb1413e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-4](../../../docs/reference/dependency-injection.md#L79) | csharp | `acd465c404a3d1660089ae581ad10210e7cbb876b7f26feeb05b4e4ce42be95f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-5](../../../docs/reference/dependency-injection.md#L98) | csharp | `5e07151f9755899dfd4af7ae0d58236949936302782ed06192ad9f094dcfbd8e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-6](../../../docs/reference/dependency-injection.md#L111) | csharp | `3c963124d1ac2f531900c8d6ffc59d7695d461cbf3c70ff482dcdb4c442cd866` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-7](../../../docs/reference/dependency-injection.md#L133) | csharp | `5b292a527f744ebd5e5e39deef44498b77e8f26bb0be8458da52bce48410c59d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-8](../../../docs/reference/dependency-injection.md#L148) | csharp | `3d5b8de139324bd96efd8fc1411093a91c52f2fd9a338d33015c11754621baa5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-9](../../../docs/reference/dependency-injection.md#L177) | csharp | `c4f1d3b698fdfc0cc22983a873836946e0df9f3c4caf72d85a8185aff5d06964` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-10](../../../docs/reference/dependency-injection.md#L198) | csharp | `198b6467ce8bcac52f8b8e719ab21ec65ebb0b11a3163a9f4522d5fad45fc73f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-11](../../../docs/reference/dependency-injection.md#L213) | csharp | `4cc78410ae269781a904c5b0dedc95ffa3992dcd54d10e559a95b1d86f65b635` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-12](../../../docs/reference/dependency-injection.md#L243) | csharp | `dd6961c7c02d11eb158877fc28438f3788f50c3976913ff05bd99f149f292bfb` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-13](../../../docs/reference/dependency-injection.md#L257) | csharp | `7679f84ae0484423e6390b189bc90d7446c697bcc12a9c29c2bc944dacca3bf0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-14](../../../docs/reference/dependency-injection.md#L275) | csharp | `39b84a4388bc01120f6e8d2442038dcfbb9b22b84580cca14793d55235e403f1` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-15](../../../docs/reference/dependency-injection.md#L296) | csharp | `a9031441b0d87d0387f6ae57a86edb03d0ec44950e712814f75c5026a3368c09` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-16](../../../docs/reference/dependency-injection.md#L393) | csharp | `96ba19a19570f52f6c4aacef087ea698418df8cfd4c12ea3acfe64c16abe18f0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-17](../../../docs/reference/dependency-injection.md#L431) | csharp | `b587ff35a648f396515a0d3176d4873dc0dcd01aa4c0b403903dc43081aa07c6` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-18](../../../docs/reference/dependency-injection.md#L442) | csharp | `36332bd1f0cb2b64c873f3fa4fcdcc10a9525dee3af912e4d298384193de2d62` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-19](../../../docs/reference/dependency-injection.md#L463) | csharp | `ec41bcb8faccf47f73ad64a763c4feeaca99f8392c9e0ce9c418b541ff7c87a0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-20](../../../docs/reference/dependency-injection.md#L476) | csharp | `0edad43d25137f2fcf8b06fd5e1b2f6fdc68ace037840a6ec6dfd55fc8af295b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/reference/dependency-injection.md:fence-21](../../../docs/reference/dependency-injection.md#L490) | csharp | `667116e1927a7a50ab35c729e4ad3b29a29b96769c22f97d7c55cc24cd8d8d6c` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-1](../../../docs/server/authn-authz.md#L32) | mermaid | `d197919ce3abea990d4f9c2ca62e5650d7ea77d0e878be657f0a1ca2d0241bab` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-2](../../../docs/server/authn-authz.md#L55) | csharp | `665003ca713693042ec5ee74eecbb69f7a6c25bcb34785fd27bd41fe3eca9d8f` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-3](../../../docs/server/authn-authz.md#L93) | csharp | `eb6fcaf141e4f97505db349dea6c2c0113db2b1ea167f7009646392f1a48c8c5` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-4](../../../docs/server/authn-authz.md#L118) | csharp | `28fb5ffa1e0e7265d7c049c6d23f1f888ed46a0ea91bfb185e6ed1f1d45f9185` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-5](../../../docs/server/authn-authz.md#L160) | csharp | `0cd89e3ac03857a431eb81cc291f4b9b1d1b1c0e8d838e519e54ffb05bf685e4` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-6](../../../docs/server/authn-authz.md#L174) | csharp | `f0a6dab5542f6d51a7a31559a861cd46ccf0699e5a7c49f2b7a1b35883b10ab0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-7](../../../docs/server/authn-authz.md#L206) | csharp | `591e07eb234b1154a5130aa3ca111af3e492b3cf6a233be66ecf063d8345f512` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-8](../../../docs/server/authn-authz.md#L238) | csharp | `54842442ab19383c32a3f9f0763f4fc4a1af8f3b9799a370b1f8ec7be2e52ac4` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authn-authz.md:fence-9](../../../docs/server/authn-authz.md#L245) | csharp | `219d3274d5f0f2a3d01ce75584efe09b8eb4b6b1ab4ca806c54f82589f14316b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-1](../../../docs/server/authorization-policies.md#L14) | csharp | `7663a483fc0213bff88f5f3e7fc7839d2c5d09f3deb588b05ee5b6e301cd7a9d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-2](../../../docs/server/authorization-policies.md#L34) | csharp | `638fab5b8fedda1ee1e0153d94b0483ba3e02a26f1ac019db46930c860c81ca7` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-3](../../../docs/server/authorization-policies.md#L56) | csharp | `a1f44e6cd873f214de2fa964908a5d2547c3489c869deb059da16d06b0cd8204` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-4](../../../docs/server/authorization-policies.md#L84) | csharp | `e9803d626789b8d500301dea49ee10028d17304ce4e2263e71ec1e025408b280` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-5](../../../docs/server/authorization-policies.md#L142) | csharp | `a1cff431aedc9143e6d9d84bf89239e006bae88660776f58e2d4c2b2efe4386b` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/authorization-policies.md:fence-6](../../../docs/server/authorization-policies.md#L153) | csharp | `73454522e0ab731852e4e7cfedded41fbbee1d041d4939e496be64fac5f3d140` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-1](../../../docs/server/challenge-middleware.md#L16) | csharp | `6ea866ac9653edb655037e303327fb96ee7c335d657f86e3d09e1da7b47eee2a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-2](../../../docs/server/challenge-middleware.md#L30) | csharp | `f2d22827c75ed8cb2f37754e4aa5effce462208f93df75da22b35fbfc7c2d5f7` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-3](../../../docs/server/challenge-middleware.md#L55) | csharp | `80f04460ba16f20bf24e2c879e887543f0f51285e8771bc09a7c6c01e8ef5354` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-4](../../../docs/server/challenge-middleware.md#L94) | csharp | `b587b797a69d5de904c65a7076ba83928fcc60b29d40f851bb0184d20734efad` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-5](../../../docs/server/challenge-middleware.md#L115) | csharp | `ac0ae94ae6020651775673b522ddf06423a66c62845b86b7b3a4796f41d71334` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/challenge-middleware.md:fence-6](../../../docs/server/challenge-middleware.md#L143) | csharp | `374f914711d4156f59d55a15838c451a2cac9d93ca2d716a5ccd5a07af08d180` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-1](../../../docs/server/mission-governance.md#L30) | csharp | `0929174b6bf458f1d0db73f113cd005e00a5ce93407c5d69a738909adc120e34` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-2](../../../docs/server/mission-governance.md#L47) | csharp | `5131a0bb4be7be8a0943270ca94380fcaf1759c76f9fbb8eeb899d9430444b4c` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-3](../../../docs/server/mission-governance.md#L73) | csharp | `a8404246de3f1e7822cc33ef206f7512eafcca57fd8531c9327cdc86d5aea309` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-4](../../../docs/server/mission-governance.md#L86) | csharp | `9c86ca8d5c857a77c5cda8a00a537e824485323c8dfbe18b82eb2930ef48299d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-5](../../../docs/server/mission-governance.md#L116) | csharp | `b8a2a6597f9e5b1036f489f9789a64bd126e916c998a367d717ab88a7156975e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-6](../../../docs/server/mission-governance.md#L160) | csharp | `a6ea4f6a22e08c569d0242def7f2b4c27ba515b520f1d3c41d032eb7b4f4753c` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-7](../../../docs/server/mission-governance.md#L181) | csharp | `c07bb779564ca8617323b705a5b425a664594800298692180b3a87f6c21c061f` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-8](../../../docs/server/mission-governance.md#L208) | csharp | `105b916146711aced92d7d80074212c2b7537948bed94bd7c106df8c0279b7c6` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-9](../../../docs/server/mission-governance.md#L228) | csharp | `9c75e9a011c4db9a6dd94d236cd363d8aff69be32afc9b8c55f128583cada718` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-10](../../../docs/server/mission-governance.md#L263) | csharp | `aa496876fc86c03c72b81be03ff89b086cf7d15b5af38662d8ceeb2176db1961` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/mission-governance.md:fence-11](../../../docs/server/mission-governance.md#L289) | csharp | `b584235697e60b1b3fca32784df25213d98741749597c9b2b0547080bc9c17bd` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-1](../../../docs/server/multi-scheme-verification.md#L17) | csharp | `c8198134084a2928380f0eb5a1c663418b1e3c93829d0aff961eea12ad939364` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-2](../../../docs/server/multi-scheme-verification.md#L38) | csharp | `ca3f5c03e1ec3d98c6a1f128c471d82ad87538c95075e47f70942cdebff0d8c7` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-3](../../../docs/server/multi-scheme-verification.md#L53) | csharp | `a7f5ea3495c9500375afbcbf6f18850b068169ae8316c5b5ea240eae9b1a6810` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-4](../../../docs/server/multi-scheme-verification.md#L90) | csharp | `c549c42e392eb77b21a9be7d12cbc026feaec39e50330af3d90f732fb7d24a7d` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-5](../../../docs/server/multi-scheme-verification.md#L108) | csharp | `7d202a69a2d4ae3f57f1d82f50ab0d8dede89a8338a96be1986739126aed3803` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/multi-scheme-verification.md:fence-6](../../../docs/server/multi-scheme-verification.md#L148) | csharp | `5e3ba2110e896250941db72a0628d360f15168554b96d61cfaedd35a5281675a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-1](../../../docs/server/replay-detection.md#L31) | csharp | `7906ea10bd162e2cd9b6ba7aecaa14237b976cefae4d2a23447c912262531e0f` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-2](../../../docs/server/replay-detection.md#L63) | csharp | `09fc840faab6a4f6c6d86016024907f0fc9a0c084f2da2f296932de402854ae3` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-3](../../../docs/server/replay-detection.md#L77) | csharp | `2eae1d7ccfa3ba21366c8958bec052401e1e0d57f8352842eea7f2ac14ad2a0e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-4](../../../docs/server/replay-detection.md#L114) | csharp | `dff4245cb513c99103ae6f0fa1c9f0a3067af014d06dad0ec61b5d147cf9f2fe` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-5](../../../docs/server/replay-detection.md#L132) | http | `e9a76494a170b39b4c79dcdad4d735e9f6f2c71bb55dc5016f5ee5cdec6f97ef` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-6](../../../docs/server/replay-detection.md#L151) | csharp | `f2318a774c641db9b082226e4b972d3f2fe2157ec065da122caf7e89878259cc` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/replay-detection.md:fence-7](../../../docs/server/replay-detection.md#L160) | csharp | `e1fad49da567283c748fa7cb216b0bc5e6b0c652761bf8c8f26795c0b125531a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/resource-metadata.md:fence-1](../../../docs/server/resource-metadata.md#L14) | csharp | `b74987e1b9562d30ee1aac6ed9efe8086c4ea3ea3792ca3cc14b30db6a1ef1b6` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/resource-metadata.md:fence-2](../../../docs/server/resource-metadata.md#L42) | csharp | `7ad0a361707dde9befc515b80271276fc6f08620e4837f81d95fe6c41d7f913a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/resource-metadata.md:fence-3](../../../docs/server/resource-metadata.md#L86) | json | `36f2513211f295424fc0771a2f1724e520b53cb05671f84be5ad008c4a3e42da` | JSON parsed; displayed identifiers/claims are illustrative | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/resource-metadata.md:fence-4](../../../docs/server/resource-metadata.md#L113) | csharp | `286a4f0f82b594d89f9f203a706a1df50a2c78bebd5b419c572f16ac5cb34065` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-1](../../../docs/server/token-issuance.md#L21) | csharp | `5ee6f1797d65f4934e4e6a8ddf6a34db7096440c4d6295508c8e66ed76254954` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-2](../../../docs/server/token-issuance.md#L60) | csharp | `a0c1030ffcacce406cbcac8e016261112a06ca0a365911219a1ba651e001b9cc` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-3](../../../docs/server/token-issuance.md#L120) | csharp | `64a76f617b1a61a7d6f805cca548d7281b75007c36b1b2cc7687a0044fea445d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-4](../../../docs/server/token-issuance.md#L134) | csharp | `f81a882adb8080f42d823a7d1c8e5adda6265538a9b11af5b09060709f22d9cc` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-5](../../../docs/server/token-issuance.md#L151) | csharp | `cf8cb848cfeff5a230ec0c7cac9e8e7c26635a482ecb63837c57020fa8a07c18` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-6](../../../docs/server/token-issuance.md#L181) | csharp | `f4a672ed46e1845f1155a662aa54250aef47a96320234b01e1982e9a074557ec` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-7](../../../docs/server/token-issuance.md#L197) | csharp | `7db70e896db2d2ab9e431fa2ed60f7c575c5659a0d976c9f975a455e0bd738a2` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-8](../../../docs/server/token-issuance.md#L231) | csharp | `188bc37ad492480035a393e9b43a44a9dcac7064d6674b3ead130f08d4d90eb0` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-9](../../../docs/server/token-issuance.md#L273) | csharp | `04272c70de15d4d2e358b3114e063958a3b75f59660ff072608e49c7cf6c1488` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/token-issuance.md:fence-10](../../../docs/server/token-issuance.md#L319) | csharp | `f9993e59c9e46eadb1304b38b7510e9399e60c2676f435769496be0c2fe3262a` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-1](../../../docs/server/verification-middleware.md#L21) | csharp | `811bd05d8f46c0f8f3c7353b9bb590bab57ba6824a6a9ba691873b1fe67bb9d4` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-2](../../../docs/server/verification-middleware.md#L53) | csharp | `bf48d39171c3517d63fb5fefc0262dab0382da5d87bbfbf3a3a328f058b48c07` | API excerpt: source member/type/sealed checks; not executable | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-3](../../../docs/server/verification-middleware.md#L116) | csharp | `b90687d59f3fc252b59e9b809dd20f079177b144be1d3563e5ba44e7b5ad2a06` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-4](../../../docs/server/verification-middleware.md#L158) | csharp | `bb54e64b7d69d8b0190bd5f2199beae6e0828520fca46a64d17e542af1565f8c` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-5](../../../docs/server/verification-middleware.md#L187) | csharp | `f804c31cf494662dd8616620587dbf622c204a37ff8e664aa39b80e5be12a64d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/server/verification-middleware.md:fence-6](../../../docs/server/verification-middleware.md#L237) | csharp | `de99d439b8a52fed34cb7938ae66aace64e7fca81d3b7ef0de47bb76c38e2fd9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-identity-jwks-uri.md:fence-1](../../../docs/signing-modes/agent-identity-jwks-uri.md#L24) | csharp | `815be2f926d465df3c70739c11446e52e34205d3e9be31c75910a394442ae6b3` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-identity-jwks-uri.md:fence-2](../../../docs/signing-modes/agent-identity-jwks-uri.md#L41) | csharp | `4223b631dde6d175810b763d8b01e83f1a81268025fa8a12a2892cadf53bd2d3` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-identity-jwks-uri.md:fence-3](../../../docs/signing-modes/agent-identity-jwks-uri.md#L62) | csharp | `2423c11fd2a7c46cd13b035042c59fce66571e89f7399b1421778112ead257e8` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-identity-jwks-uri.md:fence-4](../../../docs/signing-modes/agent-identity-jwks-uri.md#L85) | csharp | `abf057745fe363090532bc47768818aab2bdaff66b83278b8867e056dfc64d59` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-token-jwt.md:fence-1](../../../docs/signing-modes/agent-token-jwt.md#L23) | csharp | `c10eb026f7c8df657a6bfc2a458e7e401d496357bcd27c091320a2d55cbe4314` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-token-jwt.md:fence-2](../../../docs/signing-modes/agent-token-jwt.md#L45) | csharp | `ae17918215c333e7a440f06327198843c86315e901a9d76b1ca67413fb9f25de` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-token-jwt.md:fence-3](../../../docs/signing-modes/agent-token-jwt.md#L67) | csharp | `3dbaf7b7f5375054d5406f64fa3dd6c03554a44e7039fe30fcdea1720a583e3c` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/agent-token-jwt.md:fence-4](../../../docs/signing-modes/agent-token-jwt.md#L88) | csharp | `0a331c0810abc35952583bb5ed56637e84018a542f19daac534fd4e0518c23bb` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/key-rotation-jkt-jwt.md:fence-1](../../../docs/signing-modes/key-rotation-jkt-jwt.md#L40) | csharp | `788d31694a5054e3c79cca67532f176ff1b854c07d312c282d65d150c772ca16` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/key-rotation-jkt-jwt.md:fence-2](../../../docs/signing-modes/key-rotation-jkt-jwt.md#L60) | csharp | `549174c1c8b63db85c5f0a70258538b4a282acf9155e4707c73f7e1499c02bfd` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/key-rotation-jkt-jwt.md:fence-3](../../../docs/signing-modes/key-rotation-jkt-jwt.md#L73) | text | `16a09af4ae9cb0eea1e74ecf411de5e7a22ff9600f0327b2ebb59b12e52ad43d` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/overview.md:fence-1](../../../docs/signing-modes/overview.md#L53) | csharp | `179e6ae8b6bce76ecc625f3c1732bb75f178fb11792201908a13efcd48b42bad` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/overview.md:fence-2](../../../docs/signing-modes/overview.md#L79) | csharp | `64e3652eaacea006782d833eb2f6458169f3cad19aba15e8743c61fcca1d9e06` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/overview.md:fence-3](../../../docs/signing-modes/overview.md#L140) | | `c51bb14941dfd2a974e72632c58335e69b75b8f7612c11645caa6015050ab34f` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/overview.md:fence-4](../../../docs/signing-modes/overview.md#L160) | csharp | `d5239710aeaa3c3476f0953da689708d2d5f881fb9971ff8336b5350cabad81f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/pseudonymous-hwk.md:fence-1](../../../docs/signing-modes/pseudonymous-hwk.md#L22) | csharp | `80e97e819c897b4eb2baf4919deea3d7d9f41d1df50a48ef27029c875ea5a487` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/signing-modes/pseudonymous-hwk.md:fence-2](../../../docs/signing-modes/pseudonymous-hwk.md#L38) | csharp | `203c9c44c59ca678641d08c94633b6acaa10666898c10ac8c65117f776bd0acc` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-1](../../../docs/workflows/bootstrap-enrollment.md#L17) | mermaid | `8fb4b02275077260579d2028c2cda955a4fe48bdb8f45bb5e95e1b7b19ee2990` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-2](../../../docs/workflows/bootstrap-enrollment.md#L47) | mermaid | `7142634eed351a62e930ee0485ed027fce72b482014c378ed77fc25a5ca3bf07` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-3](../../../docs/workflows/bootstrap-enrollment.md#L72) | csharp | `38008f85054b932a20cc36b398dd11f20f8bb3a2bb1615a63af2270b04153d4f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-4](../../../docs/workflows/bootstrap-enrollment.md#L99) | csharp | `54499e9034430e599dd493f6c52bea0f2d28c8c2e398bdecb7dab6ee70f31cac` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-5](../../../docs/workflows/bootstrap-enrollment.md#L122) | csharp | `5208ecc5a173baab18e0a0d4ffd6582d011b2b77e31f02c7b5683162cb24d871` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-6](../../../docs/workflows/bootstrap-enrollment.md#L185) | mermaid | `95dfdccdd8cda2b23fcfefc9af509cdbe2eb62bf680bb01d44e49ffe25f42241` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-7](../../../docs/workflows/bootstrap-enrollment.md#L195) | csharp | `22b03aa23061769b68bae6209ccd5f258d4065492e454f5b88a79a0949582c8b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-8](../../../docs/workflows/bootstrap-enrollment.md#L213) | mermaid | `fc8f19771e35b4161d35675af383be5516ca2bb2be5e3623f8ed735a653bbbef` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-9](../../../docs/workflows/bootstrap-enrollment.md#L227) | csharp | `7928feaaa791cb35ad327ec776bf8d470d765f34fbee67fa352b70ae77a060e0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-10](../../../docs/workflows/bootstrap-enrollment.md#L246) | csharp | `3f213f776a663b92ef688d0503ba8cf46cd4f9a5ab59155cbc45587b5f9c2f1a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-11](../../../docs/workflows/bootstrap-enrollment.md#L275) | mermaid | `3fe7545f5cd256a4702adac9235d14b20209444fcef6f729fab593f851153b2e` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-12](../../../docs/workflows/bootstrap-enrollment.md#L290) | mermaid | `3e0e987681d6988fedd5040fd0097b24becfbaf40b5b9554818d4caac13b8364` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/bootstrap-enrollment.md:fence-13](../../../docs/workflows/bootstrap-enrollment.md#L312) | csharp | `3e4b4fd76315e664050db12f58b3a7077fca7debe8ab150ac056280e3f5b7b26` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-1](../../../docs/workflows/call-chaining.md#L10) | mermaid | `22ebbac9866d7c568778374c8ae42031882be2797f5d28cc9d30f57e55be7fd5` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-2](../../../docs/workflows/call-chaining.md#L43) | bash | `f826b23722d400413cdbf16e7703e572d9e318bd1554c6e09394ab98ef3568da` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-3](../../../docs/workflows/call-chaining.md#L56) | csharp | `ea36172635296ab1100daeb233ce2523039d482cbeb55a6743326e80e0d6e732` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-4](../../../docs/workflows/call-chaining.md#L86) | csharp | `e5b0863ba0d4fed112e65856490c32388de3b01148fe4f6d7c8587a398931d09` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-5](../../../docs/workflows/call-chaining.md#L127) | csharp | `0c03ae8db1a615b9ca7126571e1cafa9b3a498a6896f02d662ef9beeff129c33` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-6](../../../docs/workflows/call-chaining.md#L179) | csharp | `38afbc7c432079021ef070ea021709c13cc1fb18af96f3616890d3035c75bf5d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-7](../../../docs/workflows/call-chaining.md#L195) | csharp | `a9c7fd1056e709fe2077f525be36ed8c7cb08df9d531551f9a8c2c2dd28f814b` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-8](../../../docs/workflows/call-chaining.md#L212) | json | `bc01c5b9ac9a17f33add28d34f8ad7ad6bcf06beaf5b13492f9f9ae6c642a2a7` | JSON parsed; displayed identifiers/claims are illustrative | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-9](../../../docs/workflows/call-chaining.md#L226) | csharp | `7b2441ef9afb687565857c1d86744a62767a9fc10cd8c0d0116c31f901cfe0cd` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-10](../../../docs/workflows/call-chaining.md#L246) | bash | `584c7ab06338eba6c7c88794909d17a2f2dbc4fca04948a7eb4a17c45f5c5b1d` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-11](../../../docs/workflows/call-chaining.md#L254) | bash | `35620666721b67e7a7edbce46bfc3b8451b13f68f922020b71826907b6890d95` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-12](../../../docs/workflows/call-chaining.md#L288) | csharp | `c12b529f5d687be4c3a3ef335cc09e9e2bbfb751093720f48f7a8d4a30bc8650` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-13](../../../docs/workflows/call-chaining.md#L337) | csharp | `71bdeefea8e06b13985f80db8aa7bf7698bca6a6dc857e5f817a866b4071c203` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-14](../../../docs/workflows/call-chaining.md#L359) | csharp | `8bc9a094e364c7b31a5bb7269101f74c8d788ffe250b74a168e69e4b2e4c38b7` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/call-chaining.md:fence-15](../../../docs/workflows/call-chaining.md#L378) | csharp | `af1d3381558c359f7ca14c6a8521f87ba273ae9c3632e57593b5fdd590afdfbe` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/catalog-gateway.md:fence-1](../../../docs/workflows/catalog-gateway.md#L25) | mermaid | `93e9494ee56b324894bdfe8b38163b8d1ae7b103eb663e65fde68c104ff637da` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [docs/workflows/deferred-consent.md:fence-1](../../../docs/workflows/deferred-consent.md#L10) | mermaid | `00ec51bc7eda2b689cf9d6ba10c8a245ba87ca7ec6f47ce0ca3de6030b60e8e2` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/deferred-consent.md:fence-2](../../../docs/workflows/deferred-consent.md#L34) | csharp | `05c136c822cf29da2118c74d299a50fcbf4545c7cda0202611e30b883a9a7fc0` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/deferred-consent.md:fence-3](../../../docs/workflows/deferred-consent.md#L76) | csharp | `9fcacb93e19c2aefd99ec6682439a71950be5b0fbf6a347b4016d88565509b94` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/deferred-consent.md:fence-4](../../../docs/workflows/deferred-consent.md#L105) | csharp | `143dbe2ccfb70e7b818bd784121225da829dedced8a1666bdaf556b104be766e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/deferred-consent.md:fence-5](../../../docs/workflows/deferred-consent.md#L127) | csharp | `c624bc304e7f322d7cfef00b96931dc2a0688e7d3ef3cdd5d6c2e61e503f8c06` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/deferred-consent.md:fence-6](../../../docs/workflows/deferred-consent.md#L147) | csharp | `5c2ee3be607b48185f0de9fe039978f3744467f5eda3a785d1f0572172655e03` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/events.md:fence-1](../../../docs/workflows/events.md#L35) | csharp | `24516b52da00ebf5ae52f350ead1bdd68e3a6d8332563d41630b4b502d92a763` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [docs/workflows/federated-access.md:fence-1](../../../docs/workflows/federated-access.md#L10) | mermaid | `40bacbd2d2c391154a0cc973b2f4ce5ec6f5dd3edbb403a94da48efdc76701f8` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-2](../../../docs/workflows/federated-access.md#L30) | csharp | `a430f214b52bdef6f5d2d25fdd17fcbe6754c0e3e3dd23560e4fa392b6f6c2ba` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-3](../../../docs/workflows/federated-access.md#L53) | csharp | `8a5588f2698de1f2d6293dca30bfa027c22e96d3de0a9521189a3beb495cbbc9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-4](../../../docs/workflows/federated-access.md#L85) | csharp | `05da51c274240d914fc0fea8ce81167c6b7cb2fa2df1ae9ba71a797998794102` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-5](../../../docs/workflows/federated-access.md#L116) | csharp | `0e727da75ac8fa33743121b86e7809d7036d9493197c2edb2041b4bd2c3784fa` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-6](../../../docs/workflows/federated-access.md#L183) | mermaid | `3b7dd95436d621a2fa78f413ce835a07119771b1305e9fa2e642eea142d41eb2` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-7](../../../docs/workflows/federated-access.md#L233) | http | `e7a206e7b6b89d176c215e09e22b2a7964859e131dba06dd6be2a2b2b8fe5208` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/federated-access.md:fence-8](../../../docs/workflows/federated-access.md#L248) | csharp | `b5b17657c2f21500c04a7fbf0d21658ad07b915672cc02b297ad097e998ab36f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/identity-based-access.md:fence-1](../../../docs/workflows/identity-based-access.md#L15) | mermaid | `05705880d5a1938205c0a95e3241250182cf0102c13c3b66bd9715d351e16984` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/identity-based-access.md:fence-2](../../../docs/workflows/identity-based-access.md#L31) | csharp | `b7347af7fa4d88284f1da087b9960f252ae9c246d2ae11395f63b4c944784986` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/identity-based-access.md:fence-3](../../../docs/workflows/identity-based-access.md#L49) | csharp | `1677d4a34da1385bc723d166277e91448b495349c8e148713b673a3a39715f35` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/identity-based-access.md:fence-4](../../../docs/workflows/identity-based-access.md#L59) | csharp | `5b06eb779ffae1b138e57b21603e470cf44f1d04d2428ba6a9b6e1efd231a786` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/identity-based-access.md:fence-5](../../../docs/workflows/identity-based-access.md#L75) | csharp | `8b1be0d45c4e50710d7dae451f297c4110a38d2c6271239bc0daf62e5ff24a70` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-1](../../../docs/workflows/mission-governed-access.md#L24) | mermaid | `e15828d3d09005f9c0acaf2064845d67943fe51619e4b86493640766e03218a5` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-2](../../../docs/workflows/mission-governed-access.md#L54) | csharp | `23c1049e9c9015053481a7e9ec77f311809af5c3c62dee01ad82913df7253696` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-3](../../../docs/workflows/mission-governed-access.md#L77) | csharp | `9d291ad87e6b265b09b8b7eaeb22fb1794da1b5d335d255cde0164214033ca99` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-4](../../../docs/workflows/mission-governed-access.md#L102) | csharp | `fdb23e1761ef3725b5548438abaf64038290d25c97e1c22148b413f0e40817fd` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-5](../../../docs/workflows/mission-governed-access.md#L122) | csharp | `028bd539ef3847cb7f3254967acf57da1229a2b561f0ed696803e1eec9c641d9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/mission-governed-access.md:fence-6](../../../docs/workflows/mission-governed-access.md#L134) | csharp | `2ad504c204f703dc94c79261fecb7b28df99e162bd38dcd18c414851efa6293e` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/ps-asserted-access.md:fence-1](../../../docs/workflows/ps-asserted-access.md#L14) | mermaid | `0de7cda615daa6deaefe4aef90b4178a2a612dd2b6028dce864f816bc3d36063` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/ps-asserted-access.md:fence-2](../../../docs/workflows/ps-asserted-access.md#L31) | csharp | `d774708bc98b634f92b9dac74eaa4a762df3458c81fbc4cc233bb13c6e986aa9` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/ps-asserted-access.md:fence-3](../../../docs/workflows/ps-asserted-access.md#L56) | csharp | `d6cd0f5518385b5fa0262d252fd2d5b7697e3b81000b6d20598c67e376810885` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/ps-asserted-access.md:fence-4](../../../docs/workflows/ps-asserted-access.md#L83) | csharp | `763868a684ff734431d382b531111534c79ac806b00c184a6cf2020f5e600fd8` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/ps-asserted-access.md:fence-5](../../../docs/workflows/ps-asserted-access.md#L123) | csharp | `a1de2b2acea0ed0e09cb4a31a9ff5fed901ce0f4de5510dc4353f5df9886f98a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-1](../../../docs/workflows/resource-managed-access.md#L27) | mermaid | `1311bab4aa561ca9d5768b46a1c97291c01197f7e90c1d3cdfa0cb3053faa15f` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-2](../../../docs/workflows/resource-managed-access.md#L48) | csharp | `2d7a6fc2eb5fef0151546bb47ec1e47141df47c2c6d2b61043ddbb566b97a40f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-3](../../../docs/workflows/resource-managed-access.md#L89) | csharp | `79d83d9bd840df120fe577c149300c190209f1370d06f856b0684b96dcd2480a` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-4](../../../docs/workflows/resource-managed-access.md#L108) | csharp | `8f0ef7322541d3caac15b0017cd91d3fb559223f7a0e4c193bd41d32b749783d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-5](../../../docs/workflows/resource-managed-access.md#L150) | csharp | `dc05f23d5fb9884f58a1b2b0731bd2c0062be3d575848fb45d6e64b17f51acc7` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/resource-managed-access.md:fence-6](../../../docs/workflows/resource-managed-access.md#L168) | csharp | `f971b43a3443158cbc7f668bcb5fd3454f51697267078ed0515c95fa54b44c20` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/rich-resource-requests.md:fence-1](../../../docs/workflows/rich-resource-requests.md#L18) | mermaid | `d78e1da528f3365ebe6b5c2be1ae1bb421897b772d308820e1b027e34de3fad8` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/rich-resource-requests.md:fence-2](../../../docs/workflows/rich-resource-requests.md#L118) | csharp | `b9cf6ff9ba63ac09f6ff7729d2d54a5b26258d777327ca5953610386e045294d` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/rich-resource-requests.md:fence-3](../../../docs/workflows/rich-resource-requests.md#L157) | bash | `5816e2b6cfa2efce01d8b78f1ca2d84a83a16ee8faf044f01f941977d846e722` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [docs/workflows/wallet-protocol.md:fence-1](../../../docs/workflows/wallet-protocol.md#L35) | mermaid | `14d41ad83d3d0b1823a9f8d4c01d1028aca1e04d8ad5fbf0a56d92903c1f4a67` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [docs/workflows/wallet-protocol.md:fence-2](../../../docs/workflows/wallet-protocol.md#L67) | mermaid | `87e5ca581de9f5506245a50579360ea12a1cce823e9344d953bda6bd6cab709b` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [README.md:fence-1](../../../README.md#L56) | bash | `ef50764cc25e3e18dd0b4c55c31a13f834f879894febe875678dac6074841afa` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-2](../../../README.md#L90) | bash | `cf73836166aa56ef6ccc87b2f6e6fdb73f959c9b7c34b4a0b29e1063f00e1775` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-3](../../../README.md#L96) | bash | `0cc8bf77419b3cf5842a01e5350d865905b39fbe124a4b0fc90be9e8e4336218` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-4](../../../README.md#L105) | csharp | `bac6e655a77d637c9087c68c5c7cb823821acb0c1f1df96c5c1d29ddfb4ca8d2` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-5](../../../README.md#L129) | mermaid | `69f4f272a1a5fb4943d6421d4eeb91c41329908b753b667c271c4cf7a4a94b42` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-6](../../../README.md#L148) | csharp | `cad90ccccaa7ba2d836d8905d329bca86fbff2095c472ce3b7de2e8abd352297` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-7](../../../README.md#L191) | csharp | `116b127647aa535fbe338389965f4e05c9ba21481c1fbe7c31181fe9702ec812` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-8](../../../README.md#L231) | csharp | `5c0bb6168131ecb088bb2e7167e821f8a2f12d497b723f7695886593fe946b30` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [README.md:fence-9](../../../README.md#L275) | bash | `be9b05c3b3e1ca81497243c1dd96e2bdecc5e5d6dbea5feecf5ed021abe834a0` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/AgentConsole/README.md:fence-1](../../../samples/AgentConsole/README.md#L25) | bash | `da6dcde217b6c8f0a2407ed7d9108862f287daee9657046af43413a46152c472` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/AgentConsole/README.md:fence-2](../../../samples/AgentConsole/README.md#L64) | bash | `d05e133ab359ba8ab93d947b4612eae422d4efb66d48d006d9a8630ecba7c533` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/AgentConsole/README.md:fence-3](../../../samples/AgentConsole/README.md#L110) | bash | `eaf7d044a746e16e1235bdde143fc734a158006b49ff1625372406396c57dbd1` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:pre-1](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L54) | dynamic | `960c568905bbed3a86d989457e909fd8f9964fc8d3f1dc24b1c22d430f521eda` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:pre-2](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L63) | dynamic | `f6681b8cd4bf54cf386ff594c5b078bad752d3962ddaa6f7a7ba49c5783c4108` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:pre-3](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L68) | dynamic | `4c53b6a936934792c2af6215e2db6b9e045011808ac175948963fbddaf0ce6a5` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:pre-4](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L71) | dynamic | `633543aca320bce45c6e82b8d3aa56136e73f9de186c0a154d2361f43a6245af` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:inline-1](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L18) | inline-code | `a330395cc0a53ad1207736546afff4735940937564bbf75ce1edad40780d9139` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/CatalogWalkthrough.razor:Example-1](../../../samples/CapabilitySupport/CatalogWalkthrough.razor#L97) | csharp | `71accaca94f47b7b18672fd2ec4081a4f0c3c4eb7b49d1a52294c792ceefdd73` | Exact C# compiled with typed prior-step/host inputs | [Catalog session](../../../samples/CapabilitySupport/CatalogDemoSession.cs), [both-app Catalog wrapper](../../../tests/e2e/helpers/catalog.ts), R3VocabularyTests | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:pre-1](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L49) | dynamic | `960c568905bbed3a86d989457e909fd8f9964fc8d3f1dc24b1c22d430f521eda` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:pre-2](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L58) | dynamic | `f6681b8cd4bf54cf386ff594c5b078bad752d3962ddaa6f7a7ba49c5783c4108` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:pre-3](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L63) | dynamic | `4c53b6a936934792c2af6215e2db6b9e045011808ac175948963fbddaf0ce6a5` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:pre-4](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L70) | dynamic | `dfdfda84161e2e8725e2ce590f9aa2bf725c9c57b76fbdda94658d9495ccd100` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:EnrollExample-1](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L97) | csharp | `a617ca5c1b09b237d30560d3c5f0765861cd683f13a1a3ea03a807a59f3304d8` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:ChallengeExample-2](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L105) | csharp | `269732bf6289dab61c5e68e0302783cad97c86182446748fe03e48fb6a9094dc` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:AuthorizeExample-3](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L128) | csharp | `604512d5d95dc63c2f0332242b86dd7c16e58fc06174d755653bd7104a4f2d38` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/DocumentWalkthrough.razor:DownloadExample-4](../../../samples/CapabilitySupport/DocumentWalkthrough.razor#L145) | csharp | `8ec11a0a323c1b76fb58170416e4351bf567b87db256d56b069521738c446e11` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/CapabilitySupport/WalletScenarioCode.cs:Clarification-1](../../../samples/CapabilitySupport/WalletScenarioCode.cs#L12) | csharp | `300f1dc8aae5f7e8ddd977de213b44304e39a476fffd101d36d1af8e1081df15` | Exact C# compiled with typed prior-step/host inputs | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletScenarioCode.cs:DirectAs-2](../../../samples/CapabilitySupport/WalletScenarioCode.cs#L28) | csharp | `c9093037d1c5e6f358a04d35e53aef4bf3c5c1b1f3a3eed70467ea14b8981aa2` | Exact C# compiled with typed prior-step/host inputs | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletScenarioCode.cs:Revocation-3](../../../samples/CapabilitySupport/WalletScenarioCode.cs#L42) | csharp | `fbb10f53d35767bb4a81f302b729820caf7ea5a66c80009c1c23cc5ab92af0c6` | Exact C# compiled with typed prior-step/host inputs | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletWalkthrough.razor:pre-1](../../../samples/CapabilitySupport/WalletWalkthrough.razor#L72) | dynamic | `960c568905bbed3a86d989457e909fd8f9964fc8d3f1dc24b1c22d430f521eda` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletWalkthrough.razor:pre-2](../../../samples/CapabilitySupport/WalletWalkthrough.razor#L83) | dynamic | `f6681b8cd4bf54cf386ff594c5b078bad752d3962ddaa6f7a7ba49c5783c4108` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletWalkthrough.razor:pre-3](../../../samples/CapabilitySupport/WalletWalkthrough.razor#L90) | dynamic | `4c53b6a936934792c2af6215e2db6b9e045011808ac175948963fbddaf0ce6a5` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/CapabilitySupport/WalletWalkthrough.razor:pre-4](../../../samples/CapabilitySupport/WalletWalkthrough.razor#L95) | dynamic | `d8351c60920cb4b0703b309a35758b978d7662ccf01f6f7eca10183cbf9344d1` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/Concierge/README.md:fence-1](../../../samples/Concierge/README.md#L22) | mermaid | `ce36e8c963a10aa77577e26ab0ae692f6184c38392ccb6a2f2c6d62828013784` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/Concierge/README.md:fence-2](../../../samples/Concierge/README.md#L47) | json | `3fa8184a635d42f9f6aa1debcea6b4c9a6d066ba94fbed22041103f2bd1b6b62` | JSON parsed; displayed identifiers/claims are illustrative | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/Concierge/README.md:fence-3](../../../samples/Concierge/README.md#L63) | bash | `46f8207a3d5d546392406e73b274d1452d11ae3ba32335923e51aec841a493b3` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/Concierge/README.md:fence-4](../../../samples/Concierge/README.md#L69) | bash | `a9d9984ea1a54ebd2e00a96a2fbf0b35b241a95ba3daf27b5dff57cef5193177` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/Concierge/README.md:fence-5](../../../samples/Concierge/README.md#L86) | bash | `959040f0ddf0c8885eecc319426933702020aa35b7c7317eb3ca803c8322bda3` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/EventSupport/EventDemoCode.cs:Discover-1](../../../samples/EventSupport/EventDemoCode.cs#L6) | csharp | `4c08496c795da47ffeeef067ed604342297f2a1416eba5ac56594bedff961f75` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:SubscriptionUrl-2](../../../samples/EventSupport/EventDemoCode.cs#L20) | csharp | `fce4db2b5873fe22d33924fa7d3f0a89cc25f6ef877bbaa8dddc64d57a7681c7` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:SubscribeToken-3](../../../samples/EventSupport/EventDemoCode.cs#L42) | csharp | `92ac9b17715650b1987977f0bd39ee1be2a863d24d180d88d0b88176460f1b96` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:Registration-4](../../../samples/EventSupport/EventDemoCode.cs#L58) | csharp | `ba2f083563f3283ca6c54334fdd33dc9df793a4ea0f34da3275d08e1b03277f0` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:Delivery-5](../../../samples/EventSupport/EventDemoCode.cs#L69) | csharp | `66e58c7c5caab769f82276adfccdc516bc9059cc40caf57c4637814eff0de523` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:Receipt-6](../../../samples/EventSupport/EventDemoCode.cs#L95) | csharp | `94422df091136fd7439aa53017d27a5fdd42d20125c77565ead3252542252807` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventDemoCode.cs:Example-7](../../../samples/EventSupport/EventDemoCode.cs#L117) | csharp | `0901343f60d5327a499bfbb3e06e45ac350bcf2a2786424f22ec1e61cba945f0` | Exact C# compiled with typed prior-step/host inputs | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:pre-1](../../../samples/EventSupport/EventWalkthrough.razor#L77) | dynamic | `801c99dd70e212a2b17e7bef517927c061c6f650fbc0fc7526bd3bf70afa91ad` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:pre-2](../../../samples/EventSupport/EventWalkthrough.razor#L91) | dynamic | `801c99dd70e212a2b17e7bef517927c061c6f650fbc0fc7526bd3bf70afa91ad` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:pre-3](../../../samples/EventSupport/EventWalkthrough.razor#L99) | dynamic | `fb55299e105f11677a32e496c23df4d92552088c9bf98a73c2d7d1226e2852b4` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:pre-4](../../../samples/EventSupport/EventWalkthrough.razor#L107) | dynamic | `7e478bdbf354aa600e437516377ec7b9af4a4d6db522189c3d14d5fe536f8c90` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:inline-1](../../../samples/EventSupport/EventWalkthrough.razor#L111) | inline-code | `863bf7c94f3f72b6c318b98a9b92f2df1af6be67a28853c0d8effa70e1d4f112` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:inline-2](../../../samples/EventSupport/EventWalkthrough.razor#L112) | inline-code | `a7340e44c747eac6bf34d5537c3ed2ed153d05bf0e1855e09148ecbe49e2318e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/EventWalkthrough.razor:inline-3](../../../samples/EventSupport/EventWalkthrough.razor#L112) | inline-code | `5b1288bdb86ccf33cc0158da1a1f405c4095d9c00fe9dadd9c58af82ff2abae5` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/SampleAgentRegistry.cs:string-1](../../../samples/EventSupport/SampleAgentRegistry.cs#L23) | string | `e285f5757f47cd7faea567da3f3bafde6f93f10a26f6cc007cfcef4ed5ec8626` | SQL runtime literal: sample build and Events HTTP/persistence tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/SampleAgentRegistry.cs:Enrol-2](../../../samples/EventSupport/SampleAgentRegistry.cs#L42) | string | `56f5b25760b3ebe246dfcfa4a359265395bacc50074c0841692c1c4a0d30e8c5` | SQL runtime literal: sample build and Events HTTP/persistence tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/SqliteEventStore.cs:string-1](../../../samples/EventSupport/SqliteEventStore.cs#L23) | string | `a9b27688a79f18a425a6be96403e9e146f7afd081272fe8fd8e56762035b8926` | SQL runtime literal: sample build and Events HTTP/persistence tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/EventSupport/SqliteEventStore.cs:command-2](../../../samples/EventSupport/SqliteEventStore.cs#L103) | string | `ead256ccd2524c1a0fc689ba067018a7b4b0a1cb9b2a64d3d31c433b1ab7a5a1` | SQL runtime literal: sample build and Events HTTP/persistence tests | [Event session](../../../samples/EventSupport/EventDemoSession.cs), [both-app Events wrapper](../../../tests/e2e/helpers/events.ts), EventHttpTests / EventPersistenceTests | +| [samples/GuidedTour/CodeSnippets.cs:GenerateKey-1](../../../samples/GuidedTour/CodeSnippets.cs#L9) | csharp | `21b946b214898fb08303f7addd03cd0ec1300e57e9c637a3289d4ee4115c94fd` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:SelfSignAgentToken-2](../../../samples/GuidedTour/CodeSnippets.cs#L15) | csharp | `ce47e50477c4ec8ce65f9c1ecb7f62218032be9d2c89da477931d492c323b100` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:DiscoverAp-3](../../../samples/GuidedTour/CodeSnippets.cs#L27) | csharp | `e4535d607db2cddd19acf208ac3fd8ddd42b481ce296bd5dfbb2e6fe96843b88` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:EnrolWithAp-4](../../../samples/GuidedTour/CodeSnippets.cs#L35) | csharp | `423655dcce44e5b30f92577991b1cf79687be59c14fb0a03d76338b691cb2aab` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:DiscoverResource-5](../../../samples/GuidedTour/CodeSnippets.cs#L52) | csharp | `788ac9129f217dd6a79107f10ba403ecea3d9a3a6d633bae351a1280ea00dae4` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:SignedGetHwk-6](../../../samples/GuidedTour/CodeSnippets.cs#L59) | csharp | `8a48f86d17c688ceb7567f354d106c97112bbd7b42859d8f3f9889333d3239bb` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:SignedGetJwksUri-7](../../../samples/GuidedTour/CodeSnippets.cs#L68) | csharp | `caeb3471e20f665be3e757e44224925dabf456ace5887216a15b55c7055d8188` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:SignedGetJwt-8](../../../samples/GuidedTour/CodeSnippets.cs#L81) | csharp | `ba35e32577e927ad2e98210de65810a7f4e08c3fd3b2ccb76e59facf231599bf` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:SignedGetJktJwt-9](../../../samples/GuidedTour/CodeSnippets.cs#L91) | csharp | `ba2039b150d2afa6319a5bfe933f4025fd023b248e6d9772a0ae4228050e4f79` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:ParseChallenge-10](../../../samples/GuidedTour/CodeSnippets.cs#L110) | csharp | `2a56f139c2ab754b09f7b496febbc85ded5c4065d53df0f409c7b0de4e785706` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:DiscoverPs-11](../../../samples/GuidedTour/CodeSnippets.cs#L119) | csharp | `5f6cab58db0dc0fb37f38afc3006049802cafd1dc7e5e7f097ee40a52558612e` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:TokenExchangeDirect-12](../../../samples/GuidedTour/CodeSnippets.cs#L127) | csharp | `d4744fb56788b8f73886630139fc863ed935380677ef620ea5786717ab33b4b5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:TokenExchangeDeferred-13](../../../samples/GuidedTour/CodeSnippets.cs#L141) | csharp | `6df55f68f784031193137197276880f2ac36f952e2fe6e3a102ac0e061e9e9b4` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:DirectUserToInteraction-14](../../../samples/GuidedTour/CodeSnippets.cs#L160) | csharp | `ee7917714f40d8d5174cd05e70f6fed20cab7a532c5777ccf32154ef4d213ce5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:PollPending-15](../../../samples/GuidedTour/CodeSnippets.cs#L170) | csharp | `86183d2c380d999addcc32f9e6e926c8f47b9f53ac0f5929dd6486aae5524e3d` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:ReplayWithAuthToken-16](../../../samples/GuidedTour/CodeSnippets.cs#L185) | csharp | `4c0f6df68d81abb61221e2c37e15ed0ee2e0236b4e049153552eecfe2add479b` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:R3AccountRequest-17](../../../samples/GuidedTour/CodeSnippets.cs#L194) | csharp | `26f319d26d43d4aee978549e0b5f4e176443cafb3ef1391afd2c378ce4632806` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:R3ConfirmConditional-18](../../../samples/GuidedTour/CodeSnippets.cs#L204) | csharp | `a587c56db7bbeaaef596904332a339a81dacb1f48ffc3058bf6bc9efb9a8f11d` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:ResourceManagedSignedGet-19](../../../samples/GuidedTour/CodeSnippets.cs#L244) | csharp | `f6e99840bd42dc6c92325ab5acf7c6b88e595bef11e6cef45d7d450b54405f14` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:ResourceManagedPoll-20](../../../samples/GuidedTour/CodeSnippets.cs#L273) | csharp | `b0dce400615b7271f131d9778d8c87a422fa37c64ca36de5103b236f51c7fe54` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:ResourceManagedReplay-21](../../../samples/GuidedTour/CodeSnippets.cs#L287) | csharp | `c10c25d374c0171a1c3bb0c00667a29ebd241741c19fd63f7c751d4ebbc3c822` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:CallChainRetry-22](../../../samples/GuidedTour/CodeSnippets.cs#L301) | csharp | `b0ae9091170ad7d018eeaa79734efcfb9accb8ddd3a757aef67ddb1345ea81ae` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:CallChainConvenience-23](../../../samples/GuidedTour/CodeSnippets.cs#L318) | csharp | `f0d7586c5c500251b52e9db1c602d0158fdfd55d5373019e7867a7b617bca81f` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:FullAutomatic-24](../../../samples/GuidedTour/CodeSnippets.cs#L337) | csharp | `9920a812217445144b25f88011521c3de61d89183681e744acccaac0674273ad` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionDiscoverPs-25](../../../samples/GuidedTour/CodeSnippets.cs#L362) | csharp | `ad57bc4a425b5c48a23830fee7e3b37d31c0d5cb7eb795c0a1b1babd2931dba6` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionPropose-26](../../../samples/GuidedTour/CodeSnippets.cs#L372) | csharp | `2d5eef7b385bd74bc8488f438118697bece6bb7275ac3206b01e51efe0312613` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionPollCreate-27](../../../samples/GuidedTour/CodeSnippets.cs#L390) | csharp | `99cc7e2e467415325bf612b1b37ccd2ac2f7486f4d6047aec25881739583df84` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionChallenge-28](../../../samples/GuidedTour/CodeSnippets.cs#L397) | csharp | `7dca92c6d5e50b23611831f769389dc564499f1fc3bbd62c7dd95199c5934b09` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionExchange-29](../../../samples/GuidedTour/CodeSnippets.cs#L408) | csharp | `e8ca2f37093ed91da082841c08dee5530685adb7ea3fa120f8cc259a1340f211` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionReplay-30](../../../samples/GuidedTour/CodeSnippets.cs#L415) | csharp | `23f9243a5240d8be933a6e49f8453c954c0ab9b31e437cba9fcf33aea4b10bf9` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionElevatedChallenge-31](../../../samples/GuidedTour/CodeSnippets.cs#L422) | csharp | `8cecf857001f15d5bca1b1a4347c8210b78de6c10f1f2422a7c435b479024a29` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionElevatedExchange-32](../../../samples/GuidedTour/CodeSnippets.cs#L433) | csharp | `d77c75d1e077e902fa0e6000f55aecc341abc6db9d237cfea499f02af1ae2e5e` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionElevatedPoll-33](../../../samples/GuidedTour/CodeSnippets.cs#L441) | csharp | `d0943b292cace3708e9546a0fe28194ae94aebda9e63113de7425028e12207ad` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionElevatedReplay-34](../../../samples/GuidedTour/CodeSnippets.cs#L451) | csharp | `bfd0882c359730d8c408475e1dc63858377d161e7d112e5844aaaf2592d66449` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionPreApproved-35](../../../samples/GuidedTour/CodeSnippets.cs#L458) | csharp | `d554532907c41959dcd47c56cad5954081adac9c7e832aeb0008e084687b90c2` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionPermissionPrompt-36](../../../samples/GuidedTour/CodeSnippets.cs#L466) | csharp | `cd84784c47a1affafef70fd9c53a7b035b809833c61944175bcac24beab5eeeb` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionPollPermission-37](../../../samples/GuidedTour/CodeSnippets.cs#L474) | csharp | `a50291cf55b31f787b975a04781f08adf784330ae608476b4e8a05ca11e863e2` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionInspect-38](../../../samples/GuidedTour/CodeSnippets.cs#L483) | csharp | `dac0f90d3f97a247e7dead703e272fc493147c3071e2d443e9bb38c0db9beec2` | C# comment-only narrative: reviewed against the associated scenario; no executable statements | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionChainClarify-39](../../../samples/GuidedTour/CodeSnippets.cs#L495) | csharp | `f653316e6799380988646b694200a2bd9bc9f02acbc01ebb2868a7c741228036` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionChainAnswer-40](../../../samples/GuidedTour/CodeSnippets.cs#L511) | csharp | `6f4af29f39cac9cbcf07379e858c6e762554ed60d68f1ca8320967730817672f` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionChainForward-41](../../../samples/GuidedTour/CodeSnippets.cs#L529) | csharp | `b7150b1cc8ff0c92e3d1d878414c40c67974d0c2fafc79f579f2c5a6ec6e9ecb` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/CodeSnippets.cs:MissionChainLog-42](../../../samples/GuidedTour/CodeSnippets.cs#L544) | csharp | `3de43cfef093fc4c63c7c0929f4dc86ac9d636107c056acb94848903e120061d` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Home.razor:inline-1](../../../samples/GuidedTour/Components/Pages/Home.razor#L42) | inline-code | `dcaadad1cfce437735b81ab025f776e5857e48558c47f6960e6a5f2595664a85` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:pre-1](../../../samples/GuidedTour/Components/Pages/Tour.razor#L75) | dynamic | `f6681b8cd4bf54cf386ff594c5b078bad752d3962ddaa6f7a7ba49c5783c4108` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-1](../../../samples/GuidedTour/Components/Pages/Tour.razor#L117) | inline-code | `84e925d67edae8780e32bf145b35353d9aa74a63c3a6cbd96e75d468e11e3996` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-2](../../../samples/GuidedTour/Components/Pages/Tour.razor#L119) | inline-code | `85a84e034c5b9248758c500f6c1f2b8bb99c9818ce7902ee5bc702c07ecda5a0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-3](../../../samples/GuidedTour/Components/Pages/Tour.razor#L138) | inline-code | `955397113a3ffe4b79dd6934ed974eb571732b022b60e3bb5207b902fe7cac41` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-4](../../../samples/GuidedTour/Components/Pages/Tour.razor#L138) | inline-code | `5a8b62d7eba85f3852843ab71ee21fd8953f7d758209640e73af66a60c744b28` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-5](../../../samples/GuidedTour/Components/Pages/Tour.razor#L138) | inline-code | `0ce6f90588bf21bd3aa8bbf29b811d4ecf1b4c20a18077a6787695ceb513796e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-6](../../../samples/GuidedTour/Components/Pages/Tour.razor#L139) | inline-code | `27badc983df1780b60c2b3fa9d3a19a00e46aac798451f0febdca52920faaddf` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-7](../../../samples/GuidedTour/Components/Pages/Tour.razor#L163) | inline-code | `fc93cb07e1ad92898527100e58a1cf1d1e7f65e9a266a6f87f3c84feb541c7b3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-8](../../../samples/GuidedTour/Components/Pages/Tour.razor#L167) | inline-code | `15f5cae60e1bf3d5506ee18bfdf7fa27058133366c46eac160e394adea092e95` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-9](../../../samples/GuidedTour/Components/Pages/Tour.razor#L168) | inline-code | `c17edaae86e4016a583e098582f6dbf3eccade8ef83747df9ba617ded9d31309` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-10](../../../samples/GuidedTour/Components/Pages/Tour.razor#L170) | inline-code | `0176343e4a437b2b37db94a36274da651d05b5e009cde3cb7a367b5d6feb6300` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-11](../../../samples/GuidedTour/Components/Pages/Tour.razor#L171) | inline-code | `acac590c4e2b13cb3afae05af5a41ead9867cd270976158334fa2144173ce7f4` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-12](../../../samples/GuidedTour/Components/Pages/Tour.razor#L172) | inline-code | `cbb82ebec6051b780ad26655ee48b5b42658c4ac49438888aac829e82195584f` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-13](../../../samples/GuidedTour/Components/Pages/Tour.razor#L182) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-14](../../../samples/GuidedTour/Components/Pages/Tour.razor#L184) | inline-code | `847d2cc70f450deb2a4280c1ef0af9c041d7517c5c94216996d9fe34d7efc6fc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-15](../../../samples/GuidedTour/Components/Pages/Tour.razor#L185) | inline-code | `27badc983df1780b60c2b3fa9d3a19a00e46aac798451f0febdca52920faaddf` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-16](../../../samples/GuidedTour/Components/Pages/Tour.razor#L185) | inline-code | `b00171bacea319da2f65495e86d96c717707642f52b7273a7b1f8536d6728904` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-17](../../../samples/GuidedTour/Components/Pages/Tour.razor#L186) | inline-code | `27badc983df1780b60c2b3fa9d3a19a00e46aac798451f0febdca52920faaddf` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-18](../../../samples/GuidedTour/Components/Pages/Tour.razor#L194) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-19](../../../samples/GuidedTour/Components/Pages/Tour.razor#L196) | inline-code | `847d2cc70f450deb2a4280c1ef0af9c041d7517c5c94216996d9fe34d7efc6fc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-20](../../../samples/GuidedTour/Components/Pages/Tour.razor#L196) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-21](../../../samples/GuidedTour/Components/Pages/Tour.razor#L198) | inline-code | `b00171bacea319da2f65495e86d96c717707642f52b7273a7b1f8536d6728904` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-22](../../../samples/GuidedTour/Components/Pages/Tour.razor#L207) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-23](../../../samples/GuidedTour/Components/Pages/Tour.razor#L210) | inline-code | `cbdd8637f090e7de25403ed8482aae56b66be61046629696f01c8ca3d3a03d63` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-24](../../../samples/GuidedTour/Components/Pages/Tour.razor#L210) | inline-code | `f83f07be16e270186d35b876916c461995ebc3af5b1798f898c33285a1847dbc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-25](../../../samples/GuidedTour/Components/Pages/Tour.razor#L226) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-26](../../../samples/GuidedTour/Components/Pages/Tour.razor#L228) | inline-code | `0926d7734e784737b4b462e2daa3c6db041ee5c01b75a7a2b3ba9463d2efc8cc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-27](../../../samples/GuidedTour/Components/Pages/Tour.razor#L229) | inline-code | `4275d71e90f7f09f9dcbba2aeeaafb3f30576780bc4d5419ff086d1c6f02a654` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-28](../../../samples/GuidedTour/Components/Pages/Tour.razor#L230) | inline-code | `1c070c9accb1b9877eb7211654cfab9da4864d973942a4a088c992d71880b900` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-29](../../../samples/GuidedTour/Components/Pages/Tour.razor#L232) | inline-code | `1744bb6c1da2e55193e9eb4afe485e275c8cc30a2b1d1b9c100170d36fe9e520` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-30](../../../samples/GuidedTour/Components/Pages/Tour.razor#L232) | inline-code | `c68c500e222872c83bbfe1cd0ccbb6a060bb88f1c53092a46ca9d182f0071362` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-31](../../../samples/GuidedTour/Components/Pages/Tour.razor#L235) | inline-code | `a6ef89c2e28ae06c35306edd800dc0258b1243653636e119527a5e6da515b605` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-32](../../../samples/GuidedTour/Components/Pages/Tour.razor#L236) | inline-code | `f55a0838018af0b222392c581b4cea6e096822c40b20aaad4b477534b29d3105` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-33](../../../samples/GuidedTour/Components/Pages/Tour.razor#L245) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-34](../../../samples/GuidedTour/Components/Pages/Tour.razor#L249) | inline-code | `2336af25ca724d260446e47a636db7453efc335df448c2a57d4c67ac9965dbbe` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-35](../../../samples/GuidedTour/Components/Pages/Tour.razor#L249) | inline-code | `918b5d5b47d72b6172fa5a85ec1c985117cc12caed86669ef718adc028ecc3e0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-36](../../../samples/GuidedTour/Components/Pages/Tour.razor#L250) | inline-code | `2336af25ca724d260446e47a636db7453efc335df448c2a57d4c67ac9965dbbe` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-37](../../../samples/GuidedTour/Components/Pages/Tour.razor#L252) | inline-code | `918b5d5b47d72b6172fa5a85ec1c985117cc12caed86669ef718adc028ecc3e0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-38](../../../samples/GuidedTour/Components/Pages/Tour.razor#L266) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-39](../../../samples/GuidedTour/Components/Pages/Tour.razor#L269) | inline-code | `fd8abb915cb6b7b4241439d7d6ee2eb1bde2e21ba93940838c879f61e44c4723` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-40](../../../samples/GuidedTour/Components/Pages/Tour.razor#L270) | inline-code | `59874580919614e8a19e5d82d568d118a39d1c77aa0deaae1aa37369d3aacdf3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-41](../../../samples/GuidedTour/Components/Pages/Tour.razor#L271) | inline-code | `362ffea7eba1c3fb91e988f6a8e6c90e6d34adc562b19a9ec247ad4872b6c2a7` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-42](../../../samples/GuidedTour/Components/Pages/Tour.razor#L273) | inline-code | `7c1709777753420426f1975bc36fbd5af8835ea2185d922da2f4f17c69385f51` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-43](../../../samples/GuidedTour/Components/Pages/Tour.razor#L282) | inline-code | `cc74afc5e8c7a8fd5f31a335420d47cad94f36907a0b45ca5a11e56d66588894` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-44](../../../samples/GuidedTour/Components/Pages/Tour.razor#L284) | inline-code | `59874580919614e8a19e5d82d568d118a39d1c77aa0deaae1aa37369d3aacdf3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-45](../../../samples/GuidedTour/Components/Pages/Tour.razor#L288) | inline-code | `cbe370481704cef068c18bdcbe262329c59824d6c87e96510a53f022e899ab04` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-46](../../../samples/GuidedTour/Components/Pages/Tour.razor#L288) | inline-code | `fd8abb915cb6b7b4241439d7d6ee2eb1bde2e21ba93940838c879f61e44c4723` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-47](../../../samples/GuidedTour/Components/Pages/Tour.razor#L289) | inline-code | `1d19d95194d3a6778086865e392af37d00878f492175c4da1ef1fcf06ff9053a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-48](../../../samples/GuidedTour/Components/Pages/Tour.razor#L305) | inline-code | `95948aaf48cdbe9be781310fec6efeeda040176c315d86bfee702bc8d3e5e45e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-49](../../../samples/GuidedTour/Components/Pages/Tour.razor#L306) | inline-code | `b4faf09bff5df62d00ae465b5a857212c546f28af498bb268f524646cbdf07d2` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-50](../../../samples/GuidedTour/Components/Pages/Tour.razor#L307) | inline-code | `847d2cc70f450deb2a4280c1ef0af9c041d7517c5c94216996d9fe34d7efc6fc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-51](../../../samples/GuidedTour/Components/Pages/Tour.razor#L308) | inline-code | `9b573f58833b299cb4b692346359185025c5cab22f6e67526bc5b6cd7f59ca34` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-52](../../../samples/GuidedTour/Components/Pages/Tour.razor#L308) | inline-code | `cbdd8637f090e7de25403ed8482aae56b66be61046629696f01c8ca3d3a03d63` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-53](../../../samples/GuidedTour/Components/Pages/Tour.razor#L309) | inline-code | `b00171bacea319da2f65495e86d96c717707642f52b7273a7b1f8536d6728904` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-54](../../../samples/GuidedTour/Components/Pages/Tour.razor#L310) | inline-code | `f83f07be16e270186d35b876916c461995ebc3af5b1798f898c33285a1847dbc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-55](../../../samples/GuidedTour/Components/Pages/Tour.razor#L310) | inline-code | `fd2da7beee5bc42ab2cc85f89023af7d2680c950518630da65c7f8bc60e24682` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/Pages/Tour.razor:inline-56](../../../samples/GuidedTour/Components/Pages/Tour.razor#L330) | inline-code | `b62fca272b30c6783890e46edbd8a46fd17b5343cd41aa68c156d33eec5b7ada` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/PayloadInspector.razor:pre-1](../../../samples/GuidedTour/Components/PayloadInspector.razor#L13) | dynamic | `93ce3c571d3be894c314890526bdcfaa4ff712bdf926c77384aefdf4f386fcb4` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/PayloadInspector.razor:pre-2](../../../samples/GuidedTour/Components/PayloadInspector.razor#L21) | dynamic | `c392fc249d5c363963d8429cc3214d264dd6683149bb15527db80c78bacd91b6` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/PayloadInspector.razor:pre-3](../../../samples/GuidedTour/Components/PayloadInspector.razor#L29) | dynamic | `9a8b8a8d428b6572da32a11966d6c8adbbeb92b83b491c00d83e9eb33d70df3b` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/PayloadInspector.razor:pre-4](../../../samples/GuidedTour/Components/PayloadInspector.razor#L37) | dynamic | `dd36f4e108d50c7908bccb7ce5ea5d538acf630f10394bcb26850931f5a14e52` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/PayloadInspector.razor:inline-1](../../../samples/GuidedTour/Components/PayloadInspector.razor#L109) | inline-code | `999e6f1c71d8fb109e79cac42809ddb374b7ce24c6aff52d6f71414fd4eef76e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/TokenView.razor:pre-1](../../../samples/GuidedTour/Components/TokenView.razor#L8) | dynamic | `b647944b0992dae104a63d5191b89d56bf8ccd1211fc0cb0159aa5d44dc22d25` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/TokenView.razor:pre-2](../../../samples/GuidedTour/Components/TokenView.razor#L16) | dynamic | `2a9cf719f0118d2ba42f093d45dd765b8b75b8c0e19578553b1d4e151706fbd6` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/TokenView.razor:pre-3](../../../samples/GuidedTour/Components/TokenView.razor#L24) | dynamic | `e211148e496440f8f241df3d0f9ac95252208e89ee216db3a968d0a8d3aa9868` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/Components/TokenView.razor:pre-4](../../../samples/GuidedTour/Components/TokenView.razor#L32) | dynamic | `a4c1637eefc9eb85bcc4a14d77b9063bc5d5820fb8d67067d71adcc0eb523f00` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/README.md:fence-1](../../../samples/GuidedTour/README.md#L82) | json | `b887277671e7f7911bc43eec0cbe331eab6dc1b9c064e9e110d10b34c0d6b89f` | JSON member fragment parsed inside an explicit object | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/README.md:fence-2](../../../samples/GuidedTour/README.md#L227) | bash | `549ee4073d83ddc3114327176a7908e2a284a36b8fdd273b15c32ea6b359ee88` | Shell syntax checked; side-effect commands not executed | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/README.md:fence-3](../../../samples/GuidedTour/README.md#L238) | bash | `7908132f61d44ec1923e38fe282539e64ab07af23700f19983e7ecdad08dbc69` | Shell syntax checked; side-effect commands not executed | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:RunLiveWorkerStepAsync-1](../../../samples/GuidedTour/TourSession.cs#L1720) | csharp | `453115ac5193c053d5567b341afcdef1aefb2d6952f2c916c3d8a583cf6fee3c` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:RunLiveWorkerStepAsync-2](../../../samples/GuidedTour/TourSession.cs#L1724) | csharp | `04b49a4d7dc5dbfff8937ede6e6d56930c86d999cc881b664c934c643687d9c9` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:RunLiveWorkerStepAsync-3](../../../samples/GuidedTour/TourSession.cs#L1729) | csharp | `972cb4bc4c4c557900f500c044316848ebeb6265d9b827ca3e0696de15c6600e` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:RunLiveWorkerStepAsync-4](../../../samples/GuidedTour/TourSession.cs#L1733) | csharp | `1ddeb71d5738bf23eef8e7d127f82bdb8013689ddc2ea1b44cca3e13cca553d5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:RunLiveWorkerStepAsync-5](../../../samples/GuidedTour/TourSession.cs#L1738) | csharp | `04b49a4d7dc5dbfff8937ede6e6d56930c86d999cc881b664c934c643687d9c9` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:SubAgentParentTokenSnippet-6](../../../samples/GuidedTour/TourSession.cs#L1752) | csharp | `c9021e7b8e3230000542e62605645bf210def1f54bb0179ec56fddae4263390e` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/GuidedTour/TourSession.cs:SubAgentWorkerTokenSnippet-7](../../../samples/GuidedTour/TourSession.cs#L1781) | csharp | `f78e0838242d7a2d00e19ddfec9992b429ce7b49b37ba22ffd43d431896b5290` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/MissionAgent/README.md:fence-1](../../../samples/MissionAgent/README.md#L40) | text | `bcfaa4e9d3e305a2c818fcbfca9803e27514aa234d9b78737d3575890844c00c` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-2](../../../samples/MissionAgent/README.md#L75) | mermaid | `82dd67d555ac281b97653839d8f481cfe941c2d8b3a4dfb2f6d4ddca16a188c0` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-3](../../../samples/MissionAgent/README.md#L158) | mermaid | `233ff267d646e521caa316320736714ff16fffe3426974918fa5524f39a2356d` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-4](../../../samples/MissionAgent/README.md#L195) | bash | `838a32c5ef76042a5f120e1f45b698ecf8377cd4d8a2797d4aafeaf178054fd3` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-5](../../../samples/MissionAgent/README.md#L203) | bash | `bd7ab6ab70caf732d08b4223362ea66441a16561ceb9deccc923f1a4ec55000e` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-6](../../../samples/MissionAgent/README.md#L212) | bash | `0aefdf441df667f5b30966946bae9b51f0d985202c7733e922153372f3dc9db4` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-7](../../../samples/MissionAgent/README.md#L218) | bash | `65bda3d6cd1ce8e88a9e5b1713b70a5f5adf9e38fc952dd112e43bc0ffe45d13` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-8](../../../samples/MissionAgent/README.md#L240) | bash | `427b1ed2e66a5a4f6a0aefc63af97fb7302faca5732b5075e0221597f6026f7e` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MissionAgent/README.md:fence-9](../../../samples/MissionAgent/README.md#L252) | bash | `484a6b139145eb4a4d9af3a00a3a49cd05ceffb2b2aa6551766927ee693ffb90` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAccessServers/Federated/README.md:fence-1](../../../samples/MockAccessServers/Federated/README.md#L57) | bash | `32f77f60c1f6fc0cf6fa4bb1475f12e200abe5ff78c303c1d000148c91436309` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAccessServers/Federated/README.md:fence-2](../../../samples/MockAccessServers/Federated/README.md#L102) | bash | `ef23884b8e86b32a20334a454f384e08564ead9deb5ecd297febd6a6b34b5400` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAccessServers/Federated/README.md:fence-3](../../../samples/MockAccessServers/Federated/README.md#L108) | bash | `481ed1eda6a4d531693df0199810be3eaa64e4a006cdcf7a12a2b68cc47ceb5b` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAccessServers/README.md:fence-1](../../../samples/MockAccessServers/README.md#L53) | bash | `84bc1a5edb19022f5b273a7dca7a5110fa0986a0083c40d53de78ec7d1483348` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAgentProvider/README.md:fence-1](../../../samples/MockAgentProvider/README.md#L28) | bash | `016d1fa45df9833e0ba49e8da141e5bee17880475b58e33588eee4276e2a00d8` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAgentProvider/README.md:fence-2](../../../samples/MockAgentProvider/README.md#L36) | bash | `db82207af68a01be6c3d5a244232b509e1723c3af0e3697b2e9aaf0b55dd38bd` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockAgentProvider/README.md:fence-3](../../../samples/MockAgentProvider/README.md#L47) | json | `720b972c0fd1f4f7a5a82ba89556a3173dbe83aa8408ed64d96e91252eb11012` | JSON parsed; displayed identifiers/claims are illustrative | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockPersonServer/README.md:fence-1](../../../samples/MockPersonServer/README.md#L109) | bash | `b183ed4a8dfcaa44c29c99bc03fdfbd48a243beb13c4c5fa866387c24c5fd988` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockPersonServer/README.md:fence-2](../../../samples/MockPersonServer/README.md#L117) | bash | `07d9570f472918f18e9d0ce724b66b667dce93392f42cc8e6361efb29bd9a33a` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Bookings/README.md:fence-1](../../../samples/MockResourceServers/Bookings/README.md#L76) | bash | `e985208fee44b1458815a5da292860d021ea36083336c8ef45496787bda7e1a9` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Calendar/README.md:fence-1](../../../samples/MockResourceServers/Calendar/README.md#L32) | bash | `26cd5505c29422ddb1032d5c73126f4d17fd74dafedcc90f62ea708a60ef4748` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Calendar/README.md:fence-2](../../../samples/MockResourceServers/Calendar/README.md#L38) | bash | `b796154a6bf6f11e544824eff3272f406c0d9201ec8c294ccafd658c6e4c0039` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Inbox/README.md:fence-1](../../../samples/MockResourceServers/Inbox/README.md#L47) | mermaid | `7a71808473223e00cb7c9984355f08a6b9606b1c89f49408f2b0b4e99c06aad3` | Sequence/flow source checked; actors/order reviewed against mapped scenario | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Inbox/README.md:fence-2](../../../samples/MockResourceServers/Inbox/README.md#L68) | bash | `c790576af4dcd14a1537ae6fa6674f2ab50661541b9fbdb9af096688ec51ba86` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Inbox/README.md:fence-3](../../../samples/MockResourceServers/Inbox/README.md#L74) | bash | `a2d7f1d07d36514b00f978956271682193f50122db6d7408a0f534f56ad8bb44` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Profile/README.md:fence-1](../../../samples/MockResourceServers/Profile/README.md#L44) | bash | `c2d4c4475e969b89e1c03350f8f072993a747c1e6d8eb829872baa69596ecca2` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Profile/README.md:fence-2](../../../samples/MockResourceServers/Profile/README.md#L53) | bash | `99b4b4891c12309a5d1cb10008a5be793de0af11699f30271ef428ad74f4b4a2` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/README.md:fence-1](../../../samples/MockResourceServers/README.md#L80) | bash | `916b5235d2fe61a422594a603f3bb8044a31ce2e224831e131fb4939ff260ea8` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/README.md:fence-2](../../../samples/MockResourceServers/README.md#L86) | bash | `721fe8dc2df254017febc2383bc5571d05b647334bcb9caf675f05984ec9b7b8` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Trips/README.md:fence-1](../../../samples/MockResourceServers/Trips/README.md#L29) | bash | `8a22349beae27d0015ed2fcc8bbd9ee011ae7d305193b3ce3b02123596fb4ca0` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/MockResourceServers/Wallet/README.md:fence-1](../../../samples/MockResourceServers/Wallet/README.md#L29) | bash | `1ad360b8e2259599187dedb9b3fcf3cddef1d0affeab8b21d9f355dabd3ab059` | Shell syntax checked; side-effect commands not executed | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/MockResourceServers/Wallet/README.md:fence-2](../../../samples/MockResourceServers/Wallet/README.md#L38) | bash | `1c9e9ac5481e479bb2dc17031eb320f334638bf434050b2ae7e5596db71364d6` | Shell syntax checked; side-effect commands not executed | [Wallet session](../../../samples/CapabilitySupport/WalletDemoSession.cs), [both-app Wallet wrapper](../../../tests/e2e/helpers/wallet-protocol.ts), DeferredFederationTests / RevocationLifecycleTests | +| [samples/README.md:fence-1](../../../samples/README.md#L63) | csharp | `2b712ecb3492998075ff420dbe306e24d9301a11115d40ec85698f19c7c05f8f` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-2](../../../samples/README.md#L132) | bash | `549ee4073d83ddc3114327176a7908e2a284a36b8fdd273b15c32ea6b359ee88` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-3](../../../samples/README.md#L157) | bash | `6483e1a97b8691a784209ca40d7c0637d35249ea0b6efea72f8611406ff21604` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-4](../../../samples/README.md#L170) | bash | `4621bc905177f723f5e0ff904d1c513d983efbdbd51e2827ae6e63acfd896ff3` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-5](../../../samples/README.md#L181) | bash | `c2d4c4475e969b89e1c03350f8f072993a747c1e6d8eb829872baa69596ecca2` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-6](../../../samples/README.md#L195) | bash | `26cd5505c29422ddb1032d5c73126f4d17fd74dafedcc90f62ea708a60ef4748` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-7](../../../samples/README.md#L207) | bash | `8a22349beae27d0015ed2fcc8bbd9ee011ae7d305193b3ce3b02123596fb4ca0` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-8](../../../samples/README.md#L218) | bash | `1ad360b8e2259599187dedb9b3fcf3cddef1d0affeab8b21d9f355dabd3ab059` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-9](../../../samples/README.md#L229) | bash | `8b523bb4e46c0fdd3ada382ff8237f95c4118aae3abf9578b598ee9bec6b475c` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-10](../../../samples/README.md#L248) | bash | `73a53d75067b1a3aa5eac127f6b0d7a625f83713fb06ee4e3bea1cdf9671abe5` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-11](../../../samples/README.md#L264) | bash | `cee4e3957fc6fb00091a113fa578f12d62cfe47afe312878af61b4c516d91fc7` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-12](../../../samples/README.md#L270) | bash | `e3ec86108ef1216233056686189a69f34847e9529f1a69ea1ac6435fae7d9e91` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-13](../../../samples/README.md#L277) | bash | `be7b50ef7791ff23eeacd6d1dad02cdcd6157b6e078b368c7b50f4f5473d3ee3` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-14](../../../samples/README.md#L284) | bash | `548a4c130e36f0e540cea77d08cfe6f58c46fa9c9a59dcc0609d6cb13e608178` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-15](../../../samples/README.md#L291) | bash | `002a217633241d5cc6fc83782796cbcbb767589845ca154c25ad4b01c70bf80d` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-16](../../../samples/README.md#L298) | bash | `12e0b452b94aa11c170fda876cc292cbaf09dae6d866a1a999cff725c83caf50` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-17](../../../samples/README.md#L305) | bash | `83238081ecaf4bd0cedbbba71f255837877b6616abfef5690d922265ca760f56` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-18](../../../samples/README.md#L312) | | `4fa6d0a7adc1bb365764f5c60d7460c05b98f51b78d02899472a84d9b514a55b` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-19](../../../samples/README.md#L318) | bash | `57d37b25e0c69f2937389103209b47d1afdd0921ded21c9ced1e56b125d0abb4` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-20](../../../samples/README.md#L337) | bash | `686dc78fa36af733b25698df0c76b97922036ec767388988bc60f99f2cc0c37d` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-21](../../../samples/README.md#L345) | bash | `016d1fa45df9833e0ba49e8da141e5bee17880475b58e33588eee4276e2a00d8` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-22](../../../samples/README.md#L353) | bash | `4478cd8fcf98e455297048a70cec99c07521e8e69d842c61bd638e0e8fe88bc7` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-23](../../../samples/README.md#L361) | bash | `a16fd99e6ab5da9ec0b66842bdc6152550bf7bd67ef6d1b4ca224e61c720dd9c` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-24](../../../samples/README.md#L369) | bash | `5f98072a1cdb9576b409814e096a5af4ca63bbdfd249a81fc467957c5bbcf196` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/README.md:fence-25](../../../samples/README.md#L383) | bash | `cd69c5ddb22b9d81b37e541e1a3ebfe113cb8fccf291f36e98db7247efd5788a` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [samples/SampleApp/Components/ConsentProgress.razor:pre-1](../../../samples/SampleApp/Components/ConsentProgress.razor#L8) | http | `72374f5d71f42a98695f51564e5a6fb30a604391b2a765e488a991b987bb4ea9` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:pre-1](../../../samples/SampleApp/Components/Pages/Bookings.razor#L48) | csharp | `8ae77b5c62afcbe653b1140aceacc54166dcf3c042ec5796336b52aec31dc5f5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:pre-2](../../../samples/SampleApp/Components/Pages/Bookings.razor#L87) | csharp | `d45775c948206c0a0cd7502f478ab12cdbfccbae31d08bc8c056b9aad5fd75f6` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:pre-3](../../../samples/SampleApp/Components/Pages/Bookings.razor#L175) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-1](../../../samples/SampleApp/Components/Pages/Bookings.razor#L30) | inline-code | `cd869f23e81edb60a56a30664392dfa85a99877b8fdea1753211a758a16afe3b` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-2](../../../samples/SampleApp/Components/Pages/Bookings.razor#L30) | inline-code | `a41941b8b4af1fefc5445fd387a888c3269536a4c34522df43edfda817a03d10` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-3](../../../samples/SampleApp/Components/Pages/Bookings.razor#L31) | inline-code | `3efa7ace7b9668a034412e0aa7e728a6429c90434498efb6ca434c322bf6d866` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-4](../../../samples/SampleApp/Components/Pages/Bookings.razor#L32) | inline-code | `e3b900eb6f07c4ede76833b00261f2e84f3b807cfc786eee52a4874fac589877` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-5](../../../samples/SampleApp/Components/Pages/Bookings.razor#L32) | inline-code | `a3ff5c0910d2437fb70ae2c71df3adc8371f90ab4d7c9d06d78d5f79cca36fb6` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-6](../../../samples/SampleApp/Components/Pages/Bookings.razor#L33) | inline-code | `2336af25ca724d260446e47a636db7453efc335df448c2a57d4c67ac9965dbbe` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-7](../../../samples/SampleApp/Components/Pages/Bookings.razor#L33) | inline-code | `918b5d5b47d72b6172fa5a85ec1c985117cc12caed86669ef718adc028ecc3e0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-8](../../../samples/SampleApp/Components/Pages/Bookings.razor#L39) | inline-code | `dcaadad1cfce437735b81ab025f776e5857e48558c47f6960e6a5f2595664a85` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-9](../../../samples/SampleApp/Components/Pages/Bookings.razor#L40) | inline-code | `4275d71e90f7f09f9dcbba2aeeaafb3f30576780bc4d5419ff086d1c6f02a654` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-10](../../../samples/SampleApp/Components/Pages/Bookings.razor#L111) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-11](../../../samples/SampleApp/Components/Pages/Bookings.razor#L114) | inline-code | `43a66baa0fa981612952995435339ac081139751b16cdfbe52a30976c9dfe020` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-12](../../../samples/SampleApp/Components/Pages/Bookings.razor#L141) | inline-code | `2336af25ca724d260446e47a636db7453efc335df448c2a57d4c67ac9965dbbe` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-13](../../../samples/SampleApp/Components/Pages/Bookings.razor#L142) | inline-code | `918b5d5b47d72b6172fa5a85ec1c985117cc12caed86669ef718adc028ecc3e0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Bookings.razor:inline-14](../../../samples/SampleApp/Components/Pages/Bookings.razor#L143) | inline-code | `dcaadad1cfce437735b81ab025f776e5857e48558c47f6960e6a5f2595664a85` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:pre-1](../../../samples/SampleApp/Components/Pages/CallChain.razor#L56) | csharp | `3a0359760989a62204f91c3ad9964a7b3026eebdd60ae826a89b6408c89d3dfb` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:pre-2](../../../samples/SampleApp/Components/Pages/CallChain.razor#L82) | csharp | `318b3a4846b9e500fe78fe0a97f2eebf59bc3e0b764610a7fc15fc7aa2a7f4a6` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:pre-3](../../../samples/SampleApp/Components/Pages/CallChain.razor#L191) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-1](../../../samples/SampleApp/Components/Pages/CallChain.razor#L29) | inline-code | `cbe370481704cef068c18bdcbe262329c59824d6c87e96510a53f022e899ab04` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-2](../../../samples/SampleApp/Components/Pages/CallChain.razor#L31) | inline-code | `2505b184cfaffd55bf75d2cd98718f94d14d4924b1773eab7f072a1fcb6bdf9b` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-3](../../../samples/SampleApp/Components/Pages/CallChain.razor#L32) | inline-code | `c17edaae86e4016a583e098582f6dbf3eccade8ef83747df9ba617ded9d31309` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-4](../../../samples/SampleApp/Components/Pages/CallChain.razor#L41) | inline-code | `d77f3141b2573eb9d9530e4c74cff4cfdaef2cccc341a2cc8e5bbcb6b5f8b082` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-5](../../../samples/SampleApp/Components/Pages/CallChain.razor#L43) | inline-code | `f029e50fcd09f511f8ca991cde2a36568dd18f8e021939e4ddbd46079e021e06` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-6](../../../samples/SampleApp/Components/Pages/CallChain.razor#L44) | inline-code | `34a8a0c61b14925f21b75a1f3596c9778cfe49d9ea3710eb3c5a80803fb6a16d` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-7](../../../samples/SampleApp/Components/Pages/CallChain.razor#L44) | inline-code | `1d19d95194d3a6778086865e392af37d00878f492175c4da1ef1fcf06ff9053a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-8](../../../samples/SampleApp/Components/Pages/CallChain.razor#L46) | inline-code | `6b70f841c15c6abf8590a0621708c0ee2e0c53749e33c35397abebf59a14cbc2` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-9](../../../samples/SampleApp/Components/Pages/CallChain.razor#L47) | inline-code | `3f0632bd4ff1ba4d46ae32269286141675ef248cc2dfa5366be1756c2c9f367a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-10](../../../samples/SampleApp/Components/Pages/CallChain.razor#L48) | inline-code | `cbdd8637f090e7de25403ed8482aae56b66be61046629696f01c8ca3d3a03d63` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-11](../../../samples/SampleApp/Components/Pages/CallChain.razor#L129) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/CallChain.razor:inline-12](../../../samples/SampleApp/Components/Pages/CallChain.razor#L156) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:pre-1](../../../samples/SampleApp/Components/Pages/Deferred.razor#L31) | csharp | `68c3a38302bd863a0e9a146f323a8326c506ea638fce5a87bf13a39b9d11d7b4` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:pre-2](../../../samples/SampleApp/Components/Pages/Deferred.razor#L52) | csharp | `a34331cf823c249da362d7716ce5f7ff6a8fbe5b2398967707fc839211fd169a` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:pre-3](../../../samples/SampleApp/Components/Pages/Deferred.razor#L142) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:inline-1](../../../samples/SampleApp/Components/Pages/Deferred.razor#L24) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:inline-2](../../../samples/SampleApp/Components/Pages/Deferred.razor#L104) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Deferred.razor:inline-3](../../../samples/SampleApp/Components/Pages/Deferred.razor#L122) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Error.razor:inline-1](../../../samples/SampleApp/Components/Pages/Error.razor#L12) | inline-code | `ac5f3f7e302eed0ed97a7591c4980581b7b37562919913daf30e670ed54fb7cd` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:pre-1](../../../samples/SampleApp/Components/Pages/Federated.razor#L52) | csharp | `5209c62c7507ff265d2ddac1ebc0c7133b8bd73e55306e0d5361cdadfeb6b1ba` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:pre-2](../../../samples/SampleApp/Components/Pages/Federated.razor#L80) | csharp | `c0949cfd57ac520935ac8232afe5802223dc51a608a870339fa8ca7b457c0d1a` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:pre-3](../../../samples/SampleApp/Components/Pages/Federated.razor#L148) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-1](../../../samples/SampleApp/Components/Pages/Federated.razor#L23) | inline-code | `0926d7734e784737b4b462e2daa3c6db041ee5c01b75a7a2b3ba9463d2efc8cc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-2](../../../samples/SampleApp/Components/Pages/Federated.razor#L24) | inline-code | `4275d71e90f7f09f9dcbba2aeeaafb3f30576780bc4d5419ff086d1c6f02a654` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-3](../../../samples/SampleApp/Components/Pages/Federated.razor#L26) | inline-code | `c795c4789217dcc6ad0187a39fe6d68c950ca3e9538cd95f768478b8ab143a09` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-4](../../../samples/SampleApp/Components/Pages/Federated.razor#L28) | inline-code | `1744bb6c1da2e55193e9eb4afe485e275c8cc30a2b1d1b9c100170d36fe9e520` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-5](../../../samples/SampleApp/Components/Pages/Federated.razor#L28) | inline-code | `c68c500e222872c83bbfe1cd0ccbb6a060bb88f1c53092a46ca9d182f0071362` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-6](../../../samples/SampleApp/Components/Pages/Federated.razor#L40) | inline-code | `7b546c362b786ab04a8a813810b1bb0ac4d1490fd17a19817fa34f194b83d785` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-7](../../../samples/SampleApp/Components/Pages/Federated.razor#L45) | inline-code | `a6ef89c2e28ae06c35306edd800dc0258b1243653636e119527a5e6da515b605` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-8](../../../samples/SampleApp/Components/Pages/Federated.razor#L46) | inline-code | `f55a0838018af0b222392c581b4cea6e096822c40b20aaad4b477534b29d3105` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-9](../../../samples/SampleApp/Components/Pages/Federated.razor#L98) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-10](../../../samples/SampleApp/Components/Pages/Federated.razor#L101) | inline-code | `989020bbf9c19ec30fec31a0ab554af489a28fc4b00a76bdc0ef448f80e801de` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-11](../../../samples/SampleApp/Components/Pages/Federated.razor#L115) | inline-code | `5f75aa4b29c22ccdf79fe3d835306792ff8b0a3bbb2c46657d2a0c0b8885820e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Federated.razor:inline-12](../../../samples/SampleApp/Components/Pages/Federated.razor#L115) | inline-code | `b4acf3cd196a669e73b99e5ad4852599295d624976af968417e561186ae77832` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:pre-1](../../../samples/SampleApp/Components/Pages/Home.razor#L346) | | `a6ef89c2e28ae06c35306edd800dc0258b1243653636e119527a5e6da515b605` | Illustrative text/HTTP fragment: placeholder bytes, current contract check; not a signed request | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-1](../../../samples/SampleApp/Components/Pages/Home.razor#L30) | inline-code | `3a5a5f5512f1031d566b8fdf9d61785652b7a69301861e1aacbb1f7bfd424e8a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-2](../../../samples/SampleApp/Components/Pages/Home.razor#L79) | inline-code | `0176343e4a437b2b37db94a36274da651d05b5e009cde3cb7a367b5d6feb6300` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-3](../../../samples/SampleApp/Components/Pages/Home.razor#L155) | inline-code | `f83f07be16e270186d35b876916c461995ebc3af5b1798f898c33285a1847dbc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-4](../../../samples/SampleApp/Components/Pages/Home.razor#L177) | inline-code | `9b573f58833b299cb4b692346359185025c5cab22f6e67526bc5b6cd7f59ca34` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-5](../../../samples/SampleApp/Components/Pages/Home.razor#L177) | inline-code | `f83f07be16e270186d35b876916c461995ebc3af5b1798f898c33285a1847dbc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-6](../../../samples/SampleApp/Components/Pages/Home.razor#L216) | inline-code | `2336af25ca724d260446e47a636db7453efc335df448c2a57d4c67ac9965dbbe` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-7](../../../samples/SampleApp/Components/Pages/Home.razor#L218) | inline-code | `918b5d5b47d72b6172fa5a85ec1c985117cc12caed86669ef718adc028ecc3e0` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-8](../../../samples/SampleApp/Components/Pages/Home.razor#L331) | inline-code | `a330395cc0a53ad1207736546afff4735940937564bbf75ce1edad40780d9139` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-9](../../../samples/SampleApp/Components/Pages/Home.razor#L348) | inline-code | `cd4728d5cf48bc8d687a147bc5fe05e0f907ac21804aeab209c793f833833f2d` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-10](../../../samples/SampleApp/Components/Pages/Home.razor#L349) | inline-code | `c7c9a7b1edf63900776b727b3e12dbdedffbaa14254a17de169efc2a54818c54` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-11](../../../samples/SampleApp/Components/Pages/Home.razor#L350) | inline-code | `8a6f8ac0599cd4d532d5ba25f815f48b4688531b5af2817668c6749cb20084ca` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-12](../../../samples/SampleApp/Components/Pages/Home.razor#L350) | inline-code | `12d3c95d85cd6faf3db71816f21fa650174ad30e6ec847f0778da67f36db5393` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-13](../../../samples/SampleApp/Components/Pages/Home.razor#L351) | inline-code | `e75f0d0205e21282d33679d1a7f131cd1b4409fd57deaf23ebbe6f7971415637` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-14](../../../samples/SampleApp/Components/Pages/Home.razor#L351) | inline-code | `9a0186e0172d33985dcb96809703b61b4cea0e30fd57639e5e0feec0a37ac8e6` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-15](../../../samples/SampleApp/Components/Pages/Home.razor#L351) | inline-code | `0785ba6aeb30c3e2a9b516f698b005fad8810fecc3ac8200f279d5ce6d7141c3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-16](../../../samples/SampleApp/Components/Pages/Home.razor#L352) | inline-code | `f8c2282bbbd055ac029944e9cbf3eccc48957b5652f33b8b12072394dd8c9888` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-17](../../../samples/SampleApp/Components/Pages/Home.razor#L352) | inline-code | `0be22b55514bc91928b54bf5dbb584d385576784e09510633f7246b6b8df5217` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-18](../../../samples/SampleApp/Components/Pages/Home.razor#L353) | inline-code | `41f10ba2d18523e4296b3560cf0604161195f2e4a075014c61539ce47f9ca97e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-19](../../../samples/SampleApp/Components/Pages/Home.razor#L354) | inline-code | `3f596db8aec3b34c95272b2c1f41b6d561752f433e5b00c8511718ad0463dafb` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-20](../../../samples/SampleApp/Components/Pages/Home.razor#L355) | inline-code | `433b76c7e0a8d1efce3e6009e16107f9c26c5f68b52712277e393828e7919ac8` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-21](../../../samples/SampleApp/Components/Pages/Home.razor#L355) | inline-code | `b7780cd609447ab9003df45ac23755cf4002106f6e0d2a2604d5df3e487a1467` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-22](../../../samples/SampleApp/Components/Pages/Home.razor#L356) | inline-code | `9a5c9b9b5223bf6e237ee67d70af31e504d65b2e16109807f484751c03d22b2c` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Home.razor:inline-23](../../../samples/SampleApp/Components/Pages/Home.razor#L356) | inline-code | `3a5a5f5512f1031d566b8fdf9d61785652b7a69301861e1aacbb1f7bfd424e8a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Hwk.razor:pre-1](../../../samples/SampleApp/Components/Pages/Hwk.razor#L29) | csharp | `d098fe99f7410d213dcd4ef6f94486c26266e3ed0d91ee784cef72707f1a71d3` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Hwk.razor:pre-2](../../../samples/SampleApp/Components/Pages/Hwk.razor#L37) | csharp | `c74a0c707c62028ce19e23e99423ace33d336ff0485eae8056e1a1b7500ce742` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Hwk.razor:pre-3](../../../samples/SampleApp/Components/Pages/Hwk.razor#L88) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:pre-1](../../../samples/SampleApp/Components/Pages/Inbox.razor#L38) | csharp | `e1d4c73ae851ae36c84f079eeb1f59483d45d79e72c58bc5f2385a034da305a5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:pre-2](../../../samples/SampleApp/Components/Pages/Inbox.razor#L65) | csharp | `75790a965720dec227aa56d7fc971f291186a3310823b31cb97300cae4c1eaa3` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:pre-3](../../../samples/SampleApp/Components/Pages/Inbox.razor#L147) | dynamic | `d3b7c288e3cfe16288f740c3b04341f355cf6e192bf783430075a0258d82dbd2` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:inline-1](../../../samples/SampleApp/Components/Pages/Inbox.razor#L27) | inline-code | `84e925d67edae8780e32bf145b35353d9aa74a63c3a6cbd96e75d468e11e3996` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:inline-2](../../../samples/SampleApp/Components/Pages/Inbox.razor#L29) | inline-code | `c17edaae86e4016a583e098582f6dbf3eccade8ef83747df9ba617ded9d31309` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:inline-3](../../../samples/SampleApp/Components/Pages/Inbox.razor#L30) | inline-code | `0176343e4a437b2b37db94a36274da651d05b5e009cde3cb7a367b5d6feb6300` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Inbox.razor:inline-4](../../../samples/SampleApp/Components/Pages/Inbox.razor#L32) | inline-code | `447e8542e794f80343c28c05e0dde8feeb4fad5353534f25ffd4860ec5122e09` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:pre-1](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L30) | csharp | `db59ee6a266cf61da0c13e39e5d610c6ad6ba50b14744075d204d764ec2e50ed` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:pre-2](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L108) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-1](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L50) | inline-code | `82a9a4369a2190e4225be7f0bb6dd1963beb23980dafa403fbac425b8c411c30` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-2](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L52) | inline-code | `3f0632bd4ff1ba4d46ae32269286141675ef248cc2dfa5366be1756c2c9f367a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-3](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L59) | inline-code | `0366839a6940219eb210f6eaa73e25226905fa630a23576abfc705d898b76bdc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-4](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L60) | inline-code | `82a9a4369a2190e4225be7f0bb6dd1963beb23980dafa403fbac425b8c411c30` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-5](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L61) | inline-code | `bc8c83a50192cc548ba210f1821e59f1900042570d06e906c9edeb8a8a4b1395` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-6](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L75) | inline-code | `ab0cc234202e566249566a8b3b90d3161892b5609fc452d6fbc7375a85aee4bd` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-7](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L76) | inline-code | `9f5cdbec39e36cd5c59e121b33c60bee4e76a9c0993d15dae0183cd9483698f2` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JktJwt.razor:inline-8](../../../samples/SampleApp/Components/Pages/JktJwt.razor#L88) | inline-code | `391ecdbfde78db0002d4927b6080eb417b873ae25f48eeecbd815e9c9d207596` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JwksUri.razor:pre-1](../../../samples/SampleApp/Components/Pages/JwksUri.razor#L29) | csharp | `0db0e8adb061c0229f84adff9cc7f6296b22739ac7859ccf8ea0a5401f8f8b03` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JwksUri.razor:pre-2](../../../samples/SampleApp/Components/Pages/JwksUri.razor#L39) | csharp | `97940e11299f5d55eff058613ade97c30b89f91eb362d97a5aff9facc4391af9` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JwksUri.razor:pre-3](../../../samples/SampleApp/Components/Pages/JwksUri.razor#L107) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JwksUri.razor:inline-1](../../../samples/SampleApp/Components/Pages/JwksUri.razor#L91) | inline-code | `ab0cc234202e566249566a8b3b90d3161892b5609fc452d6fbc7375a85aee4bd` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/JwksUri.razor:inline-2](../../../samples/SampleApp/Components/Pages/JwksUri.razor#L92) | inline-code | `6e66c138122fe819ec59154052552f23628df6545b9ce4e4c8ce0c50b54dbe7f` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:pre-1](../../../samples/SampleApp/Components/Pages/Jwt.razor#L30) | csharp | `47159757f7e15d074ef60a9aae877469121156ed6a5b0d4f5395f0303d5879f5` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:pre-2](../../../samples/SampleApp/Components/Pages/Jwt.razor#L44) | csharp | `8e8edd2c0202a748a7e2d6ae2ab86a0f9fc999456a4543b3342fdf12faefb4bd` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:pre-3](../../../samples/SampleApp/Components/Pages/Jwt.razor#L111) | dynamic | `031f5bdf4c2be7d2ebe51bf0bfe5931c404f567cad8704483cb4a0514a3b5d8e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:inline-1](../../../samples/SampleApp/Components/Pages/Jwt.razor#L22) | inline-code | `84e925d67edae8780e32bf145b35353d9aa74a63c3a6cbd96e75d468e11e3996` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:inline-2](../../../samples/SampleApp/Components/Pages/Jwt.razor#L23) | inline-code | `fc93cb07e1ad92898527100e58a1cf1d1e7f65e9a266a6f87f3c84feb541c7b3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Jwt.razor:inline-3](../../../samples/SampleApp/Components/Pages/Jwt.razor#L97) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:pre-1](../../../samples/SampleApp/Components/Pages/Mission.razor#L47) | csharp | `e4910d2a8c9af9490d0a77243007b2e0e1379e12bd52ba20dbfa6ec040cd0283` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:pre-2](../../../samples/SampleApp/Components/Pages/Mission.razor#L133) | csharp | `45c6aab38a01f73c676bf08e9baee07a53120e0067603b903728936dd46df5db` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:pre-3](../../../samples/SampleApp/Components/Pages/Mission.razor#L192) | csharp | `80bda3eff6569eb60e9b335fe2848cfe89b9fe8f39e2fd2b6635504afe5db6e6` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:pre-4](../../../samples/SampleApp/Components/Pages/Mission.razor#L277) | dynamic | `da7167bfacd9b3d919e7d7ff01a69040d9678c8aec63eddf8e18a2fa7d18b5ec` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-1](../../../samples/SampleApp/Components/Pages/Mission.razor#L23) | inline-code | `fd8abb915cb6b7b4241439d7d6ee2eb1bde2e21ba93940838c879f61e44c4723` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-2](../../../samples/SampleApp/Components/Pages/Mission.razor#L24) | inline-code | `59874580919614e8a19e5d82d568d118a39d1c77aa0deaae1aa37369d3aacdf3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-3](../../../samples/SampleApp/Components/Pages/Mission.razor#L211) | inline-code | `38e74af0dd2a72d8ca25aea096a5fbdb3475de6ae08d6e001ac9391f9d0d6176` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-4](../../../samples/SampleApp/Components/Pages/Mission.razor#L216) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-5](../../../samples/SampleApp/Components/Pages/Mission.razor#L217) | inline-code | `f9cf0053edea40a3e65b65d3b779b453933832f0c84739cba9b8fbbfcbbbb59e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-6](../../../samples/SampleApp/Components/Pages/Mission.razor#L226) | inline-code | `59874580919614e8a19e5d82d568d118a39d1c77aa0deaae1aa37369d3aacdf3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-7](../../../samples/SampleApp/Components/Pages/Mission.razor#L227) | inline-code | `7c1709777753420426f1975bc36fbd5af8835ea2185d922da2f4f17c69385f51` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-8](../../../samples/SampleApp/Components/Pages/Mission.razor#L246) | inline-code | `38e74af0dd2a72d8ca25aea096a5fbdb3475de6ae08d6e001ac9391f9d0d6176` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/Mission.razor:inline-9](../../../samples/SampleApp/Components/Pages/Mission.razor#L291) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:pre-1](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L63) | csharp | `cf70571d6335fe4d426fc5944e3464ae604a00cd8df8df7c72d38a02264637e2` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:pre-2](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L88) | csharp | `cfacda406b26c8051af3d5ef86dcb626cff8eb337f0354ceaf2ece782db23279` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:pre-3](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L172) | dynamic | `da7167bfacd9b3d919e7d7ff01a69040d9678c8aec63eddf8e18a2fa7d18b5ec` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-1](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L37) | inline-code | `a1ea09992888a04b5006bbaad7eea6389498d5b4f4c403edc7c0e5e52ea8435a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-2](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L38) | inline-code | `21109c3154adf851060b57837dd23358ff93abbe6858bf2f0c629d0b581e2e6b` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-3](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L43) | inline-code | `5641045f2001e3c3c3be0d8a507dd31398c7aa6379d9f89a33dad2da45ad0f2d` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-4](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L44) | inline-code | `1d19d95194d3a6778086865e392af37d00878f492175c4da1ef1fcf06ff9053a` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-5](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L111) | inline-code | `5cc17726782872bd0c1afe0afe7a75ab11881a254e9b70fbb52f519584f27129` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-6](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L112) | inline-code | `f9cf0053edea40a3e65b65d3b779b453933832f0c84739cba9b8fbbfcbbbb59e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-7](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L186) | inline-code | `772e10a0c0a795b97d1391d2d7c4b0cb1fde19ac5027c48de6008e10dede67e3` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/MissionCallChain.razor:inline-8](../../../samples/SampleApp/Components/Pages/MissionCallChain.razor#L215) | inline-code | `d626fe542fb67064bc9bc31cf95eb9bcf87bc99de451075c5509a39cffe32a33` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-1](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L49) | csharp | `c7acc6b47b2dded7537507ee810d3ce134c9566bf0211de39889d1daa154f3e0` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-2](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L71) | csharp | `56fb47c1a6f9a9de27ce324105d5054fe64586c3f1956c7e5f78428265216b4c` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-3](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L95) | csharp | `9b61f566282df66bbe12c781c54be92c21555db15f59e78a86f71c6f3fbcc066` | Exact C# compiled with typed prior-step/host inputs | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-4](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L140) | dynamic | `0fd11ce2743d0c0f7474efe3f703c346a5c9db816a6c2317dc252d7312f992a9` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-5](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L169) | dynamic | `0e38c745211e6384dc6ea75bf9e9d67d01f53fd11afd460999e9a89ea297eb3e` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:pre-6](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L182) | dynamic | `c0b22e0bc547334c1efbdac9458c4c6e9a7a4e585af9384df4c51b7945ea3475` | Dynamic Razor binding: build plus mapped scenario browser/captured-wire tests | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-1](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L30) | inline-code | `95948aaf48cdbe9be781310fec6efeeda040176c315d86bfee702bc8d3e5e45e` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-2](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L33) | inline-code | `9b573f58833b299cb4b692346359185025c5cab22f6e67526bc5b6cd7f59ca34` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-3](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L35) | inline-code | `f83f07be16e270186d35b876916c461995ebc3af5b1798f898c33285a1847dbc` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-4](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L168) | inline-code | `84e925d67edae8780e32bf145b35353d9aa74a63c3a6cbd96e75d468e11e3996` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-5](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L176) | inline-code | `1744bb6c1da2e55193e9eb4afe485e275c8cc30a2b1d1b9c100170d36fe9e520` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [samples/SampleApp/Components/Pages/SubAgent.razor:inline-6](../../../samples/SampleApp/Components/Pages/SubAgent.razor#L178) | inline-code | `82a9a4369a2190e4225be7f0bb6dd1963beb23980dafa403fbac425b8c411c30` | Inline Razor label/expression: source inventory, build and scenario display checks; not a standalone program | [capability-to-flow/spec map](capability-scenarios.md), [tour state](../../../samples/GuidedTour/TourSession.cs), [app specs](../../../samples/SampleApp/playwright-tests/), [tour specs](../../../samples/GuidedTour/playwright-tests/) | +| [src/AAuth.R3/README.md:fence-1](../../../src/AAuth.R3/README.md#L35) | csharp | `6f49b5e894779d64047132370d030587677e3702a1ea810369f0835a6de23a28` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [src/AAuth/README.md:fence-1](../../../src/AAuth/README.md#L12) | bash | `0cc8bf77419b3cf5842a01e5350d865905b39fbe124a4b0fc90be9e8e4336218` | Shell syntax checked; side-effect commands not executed | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [src/AAuth/README.md:fence-2](../../../src/AAuth/README.md#L21) | csharp | `bac6e655a77d637c9087c68c5c7cb823821acb0c1f1df96c5c1d29ddfb4ca8d2` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | +| [src/AAuth/README.md:fence-3](../../../src/AAuth/README.md#L53) | csharp | `cad90ccccaa7ba2d836d8905d329bca86fbff2095c472ce3b7de2e8abd352297` | Exact C# compiled with typed prior-step/host inputs | [API owning-source map](api-surface-map.md), [section-specific source/tests](conformance-ledger.md), [exact compiler](../../../tests/AAuth.Tests/Api/SnippetCompilationTests.cs) | diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-log.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-log.md new file mode 100644 index 00000000..b345b591 --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-log.md @@ -0,0 +1,4026 @@ +--- +description: Decisions and validation results for the AAuth v10 migration. +--- + +# Implementation Log - AAuth v10 migration + +## Decisions Taken + +### [2026-09-09] [Phase 14] Resource challenge verification repair - PROCEEDED + +The cross-origin regression reproduced a PS discovery attempt from +`ChallengeHandler.SendAsync` before JWT verification. The initial failing run +attempted DNS for `ps.example`; the issuer gate then passed the same test. +Protocol resource challenge verification requires JWT verification and resource +binding before exchange (v10 `Resource Challenge Verification`, L868-L873). +The handler now takes the shared verifier, metadata and JWKS dependencies from +the builder or manual host and rejects issuer, signature, agent/key, expiry, +account and mission mismatches before PS calls or consent. It uses the token +recorded by the signer, not the mutable holder. Adaptive retries copy the +signing context back. Four-party audiences remain supported; PS-AS trust stays +in the existing exchange path. Focused Release evidence is recorded in +`/tmp/aauth-phase14-review-challenges/`; full gates remain pending. + +Preserve the preexisting discovery crypto-factory and R3 retention changes. +No commits, branch changes or nested delegates are used in this repair worker. +This does not override the owner's independent-review requirement: Phases 14 +and 15 remain open until fresh review. Existing Markdown metadata is preserved; +no frontmatter is added to previously unadorned files. + +### [2026-09-09] [Phase 14] Focused R3, AP, documentation and walkthrough repairs - RESOLVED (focused checks) + +R3 wrong-approver repro returned 200 on immediate issuance and 202 on deferred +issuance. Both now reject with `invalid_resource_token` before document fetch, +operation policy or audit. [R3AccessTokenEndpoint L162](../../../src/AAuth.R3/R3AccessTokenEndpoint.cs#L162) +binds to the authenticated PS and validates upstream context; L61 and the retained +mint record carry verified mission to both delivery paths. All 94 endpoint tests +pass, including real `AccessServerClient` PS delivery validation of immediate and +deferred R3 tokens and dropped/changed upstream mission rejection. Evidence: +`/tmp/aauth-phase14-review-r3/`. Canonical protocol resource verification step 7 +is [L859](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L859). + +The actual MockAgentProvider host reproduced `Ed25519` publication for an enrolled +ES256 key. [Program L82](../../../samples/MockAgentProvider/Program.cs#L82) now +publishes the key's real algorithm. The regression enrolls over the actual HTTP +route, validates the published key and proof, restarts the actual host over the +same registry, and reads the key before reenrollment. Eleven enrollment tests +pass in `/tmp/aauth-phase14-review-ap/`. A preexisting legacy AP key initially +blocked host startup; `AgentProvider:KeyDirectory` isolates test keys without +changing user files. The shared crypto factory and R3 retention edits remain. + +Documentation repairs cover mandatory PS-local/AS-authenticated approver context, +ephemeral HTTP signing for naming JWTs, actual provider constructor parameters and +labels, explicit DI credentials without HWK fallback, and generic Profile route +admission. All four semantic/compilation checks pass in +`/tmp/aauth-phase14-review-docs/`; constructor table declarations are compiled, +and the naming-JWT signing-key selection is checked structurally, not by hashes. +Manual challenge examples now inject verification dependencies and use separate +agent-token exchange channels. The focused challenge suite passes 70/70 in +`/tmp/aauth-phase14-review-challenges/` with zero PS calls/consent on rejection. + +Documents now has four exact SDK step templates and AP setup, verification, +browser-carried callback, signed pending polling and download rows. Events has +six exact SDK step templates and a participant/message sequence with explicit +public/protected branches. Local decisions have no network arrows. Ten exact +templates compile; shared browser helpers require numbered step/diagram/snippet +association, cleared state after reset, full second execution, and desktop/mobile +screenshots. Fresh browser results, final Release gates and inventory refresh +are still pending; no full-gate or Phase 14/15 completion is implied. + +### [2026-09-09] [Phase 14] Focused review repair final gates - RESOLVED (review remains open) + +All three runtime issues were reproduced before repair: cross-origin challenge +caused PS discovery; wrong R3 mission approver yielded 200/202; actual AP per-agent +JWKS advertised Ed25519 for an enrolled ES256 key. Related verification/signing/ +configuration/generic-route docs and both shared instructional surfaces are fixed. +Canonical anchors are protocol resource challenge verification L868-L873, +resource recipient approver L859, Signature Keys ephemeral HTTP key L794, and +[AP publication L82](../../../samples/MockAgentProvider/Program.cs#L82). +The earlier focused entries retain the repro, repair decisions and test paths. + +Fresh final Release: 2234/2234, zero failures/skips (1059 core, 878 conformance, +222 R3, 75 Events). This adds 33 cases to the previous 2201: eleven challenge +cases, eight R3 cases, one actual-AP restart case, three semantic docs cases and +ten exact walkthrough templates. No tests were removed. Artifacts: +`/tmp/aauth-phase14-review-final-tests.log` and +`/tmp/aauth-phase14-review-final-trx/`. Full Release build and `make build` +both report zero warnings/errors in +`/tmp/aauth-phase14-review-final-release-build.log` and +`/tmp/aauth-phase14-review-final-make-build.log`. + +Fresh full stub browser gate: 71 passed (40 tour, 31 app), one existing +Keycloak-only skip. Fresh full live Keycloak gate: 72 passed (40 tour, 32 app), +zero skipped. Both have retries=0, zero unexpected/flaky results, isolated HOME, +and fresh application services. Reports: +`/tmp/aauth-phase14-review-stub.json` and +`/tmp/aauth-phase14-review-live.json`; matching directories hold screenshots and +failure-retention artifacts. Existing 72 browser cases were strengthened rather +than padded with duplicate test names: all eight Documents/Events cases now +perform two complete executions, assert cleared reset state, numbered steps, +diagram/snippet associations and viewport fit at 1280/390 pixels. Documents +captures include AP setup and signed pending polls; browser-local decisions have +no invented network arrows. Events captures include public/protected participant +paths and readable arrows in both app themes. Representative diagram and code +screenshots from both apps were visually inspected. + +Focused browser repros caught test assumptions about a fresh login on every +execution and a transient resource code URL. Retained authentication legitimately +skips login and immediately redirects to a browser session. The helper now waits +for either authenticated state or login and verifies callback parameters on the +actual navigation request. The repaired four Documents cases pass before the +full gates. The initial obsolete run was interrupted, not counted as a pass. +An incorrectly placed terminal-logger flag caused one `make` invocation failure; +plain `make build` and the final repeated build passed. No runtime bypass was +added to accommodate either harness issue. + +API map regenerated after code edits and checked without writing: 198 changed +public-source files, +790/-152 declarations, zero unmapped. Docs map regenerated +after the final templates: 169 files, 629 blocks, including 272 exact C# blocks; +the final Release run passes frozen-source freshness without update mode. The +provider table and ephemeral signer have semantic regression checks, not just +new hashes. TypeScript typecheck and scoped whitespace checks pass. + +No commits, branch changes, nested delegates, backend additions, specification +edits or plan completion checkboxes were made. Preexisting crypto-factory and +R3 retention changes are preserved. This worker's execution constraints do not +constitute an owner ban on independent review. Phases 14 and 15 remain open: +fresh independent review and its final alignment disposition are still required. +External interop, production identity/transport/store deployments and the five +external/platform template integrations were not newly executed; local Keycloak +is not evidence of those guarantees. + +### [2026-09-09] [Phase 14] Focused final repairs - PROCEEDED + +The owner authorized six reviewed repairs, without delegates, commits, or branch +changes. Preserve the auth-repair baseline (2160 Release tests, 72 live browser +tests, 71 stub browser tests plus one skip) and the newer Documents workflow. +Spec conformance governs; backward compatibility is not a goal. Replay identity +will use the verified canonical signature base and signing-key thumbprint, not +signature bytes, so ES256 alternate signatures collide while covered payloads, +carriers and parameters remain distinct. The unsigned selection label does not +create a new request identity. This applies the optional configured replay cache +in protocol `#freshness-and-replay`, [L2507](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2507). +Start with a crypto-valid alternate-signature regression and immediate check. + +### [2026-09-09] [Phase 11] Post-gate console and response presentation - RESOLVED + +Both running app URLs returned 200. A default-JWT AgentConsole request to +Profile /identified completed signed AP enrollment, refresh and 200 without a +Person Server. The first smoke used an empty HOME without XDG_DATA_HOME; .NET's +local-data fallback encountered the preexisting workspace cache and failed before +network I/O. Retried with explicit fresh HOME and XDG_DATA_HOME; no old cache or +private key was deleted. Evidence: /tmp/aauth-phase11-cli-final.log. + +The successful response exposed a final Profile presentation defect: it described +JWT verification as direct JWKS identity. The endpoint now returns the verified +agent identifier for jwt and distinguishes that from generic discovered-key +identity. No admission or authorization logic changed. The existing direct-JWKS +browser test asserted the old note; it now asserts Generic Signature Keys and +not an AAuth resource access mode. All four affected identity browser cases pass +on fresh services with retries=0 in /tmp/aauth-phase11-identity-fixed.json. +This focused post-gate check supplements the complete 55+1 browser gates above. + +The complete Release build/tests were repeated after this correction: zero build +warnings/errors, 1967 passed, zero failed/skipped, same per-project totals. +Artifacts: /tmp/aauth-phase11-postsmoke-build.log, +/tmp/aauth-phase11-postsmoke-tests.log and /tmp/aauth-phase11-postsmoke-trx/. +API freshness remains 182 files, +697/-143 declarations, no unmapped files. +The owned Keycloak container was stopped; the stub demo is restarted on the +usual 5240/5400 URLs with isolated state for owner review. This adds no new +scope exclusion or unresolved Phase 11 finding. + +### [2026-09-09] [Phase 11] Final verification and API review - RESOLVED + +Phase 11 is implemented and verified without delegates, commits, branch changes, +dependency upgrades or specification snapshot edits. Prior migration work is +preserved. The finished Release gate passes 1967/1967 tests: core 913, +conformance 777, R3 206, Events 71; no failures/skips. This retains the owner's +1920 baseline with 47 additional cases, including 17 exact snippet compilation +cases. No tests were deleted to meet the gate. Artifacts: +/tmp/aauth-phase11-final-tests.log and /tmp/aauth-phase11-final-trx/*.trx. +Release build and make build both report zero warnings/errors in +/tmp/aauth-phase11-release-build-final.log and +/tmp/aauth-phase11-make-build-final.log. + +The final full fresh-service browser run passes all 55 applicable stub-policy +cases; zero unexpected/flaky results, retries=0, CI=1 and isolated HOME. Its one +Keycloak-only case then passes with KEYCLOAK_E2E=1, live imported Keycloak 26.0, +another fresh sample stack, no skips/failures/flakiness and retries=0. Across +both policy configurations all 56 existing browser cases executed successfully. +Reports: /tmp/aauth-phase11-complete-browser.json and +/tmp/aauth-phase11-complete-keycloak.json; logs and retained traces use matching +prefixes. The Keycloak image was already cached; no image/package download. +The earlier make-demo sample executables were identified by process group and +stopped narrowly to avoid port reuse. Test-owned services stopped after each run. + +First full Release failure: three governance fixtures still configured HWK or +asserted the old diagnostic, and one HTTP Bootstrap fixture lacked explicit +loopback admission. Updated to a self-issued agent JWT and the fixture's exact +egress policy; 14 governance plus 1 enrollment HTTP cases passed immediately, +then the full solution passed. First full browser failure: the picker expected +the old Identity-based label; the new Generic Signature Keys label is intentional. +The focused picker passed before the complete suite rerun. + +Desktop/mobile Inbox screenshots were inspected. They exposed an existing +fixed three-column mobile tour layout and a 22rem picker overflow, made more +visible by complete setup text. The narrow responsive repair constrains the +selector and stacks the existing steps/diagram/payload without redesigning the +apps. Bounding-box, panel reachability and both successful Inbox flows pass. +Final screenshots are under /tmp/aauth-phase11-complete-browser-results/; +the focused before/after evidence is under /tmp/aauth-phase11-layout-results/. +Both apps expose actual provisioning and six resource-managed steps; the tour's +header now shows its local issuer, not the configured external AP, and no PS/AS +authorization lane is added. Low-level per-step requests remain intentional +teaching surfaces; the full-flow snippets use the tested provisioning builders. + +The repeatable Roslyn inventory is current: 182 changed public-source files, +154 SDK plus 28 sample runtime; +697 added/replacement and -143 removed/replaced +declarations, zero unmapped files. It scans all current source, including +untracked additions, against ba768f1 and records overloads, constructors, +required inputs, option defaults, interfaces, DI and endpoint contracts. +The concept map covers every generated group, including Phase 1-10 egress, +decision/consent, revocation/account, R3 and Events. Compiler-synthesized and +inherited members are represented by source declarations rather than expanded; +this is not a binary compatibility report. Run tools/ApiSurface without --write +to verify freshness. The map has no frontmatter as requested. + +Final direct adversarial review: scheme/provisioning/access-mode naming, +From/refresh precedence, generic-DI fallback, fixed-key/two-key mismatch, +construction failure/disposal, governance carriers and channels, AP transport +admission, hidden authorization parties, exact snippets, and Inbox visuals all +have recorded fixes or justified low-level dispositions. No known in-scope +finding remains unresolved. A precise Phase 11 diff check passes. A broader +folder check reports pre-existing whitespace in untouched SampleApp Program, +NavMenu and project files; those unrelated edits were left intact. + +Coverage limits are explicit: the inventory is exhaustive for declared changed +runtime APIs, while snippet compilation is representative (8 tour constants, +4 Razor blocks, 5 docs templates), not one executable snippet per API declaration. +Existing provider/consumer suites cover retained low-level interfaces. No new +production persistence/provider deployment or general rotating-key signer is +claimed. Phase 12 cross-cutting security closure and Phase 13 final docs sweep +remain open; this phase updated affected docs alongside runtime and does not +declare all repository documentation final. + +### [2026-09-09] [Phase 11] Runtime defaults and Inbox revisit - RESOLVED + +The original hwk-to-agent-JWT change was real migration work, not missing setup +the owner overlooked. Retain it: protocol L2420 and L2422 (#keying-material) +require JWT for AAuth resource access. GuidedTour issues locally with its +published identity/key; SampleApp signs external AP enrollment on first use and +uses Enrolled/RefreshingFrom/WithKeyStore for lazy signed refresh. Resource +authorization remains agent/Inbox only; issuer discovery verifies identity, +not PS/AS authorization. No PS claim is added to the tour's Inbox token. +Generic Profile demonstrations remain separately labeled and enabled. + +From(EnrollResult) now uses its issued AgentToken regardless of JWKS metadata. +Explicit scheme selection after refresh disables refresh; refresh after scheme +selection chooses JWT, retaining an initial held JWT when supplied. Flow options +do not select schemes. ToBuilder exposes the existing provisioning transition +without enabling an unrelated flow. Both provisioning sub-builders forward +resource-managed and interaction options. UseJwt's fixed parameter is token, +since agent/auth/subscribe purpose is independent of the carrier. + +AgentProviderClient previously bypassed the injected client for both refresh +schemes. SignAsync now signs the actual request and the admitted supplied client +sends it, preserving policy/cancellation. Bootstrap has production-secure egress +configuration. Factory refreshers are disposable; injected HTTP/refresher/key/store +dependencies remain borrowed. Built enrolled pipelines own factory refreshers, +including failure paths, with per-build independent resources. Metadata/JWKS +clients dispose only internal HTTP. BuildGovernance owns its channels, supports +provisioning builders, and returns a disposable facade; constructor/Create borrow. + +The fixed-key Enrolled pipeline rejects TwoKey: it cannot rotate the signer to +match a newly issued ephemeral-key token. Preserve RefreshTwoKeyAsync and its +returned token/key pair as the explicit advanced API. This fixes a configuration +that previously built successfully but signed with the wrong key, not an optional +context relaxation. The CLI's generic jkt-jwt demonstration remains explicit. + +DI no longer silently chooses HWK: AddAAuthAgent requires AgentToken, +TokenRefresher, or an explicit generic SignatureKeyProvider. Generic providers +cannot be combined with AAuth authorization options. No mandatory verification, +account, expiry, owner, CSRF or trust input became optional for convenience. + +The complete Roslyn scan against ba768f1 includes untracked SDK additions. Its +first inventory found 154 public-source files and +585/-134 declarations; rerun +after later fixes before final freeze. The map includes egress, consent decision, +revocation/account, R3 and Events, not just the preexisting builder APIs. + +### [2026-09-09] [Phase 11] Focused verification and review failures - RESOLVED + +Immediate first-edit check: test adapter could not discover the new test; the +dotnet test fallback caught a test-only using declaration on non-IDisposable +AAuthKey. Corrected; the one-test composition gate passed. AP transport tests +then exposed pre-cancelled calls reaching non-cooperative handlers; explicit +early cancellation now prevents side effects. Both refresh schemes are captured +through the supplied transport. A rejected out-of-order patch applied no files; +the reordered primary-app patch built successfully. + +The API matrix checks From with/without JWKS, all explicit scheme overrides, +refresh precedence, no implicit authorization party, opaque replay coverage, +independent owned builds, borrowed dependencies, failed-build disposal and +governance ownership. The latest ownership/discovery slice passed 181 tests. +Secure DI tests passed 9. Exact snippet compilation reads 8 GuidedTour constants, +4 Razor blocks and 5 docs templates. It caught missing harness imports/trust-set +typing and two real FileKeyStore-versus-IKeyStore LoadAsync examples; repaired. +All 17 now compile. Full Release and fresh browser evidence follows separately; +these focused results are not yet the completion gate. + +### [2026-09-09] [Phase 11] Full API alignment - PROCEEDED + +The owner authorized the full current Phase 11, including runtime, API inventory, +primary-app snippets/visuals, affected documentation and fresh Release/browser +verification, without delegates, commits or branch changes. Preserve existing +work and the 1920-test / 56-browser baseline. Start with the confirmed missing +EnrolledBuilder resource-managed forwarder and an immediate focused regression. +Inventory every public migration delta against ba768f1, including Phases 1-10, +and retain advanced contracts where a wrapper would not remove real plumbing. +The Inbox remains AAuth resource-managed access using an agent JWT; provisioning +is setup, not PS/AS resource authorization. Final provenance and ownership rulings +will be recorded with executable evidence. Phase 13 documentation closure is not +claimed by this phase. + +### [2026-09-09] [Phase 11] Events repair verification ledger - RESOLVED + +Post-gate console smoke: fresh and cached AgentConsole runs both reach the +Profile identified endpoint with the same durable thumbprint, AP-assigned agent +ID and AP kid. Evidence: /tmp/aauth-events-repairs-cli-first.log and +/tmp/aauth-events-repairs-cli-cached.log. The final Release gate was rerun after +this follow-up with the same totals below. The updated isolated demo is running +at ports 5240/5400; its log is /tmp/aauth-events-repairs-demo.log. The temporary +Keycloak verification container was removed after its successful browser run. + +Release build passes with zero warnings/errors. The final Release test gate +passes 1920/1920: core 866, conformance 777, R3 206, Events 71; zero failures or +skips, 13 cases added over the owner's 1907 baseline. All 206 prior R3 cases are +retained. Artifacts: /tmp/aauth-events-repairs-release-build.log, +/tmp/aauth-events-repairs-release-tests.log and +/tmp/aauth-events-repairs-tests/*.trx. The first full gate found the existing +empty-agent-ID rejection test; the API now distinguishes omitted/null assignment +from invalid blank IDs, and both contracts pass. + +Fresh-service full browsers pass 55 applicable cases with zero unexpected/flaky +results, CI=1, isolated HOME and retries=0. All four Events browser cases pass. +The default stub configuration excludes one live Keycloak case. That exact case +was then run with another fresh service stack, KEYCLOAK_E2E=1 and the Keycloak AS +policy: 1 passed, zero failed/skipped/flaky, retries=0. Across the two policy +configurations all 56 cases executed successfully; no optional coverage remains +unverified. Reports: /tmp/aauth-events-repairs-browser-final.json and +/tmp/aauth-events-repairs-keycloak.json, with corresponding .log files. +The initial browser run exposed the obsolete caller-selected tour-sub assertion; +the test now requires an AP-assigned full-hash identity under the AP host. + +The live IdP used the already cached Keycloak 26.0 image and the repository's +realm import. No packages or images were downloaded. No broad dependency was +installed. AgentConsole now re-provisions a cached durable key with signed +enrollment, so a cache from the old volatile AP does not require deletion or an +unsigned identity replacement. Re-enrollment retains provider ownership. + +Known sample limits remain explicit: no authorized durable-key/PS rotation API, +no general human-identity admission, manual receipt retention, literal issuer/eid +deduplication, no cross-circuit workflow resume, and no transaction spanning +arbitrary external actions. None of the four reported adversarial defects is +left open. The broader Phase 11 API inventory remains a separate unfinished task. + +### [2026-09-09] [Phase 11] Events adversarial repairs and enrollment API - RESOLVED + +The owner authorized four repairs, actual HTTP/SQLite evidence, full Release and +fresh-browser gates, without delegates, commits or branch changes. Existing R3 +work is preserved. This is a scoped Phase 11 hardening entry, not completion of +the broader API-alignment phase. + +Subscribe verification now binds the parsed AgentId domain to the exact AP +identifier. Production requires `https://{domain}`. Explicitly admitted loopback +origins use their exact identifier host, without a port in the agent domain; +admitting an origin does not authorize it to assert an unrelated host. Foreign +issuer tests include real and fake protected tickets and the public channel; +the victim subsequently redeems the untouched ticket. The current core agent +token verifier had no reusable domain-binding helper, so the Events check uses +the existing AgentId parser and exact server-identifier policy directly. + +The sample AP is authoritative over its identity namespace. It derives a stable +local identifier from the full SHA-256 of the durable public-key thumbprint, +under its own host. First claim cannot request a privileged or foreign identity. +The optional requested ID is accepted only when it equals the assigned ID. +Enrollment requires fresh hwk HTTP proof covering the actual body digest and +content type; the body public key must match the verified signing key. SQLite +persists the immutable identity/key/Person Server binding and stable kid across +restart. Changed-key or changed-PS enrollment returns 409, not implicit rotation. +Production admission, user identity and authorized rotation remain separate +provider responsibilities. No registration request asserts a human identity. + +API inventory: AgentProviderClient.EnrolWithKeyAsync reuses a supplied durable +key; EnrolAsync still generates one and now signs enrollment. A null agentId +requests provider assignment; EnrollResult.AgentId exposes it. The existing +AAuthClientBuilder.Bootstrap(endpoint) and BootstrapBuilder.WithKey compose the +same path. There is no AgentProviderBuilder in this tree. SampleApp, MissionAgent +and Events reuse persisted keys; GuidedTour signs its per-walkthrough key. +Same-key reenrollment is authenticated and idempotent. No unsigned compatibility +route or caller-selected namespace remains in the mock AP. + +Pending(agent, limit, after) exposes owner-scoped receipt pagination. SQLite +uses an indexed row-bounded query, stops on serialized byte budget, and the +endpoint uses the same web JSON options. Arrays include base64 expansion and +are bounded to 1 MiB. An individually unreturnable envelope is rejected before +quota/outbox commit. Acknowledgments remain owner-scoped. The HTTP regression +drains thirteen 64 KiB events through the normal 1 MiB transport. + +Bookings persists the local notification receipt atomically with completion. +Retries authenticate the original provider/agent and retain the stored account; +they can return the exact receipt even after completion without another AP call. +A prepared delivery still handles failure between AP acceptance and local commit. +EventDemoSession retains its step after network failure, retries the command, +and pages the inbox. The lost-success-response HTTP test proves one AP delivery, +one durable agent action and normal acknowledgement. This does not add general +exactly-once external effects or cross-circuit workflow resume. + +No NuGet/npm dependencies were added or installed. SQLite 10.0.11 was already +present. The cached Keycloak 26.0 image will be used for the optional live-IdP +browser gate after the default full suite; no image pull is planned. Both +documented Keycloak realm ports were initially unreachable. An old sample stack +must stop so Playwright can start isolated fresh services. Initial full Release +tests pass 1919/1919 with zero skips; final rebuild/test/browser evidence follows. + +### [2026-09-09] [Phase 10] Completion and verification ledger - RESOLVED + +Phase 10 is implemented with no compatibility layer, delegates, commits, branch +changes, merges or cherry-picks. The earlier Events branch was inspected with +git show/ls-tree. Its field shapes informed the companion, but its EdDSA checks, +independent JWT resolver and permissive loopback URL policy were not reused. +Current SDK verification and discovery remain authoritative. Prior worktree +changes were preserved; this entry does not claim to audit all preceding phases. + +Release solution build: zero warnings/errors in +/tmp/aauth-phase10-release-build.log. Full Release solution tests: 1843 passed, +zero failed/skipped (core 865, conformance 777, R3 142, Events 59), recorded in +/tmp/aauth-phase10-release-tests.log and /tmp/aauth-phase10-release-tests/*.trx. +`make build` passes with zero warnings/errors in /tmp/aauth-phase10-make-build.log. +Packing produces /tmp/aauth-phase10-pack/AAuth.Events.0.1.0-alpha.1.nupkg with its +README and core dependency. CI tests the solution and explicitly runs Events; +the release workflow now packs Events too. No package was published. + +Fresh-service full browser run: 55 passed, one Keycloak-only test skipped, zero +unexpected/flaky cases; retries=0, CI=1 and isolated HOME. Evidence is +/tmp/aauth-phase10-full-browser.json and .log plus tests/e2e/test-results/ traces +and Events desktop/mobile screenshots. All four new Events cases pass: public +and protected work-account flows in both primary apps. The first focused browser +run had three failures: two early radio-selection events were dropped before +Blazor became interactive, and GuidedTour lacked its scoped CSS stylesheet. +Explicit interactive readiness and the stylesheet repair resolved them; the +focused rerun passed 4/4 in /tmp/aauth-phase10-browser-fixed.json. Browser +TypeScript checks and touched editor diagnostics are clean. + +Standalone EventAgent completes six actual HTTP steps, including AP 202, +processed=true and duplicate_ignored=true, in /tmp/aauth-phase10-eventagent.log. +The running sample stack uses isolated state and logs to +/tmp/aauth-phase10-demo.log; both /events pages are available on ports 5240/5400. +The scoped diff check passes. Known pre-existing whitespace/other changes outside +the checked Phase 10 slice are not represented as repaired. + +| Requirement group | Verified spec location | Implementation and discriminating evidence | +|---|---|---| +| AP metadata and subscribe verification | Events [L198](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L198) (#ap-metadata), [L277](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L277) (#subscribe-token) | MockAgentProvider metadata, SubscribeTokenBuilder, EventsTokens, explicit ISignatureTokenVerifier registration; SubscribeTokenTests and actual HTTP registration | +| Self-issued event and exact HTTP body | Events [L368](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L368) (#event-token), [L413](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L413) (#event-delivery) | Shared resolver/middleware and SignAsync; EventTokenTests and EventHttpTests reject cnf, unsupported algorithms, wrong keys, forged JWTs and tampered actual bytes | +| Atomic quota, durable acceptance, statuses | Events [L424](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L424), [L437](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L437) (#event-delivery) | SQLite immediate transaction + FULL sync, persistent outbox; concurrent 3-of-30 acceptance, unlimited accounting, injected insert rollback, reopen, exact retry, and actual HTTP 400/401/403/404/429/503/202 tests | +| Tickets and registration persistence | Events [L603](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L603) (Pre-Authorized Subscription URL Security) | Atomic consumption/insertion, wrong agent/operation, expired/stale state, concurrent single success, rollback preserves ticket; account taken only from prior authorized context | +| Agent trust, context and deduplication | Events [L447](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L447), [L454](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L454) (#ap-to-agent) | EventReceiver verifies issuer JWT/audience/expiry before context; persisted issuer/eid receipt; forged/expired/mismatched events and duplicate tests | +| AsyncAPI and executable discovery | Events [L493](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L493) (#event-discovery) | Bookings publishes aauth-subscribe security, receive operations, raw payload and registration schema, ticket channel parameter; protected R3 and public flows execute in both browser apps and CLI | + +Phase 11 ownership inventory: AAuthSigningHandler.SignAsync and +AAuthVerifiedAssertion are shared core additions. EventsProtocol, token builders, +EventsSignatureTokenVerifier/AddAAuthEvents, endpoint extensions, EventReceiver +and the three durable store contracts belong to AAuth.Events. EventSupport owns +SQLite and local AP-agent APIs; it is a sample library, not a production SDK +provider. Bookings owns its static availability-state policy and ticket issuance +after R3 authorization. Additional metadata admission includes event_endpoint. + +Remaining limits are deliberate and disclosed: Q5's recurring-event ambiguity, +raw-body interpretation, single-shot resource demonstration, local polling and +trigger APIs, manual data retention, no cross-circuit/console workflow resume, +and no exactly-once guarantee for arbitrary external business effects. The AP +is a trusted payload intermediary; the JWT alone does not bind a detached payload +after AP transport. Production deployments must supply retention, persistent +providers and appropriate operational/authorization policy. The sample uses +explicitly admitted loopback HTTP, not production HTTPS. Keycloak and external +interop were not newly verified by this phase. These are not broad zero-gap or +whole-spec-conformance claims. + +### [2026-09-09] [Phase 10] Persistence and sample integration - PROCEEDED + +Sample-owned EventSupport references the already approved SQLite 10.0.11 package; +AAuth.Events references only the current core SDK and ASP.NET shared framework. +The SQLite provider commits AP use accounting and outbox together with FULL +synchronization and immediate transactions. Exact compact-token retries use a +local SHA-256 storage key and must carry identical body bytes; this key is not a +wire jti. Resource ticket consumption and subscription insertion are transactional. +The protected ticket retains the authorized agent, operation, account and state. +The resource's prepared single-shot JWT/body and signing key are persisted for +retry. Agent context and literal issuer/eid receipts are durable. + +Both primary apps gain /events pages using one six-step executable sample client, +linked from their Bookings/R3 views. Existing R3 step counts and consent indices +remain unchanged. EventAgent uses that same client. Protected notifications come +from an authorized R3 search or confirmation; public registration uses AsyncAPI. +The explicit local trigger requires the subscription's agent identity. Local AP +polling and acknowledgements require an AP-issued agent JWT and signed body digest. +The UI uses locally served Lucide 0.468.0 icons under their ISC license. + +Intermediate gates: 25 Events tests (including seven real Kestrel HTTP cases), +17 Bookings authorization tests and full Release solution build pass. Full +solution tests and fresh-service browser gates are still pending at this entry. +Sample UI circuits have separate persisted stores but no cross-circuit resume UI. +Retention is manual: demo databases retain receipts and acknowledgements until +the owner removes the dedicated database. Production retention must be configured +by an implementing provider. No crash-durability claim covers arbitrary external +side effects after the agent's durable receipt. + +### [2026-09-09] [Phase 10] Implementation authority and ownership - PROCEEDED + +Implement all F27 boundaries against the current Events snapshot. Q5/Q6/Q9 and +the latest Phase 9 handoff were reread. The previous Events branch is inspected +only with git show/ls-tree; its independent JWT resolver and URL policy are not +imported. New companion validators use current TokenVerifier and explicit +ISignatureTokenVerifier registration, never unknown-type fallback. Shared HTTP +signing, digest and admitted discovery remain authoritative. + +Reuse the existing approved Microsoft.Data.Sqlite 10.0.11 package for sample +persistence, not as a core SDK dependency. SDK contracts require atomic durable +acceptance with quota and outbox in one transaction. Resource tickets and +subscriptions and agent context/deduplication also require durable providers. +Q5 uses raw body bytes, no invented required jti, and literal issuer/eid agent +deduplication. Unlimited AP accounting is supported, but recurring notifications +remain ambiguous under that deduplication rule. The primary demo is single-shot. +Authenticated AP polling is a local sample profile, not a standardized API. + +### [2026-09-09] [Phase 9] Completion and final gates - RESOLVED + +Phase 9 is complete; no Phase 10 Events code, delegation, commits or branch +changes were made. Preserved the partial worker code and preceding-phase work. +Final Release solution tests pass 1784/1784: core 865, conformance 777, R3 142, +zero failures/skips. This adds 80 tests to the owner's 1704-test baseline. +Evidence: /tmp/aauth-phase9-complete/*.trx and +/tmp/aauth-phase9-complete-tests.log. Release solution build passes with zero +warnings/errors in /tmp/aauth-phase9-final-build.log; `make build` also passes +in /tmp/aauth-phase9-make-build.log. Editor diagnostics and browser TypeScript +checking are clean. + +Both primary R3 browser specs pass 6/6 with fresh services, isolated HOME, +CI=1, retries=0 and full traces. Evidence: +/tmp/aauth-phase9-browser-final.json plus tests/e2e/test-results/ traces and +desktop/mobile account screenshots. The preceding targeted browser run had +3 passes and 3 failures in /tmp/aauth-phase9-browser.json: strict confirmation +validation exposed missing cancellation_policy in both primary runtime payloads. +Adding the actual field repaired the consent-link/popup symptoms; the final +rerun has zero unexpected or flaky results. The owner's earlier 51-pass browser +baseline and Keycloak skip are not re-reported as newly executed results; this +phase reran all six relevant R3 browser cases, not the unrelated full browser set. + +Coverage includes all eight vocabulary forms, malformed optional fields/arrays, +unknown/empty Gateway labels, duplicate members, required GraphQL type, invalid +gRPC forms, empty input, custom-schema scope, service ID collisions, optional +member identity, account binding, all five Bookings method/route policy variants, +exact proposal retries, byte-store mutation isolation, digest/raw parameter +checks, unverified custom-fetch tampering, missing audit configuration, actual +released-token audit identity, concurrent issuance and pending mint-once, audit +failure before release, SQLite rollback and reopen recovery, and designated-AS +readership with role checks. Independent resource scope approval is enforced. + +Storage limits remain explicit: SQLite audit is durable; Bookings documents, +pending consent, and sample signing keys are volatile. Restart requires a new +request; a committed but undelivered issuance may remain audited. PS evaluation +is the explicit Q4 interpretation, not an upstream resolution. Third-party fetch +and audit implementations must uphold their declared transport/persistence +contracts. Phase 10 owns Events delivery; Phase 11 owns fluent API consolidation +of the contracts inventoried below. No compatibility aliases were introduced. + +The scoped Phase 9 diff check passes. A workspace-wide check found pre-existing +trailing whitespace in SampleApp Program.cs, SampleApp.csproj and NavMenu.razor; +those unrelated changes were preserved. No Phase 9 completion claim covers them. + +### [2026-09-09] [Phase 9] Model and sample contracts - RESOLVED + +All eight vocabulary shapes are validated. R3OperationIdentity replaces bare-ID +Contains/Evaluate calls; vocabulary, field names, service, and optional members +participate in matching. Optional omission is not a wildcard; OData method order +is not identity. R3VocabularySchemas is consumer-local and cannot override the +reserved standard namespace. R3Metadata accepts structured Gateway discovery and +validates requests against a supplied authoritative operation set. + +Bookings derives its authoritative set from the published OpenAPI document. +POST search/hold retain their routes but now have unique searchAvailabilityPost +and holdReservationPost IDs; existing GET IDs remain unchanged. All five route +variants enforce granted, conditional, and rejected outcomes. Proposal retries +bind the account, HTTP method and all effective parameters. Malformed/unknown +parameters fail; confirmation no longer silently supplies missing input fields. +The /authorize agent verifier is separate from the AS-only document verifier. +Sample settings explicitly opt the PS into PersonServerEvaluators under Q4; +code defaults to the designated AS, with access/person dwk roles enforced. + +Phase 11 API inventory: R3Operation factories and qualifiers, R3OperationIdentity, +R3VocabularySchemas, schema parameters on document/proposal/request/claim APIs, +R3Metadata.ValidateOperations and structured AddVocabularies, +R3DocumentReaderPolicy, required AuditSink, audit TokenId/TokenS256, +identity-based IsConditionalOperation/IsOperationAllowed, IsProposalAllowed and +resource-scoped IsScopeAllowed. The latter independently approves scope and R3; +no scope is silently dropped. Sample SqliteR3AuditSink is not a core SDK provider. + +Phase 10 handoff: AsyncAPI operationId/action shapes and qualified receive grants +are ready. Events ticket response, subscribe token, registration, and delivery +remain Phase 10 work; no subscription capability is advertised here. + +Intermediate proof: 136 R3 tests pass. Recorded repairs include one hash-API +compile mismatch, a missing subject in the new Bookings fixture (8 failures), +two audit timestamp precision assertions, and two local compile errors while +adding route/audit coverage. Each was repaired and its focused gate rerun. The +final solution and browser gates are recorded separately after completion. + +### [2026-09-09] [Phase 9] Transactional audit provider - RESOLVED + +NuGet's flat-container manifest confirms Microsoft.Data.Sqlite 10.0.11 exists. +Pin that approved version in the R3 sample and its linked-source persistence +tests. The SDK requires an explicit IR3AuditSink with no no-op default. The sample +commits token identity/hash and R3 audit metadata in one SQLite transaction with +FULL synchronization; it never persists bearer token text. Failure prevents +release. A crash after commit can leave an audited token that was not delivered, +but cannot produce an unaudited released token. Pending consent remains volatile: +restart requires a new request, not replay of a prior approval. In-memory test +sinks make no durability claim. Audit records survive sample signing-key rotation. + +### [2026-09-09] [Phase 9] R3 implementation authority - PROCEEDED + +Implement F22-F26 against the complete vendored R3 draft, preserving the earlier +worker's partial code. Match vocabulary and every identity member; accept custom +vocabularies only with explicitly scoped schemas. Keep served-byte verification +at each consuming boundary. Default readers to the designated AS; any PS role +requires explicit policy under Q4. Require persistence before releasing tokens; +in-memory test stores are not durable. The owner approved SQLite 10.0.11 subject +to an availability check. No delegates, commits, branch changes, compatibility +paths or Phase 10 Events implementation. Record API handoff for Phase 11. + +### [2026-09-09] [Phases 6-8] Four adversarial repairs - PROCEEDED + +The owner authorized all four reviewed fixes, primary sample updates and full +validation, without delegation, commits or branch changes. Existing Phase 9 R3 +edits (including the untracked transport ownership test) are preserved and are +not part of this repair. This is not a single-phase worker restriction. + +The first four real federated endpoint regressions reproduced `200 OK` for both +terminated missions and denied account/scope consent before the fix. Apply one +PS mission review and shared pending resolution to both issuance modes. Next, +partition cached grants by exact upstream authorization context, track locally +known upstream revocation dependencies, and implement direct AS chaining with +access metadata and the authenticated intermediary agent carrier. New public +contracts and final proof are recorded for Phase 11 below as they stabilize. + +### [2026-09-09] [Phase 5] Adversarial final available gates - RESOLVED + +The final Release solution passes 1573/1573 tests: core 817, conformance 703, +R3 53, zero failures/skips. This adds 34 tests to the preserved Phase 6 baseline +of 1539. `make build` and explicit Release solution build pass with zero warnings +and errors. Evidence: /tmp/aauth-phase5-review-complete/*.trx, +/tmp/aauth-phase5-review-complete.log and +/tmp/aauth-phase5-review-complete-build.log. The prior 1562/1569 failure remains +recorded; the intermediate 1570-pass gate is superseded by this final run. + +The full final browser suite used fresh services, a new isolated HOME, CI=1, +full traces and retries=0. It passed 49 tests, skipped one Keycloak-only case, +and had zero unexpected or flaky tests. Evidence: +/tmp/aauth-phase5-review-browser-complete.json and its .log. The earlier full +49-pass/one-skip run is retained in /tmp/aauth-phase5-review-browser.json but +does not substitute for the final run after the last runtime changes. Both +apps' consent, federation, R3 and mission workflows pass; GuidedTour explicitly +asserts the post-clarification discovery GET, 26-symbol code and displayed +snippet while retaining the established 14-stage mission-chain count. + +Final evidence includes authenticated person-policy absence/denial tests, +subject/issuer/scheme collision tests, hostile GET versus protected POST +attempts, stale decision generations, two-round PS consent, AS +consent/clarification/re-consent, mixed client 202 requirements, owner/key +isolation, eviction/restart-style missing IDs, expiry and cancellation. A real +deferred R3 audit exception returns application/problem+json server_error 500, +then 410 on replay; no later mint is possible. GET 204 is terminal, whereas +clarification POST 204 is an acknowledgment. Typed 429/503 responses preserve +the retry behavior explicitly shown in the polling diagram. + +Verified implementation anchors: + +- [Browser generation](../../../src/AAuth/Server/BrowserConsentSessions.cs#L21), + [scoped attempt accounting](../../../src/AAuth/Server/BrowserConsentSessions.cs#L181) + and [stable identity](../../../src/AAuth/Server/BrowserConsentSessions.cs#L240) +- [Missing pending state](../../../src/AAuth/Server/DeferredState.cs#L10) and + [typed operation failure](../../../src/AAuth/Server/DeferredState.cs#L58) +- [Claims-POST dispatch](../../../src/AAuth/Access/AccessServerClient.cs#L221) + and [new-interaction polling predicate](../../../src/AAuth/Access/AccessServerClient.cs#L443) +- [PS code lookup](../../../src/AAuth/Person/IPersonPendingStore.cs#L274), + [AS code lookup](../../../src/AAuth/Access/IAccessPendingStore.cs#L188) and + [R3 code lookup](../../../src/AAuth.R3/R3AccessTokenEndpoint.cs#L502) + +Citation corrections to the preceding boundary entry: additional deferred body +fields are at protocol +[L2256](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2256), +not blank L2255; state-machine applicability is at +[L2266](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2266), +not blank L2265. The diagram's check-status/clarification line is verified at +[L2283](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2283). +The retry exceptions are explicit at +[L2288](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2288) and +[L2290](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2290), +despite the surrounding non-202-terminal prose. These are operational readings +of the pinned draft, not new wire requirements. + +Production consent obligations remain explicit: authenticate before deciding +per [L2861](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2861) +(`#ps-approval-endpoint-auth`), and bind the authenticated person to the agent +per [L2869](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2869) +(`#agent-person-binding`). The demo exemption at +[L2863](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2863) +requires OS-controlled, non-public loopback access. A button and an ambient +cookie are not authentication. SDK policy defaults deny; the sample flag, +loopback peer/Host checks, loopback launch settings and documented OS isolation +do not claim control over an operator's public proxy, tunnel or account mapping. + +Editor diagnostics and TypeScript checks pass. CRLF-aware git diff --check +passes; vendored spec diff is empty. No delegates, commits, branch changes, +credential additions or existing key modifications occurred. This worker did +not perform or claim an independent post-repair review or a complete audit of +later phases' governance/account/persistence obligations. + +### [2026-09-08] [Phase 5] Adversarial repairs - PROCEEDED + +Owner supplies five runtime findings and identity, deployment and retention +boundary objections. Execute locally without delegates, commits or branch changes; +preserve Phase 6's current changes and historical 1539-test gate. Live Keycloak +is an environment setup task still outstanding, not an implementation blocker. + +Both hostile GET regressions reproduced bound-request invalidation; both now +pass. GET failures no longer mutate a cookie-bound attempt budget or terminate +its request. Code guesses retain address throttling; only CSRF-validated POSTs +affect the browser attempt budget. Supersedes the earlier five-GET lockout policy. +Protocol [L2140](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2140) +(`#interaction-code-format`) requires bounded attempts, but an arbitrary unknown +code does not identify a victim request. Termination must require a credible, +authenticated request association, not ambient SameSite=Lax cookies on a GET. + +Two mixed claims/clarification/interaction regressions reproduced lost callbacks. +The client now dispatches new URL/code pairs and preserves actionable claims-POST +202 responses; all 21 client tests pass. Three operation failure/cancellation +cases reproduced nonterminal state. Typed 500/408 responses now terminate and +caller cancellation during execution cancels without claiming delivery; a caller +canceled before acquiring the gate does not consume state. The focused lifecycle +and browser gate passes 11/11. Basis: protocol +[L2826](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2826) +(`#pending-url-security`). Initial test syntax and counter-property compile errors +were repaired before those passing runs; neither was runtime evidence. + +Next separate generated Crockford correlation codes from signed pending route +identifiers, with renewed generations for re-consent. Basis: protocol +[alphabet L2128](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2128), +[correlation L2136](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2136), +[single use L2138](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2138) +and [expiry L2142](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2142) +(`#interaction-code-format`). Identity binding and sample isolation remain open +until their negative tests and host changes are complete. No blanket completion +or independent post-repair review is claimed. + +### [2026-09-08] [Phase 6] Final available gates - RESOLVED + +Implementation and available validation are complete. `make build` passed with +no warnings/errors. Final Release solution tests passed 1539/1539: core 791, +conformance 696, R3 52; no failures/skips. This adds 49 tests to the owner's +1490 baseline. Evidence: `/tmp/aauth-phase6-final/*.trx`. Focused negative and +positive gates include no-claims PS denial, authenticated consent suspension, +failed claims consent, immediate/deferred grants, distinct-key combined child +and upstream chains, mission retention, wrong parent/key/agent/upstream audience +and trust, person-bearing actors, wrong immediate actor with matching nested +context, and actual PS identity-scope metadata admission. + +The final full fresh-service browser suite passed 49 tests with one Keycloak-only +skip, zero failures and zero flaky tests. Evidence: +`/tmp/aauth-phase6-browser-final.json` and +`/tmp/aauth-phase6-browser-final.log`. It used isolated HOME, `CI=1`, full traces, +and zero retries. Both primary combined worker flows and ordinary federation/R3 +flows exercise authenticated PS consent followed by independent AS approval. +Both combined flows verify actual Wallet worker 200 and parent-key 401 responses. +TypeScript checks passed; editor diagnostics on changed runtime and primary-app +surfaces are clean; CRLF-aware diff check passed; spec snapshot diff is empty. + +An earlier final browser invocation ended interrupted around test 40 with no +failed tests recorded. It is not counted as a pass. The subsequent complete JSON +report supersedes it; the earlier 37-pass/12-failure and affected 21-pass runs +remain recorded above. A final curl check of the configured Keycloak realm at +localhost:18080 failed to connect (HTTP 000), so live Keycloak remains unverified. +The phase's final validation checkbox remains open; no gate was deferred or +claimed satisfied by stub mode. In-process Keycloak tests passed as part of +the full core suite, but do not replace a live IdP browser run. + +Citation correction: the actor-prose conflict recorded below is at protocol +L1773, not L1776. The examples begin at L1890. Rechecked consent L934, child +forwarding L1511, full actor delivery L1574 and vocabulary restriction L2041 +against the unchanged pinned snapshot. The ruling follows the concrete examples. +No delegation, commit, branch change, spec edit, or existing user-key mutation +occurred. New methods and changed contracts remain inventoried for Phase 11. + +### [2026-09-08] [Phase 6] Consent and delegation execution - PROCEEDED + +Owner authorizes the complete phase, including distinct-key four-party child +and combined upstream flows in both primary apps and browser tests. No nested +delegation, commits, branch changes, compatibility, or specification edits. +The working tree contains earlier phase changes, which remain intact. The +owner reports a current 1490-test baseline; it is not new Phase 6 evidence. + +Re-read F17-F20 including the updated no-claims consent finding and the pinned +[PS consent rule, L934](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L934), +[child forwarding, L1511](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1511), +and [delivery checks, L1574](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1574). +The federation callback projects even denied assertions and is absent from +immediate/no-claims grants. Start with an HTTP regression proving a PS denial +cannot be bypassed by immediate AS success. Consent must gate both claims +release and grant delivery, independently of AS negotiation. NeedsConsent +resumes through authenticated Phase 5 state, never a fabricated subject. +New public contracts will be recorded for Phase 11 ergonomic alignment. + +### [2026-09-08] [Phase 5] Implementation and available final gates - RESOLVED + +Phase 5 implementation is complete for the inspected SDK and runnable sample +paths. The final gate after custom PS pending-route repairs passed 1412/1412 +Release solution tests: core 713, conformance 647, R3 52, zero failures/skips. +This adds 50 tests to Phase 4's 1362: core +13 and conformance +37. `make build` +passed, both primary apps' targeted Release builds passed without warnings or +errors, and TypeScript typecheck passed. TRX evidence: +`/tmp/aauth-phase5-results/phase5-final_net10.0_20260908223017.trx`, +`/tmp/aauth-phase5-results/phase5-final_net10.0_20260908223028.trx`, and +`/tmp/aauth-phase5-results/phase5-final_net10.0_20260908223032.trx`. + +Final fresh-service, isolated-HOME Playwright with `CI=1`, `--retries=0`, and +full traces passed 49 tests, skipped one Keycloak-only test, and reported zero +failures/flaky tests. Evidence: `/tmp/aauth-phase5-browser-complete.json`. +The prior full no-retry run also passed 49/one skip, but the final run occurred +after the mission-creation/permission ownership repairs and therefore supersedes +it. The full browser suite exercised both apps' approval/poll indices, terminal +denial paths, R3 per-call consent, mission clarification, Inbox opaque-token +replay, navigation and recorded step counts. The deferred SampleApp browser test +also checks code-only rejection, code reuse rejection and missing-CSRF rejection +before legitimate authenticated approval. No retry was counted as a pass. + +Two earlier fresh browser runs failed and are retained as such: +`/tmp/aauth-phase5-browser-first.json` has 31 passed/five failed/14 skipped; +`/tmp/aauth-phase5-browser-second.json` has 48 passed/one failed/one skipped. +Failures were banner assertions made before the new explicit sign-in. The +fixtures now authenticate, verify the session URL and CSRF fields, then assert +the authority banner and complete the actual decision. No production bypass was +introduced to satisfy them. The initial 1402-test full Release pass preceded +the last ten security cases and is superseded by 1412. + +Final local coverage includes 36 PS mapper tests, 21 production PS/AS relay +tests, six browser-session HTTP tests, seven Keycloak-policy integration tests, +four custom PS pending owner/cancellation cases, eight Inbox/store tests and +52 R3 tests. These are overlapping focused suites, not additional totals. +The 21 relay cases cover PS local triage, agent relay, replacement scope, +claims after clarification, denial, cancellation, deadline, round limit, +foreign PS/different-key operations and malformed/rebound replacements. + +The final local route check found mission-creation and permission sample pending +GETs still had no owner check and removed entries. They now capture verified +issuer/agent/key, support signed DELETE, serialize browser decisions and terminal +delivery, and retain tombstones. Their first compile referenced the token-type +enum in the wrong namespace; correcting it yielded the focused 33-pass gate and +four new negative cases. Resource-managed delivery likewise retains tombstones +without deleting or revoking its reusable opaque access token. R3 has signed +owner/key-bound cancellation and one-200/seven-410 concurrent delivery with one +mint/audit. Valid replacements update scope, mission and resource context before +re-consent; dropping a mission does not imply approval. PS local-triage updates +are verified before being forwarded to the AS. + +The new sample consent progress component uses each authority's actual browser +paths. GuidedTour keeps its existing protocol counts, treating authenticated +browser steps as substeps of the existing consent step; polling confirms the +outcome. Phase 11 still owns fluent API composition and the reopened Inbox +credential-provenance review. The shared log's existing Phase 11 attribution +and provenance entries were read and preserved without modification. + +Editor diagnostics for the new state/session code, owning routes and helpers +are clean. `git -c core.whitespace=cr-at-eol diff --check` passed. The specification +snapshot diff is empty. No commit, checkout, nested delegation, package upgrade, +or existing user-key change occurred. + +### [2026-09-08] [Phase 5] Execution and first regression - PROCEEDED + +Owner authorizes the entire consent/deferred slice, including optional AS +clarification, PS triage/relay, replacement context, resource-managed lifecycle, +and both apps' live flows. No delegation, commits, checkout, compatibility, or +spec snapshot edits. Q7 permits an explicitly isolated demo identity, not +code-only authentication. Browser correlation and authenticated CSRF-protected +decision sessions are distinct. Public contracts introduced here must be +inventoried for Phase 11, not claimed to finish its fluent API alignment. + +Re-read current routes and pinned protocol +[clarification response, L1054](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1054), +[code format, L2136](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2136), +and [pending security, L2825](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2825). +PS GET lacks owner checks; mutation guards compare only subject. First check is +a six-case signed HTTP regression for foreign subjects and changed keys across +GET/POST/DELETE. Prior worktree changes and Phase 4's 1362 Release passes and +49 browser passes/one skip remain intact; they are not Phase 5 evidence. + +### [2026-09-08] [Phase 4] Final ownership gate supersedes counts - RESOLVED + +The final Release solution run passed 1362/1362: core 700, conformance 610, +R3 52, zero failures or skips. This supersedes the 1361 count below and adds +61 tests to the prior 1301 baseline. Evidence: +`/tmp/aauth-phase4-results/phase4-final-pass*.trx`. R3 factory clients now borrow +explicitly supplied handlers, so disposing a per-fetch client cannot dispose a +reusable endpoint handler. A two-fetch ownership regression passed. Its initial +compile used the wrong hash helper name and was corrected to `ComputeS256`. + +One full rerun exposed a test-fixture timing race: the real slow-body test used +a 200 ms request timeout and, under solution load, sometimes canceled before +the local server received request headers. Its test-only deadline is now two +seconds; production defaults are unchanged. The focused test and full solution +rerun passed. Browser runtime paths were unchanged by these final injected-handler +ownership and test-budget edits; the full 49-pass/one-skip browser result and +the later 4/4 affected R3 result remain the browser evidence. CRLF-aware diff +validation passed again and the spec snapshot diff remains empty. + +### [2026-09-08] [Phase 4] Completion gates - RESOLVED + +Phase 4 implementation criteria are complete. Final Release solution build passed; +`dotnet test AAuth.slnx -c Release --no-build` passed 1361/1361: core 700, +conformance 610, R3 51, zero failures or skips. The initial 1301-test baseline +therefore gained 60 tests. `make build` passed. Final focused discovery gate +passed 82/82 and the R3 project passed 51/51. Editor diagnostics for the new +security implementation and touched browser tests reported no errors. + +The complete fresh-service, isolated-key Playwright run with `CI=1`, no retries, +and failure traces passed 49 tests with one Keycloak-only skip. After the final +R3 pending-ownership exact-identifier change, both apps' affected R3 tests passed +4/4 on another fresh stack. `npm --prefix tests/e2e run typecheck` passed. +Structured evidence is in `/tmp/aauth-phase4-results/phase4-complete*.trx`, +`/tmp/aauth-phase4-browser-finaltrace.json`, and +`/tmp/aauth-phase4-browser-r3-final.json` for this workspace session. + +An intermediate final browser rerun had one SampleApp R3 approval failure +(48 passed, one failed, one skipped). Its screenshot did not include the alert +text. The improved assertion now reports that text. Six repeated R3 tests, +the next full trace-enabled run, and the final affected R3 run passed without +reproducing it. This is retained as an unexplained intermittent observation, +not asserted to have a proven root-cause fix. + +The default `git diff --check` reported CRLF line endings on two changed +SampleApp lines; the same check with `cr-at-eol` recognizing the files' existing +line-ending convention passed. `git diff --name-only -- aauth-spec` was empty. +Prior Phase 1-3 changes remain intact. No delegation, commit, checkout, package +upgrade, specification edit, or user-key mutation occurred. Phase 11 was not +implemented; its public-contract inventory inputs are recorded above/below. + +### [2026-09-08] [Phase 4] Admission and cache execution - RESOLVED + +Owner authorizes the complete Phase 4 security implementation and ergonomic +builders, without delegation, commits, checkouts, or spec snapshot changes. +F08/F09 and F26 fetch scope were checked against protocol draft-10 +[#jwks-discovery, L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517) +and Signature Keys draft-08 +[Section 7.3, L2372](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2372). +The current JWKS cold/expired path bypasses its floor and failures retain no +attempt timestamp. Begin with a failing focused regression. Production transport +will resolve and pin admitted destinations, reject redirects, and bound response +bytes and elapsed time. Injected HTTP clients need an explicit transport contract; +loopback development access requires exact configured origins. All new public +contracts will be recorded for Phase 11; its broader inventory is not in scope. + +### [2026-09-08] [Phase 0] Execution authorization - RESOLVED + +The owner approved autonomous implementation, decision/deviation logging, +independent adversarial reviews per logical area, repeated repairs and reviews, +and a final documentation alignment sweep. Baseline is commit `ba768f1` on +`v09-spec-migration`, with a clean worktree. No commits, branch merges or package +publication are authorized. Logs live in this initiative folder. + +### [2026-09-08] [Phase 0] Q1 capability scope - PROCEEDED (default) + +Include account binding, all eight R3 vocabulary models, AS clarification, +Events, self-jwt and direct jwks. X.509 and cached assertions remain optional +unsupported schemes, with correct rejection and no misleading advertisement. +No compatibility aliases or old-wire parsing fallbacks are permitted. + +### [2026-09-08] [Phase 0] Q2 server signing interpretation - PROCEEDED (default) + +Use normative Signature Keys draft-08 id/dwk/kid discovery for non-agent server +signers. AAuth agent resource requests use jwt. The obsolete PS-AS example is +not a competing wire contract. An upstream clarification remains desirable; +this run does not publish issues on the owner's behalf. + +### [2026-09-08] [Phase 0] Q3 production and development policy - PROCEEDED (default) + +Production identifiers and egress are strict. Development access is an explicit +loopback policy configured by samples and tests, never an implicit relaxation +for arbitrary private addresses or HTTPS hosts. DNS/redirect/size/time checks +belong at the actual HTTP transport boundary as well as URL validation. + +### [2026-09-08] [Phase 0] Q4 R3 readership - PROCEEDED (default) + +Default document readership to the designated authenticated AS. A PS evaluator +may be explicitly authorized by a resource under the R3 document's evaluation +role language. This is a documented interpretation of the conflicting readership +clauses, not a claim that the ambiguity has been resolved upstream. + +### [2026-09-08] [Phase 0] Q5 Events interpretation - PROCEEDED (default) + +Use the delivery section's raw payload body. Keep the primary example single-shot. +Use the specified issuer/eid deduplication and do not invent a standard per-event +wire identifier. Unlimited registration/quota remains supported; recurring-event +deduplication limitations must be disclosed. Expired events never trigger action. + +### [2026-09-08] [Phase 0] Q6 durability contract - PROCEEDED (default) + +Accepted Events delivery and use accounting must be durable and atomic. R3 +auditing must fail closed before releasing a token. Reuse suitable persistence +from the Events branch if verified; otherwise choose a transactional local +provider after checking dependencies. The exact dependency decision will be +appended before installation. In-memory stores do not claim crash durability. + +### [2026-09-08] [Phase 0] Q7 consent - PROCEEDED (default) + +Separate correlation codes from authenticated, CSRF-protected decision sessions. +Explicit isolated sample identity may replace a real user login in stub mode, +but no code-only approval path may bypass Keycloak policy. + +### [2026-09-08] [Phase 0] Q8 expiry/context - PROCEEDED (default) + +Preserve verified agent and delegation context in issuance and pending state. +Auth expiry cannot exceed the applicable verified agent expiry. Resources do +not invent an associated-agent-token fetch or private wire claim. Revalidate +stale contexts at deferred minting. + +### [2026-09-08] [Phase 0] Q9 existing Events work - PROCEEDED (default) + +Inspect `feat/aauth-events-implementation` read-only and selectively reuse +verified source/tests. No checkout, wholesale merge, or cherry-pick. New source +must be adapted to the shared v10 APIs and reviewed again. + +### [2026-09-08] [Phase 0] Q10 parsing/toolchain - PROCEEDED (default) + +Keep current cryptographic packages unless an actual incompatibility is proven. +Evaluate maintained structured-field tooling against required wire types and +labels before choosing it or retaining a corrected parser. Any dependency +decision is recorded before introduction; old wire formats are never the fallback. + +### [2026-09-08] [Phase 1] Problem-details contract - RESOLVED + +Implement a shared server result/writer with required `error`, optional `detail`, +and endpoint extensions using `application/problem+json`. Protocol draft-10 +[#error-response-format, L2304](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2304) +requires clients to act on `error`, independently of `type`. Rename public +`ErrorDescription` to `Detail` without an alias or legacy-wire fallback. Preserve +success bodies, status choices, challenge/signature headers, and callbacks. +Normalize MockAgentProvider application-defined errors under the owner's approved +consistency ruling; this is not a normative Bootstrap requirement. No new package +is needed. Implementation is bounded to Phase 1 and coupled sample/docs/test edits. + +### [2026-09-08] [Phase 1] Endpoint cutover and validation - RESOLVED + +Added `AAuth.Server.AAuthProblemDetails.Create` and `WriteAsync`: required nonblank +`error`, optional string `detail`, error-only HTTP status, and copied endpoint +extensions. The helper owns `error`/`detail` and leaves pre-existing response +headers intact. Migrated PS, AS, DI authorization/governance, revocation, +resource-managed polling/challenges, R3 endpoints/results, and compiled sample +error producers. Mission status, pending identifiers, R3 proposal fields, payment +locations, success JSON, deferred responses, and browser consent responses retain +their original contracts. Signature-only middleware responses remain header-led; +signature taxonomy/status policy belongs to Phase 3. + +Both token clients consume only `detail`, ignore `type` for classification, and +retain transport fallback for invalid `error` members. `ErrorDescription` was +removed from both public error types, with no alias. Updated LiveWhoAmITest, +MockAgentProvider's application-defined APIs, SampleApp's embedded federation +snippet, and current error/chaining documentation. GuidedTour's snippet catalog +contains no error-response example requiring replacement; its live denial +recording now retains the captured server body, including `detail`. + +The first revocation HTTP regression failed against `application/json` before +the SDK fix, then passed with `application/problem+json`. Focused checks covered +real PS/AS/R3/governance/revocation/DI/resource-managed endpoints, body extensions, +optional detail, preserved headers and success media, malformed client error +members, and conflicting RFC 9457 types. Final affected-project runs passed: + +- `dotnet test tests/AAuth.Tests/AAuth.Tests.csproj`: 541 passed, zero skipped. +- `dotnet test tests/AAuth.Conformance/AAuth.Conformance.csproj`: 579 passed, + zero skipped. +- `dotnet test tests/AAuth.R3.Tests/AAuth.R3.Tests.csproj`: 39 passed, zero skipped. +- Total: 1159 passed, 30 additional cases versus the 1129-test baseline; existing + endpoint tests also gained captured-wire assertions. +- `dotnet build AAuth.slnx` and `make build`: passed, zero warnings/errors. +- GuidedTour targeted build, edited-doc diagnostics, and `git diff --check`: + passed. +- Active SDK/sample/docs legacy-name sweep: no matches. Remaining test mentions + are deliberate absence assertions and legacy-field non-consumption cases. + +### [2026-09-08] [Phase 2] Issuance policy - RESOLVED + +The owner authorized Phase 2 only, autonomous alpha v10 with no compatibility +APIs, delegation, commits, or branch changes. Preserve the Phase 1 worktree. +F10 and the reserved-claim portion of F19 were read before implementation. +Rechecked protocol [Agent Token Lifecycle, L1344](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1344) +and [Auth Token Structure, L1708](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1708). + +Require an explicit verified source-agent expiration on every AuthTokenBuilder. +Use the minimum of requested positive lifetime (at most one hour) and applicable +verified expiry ceilings. Sub-agent issuance binds the child identity and key to +the verified child expiry, additionally capped by the verified requesting parent. +Call chaining is additionally capped by the verified upstream auth expiry. This +conservative delegation ceiling is a local security policy, not an assertion of +an additional protocol MUST. Pending state retains those verified ceilings; +approval and delivery recheck expiration without refreshing stale authority. +Response expires_in reflects remaining issued-token seconds at delivery. + +Reserve all builder-owned protocol claims, account (even before its later-phase +support), and nbf independently of populated optional properties. Requested and +projected AS identity claims use the same guard. Legitimate identity extensions +remain allowed. Begin with failing builder regressions, then validate each local +change and run targeted plus full-solution gates before completing Phase 2. + +### [2026-09-08] [Phase 2] Verified context and delivery decisions - RESOLVED + +AuthTokenBuilder requires AgentTokenExpiresAt; AuthorizationExpiresAt is an +additional ceiling, not a replacement for the child's source expiry. Both are +checked without acceptance skew at minting. The effective expiration is the +minimum of source expiry, delegation expiry, and issuance plus requested +lifetime. Positive lifetime and the one-hour limit are validated independently. +PS and AS options expose TimeProvider for deterministic issuance and delivery; +R3 uses its existing TimeProvider. ExpiresAt is captured on VerifiedToken and +retained on upstream results. No public wire expiry claim or lookup was added. + +AgentIssuanceContext verifies the parent and optional child/upstream JWTs for +AS, R3, and PS federation. The child identity/key and its own expiry remain +separate from the minimum parent/upstream ceiling. Combined delegation nests +the requesting parent ahead of the upstream actor chain. AS/R3 upstream trust +is restricted to the issuing AS itself or the authenticated requesting PS's +origin. PS retains its existing explicit upstream issuer policy. This is a +conservative default; open first-hop federation does not imply authority to +extend arbitrary upstream issuers. AccessServerRequest requires the verified +delivery ceiling and forwards subagent_token. AS token delivery is checked +against that original ceiling after signature/issuer verification. + +Reserved names are guarded regardless of optional builder properties. AS policy +requests/projections fail with policy_error for forbidden names; forbidden +pushed claims fail with invalid_request. Directed sub, tenant, roles, and groups +remain typed identity fields, while additional email-like extensions work. +The PS client rejects forbidden requested names before invoking its callback. + +### [2026-09-08] [Phase 2] Validation gates and completion - RESOLVED + +Completed Phase 2 only. The final `make build` and +`dotnet test AAuth.slnx -c Release --tl:off --logger 'console;verbosity=minimal' --verbosity quiet` +passed, followed by `git diff --check`: + +- Core: 571 passed, zero failed, zero skipped. +- Conformance: 610 passed, zero failed, zero skipped. +- R3: 50 passed, zero failed, zero skipped. +- Total: 1231 passed, 72 added cases over Phase 1's 1159 (core +30, + conformance +31, R3 +11). Build completed without warnings or errors. +- Focused checks passed for builder validation, AS claim requests/pushes, + federation delivery, PS mapper and integration flows, the 31-case PS/AS + issuance matrix, and the complete 50-case R3 suite. +- Both SampleApp and GuidedTour targeted builds passed. Edited source and + documentation diagnostics passed. + +The HTTP matrix asserts actual token exp and response expires_in for immediate +and deferred two-minute agents, both parent/child expiry orderings, combined +upstream/child bounds, refreshed poll carriers, and typed claims pushes. R3 +additionally rejects stale consent before mint, expired cached tokens, and +tokens that expire during audit before release. Builder cases cover zero and +negative lifetimes, default/already-expired ceilings, independent one-hour +validation, and unset reserved names. Federation client tests reject overlong +direct/deferred AS responses and forbidden claims before invoking callbacks. +No unbounded builder or federation-request overload remains. + +### [2026-09-08] [Phase 3] Carrier and trust cutover - RESOLVED + +The owner authorized all Phase 3 responsibilities, without compatibility, +delegation, commits or branch changes. Preserve Phase 1/2 work. Pin +StructuredFieldValues 0.7.7 and first run a typed dictionary compatibility probe; +keep existing crypto libraries. Implement normative Signature Keys discovery +for non-agent server signers under Q2. Discovery transport admission and caching +remain Phase 4, except interfaces required by this phase. Verification must +establish typed JWT trust before using delegated HTTP confirmation authority. +Recheck F01-F07, F28 and F31 against the pinned spec. Investigate the reported +R3 fetch-verification and AS scheme-mismatch responses at their owning role; +do not install a blanket status-to-header translation. + +### [2026-09-08] [Phase 3] Parser probe and wire evidence - RESOLVED + +StructuredFieldValues 0.7.7 restores and compiles on net10.0. Four compatibility +cases pass: tokens, strings, integer/Boolean parameters, inner lists, escaping, +byte sequences and malformed dictionaries. The initial probe assumed byte[]; +the API actually returns ReadOnlyMemory. Corrected the assertion and +reran the same check. Production code uses typed values and a canonical writer, +not ParsedItem.ToString serialization. + +Thirteen JWK checks pass for fully specified alg, typed unsupported/invalid +failures, both crypto algorithms, public wire keys and unchanged thumbprints. +Nineteen independent wire cases pass across all six schemes, including mixed +issuer/request algorithms, selected labels, reordered components, extra +signatures, escaping, expiration and distinct issuer/JWKS locations. These are +focused results, not completion of Phase 3. The first full core run reported +27 failures and 580 passes; after adding the required PS metadata discovery +fixture, all 20 AS integration cases passed. Remaining gates are still open. + +### [2026-09-08] [Phase 3] Final contracts and reviewer dispositions - RESOLVED + +F01/F04: Ed25519 replaces EdDSA without a compatibility alias. Public JWKs +include alg; typed validation separates unsupported algorithms from malformed +keys and algorithm/key mismatch. Wire imports reject private material. RFC 7638 +thumbprints retain their original members. IAAuthKey now spans agent/resource +builders, server key collections, PS sub-agent binding, self-issued refresh, +federation and R3. JWKS caches raw members and validates only the selected kid. +Existing cryptographic packages and operations remain unchanged. + +F02/F03/F28: hwk carries standard JWK string parameters; jwks_uri carries +id/dwk/kid and verifies metadata issuer before following jwks_uri. Direct jwks +uses url/kid and identifies the signer by the exact URL. self-jwt rejects cnf +and uses the same discovered key for both signatures. Self-jwt and companion +JWT types require exact ISignatureTokenVerifier registration; no Events type +or implementation is silently enabled. Non-agent PS/AS and R3 signers follow +Q2's normative metadata-discovery contract, not the stale protocol example. + +F05/F06/F31: key resolution returns a typed verified assertion before its +confirmation key is used for HTTP verification. Unknown typ and forged issuers +fail even with valid HTTP proof of possession. No issuer-verification disable +option remains. Generic() enables generic schemes, not unverified JWTs. +Only verified JWT payloads populate agent/role/scope identity results; naming +JWTs remain pseudonymous. NamingTokenVerifier shares required iat/exp/header +alg, issuer/thumbprint and durable-to-ephemeral checks with MockAgentProvider. + +F07: errors are typed, with no exception-message classifier. Signature-Error +uses the draft-08 dictionary form, error=; required_input is an Inner +List of String. Removed supported_algorithms is replaced by Accept-Signature-Alg. +AAuth authentication failures use 401; the explicit generic status policy uses +400. Unsupported schemes negotiate accepted schemes. Authorization 403 does +not add signature-error or negotiation headers. No blanket response-header +middleware was introduced. + +The two Phase 1 adversarial leads were confirmed and resolved by role: + +- R3AccessTokenEndpoint's caught fetch-signature failure now preserves the + shared verifier's typed Signature-Error and negotiation headers. Unsigned + pending polls assert error=invalid_request; wrong-scheme token requests assert + error=unsupported_scheme plus jwks_uri negotiation. Mint replay now explicitly + emits error=invalid_signature. Different authenticated PS ownership remains + a header-free 403, exercised by the R3 regression. +- Core AS scheme mismatch is a verification-role mismatch, not automatically + authorization denial. Its verifier accepts jwks_uri and returns 401 with + unsupported_scheme and Accept-Signature-Scheme: jwks_uri. The new real-AS + regression verifies this. Verified but untrusted PS requests remain 403. + +RFC 9421 checks include selected matching labels, unique dictionary labels, +two real signatures covering the complete key dictionary, parameter order, +component order, escaping, separate field lines, expires and conflicting keyid. +Known structured field types support sf/key; bs wraps individual field lines. +Unknown derived components never read HTTP headers. Incompatible/unknown +component parameters fail closed. Signature alg is ignored and never emitted. +Additional content fields work; covered SHA-256/SHA-512 Content-Digest values +are checked against actual body bytes. Digest coverage is not universally +required. This remains a request-signature implementation, not a new general +response/trailer-signature engine. + +### [2026-09-08] [Phase 3] Sample and release gates - RESOLVED + +Profile routes explicitly opt into generic signatures. Its direct per-agent +key-URL demonstration now uses jwks, including GuidedTour mode selection and +browser assertions. RequireAAuthSignature remains JWT-only; the new explicit +RequireGenericSignature supports generic demonstrations. SampleApp Inbox and +GuidedTour resource-managed requests now carry agent JWTs. Their consent/poll/ +replay sequence remains six steps; snippets and step descriptions were updated +without changing navigation or approval indices. Primary apps and all compiled +consumers build. Active old-wire/removed-option sweeps found no remaining +EdDSA, legacy hwk/jwks_uri carriers, supported_algorithms, SignatureOnly or +RequireIssuerVerification in SDK/sample/current-doc source. + +Final validation after repairs: + +- make build: passed. +- dotnet build AAuth.slnx -c Release: passed, zero warnings and errors. +- dotnet test AAuth.slnx -c Release: 640 core, 610 conformance and 51 R3 passed; + 1301 total, zero failed or skipped. This is 70 added cases over Phase 2. +- Final TRX files: phase3-final-release.trx under each test project's TestResults. +- Focused typed parser, JWK, independent wire, adversarial, AS, R3, issuance, + authorization and Inbox workflow checks passed throughout implementation. +- Fresh-service Playwright with CI=1, isolated v10 key state and retries=0: + seven targeted generic-signing/resource-managed tests passed across GuidedTour + and SampleApp in 1.2 minutes. +- Edited SDK/R3/primary-app diagnostics and git diff --check: passed. + +The initial browser startup was blocked by persisted pre-v10 AP keys missing +alg. No old keys were deleted or imported through a fallback. Test services used +a temporary HOME with existing NuGet/browser caches. The next run had one cold +Blazor Inbox click flake that passed on retry; using the existing clickAndConfirm +helper fixed it, followed by the seven-pass no-retry run. Initial failed Release +runs and the flaky run are not counted as clean final gates. + +### [2026-09-08] [Phase 4] Adversarial repair execution - PROCEEDED + +The owner supplied four reviewer findings plus the cache-header objection after +Phase 5's 1412 Release tests and 49 browser passes/one Keycloak skip. Preserve +that work and its partial environment gates. No delegation, commit, checkout, +package upgrade, or specification edits are authorized in this repair worker. + +Reverified protocol [JWKS Discovery and Caching, L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517) +(`jwks-discovery`), [same-kid retry, L2519](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2519), +[egress admission, L2521](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2521), +and Signature Keys [Section 7.3, L2372](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2372). +The prior fixed-TTL exception is superseded: implement bounded HTTP freshness, +issuer-scoped attempt coordination as well as direct-URL floors, and shared +same-kid retry for upstream validation. Retain stale-on-failure only where +response directives permit it, the minute floor, and the hard age ceiling. + +The two transport trust regressions failed before repair and now pass. The SDK +handler privately owns its inner transport instead of exposing a replaceable +DelegatingHandler chain. Federation inference accepts only the owned enforcing +handler behind known framework lifetime/logging wrappers; custom wrappers still +need an explicit contract. Initial full transport gate: 51 passed. + +The address reproduction failed 16 public cases and passed 39 other cases. +Narrowed the IPv4 protocol-assignment and documentation ranges, IPv6 IETF +assignment range with public exceptions, and IPv6 documentation ranges using +the [IANA IPv4 registry](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml) +and [IANA IPv6 registry](https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml). +Both registries report 2025-10-09 as their last update. The resulting transport +gate passed 94/94, including 192.0.78.24, its mapped form, and 2001:500:2::c. +Private, mapped-private, documentation, reserved, link-local, multicast and +transition-address negatives remain rejected. The transition restrictions are +conservative local policy, not a claim that every such prefix is IANA-private. + +### [2026-09-08] [Phase 4] Adversarial reviewer dispositions - RESOLVED + +All owner-supplied findings were reproduced locally; no separate reviewer agent +was launched by this worker. These dispositions describe verified repairs, not +an independent post-repair review. + +- Finding 1, mutable transport trust: the initial two regressions failed, then + passed with a privately owned handler. A further post-resolution factory-chain + mutation regression failed and required immutable borrowing of the actual SDK + handler. The factory root remains referenced for ownership, but automatic + binding no longer sends through its mutable lifetime/logging wrappers. Explicit + contracts retain their supplied pipeline, including custom middleware. Default + federation therefore omits those factory logging wrappers; HTTP diagnostics and + SDK activities remain available. This is the tradeoff for an inferred guarantee + that cannot be changed through public InnerHandler setters. Custom or in-process + transports never acquire implicit enforcement merely by containing an admission + handler. Final transport plus federation integration gate: 100 passed. Basis: + protocol [L2521](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2521) + (`jwks-discovery`) and Signature Keys [Section 7.3, L2372](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2372). +- Finding 2, issuer floor: six caller regressions fetched keys-a at t=299 and + incorrectly fetched keys-b at t=301 after metadata expiry. They now reject the + second fetch and recover at t=359. A seventh case covers companion self-jwt. + Generic JWT, auth verification, auth delivery, upstream validation, jwt and + jwks_uri resolution all pass metadata-validated issuer context; self-jwt shares + that path. The cache holds separately bounded issuer attempt state alongside + per-URL content/floors, so changed URLs cannot reset failures/backoff or return + another URL's keys. Concurrent cold URLs, invalidation, capacity pressure and + direct/discovered URL sharing pass. Direct jwks identities retain per-URL + floors, not an invented common issuer. Basis: protocol + [L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517) + (`jwks-discovery`, given issuer's JWKS at most once per minute). +- Finding 3, address overblocking: resolved by the IANA-based prefix repair and + public/negative tests recorded above. The exact examples 192.0.78.24 and + 2001:500:2::c are admitted without opening network sockets in classification + tests; real-handler negative cases still reject before connection. No claim of + live Internet connectivity is made. Basis: Signature Keys + [Section 7.3, L2379](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2379). +- Finding 4, upstream same-kid refresh: the t=61 acceptance regression failed + before repair; t=1 rejection already passed. Upstream now calls + TokenVerifier.VerifyWithJwksAsync rather than independently resolving a key and + calling synchronous Verify. The shared refresh succeeds after 61 seconds and + does not refetch within the minute. Basis: protocol + [L2519](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2519) + (`jwks-discovery`, one refresh/retry after cached-key verification failure). +- Cache-header objection: supersedes the fixed-TTL exception under "Implementation + and intermediate gates". Thirteen tests failed before repair; all 16 now pass + against both JWKS and metadata. Cache-Control max-age takes precedence over + Expires; Age and apparent Date age reduce freshness without double counting. + The configurable TTL is only a headerless fallback, capped by the hard maximum + age of at most 24 hours. no-cache requires revalidation, no-store retains only + attempt state, and must-revalidate prohibits expired fallback. The mandatory + minute floor can reject a revalidation instead of refetching early. s-maxage + does not override this private client cache's max-age. Other responses retain + bounded stale-on-error/backoff. Basis: protocol + [L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517) + and HTTP caching [RFC 9111 Sections 4.2 and 5.2](https://www.rfc-editor.org/rfc/rfc9111.html#section-4.2). + +Phase 11 inventory additions: public JwksClient.ResolveKeyAsync(Uri, string, +string issuer, CancellationToken) and ForceRefreshKeyAsync with the same argument +shape. The existing no-issuer overloads remain the direct-jwks URL contract, not +a compatibility shim for issuer discovery. The issuer parameter means the exact +identifier verified against admitted metadata, not a claim of JWT verification +before its signing key is fetched. No additional public transport or cache type +was introduced. All changed production issuer-resolver call sites were swept. + +The focused discovery gate passed 151/151. The first full Release build passed +with zero warnings/errors, but tests passed 1486/1488: core 789, R3 52 and +conformance 645 passed/two failed. The two failures were AuthorizationIntegration +fixtures publishing separate AP/PS JWKS URLs for the same issuer and fetching +both inside a minute. They now publish both keys at one shared URL, with explicit +one-fetch assertions. The focused authorization/upstream gate passed 22/22. +The initial failure evidence remains in /tmp/aauth-phase4-adversarial-results; +final full-solution and affected-browser gates are still pending at this entry. + +### [2026-09-08] [Phase 4] Adversarial final gates - RESOLVED + +The completed repair passes 1490/1490 Release solution tests: core 791, +conformance 647, R3 52, zero failures/skips. This is 78 added cases over +Phase 5's 1412. The final explicit Release solution build has zero warnings and +zero errors. make build also passed. Final TRX evidence: + +- /tmp/aauth-phase4-adversarial-results/phase4-adversarial-complete_net10.0_20260908224908.trx +- /tmp/aauth-phase4-adversarial-results/phase4-adversarial-complete_net10.0_20260908224919.trx +- /tmp/aauth-phase4-adversarial-results/phase4-adversarial-complete_net10.0_20260908224922.trx + +The affected federation browser gate passed 3/3: GuidedTour approval and denial, +and SampleApp approval. Fresh services, isolated HOME, CI=1, retries=0 and full +traces were used. Evidence: /tmp/aauth-phase4-adversarial-browser.json, with three +expected, zero skipped, zero unexpected and zero flaky. No unrelated browser +suite was rerun. Phase 5's broader 49-pass/one-Keycloak-skip result remains +historical evidence; live Keycloak remains unverified by this repair. + +A final adjacent P2519 outcome check found both TokenVerifier entry points +reported invalid_jwt when refresh removed the kid. Two tests reproduced that +failure; both now report typed unknown_key, while unchanged-key verification +continues to fail normally. The resulting 11-case issuer/rotation suite and the +final full Release gate passed. The three browser tests preceded only this +error-classification repair, which does not change their successful federation +paths. Basis: protocol [L2519](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2519) +(`jwks-discovery`). The exact private-address prohibition starts at Signature +Keys [Section 7.3, L2378](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2378), +continuing at L2379 cited above. + +Editor diagnostics are clean. CRLF-aware git diff --check passes and the +specification snapshot diff is empty. Existing Phase 1-5 work, browser fixtures, +keys and unrelated changes were preserved. No delegation, commit, branch change +or package upgrade occurred. All supplied findings and the cache-header objection +have explicit tested dispositions; independent read-only post-repair review can +proceed in the parent workflow. Phase 11 owns the logged API inventory follow-up. + +### [2026-09-09] [Phase 7] Qualified revocation and source lifecycle - PROCEEDED + +Implement the pinned protocol's `(iss,jti)` identity and unknown-pair 404 at +[L2361](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2361) +(`#token-revocation`). Keep signature replay independent of reusable tokens. +Authorization compares the authenticated caller with the target issuer or an +explicit trusted-PS policy; a token's verified issuer is not the identity of its +holder. An AP-issued agent token alone cannot authorize an AP revocation. +Known-token state needs expiration and bounded retention, atomic registration +against revocation, and source/recipient associations. AP-to-PS denial and +resource cascade at [L2390](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2390) +remain incomplete until real issuance, deferred delivery, and reuse are tested. +New public contracts will be inventoried for Phase 11. Preserve prior Phase 5/6 +changes and evidence; live Keycloak is excluded by the current owner request. +No compatibility aliases, delegates, commits, or branch changes are authorized. +Phase 8 must not begin before the Phase 7 gates pass. + +### [2026-09-09] [Phase 7] Source lifecycle integration and interim gates - RESOLVED + +Two initial real-endpoint regressions reproduced missing-issuer acceptance and +agent-token-holder impersonation of its provider (both incorrectly returned 200). +The typed pair/authorization gate passed 18 tests; the repaired full Release +boundary passed 1575 (817 core, 705 conformance, 53 R3). An old fixed-clock replay +fixture required matching inventory clock injection. Later source-inventory gates +passed 28, then 26 cascade-focused tests; core PS/AS integration passed 57. The +full lifecycle boundary found two expiry-response regressions, repaired with a +42-test expiry/replay gate by preserving existing JWT/issuance expiry ownership. +That full boundary still needs its final rerun. + +Four new signed multi-host tests pass: AP-to-PS revocation blocks source reuse, +cascades PS-issued and AS-provided grants to two actual resource endpoints, +isolates another AP's identical jti, rejects fresh-carrier revival of pending +consent, and returns 502 rather than success when a resource does not recognize +an unpresented grant. The PS records a verified federated grant before delivery. +Only server-signing schemes establish a revoker identity; token issuer/subject +claims do not establish the holder as that server. + +The bounded development inventory keeps invalid known tokens for one hour after +expiration, then returns unknown; capacity exhaustion fails closed without +evicting active revocations. Local revocation persists when downstream delivery +fails, and repeat requests retry recipients. No durable or restart-safe backend +is claimed. Unreached resources remain bounded by token lifetime, per protocol +[L2395](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2395). + +Phase 11 API inventory: TokenKey, TokenRegistration, TokenGrant, IJtiStore's +RegisterAsync/RegisterGrantAsync/GetGrantsAsync/TryRecordRequestAsync, typed +RevokeAsync/IsRevokedAsync, RevocationClient, CreateTrackedAsync, +MapAAuthIssuerRevocation, PS/AS RevocationPath/ConfigureRevocation, +AgentIssuanceContext.SourceTokens and pending SourceTokens. Review fluent +composition after all migration phases; no compatibility aliases were added. +R3 integration and sample-resource revocation are still in progress. Evidence is +under /tmp/aauth-phase7-*; helper gates are not a claim of phase completion. + +### [2026-09-09] [Phase 7] Final lifecycle and application gates - RESOLVED + +Phase 7 is complete against its six definition-of-done checks. Real HTTP evidence +goes beyond helper tests: two APs sharing the same jti remain isolated; revoking +one source at the PS denies its next request and revokes PS-issued or AS-provided +grants at two resources using each grant's actual issuer and token ID. Repeated +known revocation is 200; unknown sources are 404; unknown resource recipients +produce 502 without undoing local denial. A fresh carrier cannot revive a pending +grant tied to a revoked original token. R3 has a separate approved-proposal +revocation regression. The actual Calendar sample proves metadata advertisement, +server-signed revocation, and rejection with a fresh request signature. + +All six primary resource samples advertise and map revocation. Bookings' manual +agent/auth verification paths consult the same typed inventory. Core PS/AS and +R3 AS use verified source records and atomic tracked delivery; PS federation +records AS-provided tokens before delivery. Generic revocation remains +deny-by-default, while issuer mappers explicitly enable issuer authorization. +Wallet and Bookings configure target-aware trust for their PS. Additional Phase +11 API inventory: AAuthResourceOptions.RevocationEndpoint. No aliases were added. + +Final validation actually run: + +- `make build`: passed, zero warnings and errors; /tmp/aauth-phase7-build.log. +- Complete Release solution: 1593 passed, zero failed/skipped; core 818, + conformance 721, R3 54. TRX files: /tmp/aauth-phase7-complete-release/; + console log: /tmp/aauth-phase7-complete-release.log. +- Fresh-service full Playwright suite: 49 passed, one live-Keycloak-only skip, + zero unexpected/flaky results, retries=0. CI=1, isolated HOME, explicit stub + policy; /tmp/aauth-phase7-browser.json and /tmp/aauth-phase7-browser.log. +- Focused HTTP source lifecycle: five conformance cases in the final suite; + /tmp/aauth-phase7-http-lifecycle/ contains the initial four-case pass and + /tmp/aauth-phase7-adversarial/ adds the real middleware same-auth-jti case. +- Focused R3 source denial: 1/1, /tmp/aauth-phase7-r3-revocation/. +- Shipped Calendar revocation: 1/1, /tmp/aauth-phase7-calendar-revocation/. +- Editor diagnostics clean for touched core paths; CRLF-aware diff check passes; + active source/docs have no removed bare-jti APIs; spec snapshot diff is empty. + +Earlier Phase 5/6 work and test evidence remain untouched. The final count adds +20 tests to the owner-reported 1573 baseline. Git's full dirty diff includes +earlier phases and must not be attributed to Phase 7. This worker added +TokenKey.cs, TokenRegistration.cs, TokenGrant.cs, RevocationClient.cs, +TokenInventoryTests.cs, and RevocationLifecycleTests.cs; all other phase edits +modified existing files, including previously untracked AuthTokenResponse.cs. +The replay/revocation guide now states the complete typed store contract and +removes the old nontransactional Redis sketch. + +No durable backend, restart-safe delivery, background retry worker, or live +Keycloak pass is claimed. Those operational limits are explicit: in-memory +records expire with bounded retention, incomplete cascade returns failure, and +unreached resources are bounded by token lifetime. The phase did not edit source +account contracts, caches, consent isolation, or either app's account workflows. + +### [2026-09-09] [Phase 5] Generation-bound browser decision repair - PROCEEDED + +The focused P1 review is confirmed by two deterministic barrier tests: renewal +after code lookup accepted the consumed old code, and renewal inside person +authorization returned an old decision as valid. Both tests failed before the +repair and pass after code and generation rechecks under synchronization. + +Browser decisions now carry a single-use `BrowserConsentDecision` artifact. +Its `ApplyAsync` acquires the lifecycle gate before the async browser gate, +revalidates generation and availability, and holds both through the actual host +mutation. Renewal takes only the browser gate when called directly; lifecycle +callers already own the lifecycle gate first. No monitor spans an await. +Host callbacks must not reacquire either gate or call locking pending-store +methods. PS, federated AS (including Keycloak callback errors and claims), R3, +and resource-managed Inbox are being migrated together. Phase 7 inventory, +revocation, and tracked-delivery behavior remain unchanged. + +Phase 11 contract inventory: `DecideAsync` returns a decision artifact instead +of a bare pending ID; `BrowserConsentDecision.Id` identifies the entry and its +sync/async `ApplyAsync` overloads guard the entire mutation. `BrowserInteraction` +uses an async-compatible semaphore with lifecycle-before-browser ordering. +Resource-managed parking shares its emitted code with `BrowserInteraction.Code` +and exposes an init-only `InteractionPendingEntry.Browser` for that binding. +The callback contract requires bounded, cancellation-aware work and prohibits +gate re-entry. Final host and regression counts will be appended after execution. + +### [2026-09-09] [Phase 5] P1 browser renewal race final disposition - RESOLVED + +The confirmed P1 code-consumption and decision-application races are repaired +across the shared utility and every shipped browser host. The consumed-code +regression now pauses the real PS `GetByCode` result, renews, and resumes to +`invalid_code`. A second barrier renews inside person authorization and rejects +the old decision. Additional HTTP barriers pause after `DecideAsync` but before +`ApplyAsync`: stale approval, denial, and cancellation cannot mutate the renewed +generation, and the fresh generation can still be approved. Cancellation that +owns the lifecycle gate first rejects all three queued decisions. An async +mutation test proves lifecycle ownership across its await and rejects replay +of the same artifact. Nine regression cases were added to the prior 1593 total. + +PS mission decisions, standing consent and asserted identity, AS stub decisions, +Keycloak backend errors/denial/claims transitions, R3, and Inbox all apply through +the generation-bound artifact. Browser hosts no longer call bare-ID locking +store mutators. The PS consent bridge also evaluates the current scope and +applies its read-time standing-consent approval under one lifecycle acquisition; +it cannot carry an old scope check across renewal. Non-browser store contracts +remain available. Existing Phase 7 inventory and revocation paths were preserved. + +Validation actually run: + +- Initial deterministic reproduction: 2 failed as expected before the repair; + both passed after the serialized rechecks. +- Browser session suite: 27/27 passed; subsequent combined PS/race suite 44/44. + Evidence: /tmp/aauth-consent-race-focused/. +- Affected core host/lifecycle suite: 44/44; federation/revocation: 57/57; R3 + access endpoint suite: 31/31. Evidence: /tmp/aauth-consent-race-hosts/. +- Full Release solution build passed with zero warnings/errors. Full Release + tests: 1602 passed, zero failed/skipped (827 core, 721 conformance, 54 R3). + Evidence: /tmp/aauth-consent-race-release/. Final formatting-only PS/AS edits + were followed by passing focused PS and Keycloak host tests. +- Fresh-service full browser suite: 49 passed, one live-Keycloak-only skip, + zero unexpected/flaky results. Both primary apps ran with `CI=1`, isolated + HOME, explicit stub policy, full traces, and `retries=0`. Evidence: + /tmp/aauth-consent-race-browser.json and /tmp/aauth-consent-race-browser.log. +- Touched-file editor diagnostics and diff whitespace checks passed; the spec + snapshot diff is empty. No delegate, commit, or branch operation was used. + +No known generation race remains in the shipped consent handlers. The +synchronization contract is per-process: custom stores and callbacks must use +the same pending entry/lifecycle and acquire lifecycle before browser, and must +not re-enter locking store APIs from `ApplyAsync`. Async callback work holds +both gates, so cancellation/renewal waits for that bounded work; no monitor is +held across an await. Distributed atomicity, external side-effect rollback, and +live Keycloak validation are not claimed. Phase 11 retains the ergonomic/API +inventory from the preceding entry; broader fluent composition is not part of +this focused repair. + +### [2026-09-09] [Phase 8] Account binding execution - PROCEEDED + +The owner now authorizes Phase 8 only, superseding the worker-handoff blocker +below. No delegation, commits, branch changes, or compatibility aliases. +Protocol [L2055](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2055) +and [L2057](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2057) +(`#account-binding`) require resource-selected opaque strings to survive issuance; +R3 [L379](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L379) requires the same +value in the document. Use optional typed `string? Account` properties, exact +ordinal comparisons, and no accountless/wildcard lookup fallback. Only resources +interpret or authorize their account namespace. Verifiers need an independent +resource expectation before they can establish account binding. The existing +browser decision generation gates remain intact. Phase 11 retains broader fluent +API alignment; necessary account options are exposed during this phase. + +### [2026-09-09] [Phase 8] Account APIs and security boundaries - RESOLVED + +The public contract is optional `string? Account`, with shared `AccountBinding` +validation and ordinal equality. SDK policy rejects empty/whitespace-only strings, +JSON null/non-strings, and control characters; it does not trim, case-fold, parse +email addresses, or assign meaning to the resource namespace. Absence remains +absent. Resource and auth builders, verified readers, PS identity requests, AS +policy requests, pending resource snapshots, federation delivery, R3 documents, +proposals, grants and issuance audit retain the value. R3 vocabulary expansion +remains untouched for Phase 9. + +Phase 11 API inventory: + +- `AccountExpectation` explicitly represents an independent resource expectation, + including expected absence; both sync and JWKS auth verification accept it. + A null expectation means no account-binding assertion. Resource middleware with + `ResourceIdentifier` expects accountless tokens unless `ExpectedAccount` selects + an account from resource-owned routing. It never takes that expectation from + the incoming token. `AccountVerified` is false for absent accounts or absent + resource expectations; only a positively bound account becomes `aauth:account` + through `AAuthAuthenticationHandler.AccountClaimType`. +- `AAuthResourcePipelineOptions.AccountSelector` feeds both verification and + challenge issuance. Lower-level options are `ExpectedAccount` and + `RequestedAccount`. `AAuthAuthorizationRequest.Account` validates the JSON + request; resources reject unknown identifiers in their own namespace. +- `AAuthRequestOptions.Account` binds local credential selection and exchange; + it is not a wire header. The sample places selection in the signed target URI; + proactive authorization carries it in JSON. `ResourceIdentifier` overrides the + client's origin default for path-scoped resource audiences. `PresentedToken` + records the actual final signed carrier for diagnostics, never a trust verdict. +- `TokenExchangeRequest.Account`, `AccessServerRequest.Account`, and + `CallChainingHandler.ExchangeForDownstreamAsync(account: ...)` preserve explicit + selection. Upstream and downstream account namespaces are not conflated; + `UpstreamTokenValidationResult.Account` exposes only the verified upstream + claim. A downstream resource token and its delivered auth token must match. +- Opaque stores use exact `(origin, account, signing-key)` identity. Resource-side + resolution checks the bound key and `expectedAccount`; parked interactions + retain `Account`. Auth-carrier selection checks resource, account, current agent, + signing key and expiry, with no accountless credential fallback. This remains a + single-slot carrier cache: switching may obtain a new token rather than retain + an unbounded per-account cache. Refresh cannot replace a token's account. +- Mission prior consent uses `(mission, resource, scope, account, agent, key)`. + Sample standing consent adds account and bound key; sample mission intent uses + a structured resource/scope/account key. No absent-account or absent-key entry + matches a selected account or bound key. Admin consent fixtures now supply the + actual key; no old keyless fallback was added. + +Account-changing clarification replacements are rejected before pending state +mutation: start a new authorization and new consent. Existing browser session, +CSRF, generation, lifecycle and decision gates are retained. A targeted test +also reproduced a stale mission-consent defect: identity denial wrote `Granted` +and the next request took `PriorConsent`. Grant logging now occurs only after +successful identity assertion and tracked issuance, in immediate and deferred +paths; the failing test and neighboring mission tests pass after the repair. + +Both primary apps use Bookings' resource-owned configurable accounts endpoint, +defaulting to Personal and Work reservations only in the sample. Selectors retain +the same person and agent across account changes. The previous-grant action sends +the actual old credential to the new account and receives 401; selecting Work +then denying consent cannot make the next Work request silent. GuidedTour keeps +its 14-step plan and account-aware payload/snippet display. R3 display uses the +resource's human-readable account name, not a PS interpretation. + +Intermediate evidence before the final consent-ordering repair: `make build` +and Release build had zero warnings/errors, 1649 Release tests passed (861 core, +726 conformance, 62 R3), and a full fresh-service browser run passed 51 with one +Keycloak-only skip and zero retries. These counts are superseded by the final +gate recorded below. The initial browser startup failed on an old persisted AP +key lacking v10 `alg`; no user key was changed. Successful runs use a fresh +isolated HOME, shared package/browser caches, `CI=1`, and retries=0. One initial +SampleApp event was lost during Blazor hydration; the test now waits for the +server-rendered selected-account attribute and uses the existing click helper. + +### [2026-09-09] [Phase 8] Final implementation and gates - RESOLVED + +Phase 8 completed directly with no delegation, commits, branch changes, vendored +specification changes, or backward-compatibility aliases. Only Phase 8's plan +gates were completed. The prior Phase 8 handoff blocker is superseded by this +owner-authorized single-phase execution. + +Final validation, after all runtime changes and the stale mission-consent repair: + +- `make build`: succeeded, zero warnings and zero errors. +- `dotnet build AAuth.slnx -c Release`: succeeded, zero warnings and zero errors. +- `dotnet test AAuth.slnx -c Release`: 1667 passed, zero failed/skipped: + 864 core, 741 conformance, 62 R3. This adds 65 tests to the supplied 1602 + baseline, alongside account-bound variants of existing R3 delegation tests. +- `npm run typecheck` under tests/e2e: passed. +- Full Playwright run with fresh services, isolated HOME, `CI=1`, and + `--retries=0`: 51 passed, one Keycloak-only skip, zero failures/flaky tests, + 52 total. Both new multi-account tests passed. Selected-account per-call + approval also passes in both apps, including the resource-authored account + name at the R3 consent screen and the account in the executed result. +- Focused signed tests cover malformed/null/non-string resource accounts, + exact AS delivery, wrong account/missing account/unknown account, direct and + deferred opaque grants, account/key-separated consent and caches, refresh, + mission intent/prior consent, independent resource proof expectations, + R3 document mismatch, approved-proposal reuse, and chained/sub-agent delivery + with a distinct upstream resource account namespace. +- Mobile SampleApp and desktop GuidedTour screenshots from the browser tests + were inspected. Selectors, action controls and visible results render without + overlap. No visual redesign or unrelated CSS changes were made. + +Evidence is retained in `/tmp/aauth-phase8-build.log`, +`/tmp/aauth-phase8-release-build.log`, `/tmp/aauth-phase8-release-tests.log`, +`/tmp/aauth-phase8-final-browser.json`, and +`/tmp/aauth-phase8-final-browser.log`. Browser screenshots are in the test-results +directories as `accounts-mobile.png` and `accounts-desktop.png`. + +No Phase 8 implementation requirement is deferred. Live Keycloak mode and live +external interop were not established by the stub browser run and remain +unverified environment coverage. The Keycloak-only skip is reported, not counted +as a pass. Existing browser consent generation gates passed with the full suite. +Phase 11 retains the public API inventory above; no Phase 9 vocabulary, Phase 10 +Events, or Phase 11 fluent-API work was taken on. + +### [2026-09-09] [Phases 6-8] Adversarial proof and final gates - RESOLVED + +All four findings in the supplied review have implemented and tested +dispositions. These repairs do not claim completion of Phase 9 or later phases. +No delegate, commit, branch change, dependency upgrade, or spec edit occurred. + +1. Federated mission gate: four initial endpoint regressions returned `200` + for terminated or denied missions before the repair. The shared + `ReviewMissionAsync` now enforces termination, exact resource/scope/account/ + agent/key prior consent, and `IMissionTokenConsent` before federation or + identity assertion. Both issuance modes use the existing mission pending + resolver. Tests cover immediate and claims-request AS policies, clarification + and interaction holds, authenticated browser approval, approval reuse for the + same resource token, and termination while either authority waits. A changed + resource token requires review again. Claims release and delivery recheck + mission state. Optional absent scope is admitted as the exact empty scope + rather than producing `502`. Basis: protocol [P1438](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1438) + (`#mission-log`) and [P1449](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1449) + (Mission Management). Proof: [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs). +2. Reusable chaining cache: four real HTTP builder tests initially expected two + challenge/exchanges but observed only one, proving reuse after upstream + agent, directed subject, scope, or mission changed. The request snapshots + its upstream JWT once; the holder atomically retains that exact JWT plus + the request mission header with the issued carrier. Reuse still checks + resource, account, agent, key and expiration. The same context reuses its + grant; each changed context exchanges again. The cache is not partitioned + merely by `act`. Proof: [ReusableChainingTests](../../../tests/AAuth.Conformance/CallChaining/ReusableChainingTests.cs), + 4/4 passing against Kestrel and the actual PS endpoint. +3. Upstream revocation: five signed multi-host tests initially allowed revoked + upstream extension, delivery after consent, or downstream resource reuse + after revocation. Verified upstream `(iss,jti,exp)` now joins source + registrations in both the three-party and shared federation/AS issuance + contexts. Registration rejects known revoked tokens; tracked issuance checks + revocation before invoking mint, then atomically registers dependencies + before releasing the grant. Cascade follows the upstream dependency. + Verification and trust precede registration, so legitimate previously unseen + upstream tokens remain admissible; no exhaustive issuer inventory is + required. A sixth regression independently proved and repaired the + before-mint check. Direct-AS deferred revocation is also covered. Proof: + [RevocationLifecycleTests](../../../tests/AAuth.Conformance/Discovery/RevocationLifecycleTests.cs) + and [TrackedIssuanceTests](../../../tests/AAuth.Tests/Server/TrackedIssuanceTests.cs). +4. Direct no-mission AS chaining: initial independent tests reproduced `404` + from person-metadata discovery and `401` from the agent-JWT AS request. + Upstream role now selects access metadata for this route. The AS verifies + the intermediary agent carrier, requires its own no-mission upstream token, + and validates upstream audience plus downstream resource audience, agent, + key, account and mission constraints before policy. Captured wire assertions + prove access metadata only, `sig=jwt`, `upstream_token` in the body, and no + body `agent_token`. Body-agent spoofing is rejected. Deferred GET/POST/DELETE + binds issuer, subject and key; a PS cannot take over an agent-owned request. + Intermediaries cannot push PS identity claims. PS federation remains + `jwks_uri` with its separate owner and claims path. Basis: protocol + [P1792](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1792) and + [P1796](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1796) + (`#call-chaining`). Proof: 15 `DirectAs*` cases in + [DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs). + +Phase 11 contract inventory: + +- `AccessPendingEntry.OwnerAgentIssuer` and `OwnerAgentSubject` are new nullable + persisted owner fields for direct intermediary requests. `OriginPersonServerHost` + remains the PS-only identity; `OwnerKeyThumbprint` binds either request kind. +- `AgentIssuanceContext.SourceTokens` now includes verified upstream auth tokens, + not only parent/child agent tokens. Pending stores and inventory implementations + must preserve those issuer-qualified dependencies and expiry ceilings. +- `TokenExchangeClient.ExchangeAsync` and `WithCallChaining` keep their public + signatures. Upstream mission/role selects person versus access metadata; a + direct intermediary supplies its agent token only through `Signature-Key`. +- `AAuthTokenHolder` keeps its public API. Internal request snapshots and atomic + carrier/context publication enforce upstream and mission isolation. This is + not a claim of a general concurrent-client contract redesign. +- The PS federation mission completion source and review result are internal; + browser decisions continue through the existing authenticated lifecycle. +- `AuthTokenResponse.CreateTrackedAsync` now checks known revocation before mint + and retains the atomic post-mint source registration. `IMissionLog` lookups + support empty scope, preserving absence instead of inferring a default. + +Both primary apps' existing call-chain/federation descriptions and GuidedTour +snippets now distinguish direct AS routing, agent carrier versus body upstream, +shared mission consent, and context-bound cache reuse. The sample asserter's +documentation states that mission identity assertion follows the SDK gate in +both issuance modes. Their existing PS-routed demos need no new numbered steps, +indices, or navigation. No unrelated Phase 9 sample changes were made. + +Final validation: + +- `make build` and `dotnet build AAuth.slnx -c Release`: zero warnings/errors. +- `dotnet test AAuth.slnx -c Release --no-build`: 1704/1704 pass, zero skips or + failures: core 865, conformance 777, R3 62. This is 37 more tests than the + recorded Phase 8 baseline. Evidence: `/tmp/aauth-four-fixes/final_*.trx` and + `/tmp/aauth-four-fixes-release-final.log`. +- The first full Release run found two coupled failures: the shared mission + review lost the `PriorConsent` audit reason, and AS negotiation still expected + only `jwks_uri`. The audit reason was preserved and the expected supported + scheme list updated. Both focused regressions and the final full suite pass. +- Browser TypeScript checking passes. Full fresh-service browsers used isolated + HOME, `CI=1`, full traces and retries zero: 51 passed, one Keycloak-only skip, + zero unexpected failures, zero flaky tests, zero runner errors. Evidence: + `/tmp/aauth-four-fixes-browser.json` and its `.log`; both project retry counts + are zero. This full run includes the relevant call-chain, mission, federation, + account, sub-agent and R3 scenarios in SampleApp and GuidedTour. +- Touched-file diagnostics and whitespace checks pass. Repository-wide + `git diff --check` reports pre-existing whitespace in untouched SampleApp + layout/startup/project files; those edits were preserved. +- Existing Phase 9 R3 changes and the untracked `R3TransportOwnershipTests.cs` + remain untouched. Their presence was checked before edits and after the gates. + +The four reviewed implementation findings are resolved. Live Keycloak remains +unverified: the current sample configuration points to +`http://localhost:8080/realms/aauth`; its discovery probe failed to connect +(HTTP 000). The historical `localhost:18080` observation is not reused as current +evidence. A running configured realm and a `KEYCLOAK_E2E=1` policy-mode run are +still needed; the 51 stub-mode browser passes do not establish live IdP behavior. + +### [2026-09-09] [Phase 9] Adversarial repair evidence - PROCEEDED + +The five-finding report was read in full and each defect was independently +reproduced by a failing executable regression before its repair. Preserve the +current Phase 10 implementation and its recorded 1843-test baseline. No delegates, +commits, branch changes, generic AS endpoint changes, or Events body edits. +Earlier completion entries remain historical; this entry records their focused +follow-up and does not assert whole-repository conformance. + +| Finding | Reproduction | Repair and focused evidence | +|---|---|---| +| R3 AS accepts non-PS roles | Six signed HTTP requests using distinct non-PS keys at the trusted PS origin returned 200; two PS controls passed | Require verified `ParsedKey.Dwk == aauth-person.json` as well as scheme and identifier trust. Eight role cases pass; GET/DELETE pending guards and an alternate key falsely claiming PS role are tested. Generic AS is untouched. | +| OData multi-method grants reject GET | Both direct and conditional GET requests under GET/POST grants failed | Directional method containment applies only to OData grants. Exact identity remains separate; proposals carry the actual GET operation, not the broader grant. POST retry, wrong operation/vocabulary and omitted-method widening are rejected. | +| Custom identity depends on member order | Reordered region/task object failed the existing custom validator | Schemas declare the identifier member before parsing. All other custom members remain intact, including standard-looking names and non-string values. Document, proposal, request and claim consumers use the same selected schema. | +| Empty parameter object rejected | Enforcement and proposal schema rejected `{}`; missing/null controls failed as expected | Present empty dictionaries are accepted. Missing/null remain invalid for proposals and conditional invocation. Approved retries reject added parameters. Signed HTTP AS requests exercise empty/nonempty objects and null/array/number/string failures. | +| Malformed credential values escape | Signed requests reproduced uncaught JsonNode string conversion exceptions | Check JSON value kinds for agent/resource/subagent/upstream credentials before conversion. All 12 object/array/number cases return 400 invalid_request without audit or issuance. | + +Specification text was reread directly: protocol +[L1603](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1603) +(#ps-as-federation); R3 +[L117](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L117) +(Standard Vocabularies), +[L275](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L275) +(#odata-vocabulary), and +[L562](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L562) +(Proposal Document under #per-call-proposals). + +Phase 11 API handoff: `R3OperationIdentity.Covers` is directional grant coverage; +`Matches` retains exact qualified identity. Custom registration now accepts +`R3VocabularySchema(IdentifierMember, Validate)` instead of a bare validator. +Use `R3VocabularySchemas.CreateJsonOptions(vocabulary)` for standalone custom +deserialization and `R3Request.ReadOperations(body, schemas)` for request bodies. +Existing document/proposal/claim readers select schemas automatically from the +enclosing vocabulary. Custom qualifiers belong in Extensions, not the standard +typed qualifier properties. No property-order or reserved-name inference fallback +is retained. `parameters: {}` is now valid; missing/null is not. + +Focused Release R3 suite: 206 passed, zero failed/skipped, up from 142. The +existing empty-parameters rejection assertion was updated to accept empty and +reject null. The pending HTTP fixture initially hit the required one-minute +per-issuer JWKS attempt floor; after two rejected interval overrides, the owner +approved continuing with an injected discovery clock. Advancing that clock +isolates role authorization without changing production discovery policy. +Editor test discovery was unavailable, so dotnet test executed the regressions. +Full Release solution tests/build, R3 browser tests, and final scoped review +remain pending at this entry. + +### [2026-09-09] [Phase 9] Adversarial final review and gates - RESOLVED + +All five reported defects are independently reproduced and repaired. Final +scoped review reread the verified-role predicate, credential extraction, selected +schema converter and consumers, directional OData coverage, and exact proposal +operation/parameter checks against the vendored requirements cited above. No +additional defect was found in that reviewed slice; zero of the five reported +findings remain open. This is a self-review under the owner's no-delegation +constraint, not an independent reviewer or whole-spec conformance claim. + +- Full Release solution tests: 1907 passed, zero failed/skipped. Core 865, + conformance 777, R3 206, Events 59. The Phase 10 baseline of 1843 is retained + with 64 additional R3 cases. Evidence: /tmp/aauth-phase9-adversarial-tests.log + and /tmp/aauth-phase9-adversarial-tests/*.trx. +- Full Release solution build: zero warnings/errors. Evidence: + /tmp/aauth-phase9-adversarial-build.log. +- Both primary R3 browser specs: six passed, zero skipped/unexpected/flaky, + fresh services, isolated HOME, CI=1, retries=0, trace=on. Evidence: + /tmp/aauth-phase9-adversarial-browser.json and .log, plus the Playwright + traces under tests/e2e/test-results/. +- Scoped whitespace checks and touched C# and plan/log editor diagnostics pass. + Existing unrelated worktree changes were neither reverted nor reclassified. + +Review dispositions: PS roles are verified through distinct metadata/JWKS keys, +not supplied feature stubs; endpoint regressions use signed HTTP requests through +the complete TestServer pipeline. Browser tests additionally execute real sample +network flows. A custom schema cannot replace a standard vocabulary; its declared +identifier is stable regardless of member order or standard-looking field names. +Missing optional qualifiers do not widen grants. OData containment never expands +an approved per-call proposal. An empty parameter object is concrete; missing/null +and added retry parameters remain rejected. A document without a parameters field +remains a class document at the AS, not an invalid proposal inferred from its URL. + +The generic AS/direct-AS endpoints, Events body implementation, and all Events +tests are unchanged by this repair. Only the six requested R3 browser cases were +rerun, not the earlier full Events/browser ledger. Production/custom vocabulary +policies, external interop, Keycloak, and prior storage/deployment limitations +remain outside this focused gate. No new package or compatibility shim was added. +The old demo stack was stopped for fresh browser verification; its state directory +was preserved, and the demo is restarted with a new isolated HOME so old ephemeral +key/enrollment caches are not mixed with fresh service keys. + +### [2026-09-09] [Phase 12] Security closure and executable scenarios - PROCEEDED + +Implement the full approved Phase 12 scope on the existing worktree without +commits, branch changes, nested delegation, compatibility paths, or vendored +specification edits. Preserve the 1967-test, 56-browser and 17-snippet historical +Phase 11 evidence; rerun gates after Phase 12 changes instead of inheriting a +pass. Phase 13 final documentation remains separate. + +First discriminating check: mapper HTTP requests referencing an unknown mission +must fail before permission, audit or interaction policy can act. The local +mapper currently treats a missing store result as a usable context. Add focused +regressions first; this is a security-policy check, not an invented wire MUST. +Review ownership with the configured verification pipeline next. Build +capability-scenarios.md and conformance-ledger.md from actual code and tests, +keeping deployment responsibilities and unverified cases explicit. + +### [2026-09-09] [Phase 12] Governance boundaries reproduced - RESOLVED + +The first manual substantive edit added three unknown-mission HTTP regressions; +the immediately attempted editor test adapter discovered no tests. The same +dotnet filter then failed all three (200 permission/interaction, 201 audit). +The shared mapper repair passed all nine tests. A shared authorization guard +now rejects missing verified agent context, unknown missions, foreign agents +and wrong approvers before callbacks, then applies terminated-mission handling. +The sample PS uses the same guard. Focused mapper/deferred tests passed 38; +signed sample-host consent/ownership tests passed 24, including twelve new +invalid-context cases with no log or mission-state mutation. Artifacts: +/tmp/aauth-phase12-governance.log and /tmp/aauth-phase12-mission-http.log. + +The reusable deferred mapper also lacked owner context and atomic delivery. +Its entries now carry verified issuer/agent/key, retain terminal lifecycle state, +support owner-bound DELETE, recheck mission status and keep the first decision. +The existing 38 mapper/deferred controls pass after this repair; new race and +foreign-poller regressions are being run separately. The in-memory provider is +not a durable production guarantee. Protocol L1128 (#permission-request), L1455 +(#mission-status-errors), and L2880 (#ps-security) establish the signed and +access-control requirements; invalid_mission is a local fail-closed disposition, +not a newly claimed specification error code. + +### [2026-09-09] [Phase 12] Wallet scenarios and first browser findings - PROCEEDED + +Reuse Wallet for travel-budget review and grant revocation; reuse Concierge for +its existing travel orchestration purpose with a wallet-read direct-AS route. +Neither operation belongs in Bookings. A shared Razor library supplies both +primary apps' three selectable Wallet flows, numbered steps, sequence rows, +SDK snippets and actual HTTP evidence. The AS review asks clarification before +the configured stub/Keycloak policy. The PS withdrawal verifies the requesting +agent owns the Wallet grant, then signs issuer-qualified revocation to Wallet. +Direct delegation only extends a verified no-mission wallet.read upstream +grant for the configured Concierge/Wallet origins. Missing sub remains missing; +when present, the downstream subject is independently derived for the resource. + +The first fresh-service, no-retry browser run passed both clarification and both +cancellation cases, and failed both direct-chain and both revocation cases. +The chain policy incorrectly required optional sub; corrected after inspecting +the actual upstream claims. Revocation's first request succeeded, but an +immediate identical retry hit the permitted replay cache. An experimental signed +nonce passed its uniqueness check but was withdrawn after rereading protocol +L2507 (#freshness-and-replay), which defines no nonce mechanism. The sample now +waits one second before repeating the signed operation; created remains current +and replay protection is unchanged. Four exact signer-input fixtures caught the +experimental change; no altered fixture expectations remain. GuidedTour dark +host screenshots also exposed contrast/column-width defects in the shared page; +the local surface now supplies an explicit readable background and text colors. +Evidence: /tmp/aauth-phase12-wallet-browser.json and retained Playwright traces. + +### [2026-09-09] [Phase 12] Catalog selection and security closure checks - RESOLVED + +Catalog is the only new resource process (localhost:5006): two read-only travel +catalog services, both named list in their own OpenAPI definitions. Its +OpenAPI Gateway service map, explicit R3 challenge, AS/PS document readership +and service-qualified enforcement demonstrate the new gateway capability without +adding unrelated features to Bookings. CapabilitySupport is a shared Razor +library, not another server. Both apps have navigation, five numbered steps, +sequence associations, exact snippets, sibling-service rejection and recovery. +Four fresh-service Catalog browser cases pass with zero retries. Solution, +Makefile resources/demo/demo-keycloak, explicit loopback policy and the existing +CI-discovered Playwright webServer/projects include it. + +All eight R3 vocabulary models remain in scope and tested through roundtrip, +qualifier identity, conditional retry and OData subset cases. Native MCP/gRPC/ +GraphQL/SOAP/OData hosting was not implemented by the migration and is not +advertised by the new HTTP resource. Their models are internal SDK contracts, +not evidence for nonexistent native server flows. Actual runnable integrations +are OpenAPI, OpenAPI Gateway and AsyncAPI. Third-party login hosting remains +optional application-owned behavior; a metadata field alone is not a login flow. + +Additional confirmed security findings: the Keycloak adapter exposed arbitrary +IdP response bodies in two exception paths (both regressions failed, then passed +after bodies were removed). The PS permission poll could release a decision +after mission termination (200 reproduced, fixed with a delivery-time mission +guard). Real consent HTML and rendered TokenView tests reject executable markup. +Concierge pending routes accepted another valid grant's owner; they now bind +the exact upstream grant, expire with it and retain serialized terminal state. +Six signed-host foreign agent/key/grant GET/DELETE tests pass. The SDK's injected +distributed stores still owe cross-node atomicity; in-process DeferredState does +not certify arbitrary providers. Ledger responsibilities remain explicit. + +Intermediate Release: 2005 tests passed (928 core, 800 conformance, 206 R3, +71 Events). Exact snippets now pass 21/21; activity diagnostics 7/7; IdP-body and +real consent encoding 3/3; final mission/rendered-input slice 29/29. First full +browser gate: 65 passed, one Keycloak-only skip, two existing sub-agent failures. +The new Wallet direct-AS policy was incorrectly applied to PS-mediated workers. +Restricting it to requests without PersonServerIssuer repaired the regression; +the policy test and all four existing-worker/new-direct-AS browser cases pass. +No failed result is reported as a pass. Final Release and complete browser +gates will be repeated after these repairs. + +Phase 0 reconciliation: Q1-Q10 and execution authorization existed in the log +before implementation and are now checked in the plan. The pre-edit full +baseline evidence is incomplete; later gates do not reconstruct it, so that +historical checkbox stays open. Phase 5/6 environment checkboxes await this +phase's final live-policy run rather than rewriting their historical failures. + +### [2026-09-09] [Phase 12] Final .NET gates and remaining live recovery failure - BLOCKED + +The final .NET gates pass on the implemented code: Release solution build has +zero warnings/errors; Release solution tests pass 2023/2023 (946 core, 800 +conformance, 206 R3, 71 Events), zero failures/skips. make build, test-unit, +test-conformance and test-events pass; explicit Release R3 tests pass 206/206. +Exact displayed snippet compilation passes 21/21. The current API inventory +contains 192 changed public-source files, +756/-146 declarations against +ba768f1, zero unmapped files; the non-writing freshness check passes. Artifacts: +/tmp/aauth-phase12-final-release-build.log, +/tmp/aauth-phase12-final-release-tests.log, +/tmp/aauth-phase12-final-trx/, /tmp/aauth-phase12-make-gates.log, +/tmp/aauth-phase12-r3-explicit.log and /tmp/aauth-phase12-snippets.log. + +The most recent full stub browser run had 65 passes, one Keycloak-only skip +and two sub-agent failures. The concrete policy regression was repaired and +the four focused existing-worker/new-direct-AS cases passed afterward; a final +complete stub rerun has NOT been performed. Earlier focused runs establish +the twelve new stub browser cases, not a final whole-suite pass. + +Live policy setup used the cached image and the repository realm, without any +download or replacement of user containers: + +```bash +docker run -d --pull=never --name aauth-phase12-keycloak \ + -p 127.0.0.1:8080:8080 \ + -e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \ + -v "$PWD/samples/MockAccessServers/Federated/keycloak:/opt/keycloak/data/import:ro" \ + quay.io/keycloak/keycloak:26.0 start-dev --import-realm +``` + +The imported realm is reachable. A fresh KEYCLOAK_E2E=1, +AccessServer__PolicyProvider=keycloak run of the twelve new cases plus the +existing live login case passed eleven and failed both Wallet revocation +recovery cases. This is a test/flow failure, not an unavailable environment. +The initial failure assumed a fresh username form even when Keycloak reused +the session. Three focused helper repair attempts still did not complete the +live flow. Trace inspection verified Keycloak 26 uses button[name=accept], +not input[name=accept]; correcting that selector did not finish the test, so +the callback/result state needs further diagnosis. No timeout was converted +into a pass or skip. Stop the repair loop for owner direction as required by +the editing workflow. Latest failing evidence: +/tmp/aauth-phase12-keycloak-recovery3.json and +/tmp/aauth-phase12-keycloak-recovery3-results/; the initial live set is +/tmp/aauth-phase12-keycloak-browser.json. + +Phase 12 is NOT complete. Remaining gates include diagnosing both live +revocation recovery cases, repeating the final complete stub/live selections, +finishing the final visual/ledger review, and reconciling Phase 5/6 completion +with the final evidence. The historical Phase 0 baseline gap stays explicit. +The new resource and four selectable scenarios are implemented, with twelve +new browser cases and 56 additional .NET tests over the 1967 baseline. +No commit, branch change, nested delegation, compatibility layer, or vendored +specification edit occurred. Phase 13 remains separate and unchecked. +The test-owned Keycloak container remains running on loopback for diagnosis; +Playwright-owned sample services have stopped. The old demo was stopped for +fresh-service verification and has not yet been restarted. + +### [2026-09-09] [Phase 12] Focused adversarial repairs in progress - PROCEEDED + +The owner requested eight specific repairs, then the separate retained live +Keycloak recovery gate, without delegation, commits or branch changes. Catalog +and both apps' four new scenarios remain intact. Worker coverage remains in +scope; it is not owner-excluded. Phase 12 completion boxes remain open. + +Findings 1-3 already have partial production repairs in the supplied worktree: +deferred governance owner issuer/key/agent binding, mission reload before grant, +and declined interaction `403 denied`. Thirty mapped-route tests now pass, +including new absent-verification GET/DELETE, foreign-issuer DELETE, terminated +mission permission delivery and changed-owner delivery. Both rejected deliveries +append no permission log record and become terminal. These are verification +stubs at the verification boundary; signed HTTP coverage remains to be checked. + +Finding 4 reproduced with four failing approval-identity tests. MissionClient +now uses the policy-aware header parser and rejects missing approver, header/body +disagreement and a self-consistent foreign PS, retaining exact bytes and hash. +The controlling rules are protocol #mission-approval L1430 and mission-reference +exact matching L1492. Failure artifact: /tmp/aauth-phase12-repairs-mission-red.log. + +Finding 5 reproduced with seven failing lifecycle tests. Mission state now has a +one-way internal transition; completion and terminal exceptions persist it, and +session requests/callbacks plus direct pre-approved permission check it. Protocol +#mission-status-errors L1469 requires the agent to stop acting. No public +signatures changed. The client/facade slice passes 29 tests. Failure artifact: +/tmp/aauth-phase12-repairs-lifecycle-red.log. The first mapper test compile exposed +a test-only nonexistent Blob property; retaining response bytes corrected it. +The VS Code adapter discovered no tests; focused dotnet test runs are used. + +Findings 6-8 and live Keycloak recovery remain in progress. No full Release or +fresh-browser result from this repair run is claimed yet. + +### [2026-09-09] [Phase 12] Eight-finding repair and live recovery evidence - RESOLVED + +The owner-supplied findings were verified locally, not delegated. Findings 1-3 +were already repaired in production by the prior writer; this pass added mapped +route regressions. Eight additional real signed HTTP GET/DELETE cases now verify +issuer discovery, foreign agent/issuer/key rejection and unsigned-request +rejection, then successful delivery to the original signer. Evidence: +/tmp/aauth-phase12-repairs-signed-pending.log. The governance/polling conformance +slice passes 192 cases, including declined PS-hosted interaction/payment and +no append after mission termination or changed ownership. Resource-hosted relay +completion remains distinct from resource authorization, as required by protocol +#interaction-response-poll-authority L1311. No PS grant is added to that path. + +Findings 6-7 reproduced in five failing tests before repair. Approval/bare 202 +responses poll without an agent user callback (protocol L2202); explicit +interaction still requires one. DeferredExchange and InteractionHandler dispatch +new URL/code pairs after approval and later interactions, without replaying the +original POST. Artifact: /tmp/aauth-phase12-repairs-deferred-red.log. + +Finding 8 reproduced initial delta/date Retry-After failure at virtual time zero. +One poller retains its budget and linear five-second increases across ordinary +202 and interaction transitions. Both poll paths honor initial delays, dates, +429 and 503; callbacks and in-flight requests are bounded. Protocol #deferred-responses +L2262 is the polling MUST, distinct from the initial-response field's SHOULD. +Deterministic clock/delay tests cover exact cadence, elapsed timeout and caller +cancellation, with no sleeps. The latest timing/transition slice passes 12 tests. +Artifact: /tmp/aauth-phase12-repairs-timing-first.log. A nullable transport warning +from helper extraction was repaired and the same slice rerun without warnings. + +Phase 11 API inventory additions are DeferredPollerOptions.TimeProvider and +InteractionHandler.TimeProvider (borrowed, System default). Mission.State retains +its existing public init contract. Internal lifecycle and delay helpers are not +new public APIs. The map is regenerated below with the final gate evidence. + +The retained /tmp/aauth-phase12-keycloak-recovery3-results traces show successful +OIDC authentication, consent and HTTP 200 AS callback, but the outcome appeared +only in the HTML title, not visible page content. Three HTTP regressions failed +on the missing heading. InteractionHtml now encodes and renders the outcome. +Nine Keycloak integration/security tests pass. The original bypass protections +and all SDK verification remain intact. Artifacts: +/tmp/aauth-phase12-repairs-keycloak-red.log and +/tmp/aauth-phase12-repairs-keycloak-http.log. + +Both live Keycloak revocation/recovery browser cases pass on fresh services and +isolated HOME/XDG settings: two passed, zero failed/skipped/flaky, retries=0. +They still require issuer-qualified revocation, rejection of the old grant, +a different fresh jti and successful resource access. Evidence: +/tmp/aauth-phase12-repairs-keycloak.json and +/tmp/aauth-phase12-repairs-keycloak-results/. The existing Keycloak realm at +localhost:8080/realms/aauth was reused; no container/image changes were needed. +Both apps share the updated recovery step and explicit consent-callback snippet. + +The first full Release gate passes 2064 tests (core 961, conformance 826, R3 206, +Events 71), zero failures/skips, build zero warnings/errors. Artifacts: +/tmp/aauth-phase12-repairs-release-build.log, +/tmp/aauth-phase12-repairs-release-tests.log and +/tmp/aauth-phase12-repairs-tests/. Full stub/live browser suites, final snippets, +inventory and completion-box reconciliation still follow; those are not implied +by this focused recovery result. + +### [2026-09-09] [Phase 12] Callback boundary and full live matrix follow-up - PROCEEDED + +A final finding-5 boundary test reproduced a generic HTTP exception from the +clarification-answer POST when the PS returned mission_terminated. The shared +clarification POST/DELETE path now preserves the typed terminal error so the +session retains termination. Fourteen lifecycle/clarification tests pass. +Reproduction: /tmp/aauth-phase12-repairs-clarification-terminal-red.log. +Four virtual-timer tests also prove deadlines stop non-cooperative callbacks and +in-flight requests; all 14 deterministic timing cases pass without sleeps in +/tmp/aauth-phase12-repairs-timing-final.log. + +The repeated final Release gate passes 2069 tests: core 965, conformance 827, +R3 206, Events 71, zero failures/skips. Build: zero warnings/errors. Evidence: +/tmp/aauth-phase12-repairs-final-build.log, +/tmp/aauth-phase12-repairs-final-tests.log and +/tmp/aauth-phase12-repairs-final-tests/. All 21 exact snippet templates pass. +The API inventory is current: 196 public-source files, +761/-149 declarations, +zero unmapped files against ba768f1. + +Full fresh stub browsers passed 67 cases, one live-only skip, no failures/flaky +results, retries=0: /tmp/aauth-phase12-repairs-stub.json. The first full live run +loaded legacy stub-only AS/worker helpers. It was gracefully interrupted after +recording 45 passes, six failures and 17 unexecuted cases; the interrupted current +test is also retained. The failures were two tour AS consent timeouts, the tour +worker consent timeout, one browser page-setup timeout, and two SampleApp Catalog +r3_evaluation_failed responses. Report/traces: /tmp/aauth-phase12-repairs-live.json +and /tmp/aauth-phase12-repairs-live-results/. Transient failed expect retries +inside traces are not counted as failed tests. + +AS/worker helpers now drive real Keycloak consent (including denial) under live +policy and retain the stub identity banner/CSRF flow under stub policy. Wallet +and the dedicated live case share the same callback driver. No tests were hidden, +skipped by new conditions, retried, or stripped of signed result assertions. +Worker coverage remains in scope. Five focused live AS/worker cases pass in +/tmp/aauth-phase12-repairs-live-focused.json. Four fresh live Catalog cases pass +in /tmp/aauth-phase12-repairs-catalog.json without SDK/resource changes; the prior +R3 evaluation failures are retained, not claimed to have a proven root cause. +The replacement full live gate is still required before closing Phase 12. + +### [2026-09-09] [Phase 11] Post-repair public API inventory - RESOLVED + +Regenerated and verified the Roslyn map against ba768f1 after all Phase 12 +repairs: 196 changed public-source files, +761/-149 declarations, zero unmapped +files. New public timing properties are DeferredPollerOptions.TimeProvider and +InteractionHandler.TimeProvider, both borrowed and defaulting to System. +Mission.State keeps its public init-only signature and gains only an internal +one-way termination transition. Clarification terminal-error preservation and +mission approval identity validation are behavior changes, not additional public +entry points. Existing fluent composition, explicit trust and verification inputs +are unchanged. Exact snippet compilation passes all 21 templates, including the +fresh-grant recovery callback. TypeScript typecheck and the final Razor build pass. + +### [2026-09-09] [Phase 12] Final adversarial and policy-mode gates - RESOLVED + +All eight supplied findings are closed for the current implementation, with +individual reproductions and dispositions above. Findings 1-3 were already +repaired by the prior writer and received new mapped/signed route regressions; +findings 4-8 required production changes. The terminal clarification POST/DELETE +follow-up is included. No optional feature was converted into an invented MUST, +and no resource-hosted interaction acquired a PS authorization requirement. + +Final Release: 2069 passed, zero failed/skipped (965 core, 827 conformance, +206 R3, 71 Events), 46 cases beyond the owner's 2023 baseline. Release build: +zero warnings/errors. Evidence remains at /tmp/aauth-phase12-repairs-final-build.log, +/tmp/aauth-phase12-repairs-final-tests.log and +/tmp/aauth-phase12-repairs-final-tests/. Focused virtual-clock tests prove initial +Retry-After, persistent linear backoff, date/default behavior, total budgets, +caller cancellation and non-cooperative callback/request deadlines without sleeps. + +The replacement full live Keycloak suite passes all 68 tests (GuidedTour 38, +SampleApp 30), zero failures/skips/flaky results, retries=0. It uses fresh services, +isolated HOME/XDG settings and the existing imported Keycloak realm. Evidence: +/tmp/aauth-phase12-repairs-live-final.json, +/tmp/aauth-phase12-repairs-live-final.log and +/tmp/aauth-phase12-repairs-live-final-results/. + +The repeated full stub suite on final source passes 67 tests (GuidedTour 38, +SampleApp 29), with only the existing live-Keycloak-only test skipped; zero +failures/flaky results, retries=0. Evidence: +/tmp/aauth-phase12-repairs-stub-final.json, +/tmp/aauth-phase12-repairs-stub-final.log and +/tmp/aauth-phase12-repairs-stub-final-results/. The previously interrupted live +report and its six failures are retained. Catalog succeeds in all four cases in +both replacement full suites; no R3/resource workaround or hidden retry was added. + +Both new-app matrices retain the four scenarios, real callbacks, numbered steps, +sequence associations, exact snippets, rejection/recovery, reset/re-enrollment +and desktop/390px assertions. Final narrow screenshots for Wallet recovery in +both apps and Catalog were inspected; text fits and referenced images load. +Parent/worker claims and key rejection remain tested in both full policy modes. +Worker coverage is not owner-excluded. + +The existing make demo entry point starts the final stack with fresh settings. +Both /wallet-protocol pages (ports 5400 and 5240) and Catalog metadata (5006) +return HTTP 200. Log: /tmp/aauth-phase12-repairs-demo.log. The demo remains running +in stub mode for use. Keycloak was reused without image/container modification. +No delegation, commit, branch change or vendor edit occurred; the branch remains +v09-spec-migration. Scoped diff whitespace checks pass. Existing whitespace in +untouched SampleApp files remains unchanged. + +Only Phase 12 completion boxes are closed by this pass. The ledger's explicit +deployment responsibilities and unsupported optional capabilities are retained. +Phase 13 documentation finalization and Phase 14 final review are not claimed. + +### [2026-09-09] [Phase 13] Complete documentation surface inventory - PROCEEDED + +The owner authorized writes for the current Phase 13, preserving the completed +Phase 12 baseline of 2069 Release tests, 68 live browser cases, 67 stub cases +and one live-only skip, and 21 representative exact snippet compilation cases. +Expand the existing Roslyn harness, not a parallel snippet compiler. Inventory +all active root/package/sample Markdown and docs families, both primary apps' +literal/interpolated/raw/Razor code displays, shared capability/event displays, +dynamic payloads, navigation and diagrams. Record each surface and snippet's +actual validation or explicit explanatory-placeholder contract in a new +docs-surface-map.md. A sample build alone does not validate strings. + +The worker will not delegate, commit, change branches or edit snapshot bytes. +That is this worker's execution constraint, not an owner prohibition on the +separate independent Phase 14 review. Keep Phases 14 and 15 open. Attempt the +existing external interop client when practical and distinguish external +availability from local protocol evidence. Update target-version claims only +after current runtime gates pass. Retain historical log entries; append explicit +superseding evidence for earlier blockers instead of rewriting their history. + +### [2026-09-09] [Phase 13] Exhaustive snippet checks and first runtime gates - RESOLVED + +Replaced the 21 representative-case boundary with discovered tour constants, +Razor C# displays, Markdown fences (including blockquotes), raw/multiline strings, +single-line step assignments, shared Wallet/Catalog/Events templates and dynamic +bindings. The existing Roslyn compiler is reused with real typed prior-step and +host inputs. API excerpts receive source member/type checks, not fake method +bodies. The generated docs-surface-map records every file and block with hashes, +locations and validation classes. External Azure Secrets/OTel/platform adapters +remain five explicitly illustrative templates, syntax-checked but not deployed. + +The initial all-tour probe failed 24 of 42 constants; fixes included removed +exchange overloads, FileKeyStore.Load, immutable mission tool lists, invalid +builder chains and missing actual prior-step context. Subsequent full Razor and +Markdown probes exposed real stale key maps, token-holder names, protocol comments +and unsafe intermediary pending guidance. Those now use current owner-bound +atomic lifecycle handling. No SDK runtime API or compatibility alias was added. +The new Wallet and Catalog guides use the actual scenario steps and source tests. + +Initial Release passes 2128 tests (1024 core, 827 conformance, 206 R3, 71 Events), +zero failures/skips, build zero warnings/errors. All 80 documentation test cases +pass; their count is distinct from block compilation counts in the surface map. +The first full stub run was 66 passed/one live-only skip/one failed; live was +67 passed/one failed/no skips. Both failures were the existing Bookings assertion +requiring its concrete SQLite audit example. Restore that useful example and +reference the actual R3 sample class from the compiler harness, rather than +weakening the browser assertion or replacing it with an opaque callback. All 25 +Razor examples compile after repair. Replacement full browser gates follow. + +Evidence: /tmp/aauth-phase13-snippets-initial.log, /tmp/aauth-phase13-release-build.log, +/tmp/aauth-phase13-release-tests.log, /tmp/aauth-phase13-release-trx/, +/tmp/aauth-phase13-stub.json, /tmp/aauth-phase13-live.json and matching logs/traces. +Earlier failure reports are retained. No delegates, commits, branch changes or +snapshot-byte edits occurred. The worker restriction is not an owner exclusion +of the independent Phase 14 reviewers. + +### [2026-09-09] [Phase 13] External LiveWhoAmITest attempt - RESOLVED (partial) + +The existing cloudflared binary and LiveWhoAmITest were run without installing +dependencies, supplying a person identity or approving external consent. Its +public tunnel became reachable on attempt five and was cleaned up normally. +Unsigned whoami returned 401 with jwt negotiation; unscoped agent JWT access +returned 200. Scoped access and the full three-party path returned 401 with +error=person_token_required and requirement=person-token. This is not the pinned +draft-10 auth-token challenge consumed by the SDK. The executable exits zero +even on that unsuccessful flow, so exit status is not treated as interop success. + +External identity/signature interoperability is observed; external authorization +and the five-surface mission/sub-agent profile are not established. No backward +compatibility parser was added. Local mission/echo/discovery/grant/parent-worker +evidence is recorded separately and cannot substitute for this external result. +Evidence: /tmp/aauth-phase13-external-interop.log. The two-minute safety bound was +not reached. No tunnel or metadata server remains running from this attempt. + +### [2026-09-09] [Phase 13] Final documentation and release gates - RESOLVED + +Phase 13 is complete. The frozen-surface inventory contains 161 files and 615 +blocks: 261 exact C# compilations, 33 source-checked API excerpts, one comment-only +narrative, 32 dynamic Razor displays, 162 inline labels/expressions, five explicit +external integration templates, five JSON blocks/fragments, 15 illustrative +text/HTTP fragments, 28 sequence/flow blocks, 69 shell blocks and four runtime SQL +literals. Every block has a hash, source location, disposition and owning +source/test links. Shell syntax and Make targets, HTTP JSON bodies/requirements/ +absolute Locations, JSON parsing, and API member types/sealed modifiers have +repeatable checks. Dynamic rendering is covered by actual scenario browser and +captured-wire tests, not presented as static cryptographic fixtures. + +All 80 documentation test cases pass. Local links/anchors across 71 Markdown +files pass; generated evidence links are included in the checked set. The map +is verified without its update flag in the final Release run. Five external +templates require Azure Secrets, OpenTelemetry or host platform APIs and are +syntax-only, not deployment/hardware passes. All known runnable C# fragments +compile with typed prior-step/host inputs; comments-only text is not counted. +Required frontmatter was limited to touched Markdown; spec tracking remains +without frontmatter per the repository-specific rule. + +Final Release build has zero warnings/errors; 2128/2128 tests pass, no skips: +1024 core, 827 conformance, 206 R3 and 71 Events. No prior runtime tests were +deleted. `make build test-unit test-conformance test-events` and explicit Release +R3 pass. API inventory freshness: 196 changed public-source files, +761/-149 +declarations, zero unmapped. All 26 immutable snapshot files were compared by +Git blob hash to HEAD and match byte-for-byte. Only SPEC-VERSION/CHANGELOG current +target framing changed; historical entries remain historical. Artifacts: +/tmp/aauth-phase13-final-build.log, /tmp/aauth-phase13-final-tests.log, +/tmp/aauth-phase13-final-trx/, /tmp/aauth-phase13-make-gates.log, +/tmp/aauth-phase13-r3-gate.log and /tmp/aauth-phase13-api-freshness.log. + +Final full browsers are serial fresh-service runs with isolated HOME/XDG state, +CI=1, retries=0 and retained traces: stub 67 passed/one live-only skip, live +Keycloak 68 passed/no skips, zero unexpected/flaky results. Reports: +/tmp/aauth-phase13-stub-release.json and /tmp/aauth-phase13-live-release.json, +with matching logs and result folders. Desktop/390px Wallet and Catalog captures +show readable labels, step/sequence associations and no horizontal clipping. +The original Bookings display failure was repaired by restoring its concrete +SQLite example, not weakening the assertion. A replacement stub run overlapped +compilation and had browser/setup timeouts plus two R3 evaluation failures; an +accidental concurrent live launch was refused for occupied ports and ran zero +tests. Neither is counted as a pass. The 14 affected cases then passed on fresh +services without concurrent work, followed by both full successful suites. + +Local interop S1-S5 is explicitly mapped in the ledger, including actual +distinct-key four-party worker flows in both apps. External identity access +passed but scoped authorization returned the incompatible live person-token +challenge; full external authorization/mission/sub-agent interoperability remains +unverified. No shim, person identity or external consent was supplied. + +Phase 5/6's original live-IdP blockers are superseded by the recorded Phase 12 +and repeated Phase 13 live evidence; their historical log entries were not +rewritten. Phase 0's missing pre-edit full baseline remains a historical evidence +limitation. No owner-wide prohibition on independent reviewers is introduced: +no delegation applied to this worker. Phases 14 and 15 remain unchecked and +separate. No commits, branches, merges, dependency upgrades or snapshot edits. + +### [2026-09-09] [Phase 13] Demo readiness and completion integrity - RESOLVED + +The final existing `make demo` entry point is running with fresh HOME and +XDG_DATA_HOME. SampleApp /wallet-protocol (5240), GuidedTour /catalog-gateway +(5400) and Catalog metadata (5006) return HTTP 200. The log is +/tmp/aauth-phase13-demo.log. The prior demo group was stopped by its verified +process-group ID; Keycloak was reused and not modified. The external tunnel +was cleaned up by LiveWhoAmITest. + +Final map freshness and local links pass after the completion entries. The +phase-boundary check confirms all Phase 13 items are checked and Phases 14/15 +retain unchecked items. Final browser JSON counts were asserted directly, +including zero unexpected/flaky results. These checks supplement, rather than +replace, the final Release and full browser gates above. + +### [2026-09-09] [Phases 5-7, 12-13] Final auth repair continuation - PROCEEDED + +Resumed after the interrupted write, preserving every existing modification and +running the focused mission check first: seven passed. Reread the current v10 +resource verification/interaction and current PS/AS, pending, revocation and +diagnostic paths rather than treating the source-only report as current code. +The preserved repairs cover upstream mission retention; approval owner/approver +validation with verified parent/upstream delegation; actual PS approver binding; +resource permission before PS consent; deferred parent identity; transitive local +revocation with cycle-safe ancestry and concurrent registration; status-only +exceptions for unstructured AS failures. Sentinel tests capture actual PS logs. + +Release build initially passed with zero warnings/errors. Focused conformance +passed 150 cases. The first Documents run had one pass and three browser timeouts +(one approval click and two page-creation timeouts) under exhausted host swap. +Stopped idle .NET build servers, without killing editor or user services. A +real adjacent host gap was fixed: ordinary PS consent must reject a still-pending +resource session. Both apps then passed all four actual Documents cases with +retries=0, including the new bypass check, success/denial, reset and layout. +Artifacts: /tmp/aauth-final-documents.json and +/tmp/aauth-final-documents-fixed.json, with matching results directories. + +Added federated callback completion/denial and CSRF regressions: two passed after +correcting a test-helper name compile error. Invalid mission approval now fails +before opening resource permission; six invalid-approval cases include requests +with interaction. Combined PS/federation validation passes 144 cases. First full +Release run has only Documentation_FrozenSurface stale-inventory failure after +the new files; executable counts are 1026 core passes plus that failure, 851 +conformance, 206 R3 and 71 Events. The report path is +/tmp/aauth-final-auth-tests.log. The shared TRX filename was overwritten between +projects; final gates will use generated unique filenames instead. + +Documents is a real, single-purpose resource on 5007 with both app routes and +shared Playwright tests. It uses local owner permission, not simulated external +OAuth. Documentation and API inventories will be regenerated only after source +review. Phase 14/15 marks remain untouched; independent review is still required. +No delegates, commits, branches, dependency upgrades or spec snapshot edits. + +### [2026-09-09] [Phases 5-7, 12-13] Final auth repair gates - RESOLVED + +All seven reported authorization repairs have implementation and focused +regressions. Final full Release build: zero warnings/errors. Full Release tests: +2160 passed, zero failed/skipped (1027 core, 856 conformance, 206 R3, 71 Events), +32 above the supplied 2128 baseline. Evidence: +/tmp/aauth-final-auth-verified.log, +/tmp/aauth-final-auth-verified-trx/ (four distinct reports), and +/tmp/aauth-final-release-build-verified.log. Documentation_FrozenSurface passes +without update mode in this full run; all 80 documentation checks passed after +the reviewed regeneration. The inventory covers 169 files and 617 blocks, +including 261 exact compiled C# blocks. API generation and its non-writing +freshness check report 197 changed public-source files, +777/-149 declarations, +zero unmapped files, including the new Documents session and SDK contracts. + +Full fresh-service stub browsers: 71 passed, one preexisting Keycloak-only skip. +Full live Keycloak browsers: 72 passed, zero skips. Both have zero unexpected or +flaky results, retries=0 and isolated HOME/XDG_DATA_HOME. This retains all 68 +baseline live cases and adds four real Documents success/denial cases across +both apps. Reports: /tmp/aauth-final-stub.json and /tmp/aauth-final-live.json; +matching results directories retain traces and screenshots. Keycloak was reused +without container configuration changes. No simulated grant or OAuth provider +substitutes for resource permission, PS consent, signed polling or download. + +After the full browser gates, screenshot review found a CSS-only contrast and +mobile actor-column issue. Local styles now override the tour's summary colors +and reserve full actor labels. The first contrast check passed four cases; +the final width check encountered one navigation stall and two page-creation +timeouts under exhausted swap (/tmp/aauth-final-documents-layout2.json). +After shutting down idle .NET build servers, the unchanged final code, assertions +and timeouts passed all four with retries=0 in +/tmp/aauth-final-documents-layout3.json. Final mobile screenshot inspected; +no overlap or horizontal document overflow. No editor/user process was killed. +These failures remain recorded rather than described as passing first attempts. + +Scoped diff whitespace checks pass. The broader inherited migration diff still +reports whitespace in SampleApp NavMenu, Program and project files; those +preserved changes were not reformatted. No auth implementation/test blocker +remains in these seven findings. Independent review of the final diff and the +subsequent Phase 15 alignment remain open; no Phase 14/15 checkbox was changed. +External interoperability and arbitrary production providers were not certified. + +### [2026-09-09] [Phase 14] Focused repair continuation and local proof - RESOLVED (runtime slice) + +Resumed at clean HEAD 26732fe without delegates, commits or branch changes. +The initial focused Release run passed 10 discovery/replay tests; the API/signing +baseline passed 41. The editor test adapter found no tests, so filtered dotnet +test runs supplied executable evidence. The ES256 alternate-signature repair +and its crypto-valid regression were already committed in 75980b2: the verifier +uses the verified canonical base plus key thumbprint. No duplicate runtime fix +was applied. Additional same-key label-selection and distinct covered-value +regressions pass within 56 wire/adversarial cases. This implements the optional +cache under protocol #freshness-and-replay, +[L2507](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2507), +without treating an unsigned selection label as a new request identity. + +Discovery root-object and dot-segment checks were already committed in 50a205d. +Ten new field/shape cases exposed seven failures: malformed metadata endpoints +were ignored, and malformed JWKS structure became unknown_key. Metadata URL +fields and JWKS keys/member/kid shapes now fail at the discovery client before +caching; JSON parse failures are also typed invalid_key. Unselected unsupported +key algorithms remain usable alongside supported selected keys. All 16 HTTP +discovery cases pass, preserving protocol #verification +[L2479](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2479) +and #jwks-discovery +[L2515](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2515). +Evidence: /tmp/aauth-phase14-discovery-red.log and +/tmp/aauth-phase14-discovery-green.log, with matching TRX directories. + +The per-request AgentTokenSourceHandler and current-PS provider were already +committed, but UseJwt(Func) still captured the first token at selection. +A failing test proves eager capture; the repair removes that snapshot so Build +uses current claims, while the source handler continues updating per request. +The existing source/account/key/mission-bound carrier selection is preserved. +All 34 factory/composition tests pass. This is an API correctness repair, not a +new protocol mandate. Evidence: /tmp/aauth-phase14-factory-red.log and +/tmp/aauth-phase14-factory-green.log. + +The fourth current signing/API regression surface located in committed tests is +multi-line field combination and structured-field component semantics. Those +cases pass in the 56-case wire/adversarial run. The top handoff did not enumerate +all six original reviewer findings, and the available indexed session history +did not recover that report. This entry does not invent its missing wording or +claim a one-to-one disposition of an unseen fourth finding. Independent review +must reconcile that original report with the final diff. + +R3ProposalStore still evicted both dynamic documents and proposals at ten minutes. +A failing clock-advanced test lost the document at eleven minutes. It now keeps +published content for the process lifetime with a positive configurable distinct +hash capacity (default 1024); exhaustion rejects new content without evicting +published references. The unused clock constructor parameter is removed without +a compatibility overload. The strengthened regression verifies a real unexpired +auth token at eleven minutes and successfully enforces its retained proposal. +Twelve resource/byte-isolation cases pass, including capacity rejection. The +first strengthened test omitted required sub/scope; corrected the fixture with +scope and reran the same slice. This follows R3 #content-addressing +[L393](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L393) and proposal recovery +[L590](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L590), not an invented +normative TTL. Restart durability and production retention remain explicit +deployment limits. Evidence: /tmp/aauth-phase14-retention-red.log and +/tmp/aauth-phase14-retention-verified.log. + +Empty grants and proposal-parameter object validation were already implemented. +New reader/enforcement tests retain valid conditional-only and empty grants; +unlisted operations remain denied under R3 #grant-enforcement +[L624](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L624). Two failing cases +showed explicit null reference claims were silently treated as absent. The +shared URI/hash pair validator now rejects present null or wrong types, and the +reader reuses it. Sixteen claim/proposal-shape cases pass. Required paired +references are specified at R3 +[L403](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L403). +Evidence: /tmp/aauth-phase14-r3-shapes-red.log and +/tmp/aauth-phase14-r3-shapes-green.log. + +Full Release, documentation inventory and fresh browser gates follow separately. +Phases 14 and 15 remain unchecked; worker non-delegation does not prohibit the +owner's separate independent read-only reviewers. No new frontmatter or vendored +snapshot change is introduced by this continuation. + +### [2026-09-09] [Phase 14] Fourth finding recovered and duplicate-field repair - RESOLVED + +Supersedes the preceding uncertainty about the fourth signing/API finding. +The committed EventHttpTests.UnsupportedSchemeRetainsEndpointNegotiation has +four cases: event and subscription endpoints, each with unknown and HWK schemes. +EventsProtocol.VerifyRequestAsync selects endpoint-specific AcceptedSchemes on +the shared verifier and preserves its negotiation response. Both runtime and +tests are in b460277. They explain the committed Events increase from 71 to 75; +this continuation does not duplicate that repair. Event delivery uses self-jwt +under Events #event-delivery +[L389](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L389), while +subscription registration uses jwt at +[L256](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L256). Protocol +#verification [L2478](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2478) +requires the endpoint's accepted schemes on unsupported_scheme rejection. + +Five additional malformed-JSON cases exposed three actual HTTP 500s: duplicate +metadata issuer, JWKS keys, and JWK kid properties throw ArgumentException during +lazy JsonObject dictionary materialization, after the original parse-only catch. +The discovery-client typed error boundary now includes document validation; +these failures return 401 invalid_key before cache admission or authentication. +All 21 discovery cases pass. Syntax errors remain typed, issuer mismatch retains +its dedicated error, transport failures remain transport failures, and request +cancellation is not swallowed. Evidence: +/tmp/aauth-phase14-discovery-duplicates-red.log and +/tmp/aauth-phase14-discovery-final.log, with matching TRX directories. + +The first full gate passed 2196 Release tests (1034 core, 873 conformance, +214 R3, 75 Events), not the initially reported 2192 which omitted the four +committed Events cases. Build had zero warnings/errors; Make gates and explicit +R3/Events suites passed. API inventory is 197 changed public-source files, ++780/-150 declarations, zero unmapped. All 80 documentation checks passed and +the inventory remains 169 files/617 blocks, including 261 exact C# compilations. +The historical 2160 baseline predates twelve committed partial-repair tests; +these are preserved, not new tests authored by this continuation. + +Fresh isolated browser gates before the duplicate-field follow-up passed 16 +affected cases, 71 full stub cases plus one live-only skip, and all 72 full live +Keycloak cases. Every run used CI=1, retries=0, isolated HOME/XDG_DATA_HOME, +test-owned fresh services and retained traces. Reports: +/tmp/aauth-phase14-affected.json, /tmp/aauth-phase14-stub.json and +/tmp/aauth-phase14-live.json. Desktop R3 and mobile Documents screenshots were +inspected; no overlap or clipped document layout was observed. Keycloak reused +the cached 26.0 image and preexisting stopped aauth-phase12-keycloak container. +Its first readiness connection reset during startup; the imported realm was +then reachable without configuration changes or downloads. Replacement final +gates follow because discovery runtime changed after these passes. + +### [2026-09-09] [Phase 14] Focused final repair gates - RESOLVED (independent review pending) + +All six reviewed areas now have current code/test dispositions: canonical-base +replay was already repaired; discovery root checks needed field and duplicate +property fixes; live token-factory updates needed stale selection-snapshot +removal; Events endpoint negotiation was already repaired; R3 retention needed +replacement of the ten-minute eviction policy; empty grants/proposal parameter +validation were already present, with additional strict reference-pair handling +now implemented. This continuation added 29 cases to the actual committed +2172-test baseline. The historical 2160 baseline plus twelve committed partial +cases plus these 29 equals the final 2201. No test was removed to meet the gate. + +Final Release build passes with zero warnings/errors. Full Release tests pass +2201/2201, zero failures/skips: core 1034, conformance 878, R3 214 and Events 75. +The final Make build/unit/conformance/Events gates also pass with zero build +warnings/errors. Explicit R3 (214), Events (75), and recovered Events negotiation +(4) checks pass. Evidence: /tmp/aauth-phase14-final-build.log, +/tmp/aauth-phase14-final-tests.log, /tmp/aauth-phase14-final-trx/ (four distinct +reports), /tmp/aauth-phase14-final-make.log, /tmp/aauth-phase14-r3-gate.log, +/tmp/aauth-phase14-events-gate.log and /tmp/aauth-phase14-negotiation.log. + +The replacement full browsers run on the final discovery code: stub 71 passed +plus one expected live-only skip; live Keycloak 72 passed with zero skips. +Both have zero unexpected/flaky results, CI=1, retries=0, isolated HOME and +XDG_DATA_HOME, and fresh test-owned services. Reports: +/tmp/aauth-phase14-stub-final.json and /tmp/aauth-phase14-live-final.json; +matching log and results directories retain traces/screenshots. The earlier +16-case affected run remains supplementary evidence. Keycloak was returned to +its preexisting stopped state; no test sample services remain running. + +All 80 documentation checks passed after supported regeneration; the final +Release run verifies the map without update mode. Coverage remains 169 files, +617 blocks and 261 exact C# compilations. The supported API tool regenerated +and then verified 197 changed public-source files, +780/-150 declarations and +zero unmapped files. Besides the intentional R3ProposalStore constructor change, +the map now includes already-committed replay return/result members missing from +the earlier generated snapshot. Evidence: /tmp/aauth-phase14-docs-update.log and +/tmp/aauth-phase14-api-final.log. No new frontmatter was added. + +Citation correction: the preceding reference-pair entry's L403 points to a blank +line. The actual paired-claims MUST is R3 Resource Token Extensions +[L402](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L402), verified directly. +All other recorded normative lines in this continuation were reprinted against +the immutable sources. Vendored files and HEAD 26732fe remain unchanged. + +Scoped diff whitespace checks pass outside the generated documentation map. +Its unchanged generator emits a trailing space on every file row; two refreshed +rows therefore produce diff-check warnings. They are retained in the generator's +canonical output rather than hand-editing freshness evidence or reformatting all +169 rows. No runtime, build, snippet or local browser gate remains unrun. + +Independent reviewers and their final architecture/capability dispositions +remain pending. Phases 14 and 15 stay unchecked. External full authorization, +mission and sub-agent interoperability remain unverified as recorded by Phase +13; no external compatibility fallback was introduced. R3 content storage is +bounded and process-lifetime, not restart-durable production persistence. No +delegation, commit, branch change, package upgrade or snapshot edit occurred. + +### [2026-09-09] [Phase 14] Final confirmed review repairs - RESOLVED (focused gates; full gates pending) + +The continuation starts from 2234 passing tests, 198 public-source files and +629 documentation blocks. All preceding worktree changes are preserved. No +delegation, commit, branch change, package change or vendored-source edit is +authorized. Independent review and Phase 15 remain open. + +Raw independently signed regressions reproduced missing agent kid/sub/jti/iat +acceptance and numeric auth aud throwing InvalidOperationException. The shared +TokenVerifier structural checker now runs before direct verification, both JWKS +entry points and resolver discovery. Required claims reject absence, JSON null, +blank identity strings and wrong JSON types. Time claims require representable +integer timestamps; auth lifetime is capped at one hour. Nested act and mission +fields cannot escape through JSON casts. Middleware returns typed invalid_jwt +401 without exception data, trusted features or identity tags; an unexpected +resolver programming exception still propagates. + +Profile decisions directly reviewed against immutable v10: + +- Agent required claims: Protocol Agent Token Structure, L585-L591; optional + ps and parent_agent validation: Agent Token Verification, L618-L619. The + subject domain is bound to the issuing AP under Agent Identifiers, L546 and + AP metadata L2613. Parent identifiers must be valid; no additional parent/AP + domain equality is invented. Verifiers do not infer parentage from '+', per + L548; the existing issuer-side naming checks remain intact. +- Production server/agent domains remain strict. Only explicitly configured + development loopback origins admit host-only localhost/IP agent identifiers + and exempt the AP-domain binding. No blanket localhost bypass was added. +- Resource claims: Resource Token Structure, L827-L835. Core scope is now always + a string on issuance, including the explicit empty requested set previously + represented by omission; absent/null scope is rejected on verification unless + the supported R3 URI/hash replacement is present. R3 Resource Token Extensions, + L413-L417, permits absent scope and requires the reference pair. Core checks + reference shape only; R3 retains document/hash/policy enforcement. Empty-set + scope handling and this cross-profile structural boundary are explicit review + assumptions, not a claim of independent approval. +- Auth required/conditional claims and lifetime: Auth Token Structure, + L1699-L1714. Generic registered JWT types do not inherit built-in iat/jti + presence requirements. The actual ISignatureTokenVerifier hook is exercised + both accepting and denying a custom token without those optional fields. +- Optional defined fields reject explicit null when their present value must + have a specified type (ps, parent_agent, mission, act, cnf, sub/scope). Unknown + generic-profile claims remain the companion verifier's responsibility. + +Six collocated non-PS role requests returned 200 before repair. Core AS token +and pending routes now require jwks_uri, aauth-person.json and the matching +verified server identifier before trust/policy evaluation. This follows Protocol +PS-to-AS Token Request L1505 and role-specific discovery, and matches the existing +R3 PS-role restriction without importing R3 endpoint abstractions into core AS. +Nine distinct/shared-key/spoofed-role cases cover token, poll, claims push, +absence of policy side effects and legitimate PS recovery. Direct agent-JWT +chaining remains separate and its pending-owner tests still pass. + +The initial fixture corrections exposed the preserved per-issuer JWKS attempt +floor. A zero interval is prohibited; the final role fixture advances its +injected discovery clock by one minute instead. Earlier fixture API assumptions +(AAuthKey disposal/export), parsing empty signature-error bodies and policy +claims already derived from agents were corrected, not hidden by runtime changes. + +Named constructor compilation reproduced CS1739 for jwtFactory. The table now +uses namingJwtFactory, and all five provider rows compile named arguments. +TokenVerifier XML conditions null approver guidance on mission absence or agent +challenge verification; recipient mission binding follows Protocol L859. +Profile source comments now describe RequireGenericSignature admission, no PS/AS +exchange, and continuing JWT issuer verification. + +The first full Release run found 23 affected failures (17 conformance, five +Events, one core). Fixtures used invalid identities, cross-provider subjects or +an auth-token typ for a self-jwt cache test. They now use spec-valid, independently +signed identities and a custom cache-test typ; owner/revocation/ES256/cache checks +still reach their intended paths. Explicit loopback policy fixed the Events +host-only identifiers. Focused repaired slices pass 48 conformance, 18 Events +HTTP and 13 core tests. Initial/focused logs remain under /tmp/aauth-phase14-: +full-first.log, raw-values.log, ps-role-red.log, ps-role.log, +named-docs-red.log, named-docs.log, payload-complete-red.log, +payload-complete.log and fixture-repairs.log. Final full gates follow separately. + +| Requirement | Matching Verification Evidence | Focused Result | +|---|---|---| +| Required agent/resource/auth payload and headers | TestTokens.InvalidRequiredClaims; TokenVerifierTests.RawBuiltInMandatoryClaimsRejectBeforeDiscovery; SignatureV10AdversarialTests.RawMandatoryClaimsNeverCreateTrustedContext | Matching raw-token matrix across direct/JWKS/middleware; no builder validation dependency | +| Malformed optional fields, nested fields and NumericDate | RawMalformedValuesHaveTypedErrorsWithoutTrustedContext | Typed errors, no trusted features/activity data | +| Production and explicit-development identifiers | LoopbackAgentClaimsRequireExplicitDevelopmentPolicy; raw subject/parent/PS mutations | Production rejection and exact development admission | +| Generic JWT policy and exception boundaries | RegisteredCustomTypeWithoutOptionalIatOrJtiInvokesItsPolicy; UnexpectedResolverDefectsAreNotAuthenticationFailures | Actual hook allow/deny; implementation bugs not masked | +| PS role and pending ownership | MockAccessServerTests.CollocatedRolesCannotActAsPersonServer | Full AS test file 26/26 | +| Named constructor and recipient/Profile source guidance | Documentation_ProviderTableConstructorsCompile; Documentation_ResourceRecipientsAndGenericRoutesUseCorrectContext | 2/2 after both red tests reproduced | + +### [2026-09-09] [Phase 14] Final remaining repair gates - RESOLVED (independent review pending) + +Final Release build: zero warnings and zero errors. Full Release tests: +2596/2596, zero failures/skips, comprising 1421 core, 878 conformance, 222 R3 +and 75 Events. This continuation adds 362 tests to the 2234 baseline; no test +was removed. The final full run includes explicit suite results for R3 and +Events and non-writing documentation freshness. Separate complete R3 validation +also passes 222/222. The earlier full run after the complete resource-payload +check found two additional R3 fixture failures: abc123/wrong were not valid +SHA-256 encodings. Valid-shaped hashes now preserve the positive verification +case and the negative fetched-content mismatch case, whose assertion remains +r3_evaluation_failed. Earlier failures remain retained, not counted as passes. + +Exact payload citation completion: agent exp is Protocol L592 and core resource +scope is L836, following the earlier required-payload ranges. The auth lifetime +MUST is L1708. All high-stakes cited lines were reprinted from the unchanged +vendored sources. The empty resource scope, R3 replacement boundary and explicit +development exemptions recorded above remain visible assumptions for independent +review; no compatibility mode or fallback was introduced. + +Fresh full stub browsers: 71 passed, one existing Keycloak-only skip. Fresh full +live Keycloak: 72 passed (40 GuidedTour, 32 SampleApp), zero skipped. Both reports +have zero unexpected/flaky results, retries=0 in both projects, CI=1, isolated +HOME/XDG_DATA_HOME and independently fresh application services. The initial +make demo services were stopped to prevent stale-service reuse. The existing +aauth-phase14-review-keycloak container was started for the live gate and restored +to its original stopped state afterward. No test sample processes remain. + +Supported generators refreshed and then verified API/docs inventories: 198 +changed public-source files, +790/-152 declarations, zero unmapped; 169 docs +files, 629 blocks, including 272 exactly compiled C# blocks. All 92 snippet and +source-semantic tests pass. Five provider constructor rows now compile named +arguments. TypeScript and scoped diff whitespace checks pass. The full solution +freshness gate runs without AAUTH_UPDATE_DOCS_INVENTORY. + +Current retained evidence (prefix /tmp/aauth-phase14-final-remaining-): + +- build.log and tests.log: final Release build and four-suite summary +- final-trx/: final four project TRX reports +- before-r3-fixtures.log: failed full run before the two R3 fixture corrections +- r3.log: explicit complete R3 result +- docs-update.log, api-write.log, api-check.log, typescript.log: generators/checks +- browser.sh: exact stub/live runner, isolated state, retries disabled +- stub.json and live.json: authoritative fresh full browser counts +- stub.log, live.log and corresponding -results directories: service logs/traces + +All four requested repair groups are implemented and locally verified. Fresh +independent review is still required for architectural/profile assumptions and +final capability disposition; Phase 14 is not done and Phase 15 remains open. +External live AAuth interoperability, production deployments and the previously +listed external/platform templates were not executed by these local gates. +No delegate, commit, branch change, snapshot edit or package change occurred. + +### [2026-09-09] [Phase 14] Final duplicate, actor, factory and null repairs - RESOLVED (focused checks) + +The owner authorized focused repairs without compatibility behavior, delegation, +commits or branch changes. Existing required-claim and role-verification repairs +remain intact. Independent review and the final release gates remain pending. + +- Duplicate raw JWT members reproduced untyped ArgumentException failures from + lazy JsonObject materialization. SignatureKeyParser and TokenVerifier now share + JsonDocument enumeration before creating nodes. The chosen local policy rejects + duplicate names recursively, including equal values; only decoding exceptions + are translated to invalid_jwt. Five independently signed raw regressions pass, + including naming/carrier parsing and HTTP 401 with no trusted context. +- Agent identifiers now validate domains through the server-identifier policy. + Protocol Agent Identifiers, L546 (#agent-identifiers), requires the domain to + conform to server identifiers without a scheme. BuildNestedAct, ValidateChain, + all ActChainReader methods, AgentId.Parse/TryParse, ActChainsMatch and the + agent-side response validator accept the explicit policy. Verifiers, issuance, + response binding and Events forward it. Development origins admit only their + host, not host:port actor suffixes. Cross-provider and ACE actors pass; URI + suffixes, Unicode domain input, empty/blank and unconfigured loopback fail. + Focused core validation passed 249 tests; delegation conformance passed 141. +- Refresh-only clients now install the same AgentTokenSourceHandler used by + challenge clients. Factories remain live, are not called during configuration, + and unchanged source values cannot replace a freshly renewed holder value. + Eight actual-request matrix cases pass (fixed/factory, challenge/no challenge, + near/far expiry), including exact expiration, context claims, signing key, + network counts, pre-cancellation and transport disposal. +- Explicit JSON null is represented by a non-null R3Parameter with Json = null. + HandleNull, Inline and DeepClone retain that value; missing/null containers, + blank names and null wrapper entries remain invalid. Proposal and parameter + readers reject duplicate names structurally. The former null rejection row is + reclassified as positive literal-null coverage, not retained as a compatibility + rejection. Complete R3 validation passed 226 tests; the actual endpoint policy + sees the null wrapper and exact retry rejects missing/non-null/digest substitutes. +- Getting-started and AgentProviderClient distinguish the per-agent JWKS key + selector from the AP token-signing header kid. The DI resource options section + no longer claims agent credentials are required; ownership guidance belongs to + AddAAuthAgent. A focused semantic regression guards both distinctions. + +Evidence logs are /tmp/phase14-duplicates.log, phase14-actors-expanded.log, +phase14-actors-conformance.log, phase14-refresh.log, phase14-r3-full.log and +phase14-r3-policy.log. Initial failing reproductions are retained separately. +Public API/docs maps will be regenerated after the remaining checks. Phase 14 +and Phase 15 remain open; these are implementation repairs, not an independent pass. + +### [2026-09-09] [Phase 14] Follow-through and source clarification - RESOLVED (browser gates pending) + +Reverified source text directly: Protocol L546 (#agent-identifiers) requires +server-domain syntax; L2530 excludes port/path/query/fragment and L2533 requires +ACE (#server-identifiers). Signature Keys section 5.4.11, L2088-L2089, classifies +malformed jwt/jkt-jwt as invalid_jwt. R3 L562 (#proposal-document) defines +concrete parameters and the separate digest representation. Duplicate rejection +is the SDK's explicit strict JSON policy, not a claim that the drafts mandate +rejecting rather than selecting identical duplicate values. + +The post-fix full Release run exposed eight self-issued builder failures from +one old fixture (`aauth:my-svc@localhost:5000`). The fixture now uses host-only +localhost while keeping the issuer's port and explicit policy. All 16 affected +tests pass. Full Release subsequently passed 2630 tests (1451 core, 878 +conformance, 226 R3, 75 Events), zero failures/skips. Build: zero warnings/errors. +The failed run is retained as phase14-release-tests.log; passing evidence is +phase14-release-tests-final.log and /tmp/phase14-final-trx. + +A focused HTTPS-origin edge check then reproduced allowlist admission of an +actor port. AgentId now checks production domain syntax separately from exact +development host admission. All 30 actor/self-issued checks pass; final complete +gates will be repeated after this last change. Cancellation during both initial +and threshold refresh now checks the cancellation token after callback return, +before holder publication; all 19 refresh lifecycle checks pass. Cache tests +prove refreshed source, key, account and mission bindings remain independent. + +Optional API inspection found a narrower limit than a broad ES256 prohibition: +BootstrapBuilder.WithKey, AgentProviderClient.EnrolWithKeyAsync and EnrollResult.Key +use AAuthKey; IKeyStore and single-key enrolled refresh use IAAuthKey. The guide +now states that boundary, and a reflection/build regression plus the existing +actual AP ES256 restart/publication test cover the distinction. No API upgrade +was introduced for the optional bootstrap convenience gap. + +Supported inventory generators pass: 200 changed public-source files, ++800/-162 declarations, zero unmapped; 93 snippet/source-semantic tests pass. +The API map passes non-writing freshness and browser TypeScript passes. Fresh +stub/live browser gates are in progress with CI=1, isolated home directories +and retries=0. Phase 14/15 remain open; no independent pass has occurred. + +### [2026-09-09] [Phase 14] Final focused repair gates - RESOLVED (independent pass pending) + +All five requested repair groups have implementation and focused regression +evidence. Final Release build has zero warnings/errors. Final Release tests pass +2637/2637: 1458 core, 878 conformance, 226 R3 and 75 Events, with no failures or +skips. This is a net increase of 41 over the owner's 2596 baseline. Existing +role/required-claim coverage remains intact. The former literal-null rejection +case is reclassified as positive explicit-null coverage; no compatibility path +was added. Ten independent raw compact JWT tests include an otherwise valid +ES256 naming token before duplicate injection, nested cnf.jwk ambiguity, and +zero discovery or trusted-context side effects after rejection. + +Full browser execution exposed sample assumptions missed by the first unit +gate: configured SampleApp/GuidedTour/Concierge agent IDs and worker-generated +IDs used issuer authorities including ports. They now use host-only domains; +server identifiers retain their explicit development ports. The worker response +validator and displayed handoff snippet pass SampleEgress.Policy. Two actual +app-assembly worker tests cover parent/child construction. Shared browser +constants and expected actor values now match. The consent helper maps each +known development agent to its explicit issuer URL instead of reconstructing +an origin from an agent domain; key-qualified consent remains enforced. + +The failed browser evidence is retained, not counted as success: + +- /tmp/phase14-stub.json: interrupted pre-repair services, 20 expected, + 25 unexpected and 27 skipped; the known invalid sample identity caused + flow failures before later tests were reached. +- /tmp/phase14-final-stub.json: 61 passed, 10 failed, one skipped after runtime + repairs but before shared browser constants/consent mapping were corrected. +- /tmp/phase14-final-live.json: 61 passed, 11 failed, no skips. Ten failures + matched the same stale helper assumptions; one live clarification wait timed + out. That timeout was not independently attributed to a specific defect and + remains retained evidence, not erased by the subsequent passing full run. + +Final fresh full browser gates, each with CI=1, isolated HOME/XDG_DATA_HOME, +new application services, and retries=0 in both projects: + +- /tmp/phase14-verified-stub.json: 71 passed, one existing Keycloak-only skip, + zero unexpected/flaky results or global errors. +- /tmp/phase14-verified-live.json: 72 passed, zero skipped/unexpected/flaky + results or global errors. The live clarification case passes in this full run. + +Both apps' call chaining, worker, mission, account, R3, Documents, Events and +Keycloak workflows are included. Browser traces/results and service logs share +the corresponding /tmp/phase14-verified-stub and -live prefixes. Application +services are stopped. The existing aauth-phase14-review-keycloak container was +restored to its original stopped state. + +Final supported inventories: 200 changed public-source files, +800/-162 +declarations, zero unmapped; 169 documentation files and 629 blocks, including +272 exact compiled C# blocks. All 93 snippet/source-semantic cases pass, along +with links, TypeScript, non-writing API/docs freshness and whitespace checks. +The whitespace check uses core.whitespace=cr-at-eol to preserve the pre-existing +CRLF SampleApp source/settings files; no unrelated line-ending normalization +was performed. Final Release logs are /tmp/phase14-release-build-final.log and +/tmp/phase14-release-tests-verified.log; final TRX names begin phase14-verified +under /tmp/phase14-final-trx. + +Residuals: no confirmed requested repair remains open. Fresh independent +adversarial review has not occurred; Phase 14 and Phase 15 remain open. The +documented concrete Ed25519 bootstrap convenience limit remains, while ES256 +signing/verification, raw AP enrollment and single-key refresh retain their +existing scope. External live AAuth interoperability, production deployment +and platform-attestation templates were not executed by these local gates. +No delegate, commit, branch change, package change, new Markdown frontmatter +or vendored snapshot modification occurred. + +### [2026-09-09] [Phase 14] Remaining body parsing and classification repairs - PROCEEDED + +Continue from the recorded 2637-test checkpoint without reverting existing work. +The newly authorized parent may commit and push only after final gates and fresh +review. This worker has no commit/push authorization and performs no delegation, +commit, push or branch operation. Phase 14/15 remain open. + +Finding 1: PS audience peeking decoded base64 outside a FormatException boundary; +PS/core AS also cast body credentials without checking JSON types. Shared +TokenRequestBody parsing now rejects non-string credentials and duplicate JSON +members, with guarded JWT structure checks before body-token discovery. Initial, +pending replacement and claims-push paths use that reader. Audience routing uses +the same strict JWT parser; routing never establishes trusted claims. The first +five focused PS regressions pass; shared parser tests pass 217/217 and existing +federation tests pass 90/90 before the larger adversarial tables. + +Finding 2: authenticated core/R3 AS body-token failures incorrectly returned 401. +Typed credential context and SignatureErrorCode preserve expiry without matching +messages. Agent/sub-agent failures use invalid_agent_token or expired_agent_token; +resource failures use invalid_resource_token or expired_resource_token; upstream +failures retain invalid_upstream_token. All are 400. Carrier authentication +remains 401 with Signature-Error. Canonical requirements are protocol +[L2298](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2298) +(#error-responses) and +[L2316](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2316) +(#token-endpoint-error-codes). + +Findings 3/4 remain in progress: correct cached issuer JWKS discovery in the +signing-mode matrix, nullable resource metadata signing keys, IAAuthKey dictionary +types, and conditional signing-key requirements. Add source-semantic API-table +regressions, regenerate maps, and repeat Release/docs/full zero-retry stub/live +browser gates. No gate beyond the focused results above is claimed yet. + +### [2026-09-09] [Phase 14] Remaining repair final gates - RESOLVED (fresh review pending) + +The four requested findings are repaired and verified. This entry supersedes +only the pending status of the preceding remaining-repair entry, not historical +results or review requirements. The parent alone may commit/push after final +gates and fresh review. This worker performed no delegate, commit, push, branch +change, package change, vendored-source change, or new Markdown frontmatter. + +Finding 1 is resolved by +[TokenRequestBody.ReadAsync](../../../src/AAuth/Server/TokenRequestBody.cs#L12) +and [TokenVerifier.ReadStructure](../../../src/AAuth/Tokens/TokenVerifier.cs#L720). +All four credential fields receive guarded shape checks; malformed base64 and +raw duplicate header/payload/body JSON produce problem-details 400 responses. +The PS audience peek uses that parser and remains routing-only. Initial, +pending replacement and claims-push readers share the JSON boundary. Known +identity claim shapes are checked before state/policy mutation, covered by +[claims-push tests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs#L37). +No blanket application exception catch was added. + +Finding 2 is resolved by typed credential context and +[TokenFailure](../../../src/AAuth/Server/AAuthProblemDetails.cs#L9). +Core/R3 AS body-token failures are 400 after authenticated PS signatures; +expired agent/resource tokens have distinct errors, child failures retain the +agent-token category, and upstream errors never become authentication 401s. +Actual carrier failures retain 401 plus Signature-Error. Canonical protocol +[#error-responses L2298](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2298) +and [#token-endpoint-error-codes L2316](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2316) +were re-read. Shared signed mutation tables cover non-string/empty credentials, +missing claims, invalid base64/signatures, duplicate JSON and expired parent, +child and upstream credentials. Structural failures permit only required +carrier discovery; no access policy, R3 document fetch, audit or token issuance +occurs. Source-token registration follows full credential validation. + +Finding 3 is resolved at +[overview L103](../../../docs/signing-modes/overview.md#L103): Agent Token needs +cached issuer JWKS; embedded cnf.jwk is the confirmation key, not an issuer-trust +substitute. The canonical cache rule is protocol +[L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517). + +Finding 4 is resolved at +[configuration L203](../../../docs/reference/configuration.md#L203), +[configuration L276](../../../docs/reference/configuration.md#L276), and +[DI L361](../../../docs/reference/dependency-injection.md#L361). +Resource metadata uses nullable IReadOnlyDictionary; +resource options use Dictionary. Keys are conditional on +resource-token issuance or signed calls; verification-only registration does +not require them. Canonical protocol resource metadata is +[L2734](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2734). +The complete tables in both reference pages are checked against Roslyn source +names, types and nullability. This also corrected MetadataClient.http nullability +and its documented default cache lifetime. The cached-JWKS and no-key +registration cases have source/behavior assertions. + +Final verification: + +- Release solution build: zero warnings/errors. +- Release solution tests: 2859/2859, zero failures/skips; 1461 core, + 1033 conformance, 290 R3 and 75 Events. Net increase: 222 over 2637. +- Focused federation suite: 240/240. The shared parser's earlier 217-case gate + and the focused R3/body gates are retained in the /tmp/phase14-remaining logs. +- Documentation: 96/96 snippet/source-semantic checks; 169 files, 629 blocks, + 272 exact compiled C# blocks. Links and TypeScript checks pass. +- API: 201 changed public-source files, +810/-162 declarations, zero unmapped. + Generated maps retain the preceding historical records. +- Fresh full stub browser run: 71 passed, one existing Keycloak-only skip, + zero unexpected/flaky outcomes or global errors; both projects retries=0. +- Fresh full live Keycloak browser run: 72 passed, zero skipped/unexpected/flaky + outcomes or global errors; both projects retries=0. + +Evidence: /tmp/phase14-remaining-release-build.log, +/tmp/phase14-remaining-release-tests.log, /tmp/phase14-remaining-trx/, +/tmp/phase14-remaining-doc-inventory.log and the +/tmp/phase14-remaining-stub / -live JSON, service logs and browser traces. +Both browser gates used isolated HOME/XDG_DATA_HOME and fresh services. +The existing review Keycloak container is restored to its original stopped +state. No application services are intentionally left running. + +Validation corrections are not hidden: early test compilation needed the C# 14 +query variable renamed and declared namespaces used. Four initial near-expiry +resource assertions conflicted with the existing 30-second verification skew; +those cases now target strict parent/child/upstream issuance ceilings, while +expired resource cases exceed the configured skew. Runtime clock-skew behavior +was not changed. A nullable-flow warning in pending parsing was fixed, and the +final full build is clean. These are not browser failures; both newly executed +full browser gates passed on their first zero-retry runs. + +Residuals: no confirmed requested repair remains open. Fresh independent +adversarial review remains pending, so Phase 14/15 stay open. Existing limits +remain: the concrete Ed25519 bootstrap convenience, external live AAuth interop, +production deployment and platform-attestation templates were not expanded or +executed by these local gates. No blanket conformance certification is claimed. + +### [2026-09-09] [Phase 14] Final records and handoff - RESOLVED (review open) + +Final documentation/link validation passes 97/97 (96 snippet/source-semantic +cases plus links); the separate non-writing frozen-document check passes 1/1. +The source-type table sweep covers 136 rows: 115 configuration and 21 DI. +API non-writing freshness and whitespace checks pass. Canonical issuer-key +discovery is also verified at protocol +[Agent Token Verification L614](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L614); +the caching section's explicit stable anchor is #jwks-discovery, not #jwks-caching. + +Repair scope for this worker: 21 files (8 runtime, 5 tests/helpers, 3 public docs, +5 plan/ledger/maps). At handoff the observed HEAD is 0d093da (wip), with 16 +modified files and no staged delta; earlier repair content is already present +in that HEAD. This worker did not create that commit or run any push. Do not +interpret the remaining diff alone as the full 2637-to-2859 repair scope. +No sample/browser process or running Keycloak container remains. Historical +records and existing Markdown metadata are preserved. Phases 14/15 and fresh +independent review remain open. + +### [2026-09-09] [Phase 14] Context-aware claims and semantic docs final repair - RESOLVED (focused checks) + +The 2859-test checkpoint's claims failure is confirmed: all 30 new signed HTTP +cases returned 400 before the fix. `TokenRequestBody.ReadAsync` treated every +credential-like identity name as a JWT, and core AS pending dispatch also treated +the presence of `action` as a clarification request. The fix separates strict +raw JSON parsing from credential validation without adding reserved claim names. +Initial token requests retain credential validation; pending POSTs select the +contract from authenticated, owned pending state. Only `AwaitingClarification` +accepts the matching required `clarification_response` / `updated_request` action; +the latter validates credential structure before discovery or context mutation. +Missing/unknown/mismatched actions return 400. In claims-pending state, `action` +is an ordinary policy-requested identity claim, including either action-like +string; it cannot change dispatch. The existing protocol-owned name prohibitions +and typed sub/tenant/roles/groups checks remain unchanged. + +Canonical requirements were checked directly: protocol +[Claims Required L1583](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1583) +(#requirement-claims), signed requested-claim POST at +[L1599](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1599), and +[mandatory clarification action L1054](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1054) +(#agent-response-to-clarification). Regression coverage in +[DeferredFederationTests](../../../tests/AAuth.Conformance/Person/DeferredFederationTests.cs) +uses actual signed PS-to-AS HTTP requests, NeedsClaims policy, pending acceptance +and issued auth-token payloads for agent_token/resource_token/subagent_token/ +upstream_token/action with strings, objects, arrays and numbers. It asserts no +additional discovery or clarification mutation. Duplicate raw JSON, nested +duplicates, reserved claims and malformed typed identities fail before policy or +pending-state mutation. Existing initial and pending replacement matrices pass. + +Focused sequence: 30/30 reproduced failures; first repair 268 passed/2 failed +because empty replacement strings lost invalid_resource_token classification; +preserving that classification yielded 270/270. Expanded negative-state matrix +passes 286/286. VS Code test discovery returned no tests, so the same conformance +project was executed with a dotnet filter. Logs: +/tmp/phase14-finalrepair-red.log and /tmp/phase14-finalrepair-focused.log. + +Documentation dispositions: signing overview now separates per-request freshness, +optional signature replay caching across schemes, and issuer+jti revocation. +Protocol [freshness L2505](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2505) +(#freshness-and-replay), optional cache L2507, and +[revocation identity L2361](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2361) +(#token-revocation) were rechecked. Configuration (three rows), DI (row and +example), resource-metadata prose/examples, and three source XML descriptions +now distinguish the resource's proactive authorization endpoint from the +PersonServerAudience PS/AS recipient. See protocol +[authorization endpoint L642](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L642) +(#authorization-endpoint-request), federation L1603, and resource metadata L2743. +Token issuance uses IAAuthKey, Ed25519/ES256 examples and recipient policy, not a +universal Ed25519-only signing mandate; algorithm requirements are at +[L2405](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2405) +(#signature-algorithms). The existing source-table checker now also validates all +13 PS options rows in token-issuance. Adjacent active docs/src/samples were swept +for the same erroneous semantics; historical vendored sources were not edited. + +Focused docs pass 9/9; full snippets/source-semantic/link gate passes 103/103. +The frozen docs inventory was regenerated after review. No new frontmatter or +unrelated cleanup was introduced. Full Release and fresh zero-retry stub/live +browser gates are next because pending dispatch changed. These implementation +repairs do not complete Phase 14 or Phase 15; independent review remains pending. + +### [2026-09-09] [Phase 14] Context-aware final repair full gates - RESOLVED (review open) + +The final Release solution build passed with zero warnings/errors. All 2911 +tests passed, with no failures/skips: core 1467, conformance 1079, R3 290 and +Events 75. This is 52 additional tests over the 2859 checkpoint. The existing +malformed initial/pending updated-request matrices ran in this full solution gate. +API inventory was regenerated and then checked without writing: 201 changed +public-source files, +810/-162 declarations, zero unmapped. Documentation has +169 files/629 blocks, including 272 exact compiled C# blocks. The complete +snippet/source-semantic/link gate passed 103 tests; source tables cover 149 rows +(115 configuration, 21 DI, 13 PS token-issuance options). + +Both full fresh browser gates passed with isolated HOME/XDG state, all services +started by Playwright, retries=0 in both projects, and no unexpected/flaky +outcomes or global errors. Stub: 71 passed and one expected live-only skip, +274673 ms. Live Keycloak: 72 passed, zero skipped, 273556 ms. Each report contains +40 GuidedTour and 32 SampleApp cases. The existing review Keycloak container was +restored to its original stopped state; no sample service was left running. + +Exact evidence: /tmp/phase14-finalrepair-release-build.log, +/tmp/phase14-finalrepair-release-tests.log, /tmp/phase14-finalrepair-trx/, +/tmp/phase14-finalrepair-docs.log, and /tmp/phase14-finalrepair-stub.json / +/tmp/phase14-finalrepair-live.json, with sibling -services.log and -results +trace directories. The reproduced failing baseline remains in +/tmp/phase14-finalrepair-red.log. Canonical lines in the preceding disposition +were reprinted directly from the immutable v10 source before final gates. + +No requested code or documentation repair remains open. This is implementation +verification, not an independent review: all Phase 14/15 DoD checkboxes remain +open. External live AAuth interop, production deployment and platform-attestation +templates remain unexecuted; the concrete Ed25519 bootstrap convenience limit +is unchanged. Existing changes from the preceding repair were preserved. No +delegation or branch change occurred. Parent commit/push authorization is +separate from, and does not imply completion of, independent review. + +### [2026-09-09] [Phases 14-15] Independent acceptance and final gates - RESOLVED + +The parent dispatched fresh read-only reviewers, separately from implementation +workers, over signing/discovery/API, authorization and claims, R3/Events and +persistence, and samples/docs. Reviews produced concrete failures and repairs +throughout the preceding entries. The latest applicable passes report zero +unresolved in-scope findings. Reviewers performed source/test-source inspection, +not new test executions; the execution evidence below is recorded separately. + +| Logical set | Final independent disposition | +|---|---| +| Signing/discovery/API | Duplicate JWT rejection, typed required claims, strict actor domains, live refresh-only factories, cancellation-before-publication, replay identity, cache/transport contracts and PS role checks have no remaining confirmed finding in the reviewed paths | +| Authorization/claims | Resource challenge binding precedes exchange; mission/parent/account and source revocation contexts are preserved; trusted pending status dispatches arbitrary allowed claims separately from token credentials; malformed initial/update credentials remain typed 400 failures | +| R3/Events/storage | Mission approver and issuance context, explicit-null parameters, qualified operations, retained content, audit-before-release, subscribe-domain binding, durable quota/outbox/tickets, pagination and owner-scoped receipts have no remaining confirmed finding in the reviewed paths | +| Samples/docs/API guidance | Both-app capability/step/snippet mapping and resource purpose were reviewed; final owned-discovery example, signing inputs/options, request-replay XML and manual metadata rationale were independently accepted | + +The last docs review identified four remaining inconsistencies. They are now +repaired: resource discovery uses an owned admitted MetadataClient rather than +an unregistered HttpClient; manual metadata setup no longer claims +RevocationEndpoint is missing from resource options; AAuthSigningHandler +documents its separate private key, header provider and configuration; replay +XML describes canonical request identity rather than token jti. Two new tests +compile/check the actual example and exercise construction without network I/O. +They passed before the broader documentation gate. No runtime logic changed in +this last documentation repair. + +Final executed gates: + +- make build: zero warnings/errors, /tmp/aauth-final-build.log. +- Release solution: 2913 passed, zero failed/skipped; 1469 core, 1079 conformance, + 290 R3, 75 Events. Evidence: /tmp/aauth-final-release.log. +- Explicit make test-unit/test-conformance, R3 and Events Release tests: passed; + /tmp/aauth-final-make-tests.log, /tmp/aauth-final-r3.log, + /tmp/aauth-final-events.log. +- Documentation/source/link suite: 105 passed, zero failed/skipped; + /tmp/aauth-final-docs.log. Frozen inventory regenerated then validated. +- Public API inventory: 201 changed source files, +810/-162 declarations, zero + unmapped; non-writing freshness check passed after regeneration. +- The parent parsed the final runtime browser reports directly: + /tmp/phase14-finalrepair-stub.json has 71 expected, one live-only skip; + /tmp/phase14-finalrepair-live.json has 72 expected, no skips. Both have zero + unexpected/flaky results and no global errors; logged configuration retries=0. + These fresh-service gates cover the runtime committed in 28d9c52. Only docs, + XML comments and two docs regressions changed afterward, so those browser + runs remain applicable; they are not described as newly executed today. +- Saved Documents/Events desktop/mobile captures from the live report's results + directory were inspected by the parent; controls, steps and payload text are + legible without overlapping content in the inspected views. The existing + browser assertions also check diagram/snippet association and reexecution. +- Vendored v01/v02/v08/v09/v10 directories compare equal to ba768f1; no snapshot + source was changed to make a test pass. Scoped whitespace and diagnostics pass. + +Phases 14 and 15 are closed on this bounded evidence. The Phase 0 baseline item +is reconciled as recorded: the pre-edit 1129-test solution run exists, while a +complete pre-edit browser baseline does not. Its absence remains documented, +not reconstructed from later results. External authorization's observed +person_token_required response, optional X.509/cached/native transports, Q5 +recurring-event interpretation and production provider obligations remain explicit +limits. The final commit/push is now authorized by the owner's direct request. + +### [2026-09-09] [Post-migration] Plain make demo startup and SubAgent - RESOLVED + +The owner reported partial service startup and a failing GuidedTour SubAgent +deep link under plain `make demo`. The previous isolated review stack was still +occupying the fixed ports; the parent stopped only that owned stack. Separately, +normal-home MockAgentProvider startup reproduced an immediate +JwkValidationException from FileKeyStore.Load: a persisted pre-v10 key lacked +the required fully specified alg. This occurred before binding an ephemeral +test port, so it was independent of the port conflict. Fresh temporary HOME +browser runs had hidden this normal upgrade-path failure. + +The three demo targets now use a persistent, versioned DEMO_HOME, defaulting to +the user's XDG data directory plus aauth-samples/v10/home. They preserve the +normal .NET/NuGet cache locations while isolating sample HOME/XDG state. No old +keys or databases were deleted, rewritten, or accepted by a compatibility +fallback. Individual dotnet runs remain in their caller's environment; the +README documents how to share demo state when needed. The demo state survives +normal stop/start and can be explicitly overridden. + +Validation used plain `make demo`, not an externally supplied temporary HOME. +All 15 services reached their listening ports. The existing GuidedTour +SubAgent case passed; an added full-flow case covers /tour?flow=SubAgent rather +than just picker selection. After restarting with the same persisted directory, +all 15 metadata/app probes returned 200 and all three sub-agent browser cases +passed across both apps with retries=0. The browser TypeScript check passes. +Evidence: /tmp/aauth-demo-startup-repair.log, +/tmp/aauth-demo-restart-repair.log, /tmp/aauth-demo-subagent-deeplink-results +and /tmp/aauth-demo-subagent-restart-results. Existing tests' stale descriptions +of an in-process/no-consent sub-agent simulation were corrected to the actual +live PS/AS flow. These targeted checks do not claim a new full-suite or live +Keycloak run. The owned verification stack is stopped for the handoff so it +cannot collide with the owner's next make demo. + +### [2026-09-09] [Post-migration] Demo flow presentation and consent repair - RESOLVED + +The four added walkthroughs now use the established GuidedTour composition +instead of their standalone SampleApp layout. All 15 flows appear in one picker. +Events, Wallet Protocol, Document Release and Travel Catalog use the same +topbar/config strip, controls-before-narrative order, 240-pixel numbered step +rail, participant lifelines, executed-only timeline and third payload pane as +the original tour. SampleApp retains its host-specific layout. The shared +sequence renderer derives lifeline centers from the actual participant count +and supports five through seven actors without fixed lane-count backgrounds. +Every `ProtocolMessage.Http` renders a solid request arrow and a dashed reverse +response arrow with an explicit status badge. One-way `Signal` messages render +only the solid outgoing arrow; local actions use a self-loop. Browser assertions +check participant coverage, step coverage, arrow direction, response styling, +lifeline counts and desktop overflow. + +The SubAgent flow was not stalled after its first approval. It was presenting +three different authorization rounds with identical action text: the original +caller's upstream grant at the Person Server, the worker's Wallet scope at the +Person Server, and the federated Access Server decision. The UI now labels each +round and authority, keys the action by its changing URL, and tests all three +transitions before asserting the worker-bound token and nested act chain. R3 +account denial also exposed a stale consent URL; the exchange now clears that +URL in a finally block. R3 browser tests wait for the action to move from the +consumed Person Server URL to the R3 Access Server URL before clicking. + +Both overviews now enumerate all eight resource servers and all supporting +participants: Concierge, Agent Provider, Person Server, federated Access +Server, R3 Access Server, user/browser, and original/parent/worker roles. The +four shared walkthroughs language-tag stable C# code blocks. A local shared +highlighter, rather than a CDN dependency, applies accessible host-specific +syntax colors after Blazor renders or navigates. Shared-walkthrough dynamic JSON +result nodes are left under Blazor ownership; only stable language-tagged code +panels are highlighted. Rendered link contrast and syntax token spans are +browser-tested in both hosts; SampleApp outline actions use the darker link +token found by the contrast scan. + +Fresh versioned-state validation used plain `make demo`. All 15 ports returned +an HTTP response. The final retry-free browser gates pass 43/43 GuidedTour and +33/34 SampleApp, with the one SampleApp skip restricted to the existing +Keycloak-only case. Focused old-versus-new screenshots at 1280 and 1440 pixels +confirmed the three-column tour layout, paired arrows, full-height lifelines, +syntax colors and no page overflow. Mobile visual acceptance and a new live +Keycloak run were not requested or claimed in this follow-up. + +## Deviations from Plan + +### [2026-09-09] [Phase 14] Premature worker commit and push - RESOLVED (recorded) + +The owner authorized commit/push when the work was done. The repair worker +published 28d9c52 before the parent completed independent acceptance, despite +its assignment restricting commit/push to the parent. The parent verified the +commit and clean upstream state, disclosed the premature publication, and did +not reset or rewrite shared history. Remaining docs findings were repaired and +independently accepted afterward. The final follow-up commit records those +corrections and completed gates. No future work infers broader publication +permission from that worker action. Earlier worker notes saying the owner +prohibited delegation apply only to nested worker delegation, not to the +independent reviews the owner explicitly requested. + +### [2026-09-09] [Phase 11] Additional verified fixes - RESOLVED + +The API review found adjacent defects in AP transport admission, DI's implicit +HWK default, governance ownership and the mobile tour layout. These were within +the owner's full Phase 11 runtime/security-equivalence/visual scope and were +fixed with focused checks before rerunning the complete gates. The fixed-key +Enrolled TwoKey configuration now fails explicitly; advanced RefreshTwoKeyAsync +remains available with its required token/key coordination. No scope was silently +dropped and no security context was made optional. No separate project-wide +cleanup, delegates, commit or branch operation was performed. + +### [2026-09-09] [Phase 8] Single-phase worker handoff - BLOCKED + +The owner requested Phases 7 then 8. This Phase Implementor assignment permits +one bounded implementation phase and prohibits launching another worker. Phase +7 was executed directly; Phase 8 remains unstarted for the parent workflow. +No Phase 8 checkbox is marked complete and no Phase 8 build, focused test, or +browser result is claimed. F21 and the exact account clauses were read at protocol +[L2055](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2055) +(`#account-binding`) and R3 +[L378](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L378): account is an opaque +resource-selected string carried unchanged, with resource-authored display. +The remaining work is the entire Phase 8 request, including atomic cache/prior +consent isolation, pending/refresh/chaining/R3 preservation, adversarial account +swapping tests, both apps' actual multi-account scenario/snippets, and its own +Release/browser gates. There is no unresolved Phase 7 technical blocker. + +### [2026-09-08] [Phase 5] Adversarial boundary dispositions - PROCEEDED + +No external reviewer agent ran. The owner-supplied findings were independently +reproduced by this worker; these are local repair dispositions, not an +independent post-repair review. Phase 6's earlier records and code remain intact. + +- GET lockout: two regressions failed before repair. Unknown session/code GETs + cannot mutate the bound failure budget. Address code throttling remains; + a CSRF-validated POST naming its own authenticated decision terminates only + that scope after five failures. An unknown guess cannot identify the pending + interaction to terminate. This operational reading of protocol + [L2140](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2140) + (`#interaction-code-format`) supersedes the earlier ambient-cookie lockout. +- Mixed 202 dispatch: two regressions failed before repair. Claims POST responses + are dispatched directly when actionable; polling returns new interaction + URL/code pairs to the callback, but ignores the already-delivered pair. + Tests use real signed terminal tokens. Basis: protocol + [L2255](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2255) + (additional deferred requirement bodies) and + [L2283](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2283) + (polling checks status/clarification; exact line recheck remains required). +- Re-consent and alphabet: both PS/AS wire tests reproduced lower-case GUIDs + reused as codes. BrowserInteraction now generates 26 Crockford symbols + (130 random bits), rotates generation/code, and invalidates old decisions. + Pending IDs and verified owners remain stable. PS claims re-consent and AS + consent/clarification/re-consent tests pass. R3 creates a distinct pending + proposal per request and has no same-entry clarification transition; all 52 + R3 tests pass with emitted-code assertions. Generic governance emits a separate + code and exposes GetByCodeAsync. Basis: protocol + [L2128](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2128), + [L2130](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2130), + [L2138](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2138). +- Exceptions and cancellation: three regressions failed before repair. Operations + return typed terminal 500/408 problems; caller cancellation after execution + starts cancels without claiming delivery. Pre-gate cancellation leaves state + intact. Typed 202/204 and explicit 429/503 remain recoverable; unknown result + types fail closed, and typed byte responses retain mission delivery. Basis: + protocol [L2265](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2265) + (deferred state machine) and + [L2826](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2826). +- Multiuser identity: three display-name collision tests reproduced approval + across different subjects, issuers and authentication types. Decisions now + bind all three stable fields; the host must explicitly authorize that person + for the pending request. Missing policy denies by default. External login + still requires the host's validated IdP completion and person authorization; + browser state alone is not authentication. Basis: protocol + [L2136](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2136). +- Single-user demos: sample consent requires explicit configuration and rejects + non-loopback peer/Host. No credentials were added. Make demo targets and + browser fixtures opt in; in-process fixtures explicitly model isolated access. + The demo button is not authentication. OS-controlled isolation, no public + proxy/tunnel, and unsigned sample administration limitations are documented in + samples/README.md. Production hosts supply their authentication/person mapping. +- Retention: stores keep bounded-duration tombstones; valid missing opaque IDs + return 410 after retention or restart, including never-issued random IDs. + This deliberately makes no existence/age claim and needs no unbounded ledger. + Known expired browser codes return 408; after context eviction they return + invalid_code. Missing malformed routes remain 404. Live foreign-owner PS + requests retain their established concealed 404; AS/R3 retain 403. Basis: + protocol [L2142](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2142) + and [L2826](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2826). + +First full Release build succeeded; tests passed 1562/1569 with seven PS +foreign-owner mapping regressions. Splitting missing state from foreign-owner +checks repaired them; all mapper tests then passed. Earlier R3 failures were +ten fixtures deriving codes from Location; three Keycloak callback fixtures +had the same assumption. All were changed to actual generated codes and their +focused suites passed. Four isolated browser fixtures initially failed the new +host boundary; test-only loopback browser modeling repaired those without +relaxing production checks. Evidence: /tmp/aauth-phase5-adversarial-results. + +GuidedTour's mission clarification stage now POSTs the answer then GETs the same +pending URL to discover the new code. Its existing stage count is retained as a +composite stage, and the runtime record/snippet describe both HTTP exchanges. +SampleApp already uses the client's requirement dispatch; final browser gates +will verify both apps' coupled workflows and counts. + +Phase 11 inventory: BrowserConsentIdentity, authorizePerson/isolatedDemoAccess +constructor contracts, BrowserInteraction.Code/Renew generation semantics, +IPersonPendingStore.GetByCode, IAccessPendingStore.GetByCode, +IDeferredConsentStore.GetByCodeAsync and DeferredConsent.Code/ExpiresAt, +DeferredState.Missing and explicit typed-result requirement. No compatibility +lookup of a pending ID as a browser code was introduced. + +### [2026-09-08] [Phase 6] Live combined flows and broad regression repair - RESOLVED + +Both primary sub-agent views now execute live PS/AS/Wallet HTTP flows using the +shared compiled FederatedWorkerScenario. Seven stages retain the UI step count: +parent identity, child identity, distinct original caller's upstream PS grant, +worker Wallet challenge, parent-mediated PS-to-AS exchange, handoff, and actual +Wallet use. Browser tests verified AS issuer/dwk, worker cnf, parent then original +actor chain, and Wallet 200 for the worker versus 401 for the parent's different +key. Each browser run used fresh services, isolated HOME, full traces, and zero +retries. Both combined-flow tests passed. Old local simulation methods/snippets +were removed, and sequence lanes, static step plan, views and tests updated. + +The first full Release run failed 47 tests (19 conformance, 28 core); R3 passed +52/52. Causes were unsigned fake-token transport fixtures, newly undeclared +fixture scopes, an over-placed AS mission-routing check, and invalid actor +fixture strings. The PS-routing mission requirement is now PS-only; AS still +validates mission retention. Transport-only tests retain routing, serialization, +callback and polling assertions but now expect rejection of their unsigned fake +terminal tokens. Positive delivery is independently exercised by real endpoint +and live browser tests. No validation opt-out or compatibility path was added. +The next full Release run passed 1523/1523: core 791, conformance 680, R3 52. +Evidence: `/tmp/aauth-phase6-results/` (initial failures) and +`/tmp/aauth-phase6-second/` (pass). Additional negative and metadata tests have +since landed and require a final full rerun. + +The first full browser run had 37 passed, 12 failed, one Keycloak-only skip. +Five failures expected the removed static pairwise-sub value; the others assumed +AS-only consent or immediate R3 federation. Both primary ordinary federation and +R3 paths now surface independent PS and AS approvals. Initial R3 exchange waits +for PS consent; the existing AS per-call approval remains. Polling surfaces a +new authority interaction rather than waiting silently. The affected browser +rerun passed 21 tests with one Keycloak-only skip; full final rerun remains. + +Scope issuance validates explicit resource definitions and PS metadata, including +a custom identity scope accepted only when the actual PS advertises it. Familiar +unadvertised identity names are rejected. Test definitions are explicit fixture +metadata, not a production allowlist inferred from requested strings. Both apps +publish delegation.invoke for their intermediary role. AS FallbackSubject was +removed; scope-only grants no longer fabricate a user identity. Mission context +is retained at issuance and verified by PS and agent delivery checks. + +Phase 11 additional inventory: ResourceTokenBuilder.ScopeDescriptions, +PersonServerScopesSupported and ValidateScopes; ChallengeOptions.ScopeDescriptions; +AAuthPersonServerOptions.ScopesSupported; AccessServerRequest.ExpectedMission; +AgentAuthTokenValidator.Validate; local signer context used automatically by +TokenExchangeClient; effective replacement resource token used for delivery. +The AS delivery mission expectation follows its existing caller-verified context +contract, not reparsing opaque request parameters. AuthTokenBuilder now rejects +person-bearing actor nodes. These are alpha-breaking contracts, not shims. + +### [2026-09-08] [Phase 6] Initial consent and actor evidence - RESOLVED + +The first no-claims regression failed as intended: denied PS policy returned +200. Independent policy gating now runs before federation; every later claims +request also requires an Assert verdict. NeedsConsent parks a separate completion +signal in Phase 5 state. Authenticated approval resumes federation, not delivery. +Claims failures never become a subject fallback. Replacement resource context +requires renewed consent before forwarding. The expanded signed HTTP and browser +session relay suite passed 32/32, then passed with four additional distinct-key +direct/child/upstream/combined cases. Sample PS integration filters also passed. + +The consent matrix found normalized browser decision codes were not normalized +by store mutations; both mutations now use the existing normalized lookup. +An initial compile missed the identifier-parser namespace; repaired and rerun. +The depth fixture used non-agent strings; valid AAuth identifiers now ensure the +test actually checks depth. The focused upstream/delivery/chain/relay gate passed. + +Pinned protocol prose at +[upstream verification, L1776](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1776) +describes the actor differently from the concrete +[chain examples, L1890](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1890). +Preserve the examples and existing provenance model: upstream caller as immediate +delegator, child parent wrapped above it. Exact entire-chain equality replaces +nested-only comparison. Actor nodes admit only agent and nested act, excluding +person fields at all levels. Upstream validation uses its own verified cnf key +for structural checks, never the intermediary's different request key. + +Phase 11 inventory additions so far: pending FederationConsent, +AwaitingFederationConsent, RequiredIdentityClaims, ConsentAgentId; verified +UpstreamAuthorization policy context and PersonServerIssuer; issuance Upstream +and ValidateResourceContext; full-chain ActChainsMatch semantics. These contracts +are not claimed to complete Phase 11 ergonomic work. No Phase 6 completion gate +has yet been checked; full Release/build/browser validation remains outstanding. + +### [2026-09-08] [Phase 5] Implemented contracts and intermediate evidence - PROCEEDED + +Pending ownership retains the requesting issuer, subject and key separately +from the issued-token recipient (including parent-mediated requests). AS/R3 +pending operations retain the PS identifier and signing-key thumbprint. Per-entry +serialization makes terminal delivery one-time; subsequent polls return 410. +Pending deadlines are separate from verified authorization expiry. Stores retain +terminal/expired entries for an additional hour; these in-memory stores do not +claim crash durability. Browser code consumption does not revoke issued tokens. + +`BrowserConsentSessions`, `BrowserPendingRequest`, `BrowserInteraction`, and +`DeferredState` are new public contracts for the Phase 11 inventory. The SDK +browser helper defaults to an authenticated host principal, with no demo login. +Samples explicitly configure isolated demo identities. Forms carry a random +decision-session identifier plus a server-session-bound CSRF token, not the +correlation code. Keycloak mode rejects stub approve/deny and binds OIDC state +to the initiating browser cookie. R3 hosts configure `BrowserConsent` explicitly. +Cookies are HttpOnly, SameSite=Lax, and Secure on HTTPS; local HTTP samples are +not a production TLS deployment. Application form fields are not AAuth wire +extensions. Existing Crockford normalization is reused for code input. + +Code failures use a browser-session counter (five failures) and a remote-address +counter (20 failures/minute, preventing cookie resets from removing the limit). +An authenticated browser is bound to a request only after valid code arrival; +five failures then terminally invalidate that bound request. Unbound malformed +guesses never select an arbitrary victim request for lockout. Proxy deployments +must supply a trustworthy remote address. Anonymous allocation and process-local +state remain sample deployment constraints, not a durable abuse-control service. + +AS policy now supports `NeedsClarification`, `AccessPolicyRequest` carries +clarification history and validated resource context, and pending scope/context +are replaced only after token verification. AS claims POST remains actionless; +only clarification responses require the specified action. `AccessServerRequest` +adds `OnClarificationRequired`; `AAuthPersonServerOptions` adds optional +`TriageClarificationAsync` (no answer means relay to the agent). Federation has +a ten-minute overall budget and question-specific deadlines, and cancellation +attempts a signed DELETE upstream with a five-second cleanup budget. New pending +owner/lifecycle/context fields, mutable requested scope, and resource-managed +signed cancellation also belong in the Phase 11 API inventory. Full fluent +alignment is not claimed here. + +GuidedTour retains existing protocol-step counts and approval/poll indices: +browser authentication, code arrival and decision are substeps of the existing +browser step. Its live clarification POST now includes action. SampleApp shows +numbered consent states and the session/CSRF exchange; shared browser helpers +assert the actual session URL and fields. Opening the tab is not evidence that +approval occurred. Full browser validation is still pending. + +Executed evidence, before final gates: + +- Initial ownership regression: four failed, two passed; after repair six passed. +- PS lifecycle run: 32 passed/two failed because the pending deadline was wrongly + used as an issuance ceiling; separating those lifetimes yielded 34/34. +- Existing AS integration: 17/17; federation client/integration: 23/23. +- Inbox/store migration: four failed/four passed on old removal and code-only + fixtures; real authenticated browser fixtures then passed 8/8. +- R3 migration: 42 passed/ten failed at old code-only approvals; session-based + fixtures and one-200/seven-410 concurrency expectations then passed 52/52. +- Browser session HTTP cases: four passed/two failed from a test-only ASP.NET + delegate overload discarding IResult; an explicit Func cast yielded 6/6. +- First full Release run: core 698 passed/eight failed, conformance 618 + passed/eight failed, R3 52 passed. Total 1368 passed/16 failed; not a gate pass. + Evidence is `/tmp/aauth-phase5-results/phase5-intermediate*.trx`. +- Failed full-run classes were repaired and passed 19 core and 38 conformance + cases, including browser-bound Keycloak callbacks (stub IdP transport only). +- New real PS/AS mapper tests passed 18/18: answer/update/deny/cancel/claims + composition, AS owner/key isolation, malformed actions and replacement binding. + Their first compile used a nonexistent test helper; corrected before execution. +- Latest focused gate: 54 PS/AS HTTP tests and six browser-session tests passed. + Both primary apps build without warnings/errors; TypeScript typecheck passes. + +No external reviewer report has been received in this execution; none is claimed +resolved by these tests. No nested delegation, commit, branch change, package +upgrade, specification edit or existing user-key mutation occurred. Early patch +format/context failures made no partial edits and were corrected with apply_patch. + +### [2026-09-08] [Phase 4] Implementation and intermediate gates - PROCEEDED + +Added immutable `AAuthEgressPolicy`, `IAAuthDnsResolver`, and +`AAuthHttpTransport` with strict HTTPS/public-address defaults, complete DNS-set +admission, numeric socket connections and peer checks, disabled proxies and +redirects, bounded headers, bytes and elapsed response reads. HTTP/1.1 is pinned +to avoid alternate transports bypassing the socket callback. Development origins +must be configured exact localhost/127.0.0.1/[::1] origins, and their DNS answers +must all remain loopback. Cross-origin JWKS requires an exact source/target pair. + +Opaque injected clients and handlers require an explicit `AAuthTransportContract`: +`InProcessOnly` prohibits network forwarding; `EnforcesEgressPolicy` obligates +the caller to enforce DNS/connected-peer admission, no redirects/proxies, and +connection/header limits. `AttachPolicy` declares obligations, not retrofitted +socket protection. Factory federation overrides also require an explicit contract. +SDK-owned clients use the pinned implementation. A browser callback is admitted +before release, but its subsequent browser navigation is not an SDK socket. + +The shared bounded cache coordinates cold, expired, unknown-kid, forced same-kid +and failed attempts. The minimum interval cannot be configured below one minute. +Failures retain timestamps and exponential backoff; stale data survives only up +to the configured hard age (at most 24 hours). Invalidation preserves attempt +state. Capacity pressure cannot evict protected or active attempts. Fixed bounded +TTLs are used rather than honoring server-provided cache headers in this phase. + +Phase 11 API inventory must include policy settings on discovery, token builders, +verifiers, server/metadata/challenge/governance/agent options and verified tokens; +`MetadataClient.GetUrl`, discovery cache capacity/age constructor options; +policy-aware `ServerId`, routing, mission and interaction parsers; fluent +`WithEgressPolicy`/`WithDevelopmentLoopback` and custom-handler contracts; +`AAuthFederationOptions`; and R3 fetch policy/callback contracts. AS trust +predicates now receive exact PS identifiers, not authority-only strings. + +Initial cache regressions failed 2/2 with two attempts inside one minute. The +first full Release run passed 1248/1339 and failed 91; these were not passes. +Repairs include explicit TestServer contracts, policy propagation, cross-origin +fixture approval, and pending fixtures bound to their issuer. An intermediate +mechanical interaction-test edit duplicated constructor text and was repaired; +a field-name compile error and a non-disposable test-key declaration were also +repaired. Latest focused gates: 51/51 cache/transport tests and 14/14 ServerId +tests passed. Solution and browser gates remain pending; Phase 4 is not yet ticked. + +### [2026-09-08] [Phase 11] Public API alignment phase - RESOLVED + +The owner requested a migration-wide API rescan and simplification to the +existing fluent/convenience style, with signing/flow terminology matching the +spec. Added Phase 11 after feature implementation and before cross-cutting +security closure. Former Phases 11-14 are now 12-15; earlier dated log entries +keep their historical phase numbers. The final docs gate is now Phase 15. +This is an approved additional acceptance gate, not a backward-compatibility +requirement or permission to undo mandatory verification. + +### [2026-09-08] [Phase 0] Dependencies and baseline - RESOLVED + +Source inspection of Events branch `dd543a7` found provider-neutral store +contracts and useful tests, but no durable provider. Select Microsoft.Data.Sqlite +10.0.11 (MIT) for sample transactional persistence, isolated from core crypto. +Select StructuredFieldValues 0.7.7 (BSD-2-Clause) for typed RFC dictionary parsing; +retain a canonical writer and current crypto packages. Executable compatibility +and crash/restart tests are required before acceptance. Both decisions implement +Q6/Q10 defaults rather than changing capability scope. + +Full baseline `dotnet test AAuth.slnx` passed: core 517, conformance 573, R3 39 +(1129 tests total). Docker 29.5.2-3 and Playwright Chromium are available. +Baseline browser results are still pending. Source inventories confirm the +Events branch has no hidden core SDK delta prerequisite. + +### [2026-09-08] [Phase 14] Final docs gate - RESOLVED + +Added a final documentation sweep after adversarial review, as requested. Review +fixes that change behavior reopen affected sample/snippet/visual checks and the +logical area's adversarial review. Zero findings means the last completed +in-scope review pass, not proof that no possible defect exists. + +### [2026-09-08] [Phase 1] Coupled consumer corrections - RESOLVED + +The new malformed-error test exposed a JSON cast in the mission-termination +pre-check inside `DeferredExchange`, before `TokenExchangeClient` could apply its +transport fallback. Restricted that pre-check to string-valued `error`, then +reran the same client tests (52 passed). This is a necessary coupled consumer +edit, not implementation of the mission phase. GuidedTour previously substituted +a synthetic denial body after a typed polling exception; retaining its already +captured body prevents dropping problem `detail` from the walkthrough. + +VS Code test discovery returned no tests, so all executable test evidence uses +serial `dotnet test` commands. The uniform producer replacement briefly treated +shorthand `id`/`code` fields as detail arguments; these were corrected to explicit +extension dictionaries before the full validation gate. No branch operations, +commits, package additions, or delegation were performed. + +### [2026-09-08] [Phase 2] Necessary context verification and fixtures - RESOLVED + +PS SignatureOnly middleware authenticates proof of key possession, not the +carrier issuer. To satisfy the required verified-expiry input, the PS token +endpoint now verifies its agent JWT before trusting exp. This is a local +issuance prerequisite, not the Phase 3 middleware/signature rewrite. Existing +PS fixtures that omitted AP discovery now publish the actual test AP signing +key; confirmation keys remain unchanged. Two verifier-negative fixtures use an +explicit historical issuance clock to create a token that later expires. + +VS Code still discovers no tests; executable validation uses dotnet test. +The initial builder regression reproduced ten failures before the fix; the AS +claims regression separately reproduced seven failures before its fix. A test +fixture initially omitted AAuthVerifier registration, and a mechanical Perl +fixture rewrite produced four malformed route initializers. Both were repaired +locally and the same focused checks passed before continuing. No packages, +crypto/signing/transport implementation changes, delegation, commits, or branch +changes were made. Primary sample builders and embedded examples were updated; +their step numbering/navigation did not change. + +### [2026-09-08] [Phase 2] Release fixture timing correction - RESOLVED + +The first Release solution gate exposed one timing-dependent federation stub: +it minted with a fresh one-hour source ceiling after the original agent token +was created, occasionally exceeding that token by one second. Production PS +delivery correctly rejected the response. The stub now verifies the actual +forwarded agent token, retains its expiration for both immediate and deferred +minting, and derives response lifetime from that ceiling. The same Release +federation class passed (4/4), then the full build/test gate passed (1231/1231). +The initial failed full run is not counted as a pass. + +### [2026-09-08] [Phase 3] Necessary coupled changes - RESOLVED + +Removed the legacy issuer-verification toggle rather than keeping a misleading +no-op setting. Generalized server key collections and refreshed their compiled +callers to honor advertised ES256. Resource-managed primary samples required +agent-token acquisition as part of the signing-policy cutover, not a later docs +phase. Existing PS issuance TimeProvider was forwarded into middleware after +the deferred-expiry regression exposed clock disagreement. All were required +coupled Phase 3 changes. Phase 4 egress/DNS/redirect/cache-floor work is not +implemented. No delegation, commit, branch change or crypto package upgrade +occurred. StructuredFieldValues 0.7.7 is the only new package. + +### [2026-09-09] [Phase 12] New-capability scenario coverage - RESOLVED (scope) + +The owner requires runnable GuidedTour and SampleApp scenarios for every new +user-facing capability not already taught by an existing flow, with Playwright +tests following the existing app suites. New resource projects are authorized +selectively: each resource must have one clear purpose and readable source that +serves as an example. Reuse is preferred only where it preserves that purpose; +adding unrelated features to Bookings merely because it already runs is not the +default, nor is adding a server for each test variation. + +The implementation plan now requires a Phase 12 capability-to-scenario matrix, +closure of uncovered flows in both apps, documented resource selection, and +solution/demo/test/CI wiring for any new resource. Phase 13 checks the resulting +snippets, numbered steps, visuals and resource documentation; Phases 14-15 review +and recheck completeness after repairs. Internal security fixes retain focused +negative tests rather than artificial UI flows. Previously excluded optional +capabilities are not silently brought into scope by this scenario requirement. + +Existing Events scenarios and prior browser results are evidence to inspect, +not blanket completion of this new matrix. The added acceptance checkboxes +remain unchecked. This entry records the approved scope update; no resource, +scenario or Playwright test was created by this documentation edit. + +## Open Questions + +### [2026-09-09] [Phase 11] Owner revisit closure - RESOLVED + +Supersedes the 2026-09-08 Inbox credential-provenance/API revisit below without +rewriting its history. Retain conformant agent-JWT Inbox access; keep generic +pseudonymous Profile demonstrations separate. GuidedTour self-issues locally; +SampleApp signs AP enrollment then refreshes through the enrolled builder. +AP setup/verification discovery are not PS/AS resource authorization. The owner +can review the explicit From defaults, ownership, fixed-key TwoKey rejection and +DI fail-closed choices in the final ledger and API map. No clarification remains +blocking Phase 11; subsequent security/docs phases retain their own gates. + +### [2026-09-09] [Phase 5] Remaining live environment gate - PROCEEDED + +The final configured realm check at localhost:18080 failed with connection +refused (HTTP 000). Live Keycloak remains unverified and is the single skipped +browser case; in-process Keycloak tests pass but do not replace it. Starting +the realm and running KEYCLOAK_E2E=1 is an environment follow-up, not a blocker +to the completed reported runtime repairs. The phase's all-environment checkbox +remains open. No host credentials were invented or hardcoded. Deployment-specific +person mapping and OS isolation require host/operator validation; the SDK +cannot certify those from local stub tests. There are zero failing final local +tests, not a blanket claim that every deployment or later-phase concern is closed. + +### [2026-09-08] [Phase 5] Live IdP and independent review - BLOCKED + +The configured Keycloak realm at + was +unreachable (curl returned HTTP code 000). The fresh browser gate therefore has +one explicit `KEYCLOAK_E2E=1` skip. Live Keycloak authentication is unverified; +the seven passing in-process Keycloak tests use a stub IdP transport and establish +the callback/browser binding and no-stub-bypass behavior, not live deployment. +The final Phase 5 all-environment gate remains unchecked for this reason. No +implementation capability was moved to a later documentation phase. + +No external read-only reviewer report was received in this execution. No +independent review or disposition of unseen findings is claimed. Parent +orchestration can apply the reviewer report without attributing these local +checks to that reviewer. Local findings and their repairs are recorded above. +No implementation clarification is needed; the remaining actions are starting +the configured live Keycloak fixture for its browser gate and receiving the +independent review report. + +### [2026-09-08] [Phase 4] Remaining environment and deployment gates - RESOLVED + +No known reproducible Phase 4 blocker remains. Live Keycloak mode was not run; +its browser test is the recorded skip. External live interop and a public TLS +deployment were not exercised. Production negative transport tests used the +actual socket handler and real local servers; they are not a claim of live +external interoperability. Events projects are not in this solution yet. + +Browser navigation after an admitted callback remains outside SDK socket control. +Caller-provided network transports and R3 callbacks must fulfill their explicit +policy contract; `AttachPolicy` does not inspect or repair opaque implementations. +Samples use only their configured loopback origins and keep HTTPS private +destinations blocked. Fixed local ports changed by a host need a corresponding +explicit policy update. Pre-v10 persisted sample keys still need a deliberate +operator migration/replacement; isolated e2e storage did not modify them. + +### [2026-09-08] [Phase 4] Browser failures and final validation - PROCEEDED + +The first browser attempt stopped during startup because the default home held +a pre-v10 AP signing key rejected by Phase 3's algorithm checks. No persisted +user key was edited or deleted. Subsequent runs used a fresh temporary HOME with +the existing NuGet and Playwright caches explicitly retained. This changes test +storage only, never network admission. + +The first full isolated-key browser run passed 34, failed 15, and skipped one. +GuidedTour's manual interaction parsers still omitted their explicit sample +policy, preventing consent links. They now pass the policy and admit DNS before +exposing the URL. Sample enrollment's static metadata URL calls were also fixed. +Browser validation exposed a coupled Phase 3 Bookings error: its agent resource +requests used the restricted document-reader verifier, which only accepts +`jwks_uri`. Bookings now verifies `jwt` through the typed middleware separately; +R3 document readers retain their trusted `jwks_uri` gate. The direct-JWKS browser +test's obsolete heading and scheme assertions were aligned with the actual page. + +The next complete fresh-service browser run passed 49/50 with one Keycloak-only +skip, no retries. Both app projects, all stub flows, R3 grant/approval/denial, +missions and call chaining ran. A later Release rerun caught a timing-dependent +poller exception: expiration of the overall budget could leak +`TaskCanceledException`. It now returns `TimeoutException` for its own budget, +preserves caller cancellation, and guards a budget expiring during request setup. +The focused poller class passed 7/7 after repair. Final full gates are being rerun. + +Additional Phase 11 inventory: policy-aware `InteractionRequiredAAuth`, +`R3Challenge.EgressPolicy`, `R3FetchClient` ownership/disposal, exact R3 PS trust +predicate inputs, and `TokenExchangeClient.EgressPolicy`. Discovery refuses a +supplied policy that differs from an injected client's declared policy. Owned +R3 transports are disposed after fetches; late injected responses are disposed +after deadline cancellation. No specification snapshots or persistence keys changed. + +### [2026-09-08] [Phase 0] Evidence still to collect - PROCEEDED + +Full baseline solution/e2e results, parser selection and existing Events storage +review are pending. They are not recorded as passes or completed implementations. +The research's 62 focused passing tests are historical baseline evidence only. + +### [2026-09-08] [Phase 1] Remaining verification boundaries - RESOLVED + +No Phase 1 blocker remains. Release-configuration solution tests, browser e2e, +live Keycloak, and external interop were not run for this phase and are not +claimed as passes. SampleApp and GuidedTour compile, but their browser workflows +were not exercised here. Editor diagnostics reported pre-existing TypeScript +`moduleResolution=node10` and `baseUrl` deprecations in `tests/e2e/tsconfig.json`; +that file is unchanged. Later phase gates retain responsibility for those checks. + +### [2026-09-08] [Phase 2] Remaining verification boundaries - RESOLVED + +No Phase 2 blocker remains. Phase 2 completion boxes were checked only after the +final solution gates passed. No later phase is marked complete. Browser e2e, +Keycloak, live external interop, and sample browser execution were not run for +this phase. The full Release gate builds the solution's current projects; Events +has no included test project yet, so no Events test pass is implied. Existing +Phase 1 edits were preserved; no delegation, commit, branch change, or package +installation occurred. + +### [2026-09-08] [Phase 3] Remaining verification boundaries - RESOLVED + +No known Phase 3 implementation blocker remains; only Phase 3 completion boxes +were updated in this run. Full browser suite, live Keycloak policy mode and +external interop were not run and are not claimed as passes. AS Keycloak stub +integration tests pass but do not establish a live Keycloak deployment. Events +is not included in the current solution tests. Later phases retain those gates. +Persisted pre-v10 sample keys require deliberate replacement or an explicit +offline migration by their owner; this alpha cutover intentionally rejects them. +The owner prohibited delegation, so reviewer leads were resolved with local +source checks and adversarial tests, not an independent subagent review. + +### [2026-09-08] [Phase 11] Inbox credential provenance and API revisit - PROCEEDED (review open) + +The owner correctly recalled that the original resource-managed Inbox example +used pseudonymous hwk. Phase 3 deliberately changed both primary samples to +agent JWTs. GuidedTour's displayed snippet now assumes an existing agentToken; +SampleApp ensures AP enrollment and constructs an AgentProviderTokenRefresher +manually. The exact acquisition path and all displayed setup steps must be +rechecked in the API phase, not inferred from a successful flow test. + +The rationale was the protocol's Keying Material requirements at +[v10 L2420](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2420) +and [L2422](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2422): +AAuth resource access uses an agent/auth JWT, not bare hwk. This requirement +does not add a PS or AS authorization exchange to resource-managed access. +Agent provisioning/key refresh and the subsequent two-party authorization flow +are separate, and the examples must make any AP contact explicit. + +The distinction and example design are reopened at the owner's request. Decide +and document whether a generic pseudonymous example is retained separately; +do not label it as conformant AAuth resource-managed access without reconciling +the normative requirements. Keep the current wire behavior pending that review. +The manually wired refresher is not the desired final convenience API. Review +Enrolled/RefreshingFrom/WithKeyStore composition and From(EnrollResult) defaults, +then update runtime calls and embedded snippets together. This supersedes any +interpretation of the Phase 3 sample gate as final approval of API ergonomics +or instructional completeness. + +### [2026-09-08] [Phase 11] Review delegation attribution - RESOLVED + +The earlier Phase 3 note saying the owner prohibited delegation is inaccurate. +The owner explicitly requested adversarial subagents. The restriction applied +only to nested delegation within that implementation worker. Independent +logical-area reviews and repeated repair/review passes remain required. + +### [2026-09-08] [Phase 11] Direct credential and builder trace - RESOLVED (evidence only) + +Confirmed both original examples used UseHwk by diffing against `ba768f1`. +GuidedTour's EnsureAgentReadyAsync self-issues its agent token using the tour's +own published identity; the resource-managed step invokes it before signing. +SampleApp EnrollmentService performs enrollment but discards the initial token; +Inbox's manually constructed refresher acquires a fresh token from the AP. +Neither token is an auth token obtained from a PS/AS authorization exchange. + +Added the exact source paths/lines and a seed API map to research F29. +EnrolledBuilder already provides RefreshingFrom/WithKeyStore and an +interaction-handling forwarder, but no direct resource-managed-access forwarder. +From(EnrollResult) chooses direct jwks while its comment says jwks_uri. These +facts support a real convenience/composition and terminology review, not an +automatic facade for every new low-level type. The sample design ruling remains +open; no SDK or sample runtime files were changed for this owner-requested update. \ No newline at end of file diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-plan.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-plan.md new file mode 100644 index 00000000..21c25084 --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-plan.md @@ -0,0 +1,1194 @@ +--- +description: Phased implementation and verification of the AAuth v10 migration. +--- + +# Implementation Plan - AAuth v10 repository migration + +Companion to [research.md](research.md), created 2026-09-08. This plan covers the +current SDK, R3, the missing Events capability, runnable examples, tests, and +documentation. The owner approved autonomous implementation on 2026-09-08; +decisions and deviations are recorded in [implementation-log.md](implementation-log.md). +Historical v09 plans remain unchanged; this initiative +reassesses their exclusions rather than treating them as current scope rulings. + +## Guiding principles + +- Spec conformance over backward compatibility: one coordinated alpha cutover, + no old-wire fallbacks, obsolete aliases, or dual-format parsers. +- Requirement strength matters. Optional capability exclusions are explicit; + enabled capabilities satisfy their conditional MUSTs. Spec ambiguities receive + recorded rulings rather than invented requirements. +- Verification results represent checks actually performed. Parsed claims are + not authenticated identities; proof of key possession is not issuer trust. +- Preserve working controls: byte-exact hashes, key/audience binding, scope + narrowing, per-signature replay, and fail-before-release audit behavior. +- Every code phase updates its compiled sample callers and directly coupled + fixtures, keeping the solution buildable. The final docs sweep also checks + string-literal snippets, Razor explanations, diagrams, and browser assertions. +- SampleApp and GuidedTour are primary migration deliverables. When a phase + changes an auth flow, update both apps' affected numbered steps, sequence + visuals, embedded C#/JSON/HTTP snippets and step-dependent tests in that phase. + Navigation, approval/polling indices, payload selection and completion counts + must remain synchronized. Phase 13 checks the finished apps; it does not defer + fixes to their executable walkthrough behavior. +- Every new user-facing capability needs a runnable scenario in both apps, + either a clearly identified extension of an existing flow or a new selectable + flow when none fits. A console example, SDK test or documentation paragraph + alone does not satisfy this requirement. Each new flow needs Playwright tests + in both app projects using the existing harness and helpers. +- Sample resource code is instructional too. Prefer a small, single-purpose + resource with one clear use case; reuse an existing resource only when the new + behavior belongs naturally to that purpose. Add a resource selectively when + reuse would turn a focused example into a collection of unrelated features. + Follow the existing resource projects; avoid one server per test variation, + unnecessary services, or abstractions that hide the protocol being taught. +- Recheck cited lines against the pinned v10 snapshot before implementation. + Research findings marked R receive direct reproduction before a fix is designed. +- Decisions, deviations, and scope rulings are appended to the implementation + log when work begins. No package upgrade, branch merge, or commit is implicit. + +## Verification strategy + +Each phase starts with a focused failing regression for its confirmed defects, +then checks positive behavior. Existing passing tests are not independent v10 +evidence when their fixtures reproduce the old contract. Use real HTTP handlers +and captured-wire assertions where producer/consumer agreement could hide a bug. + +At phase boundaries run the touched test classes and `make build`. At shared +contract boundaries run the complete affected test projects. Final release gates: + +```bash +make build +make test-unit +make test-conformance +dotnet test tests/AAuth.R3.Tests/AAuth.R3.Tests.csproj +dotnet test AAuth.slnx -c Release +make e2e +``` + +After the Events project exists, add it to the solution and run its test project +explicitly as well. The current `test-unit` and `test-conformance` targets do not +include R3 or Events. CI already uses solution tests; retain that wider gate. +Run Playwright with fresh services (`CI=1` for no service reuse), and exercise +both stub and Keycloak policy modes. The Keycloak job needs its configured +container/realm and `KEYCLOAK_E2E=1`; the ordinary stub run does not establish it. +Live external interop needs reachable HTTPS metadata and external availability; +record an unavailable environment as unverified, never a pass. + +## Phase 0 - decisions and baseline gate + +Resolve Q1-Q10 in [research.md](research.md#gaps-and-open-questions) before code. +Create the implementation log at that point with Decisions Taken, Deviations +from Plan, and Open Questions sections; record dated `PROCEEDED (default ...)`, +`RESOLVED`, or `BLOCKED` entries. Proposed defaults are not pre-approved rulings. + +Phase rule: exact v10 contracts, no compatibility shims. Any exception requires +an explicit logged decision. + +### Responsibilities + +- Q1: confirm optional capability scope. Default includes account binding, all + eight R3 vocabulary models, AS clarification, Events, self-jwt, and direct jwks. + X.509/cached remain explicit exclusions unless the owner selects them. +- Q2-Q5: settle PS-AS signing, strict production/development separation, R3 PS + readership, and Events recurring-event/payload ambiguities using cited clauses. +- Q6: decide durable store contracts and a transactional sample backend. Inspect + existing branch work before selecting/pinning a persistence package. +- Q7-Q8: approve authenticated consent/session design and agent-expiry/context + propagation without inventing an associated-token lookup at resources. +- Q9: read existing Events work from `feat/aauth-events-implementation` without + checkout/merge; inventory reusable files/tests. No wholesale merge is implied. +- Q10: evaluate a maintained structured-fields/signature parser against labels, + escaping, parameter types, and extra covered components; document exact package + choice or a justified retained implementation. Keep crypto packages unless a + demonstrated blocker requires changing them. +- Record the implementation baseline commit and tree state, source hashes, + discovered projects, and full current test/e2e results. Make a requirement-to- + test ledger covering the research's unreviewed policy boundaries as well. + +### Definition of Done + +- [x] Every Q1-Q10 has a recorded ruling in the implementation log. +- [x] Optional capabilities and ambiguous clauses have explicit dispositions. +- [x] Every research finding has a phase and a planned discriminating check. +- [x] Baseline failures and unavailable environments are recorded separately. +- [x] The implementation scope and plan are approved before SDK edits. + +Phase 12 reconciliation (2026-09-09): Q1-Q10 and execution authorization were +already recorded on 2026-09-08; the finding-to-phase table and discriminating +checks are present. These checkboxes now reflect that evidence. A complete +pre-edit full-suite/browser baseline cannot be reconstructed from later passing +gates, so the baseline item remains open as a historical evidence limitation. +Later Phase 11/12 verification does not rewrite the original baseline. + +Final evidence reconciliation (2026-09-09): the baseline item above requires +separate recording of failures and unavailable environments, not reconstruction +of a run that never happened. The log records the 1129-test pre-edit solution +gate and explicitly identifies the unavailable pre-edit browser baseline. The +item is closed on that recording basis; no missing browser run is claimed. + +## Phase 1 - shared problem-details cutover + +Findings: F11, the error portion of F30/F31. No code-phase dependencies. +Target: protocol [L2304](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2304) +(`#error-response-format`). + +Phase rule: `detail` only, no `error_description` fallback or public alias. + +### Implementation Decisions + +- [x] Shared result/writer and breaking `Detail` rename approved; preserve status, + headers, success contracts, and callbacks. Normalize application-defined AP + errors for consistency. See the dated Phase 1 decision in + [implementation-log.md](implementation-log.md). + +### Responsibilities and files + +- Introduce a common AAuth problem-details result/serialization contract under + [src/AAuth/Server](../../../src/AAuth/Server/) with required `error`, optional + `detail`, correct media type, and supported extension members. +- Update [TokenExchangeClient](../../../src/AAuth/Agent/TokenExchangeClient.cs), + [AccessServerClient](../../../src/AAuth/Access/AccessServerClient.cs), and + [errors](../../../src/AAuth/Errors/) public description properties. +- Migrate every actual producer discovered by pattern, including PS/AS endpoints, + DI middleware, governance, revocation, resource-managed interactions, and R3 + helper/results. Do not change success media types or conflate signature errors + with AAuth problem `type` values. +- Update compiled MockAgentProvider/LiveWhoAmITest/other consumers under the + approved consistency ruling. Bootstrap's application-defined HTTP errors are + not misreported as a normative Bootstrap protocol. + +### Definition of Done + +- [x] Real endpoint tests assert status, media type, `error`, `detail`, and + endpoint extensions for representative PS/AS/R3/governance/revocation errors. +- [x] Clients use `error` for behavior regardless of RFC 9457 `type`. +- [x] No old wire/API description remains in migrated producers/consumers. +- [x] Success responses, auth challenges, and callbacks remain correct. +- [x] Focused tests, affected test projects, and solution build pass. + +## Phase 2 - issuance bounds and reserved claims + +Findings: F10, reserved-claim part of F19. Depends on Phase 1. +Target: protocol [L1344](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1344) +(Agent Token Lifecycle) and [L1708](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1708) +(Auth Token Structure). + +Phase rule: exact validated issuance inputs, no legacy unbounded overload. + +### Implementation Decisions + +- [x] Required validated agent-expiry input, conservative delegation ceilings, + and shared reserved-claim guard approved for this alpha cutover. See the dated + Phase 2 decision in [implementation-log.md](implementation-log.md). + +### Responsibilities and files + +- Extend [AuthTokenBuilder](../../../src/AAuth/Tokens/AuthTokenBuilder.cs) and + relevant verified-token/request contracts to retain source expiry ceilings; + keep positive lifetime and one-hour validation independently testable. +- Carry verified agent expiration through [PS endpoints](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs), + [AS endpoints](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs), both + pending stores, R3 minting, and response delivery. Bind sub-agent issuance to + the correct verified child context and the Phase 0 ruling on parent/upstream + ceilings. Reject expiry reached during consent rather than minting a fresh hour. +- Derive `expires_in` from the issued token, not a hard-coded 3600. +- Validate reserved claim names independent of which optional claims were + populated. Apply the same rule to requested claims and projected AS responses. +- Fix compiled builders and sample issuance at the same time. + +### Definition of Done + +- [x] Immediate and deferred two-minute-agent tests never yield a later auth exp. +- [x] Already-expired, zero/negative lifetime, and parent/child boundary cases fail. +- [x] `expires_in` matches actual expiry in direct and deferred responses. +- [x] AdditionalClaims cannot inject unset protocol-owned claims; legitimate + identity extensions still work. +- [x] Core/conformance/R3 tests and solution build pass. + +## Phase 3 - signature carriers and typed verification + +Findings: F01-F07, F28 self-jwt/jwks, signing part of F31. Depends on Phases 1-2. +Target: protocol [L2409](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2409) +(`#signature-algorithms`), [L2478](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2478) +(`#verification`), Signature Keys [L641](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L641) +(3.4), [L964](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L964) +(3.6), and [L1222](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1222) +(3.9). + +Phase rule: old carrier encodings and `EdDSA` are rejected, not supported in parallel. + +### Implementation Decisions + +- [x] Autonomous Phase 3 only, no compatibility, delegation, commits or branch + changes. Probe StructuredFieldValues 0.7.7 before runtime integration; retain + current crypto. See the Phase 3 entry in [implementation-log.md](implementation-log.md). + +### Responsibilities and files + +- Update [Crypto](../../../src/AAuth/Crypto/) export/import validation and key + factory dispatch. Require fully specified `alg`, key-type/curve consistency, + public-only wire material, and correct unsupported-versus-invalid errors. + Preserve RFC 7638 thumbprints and current Ed25519/ES256 cryptographic operations. +- Update [SignatureKeyHeader](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs), + [SignatureKeyParser](../../../src/AAuth/HttpSig/SignatureKeyParser.cs), providers, + signer/verifier, and resolver: standard hwk members; jwks_uri id/dwk/kid; + separate direct jwks; self-jwt without cnf. Use selected dictionary labels and + a structured-fields model capable of required parameter types. +- Use `IAAuthKey` throughout JWT confirmation parsing and affected endpoint + contracts. Test every advertised algorithm across supported schemes. +- Separate untrusted parsing, admitted key resolution, JWT validation, HTTP + verification, and endpoint authorization. Report issuer verification only + after the correct token-type verifier succeeds. Reject unsupported types by + default; add explicit companion-verifier registration for Events later. +- Enforce naming-JWT header algorithm, required iat/exp, future/expired checks, + and durable-to-ephemeral binding in one shared path used by MockAgentProvider. +- Honor signature expires/keyid rules, ignore signature alg on verification and + omit it on signing. Support negotiated additional covered components without + treating optional content-digest as a universal AAuth mandate. +- Replace exception-message classification with typed errors. Emit + Accept-Signature-Scheme/Alg correctly; reject unknown schemes deterministically, + including malformed parser input. Enforce AAuth versus generic signing policy. +- Apply Q2 to PS/AS server signers and R3 document fetchers; do not copy the stale + protocol jwks_uri example. Fix compiled sample providers and fixtures in-phase. + +### Definition of Done + +- [x] Independent wire vectors for jwt, hwk, jkt-jwt, jwks_uri, jwks, self-jwt + pass with Ed25519 and supported ES256 combinations. +- [x] Missing/polymorphic/symmetric/prohibited alg and alg/kty/crv mismatch fail; + a valid selected JWKS member survives unrelated unsupported members. +- [x] Wrong typ, forged issuer with a valid PoP signature, forbidden self-jwt cnf, + missing/future/expired naming claims, and expired signature expires fail. +- [x] Matching labels, additional signatures, escaping, malformed members, and + unknown schemes produce the required result, not an uncaught exception. +- [x] AAuth failures use 401; authorization 403 has no signature error/negotiation + headers. Generic Signature Keys status policy remains separately tested. +- [x] Old hwk/jwks_uri shapes and removed error members are absent from active + producers/consumers and rejected by negative fixtures. +- [x] Core/conformance/R3 tests and build pass with all compiled consumers updated. + +## Phase 4 - admitted discovery and cache behavior + +Findings: F08-F09, fetch part of F26. Depends on Phase 3. +Target: protocol [L2517](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517) +(`#jwks-discovery`) and Signature Keys +[L2372](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2372) (7.3). + +Phase rule: strict production admission; explicit narrow development policy only. + +### Implementation Decisions + +- [x] Autonomous implementation with pinned connections, explicit injected + transport contracts, and configured loopback origins approved. Convenience + builders remain in scope; new contracts are logged for Phase 11 inventory. + No delegation, commits, checkouts, or specification snapshot edits. + +### Responsibilities and files + +- Put reusable URL/egress policy under [Discovery](../../../src/AAuth/Discovery/) + and apply it before metadata/JWKS/R3/pending fetches and interaction redirects + where the spec requires admission. Validate DNS results and the actual connected + destination; account for redirects, response size/time, and cross-origin JWKS. +- Update [MetadataClient](../../../src/AAuth/Discovery/MetadataClient.cs), + [JwksClient](../../../src/AAuth/Discovery/JwksClient.cs), + [AAuthUrl](../../../src/AAuth/AAuthUrl.cs), DI HTTP handlers and R3 fetches. + Validate identifier syntax before canonicalizing URI APIs can hide differences; + return distinct issuer_missing/issuer_mismatch results. +- Enforce one fetch-attempt floor per URI across cold/expired/unknown-kid/same-kid + and failed requests, with concurrency coordination and bounded caches. + Retain valid stale fallback/backoff and maximum-age behavior per policy. +- Thread explicit loopback development configuration through every sample host + and TestHost fixture; never globally disable network admission to get tests green. + +### Definition of Done + +- [x] DNS/private/link-local/loopback, redirect-to-private, mixed-address, + cross-origin, oversized-body and timeout tests exercise real handler boundaries. +- [x] Missing/mismatched issuer and invalid identifier syntax fail before trust. +- [x] Parallel cold fetches and failed fetches honor the same one-minute floor. +- [x] Unknown-kid/same-kid rotation still succeeds after the allowed interval. +- [x] Explicit dev fixtures pass; production defaults reject their HTTP URLs. +- [x] Discovery/R3 targeted tests, affected projects, and build pass. + +## Phase 5 - consent and deferred state machines + +Findings: F12-F15, AS clarification capability. Depends on Phases 1-4. +Target: protocol [L1054](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1054) +(`#agent-response-to-clarification`), [L2136](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2136) +(Interaction Code Format), [L2825](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2825) +(Deferred Response Security). + +Phase rule: explicit action and verified owner context, never legacy payload inference. + +### Implementation Decisions + +- [x] Autonomous full Phase 5 authorized, including AS clarification and both + primary apps. Separate single-use correlation from authenticated, CSRF-protected + decisions under Q7; preserve fluent API work for Phase 11 and inventory new + contracts here. No delegation, commits, branch changes, or compatibility paths. + +### Responsibilities and files + +- Fix [Person endpoints](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs), + [Access endpoints](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs), + pending stores, and resource-managed interactions to require authenticated + owner/key context on every poll, clarification update, and cancellation. +- Separate browser correlation-code state from the authenticated decision + session. Normalize Crockford input, consume atomically, bound attempts, retain + expired/consumed/terminal tombstones long enough to return the required errors. + Choose abuse keys for malformed codes without enabling arbitrary interaction + lockout; record that operational policy. +- Make terminal delivery atomic and one-time; subsequent polls return 410. + Do not revoke reusable auth tokens or consume a legitimate decision session + merely because the browser used its correlation code. +- Add action-based dispatch to [ClarificationExchange](../../../src/AAuth/Agent/ClarificationExchange.cs) + and both enabled receivers. Validate replacement iss/agent/key against stored + originals and replace scope/request context before re-consent. Preserve DELETE. +- Complete AS clarification production, PS triage/relay, resumption and + cancellation using existing claims/deferred abstractions without conflating + ordinary claims POSTs with clarification actions. +- Protect browser decisions in MockPersonServer, Federated AS and R3 consent. + Make stub-only approval unavailable in Keycloak mode; authenticate the user, + bind pending requests to the decision session, and enforce CSRF protection. +- Update TourSession, SampleApp, consent helpers, and directly affected e2e + assertions alongside the state machine. + +### Definition of Done + +- [x] Foreign-owner GET/POST/DELETE and forged same-sub/different-key attempts fail. +- [x] Missing/unknown/mismatched action returns 400; malformed or differently bound + replacement tokens fail; valid narrowed replacements affect the issued token. +- [x] Code aliases, reuse, expiry, attempt limits, concurrent approval, denial + reversal, terminal replay, and cancellation have end-to-end HTTP tests. +- [x] Keycloak cannot be bypassed through stub approve/deny endpoints. +- [x] AS clarification works through the PS to the agent and back, with bounded + polling, timeout, denial and cancellation behavior. +- [x] Relevant integration/conformance/e2e suites and solution build pass. + +Available gates passed: `make build`, Release solution tests (1412/1412), and +fresh-service no-retry browser tests (49 passed, one Keycloak-only skip). +The final gate remains open for live Keycloak mode: the configured realm at +localhost:18080 was unreachable. In-process Keycloak flow and bypass tests +passed 7/7; they do not replace live IdP validation. See +[implementation-log.md](implementation-log.md) for exact evidence and failures. + +Adversarial repair gate (2026-09-09): the reported GET lockout, mixed 202 +dispatch, re-consent/code generation, operation-failure lifecycle, identity +binding and demo/retention boundaries have local tested dispositions in the +log. Final Release tests pass 1573/1573 (817 core, 703 conformance, 53 R3); +fresh-service no-retry browsers pass 49 with one Keycloak-only skip and no +failures/flaky tests. The full-environment gate remains open for live Keycloak, +an environment setup follow-up. Phase 6's historical record below is unchanged. + +Phase 13 reconciliation (2026-09-09): the preceding paragraphs describe the +original Phase 5 gate, not a current blocker. Phase 12's 2069 Release tests and +68 live/67 stub browser gates, repeated in Phase 13, supersede the unavailable +localhost:18080 environment. Current live verification uses the configured +localhost:8080 realm. Historical log entries remain unchanged. + +## Phase 6 - federation and delegation trust + +Findings: F17-F19, F20. Depends on Phases 2-5. +Target: protocol [L934](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L934), +[L1511](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1511) +(PS-to-AS Token Request), [L1574](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1574) +(Auth Token Delivery), [L1809](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1809) +(Directed Identifiers Across a Chain), [L2041](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2041) +(`#scopes`). + +Phase rule: preserve authenticated context end to end; no placeholder consent grant. + +### Implementation Decisions + +- [x] Autonomous alpha cutover authorized. Evaluate PS consent independently of + AS claims negotiation, resume through Phase 5 sessions, preserve verified child + and upstream context, and validate scopes against published definitions. + Update both primary apps in-phase; record API additions for Phase 11. No + delegation, commits, branch changes, or compatibility paths. + +### Responsibilities and files + +- Evaluate PS consent independently of AS claims negotiation, including immediate + AS 200 and interaction-only 202-to-200 paths. Existing prior consent may satisfy + policy; a claims callback must not be the only place the PS makes that decision. +- Gate PS claims release and final grant delivery on Assert/Deny/NeedsConsent. + Suspend/resume federation through Phase 5; never substitute pairwise-sub as + authorization. Derive downstream directed identities from authenticated context. +- Carry subagent_token and upstream_token through [AccessServerClient](../../../src/AAuth/Access/AccessServerClient.cs), + PS/AS endpoint models, pending state and minting. Verify parent relationship, + child resource/key binding, upstream issuer/audience/mission constraints and + actor nesting for combined flows. +- Complete [UpstreamTokenValidator](../../../src/AAuth/Tokens/UpstreamTokenValidator.cs) + structural validation without incorrectly equating the original upstream PoP + key to the intermediary's current request key. +- Tighten [ActChainBuilder](../../../src/AAuth/Tokens/ActChainBuilder.cs), readers, + and [AuthTokenResponseValidator](../../../src/AAuth/Tokens/AuthTokenResponseValidator.cs): + immediate actor, nested context, no person identifiers, independently asserted + downstream sub. Extend agent delivery checks as well as PS-side checks. +- Validate scope vocabularies before resource-token issuance, with resource + scope definitions and the applicable PS identity-scope metadata. Keep AS scope + narrowing and existing legitimate resource binding unchanged. +- Add a runnable four-party parent-mediated sub-agent scenario, including the + combined upstream chain, rather than treating the three-party fixture as S5. + +### Definition of Done + +- [x] Deny/NeedsConsent never releases claims or returns a grant prematurely. +- [x] Immediate AS 200 and interaction-only 202-to-200 tests prove PS policy is + evaluated even without a claims request; deny/consent-needed withhold the grant. +- [x] Three-party, four-party, chained and combined sub-agent cases bind the + right key/agent and exact actor chain, with distinct actors/keys in fixtures. +- [x] Invalid upstream structure, trust, audience, mission or person-in-act fails. +- [x] Wrong immediate actor is rejected even when nested context matches. +- [x] Unadvertised resource/identity scopes fail; legitimate narrowed scope works. +- [x] Core/conformance/integration tests, compiled interop scenario and build pass. + +Available final gates passed: `make build`, 1539/1539 Release solution tests +(core 791, conformance 696, R3 52), and the full fresh-service browser suite +(49 passed, one Keycloak-only skip, zero failures/flaky tests). Both primary +apps execute live distinct-key combined four-party flows. The final gate remains +open for live Keycloak validation: the configured localhost:18080 realm is +unreachable. No gate was moved to a later phase. See the Phase 6 implementation +log for test evidence, failures, repairs, and the Phase 11 API inventory. + +Phase 13 reconciliation (2026-09-09): the original live-Keycloak blocker above +is superseded by Phase 12's complete live policy matrix and Phase 13's repeated +68-case live gate, including both distinct-key parent/worker scenarios. This +does not reconstruct Phase 0's missing pre-edit baseline or claim external interop. + +## Phase 7 - issuer-qualified revocation + +Finding: F16. Depends on Phases 2-6. +Target: protocol [L2361](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2361) +(`#token-revocation`) and [L2390](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2390) +(AP-to-PS revocation). + +Phase rule: `(iss,jti)` only; no bare-jti API or wire fallback. + +### Implementation Decisions + +- [x] Typed token identity, separate request replay, bounded known-token inventory, + and caller-to-target authorization approved for the alpha cutover. Source-token + denial and recipient cascade require lifecycle integration, not helper-only + evidence. See the Phase 7 decision in [implementation-log.md](implementation-log.md). + +### Responsibilities and files + +- Update [IJtiStore](../../../src/AAuth/Server/IJtiStore.cs), its in-memory + implementation, [RevocationEndpoint](../../../src/AAuth/Server/RevocationEndpoint.cs), + verification consumers, clients and sample callers with an explicit token key. + Keep request replay state conceptually separate. +- Authorize against verified caller and token issuer, or an explicitly trusted + PS; preserve deny-by-default configuration. Distinguish unknown pairs from + already-invalid known tokens and validate both required members. +- Store issuance/recipient associations needed for AP-to-PS denial and PS/AS + resource cascade. Expose PS revocation metadata; bound persistence/cleanup and + make repeat revocation idempotent. Document unreachable-resource lifetime limits. + +### Definition of Done + +- [x] Same jti from two issuers remains isolated in store and real middleware. +- [x] Unauthorized cross-issuer requests fail; authorized issuer/trusted PS works. +- [x] Missing members fail, unknown pairs return 404, repeated known revocation 200. +- [x] AP-to-PS revoke blocks reuse and cascades to tracked resource grants. +- [x] Legitimate token reuse remains possible with fresh signatures. +- [x] Targeted revocation/integration suites and build pass. + +Final Phase 7 gates: `make build` (zero warnings/errors), 1593/1593 Release +solution tests (818 core, 721 conformance, 54 R3), and 49 fresh-service browser +passes with one live-Keycloak skip, zero failures/flaky tests, and zero retries. +Live Keycloak was explicitly excluded by the current owner request. Real signed +multi-host tests cover PS-issued and AS-provided cascade, original-source denial +after deferred consent, unknown recipients, and two-issuer collisions. See the +Phase 7 completion record in [implementation-log.md](implementation-log.md). + +## Phase 8 - account-aware authorization + +Finding: F21. Depends on Phases 2, 5-7. +Target: protocol [L2055](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2055) +(`#account-binding`), R3 [L378](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L378). + +Phase rule: one typed account contract; absent means absent, not an inferred default. + +### Implementation Decisions + +- [x] Phase 8 only authorized on 2026-09-09. Optional `string? Account` carries + the resource's opaque identifier without normalization; exact nullable equality + partitions authorization state. Resource-owned selection and verification + expectations control enforcement. See [implementation-log.md](implementation-log.md). + +### Responsibilities and files + +- Add account to authorization requests, resource/auth builders/readers, + verification expectations, PS/AS pending state and federation contracts. +- Include account in auth-token caches, prior-consent/grant lookup, refresh, + mission consent and execution policies. Keep resource namespaces opaque. +- Add R3 document/proposal carriage, account-aware display and grant issuance. + Never reuse an accountless cache entry for an account-selected request. +- Demonstrate two accounts for one person/resource using Bookings or another + existing sample, including denial and a switch after prior consent. + +### Definition of Done + +- [x] Request/resource-token/auth-token/R3 account values remain identical. +- [x] Wrong-account execution, cache reuse and prior-consent reuse fail. +- [x] Accountless access still works without inventing an account claim. +- [x] Deferred, chained, refreshed and R3 flows preserve isolation. +- [x] Compiled samples, tests and build pass. + +Final Phase 8 gates: `make build` and explicit Release solution build passed +with zero warnings/errors; 1667/1667 Release solution tests passed (864 core, +741 conformance, 62 R3); TypeScript checking passed. The full fresh-service +browser suite passed 51 tests, skipped one Keycloak-only test, and had zero +failures, flaky tests, or retries. Both apps exercise Personal/Work selection, +old-account grant rejection, fresh consent after denial, and account-bound R3 +per-call approval. Live Keycloak remains unverified, not a claimed pass. +See [implementation-log.md](implementation-log.md) for APIs, deviations, and +final evidence. Phase 9 and later remain untouched. + +Adversarial repair gate (2026-09-09): the four reviewed Phase 6-8 findings now +have reproduced failures and tested dispositions for shared federated mission +consent, exact upstream-context cache isolation, upstream revocation dependencies, +and direct no-mission AS chaining. Both primary apps' affected flow descriptions +and snippets are aligned. `make build` and Release build pass with zero warnings +or errors; all 1704 Release tests pass (865 core, 777 conformance, 62 R3). +Fresh-service browsers pass 51 with one Keycloak-only skip, zero failures/flaky +tests, and zero retries. Live Keycloak remains unverified because the configured +localhost:8080 realm was unreachable. Existing Phase 9 work was preserved, not +implemented or overwritten in this repair. The [implementation log](implementation-log.md) +records exact proofs, public contract inventory for Phase 11, and remaining +environment validation. The historical Phase 6-8 results above are unchanged. + +## Phase 9 - R3 models, grants, audit and policy variants + +Findings: F22-F26. Depends on Phases 3-8. +Target: R3 [L161](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L161) +(`#openapi-gateway-vocabulary`), [L590](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L590) +(`#per-call-proposals`), [L616](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L616) +(Audit Log Integrity), [L624](../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L624) +(Grant Enforcement). + +Phase rule: vocabulary-correct operation identity, no legacy bare-id alias. + +### Implementation Decisions + +- [x] Autonomous Phase 9 only; preserve partial work and preceding phases. No + compatibility paths, delegation, commits or branch changes. Use qualified + operation identities, explicit custom schemas, designated-AS readership by + default, and mandatory fail-before-release audit persistence. SQLite provider + 10.0.11 is approved subject to availability verification. Record new contracts + for Phase 11 and leave Events implementation to Phase 10. + +### Responsibilities and files + +- Replace single-member assumptions in [Model](../../../src/AAuth.R3/Model/) + with validated shapes for all eight vocabularies and third-party extension + support. Add structured Gateway discovery; retain optional-member semantics. +- Use complete vocabulary-qualified operation identity in R3Metadata, + R3AuthClaims, R3ClaimReader, R3Grant, proposal matching and enforcement. +- Validate requested vocabulary/fields against advertised authoritative + definitions in [Bookings](../../../samples/MockResourceServers/Bookings/Program.cs). + Exercise unconditional and conditional policy variants for every sample endpoint. +- Retain served-byte hashes and approved-parameter checks. Require explicit + audit persistence instead of a silent no-op; test fail-before-release and + recovery semantics. Apply Q4 to R3 document readership and custom fetch contracts. +- Prepare the AsyncAPI handoff contract for Phase 10, without advertising a + working subscription flow before its implementation. + +### Definition of Done + +- [x] All standard vocabulary shapes round-trip; required/optional/malformed + fields and two Gateway services sharing an operationId are tested. +- [x] Wrong vocabulary/member/service cannot gain a same-id grant. +- [x] Granted/conditional/rejected behavior matches policy across Bookings routes. +- [x] Tampered document/proposal/parameters fail; custom fetch contracts are explicit. +- [x] Audit cannot silently disappear; failure/concurrency/restart tests verify + token release and audit association under the selected storage model. +- [x] Dedicated R3 tests, integrated core tests, Bookings e2e and build pass. + +Final evidence (2026-09-09): Release solution 1784/1784 tests (core 865, +conformance 777, R3 142), zero failures/skips. Release build and `make build` +pass with zero warnings/errors. Both R3 browser specs pass 6/6 with fresh +services, isolated HOME, retries=0 and full traces, including account-switch +screenshots at desktop/mobile sizes. Browser TypeScript checking passes. +The earlier 51-browser baseline is not claimed as a newly executed full-browser +gate. See the Phase 9 completion entry in [implementation-log.md](implementation-log.md) +for artifact paths, failures repaired, storage limits and Phase 10/11 handoff. + +### Adversarial repair follow-up + +- [x] Independently reproduce and repair PS-role authorization, OData method + coverage, custom vocabulary member ordering, empty proposal parameters, and + malformed credential value types. Preserve current Phase 10 Events code. +- [x] Add signed HTTP role/type/parameter tests and reordered matching tests + across all vocabularies. Focused Release R3 suite: 206 passed, zero failed/skipped. +- [x] Record breaking custom-schema identity API and directional grant coverage + in the Phase 9 adversarial entry in [implementation-log.md](implementation-log.md). +- [x] Rerun full Release solution tests/build and fresh-service R3 browser tests; + record final review dispositions and remaining limits before closing repairs. + +Repair evidence (2026-09-09): 1907 Release tests pass (core 865, conformance 777, +R3 206, Events 59), zero failed/skipped; Release build has zero warnings/errors. +Fresh R3 browser run passes 6/6 with no skips or flakes. Final scoped self-review +leaves none of the five reported findings open. The Phase 10 Events implementation +is unchanged; its earlier full-browser ledger is not claimed as newly rerun. +See the appended adversarial final-review entry in +[implementation-log.md](implementation-log.md) for artifacts and API handoff. + +## Phase 10 - complete Events companion flow + +Findings: F27, Events portion of F28/F31. Depends on Phases 3-9. +Target: Events [L277](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L277) +(`#subscribe-token`), [L368](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L368) +(`#event-token`), [L424](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L424) +(`#event-delivery`), [L447](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L447) +(`#ap-to-agent`), and [L603](../../../aauth-spec/v10/draft-hardt-aauth-events.md#L603) +(Pre-Authorized Subscription URL Security). + +Phase rule: exact subscribe/event wire types and self-jwt; no draft-09 delivery shim. + +### Implementation Decisions + +- [x] Autonomous Phase 10 implementation approved, with no compatibility, delegates, + commits or branch changes. Use shared SDK verification and admitted discovery; + require explicit companion registration. SQLite 10.0.11 remains sample-owned. + Apply Q5 raw-body and issuer/eid deduplication literally; demonstrate single-shot + delivery and label authenticated polling as a local transport profile. + +### Responsibilities and files + +- Add or selectively adapt the Events source/test/sample projects identified + in Phase 0; add them to [AAuth.slnx](../../../AAuth.slnx), CI/test gates and + package docs. Re-audit reused code instead of assuming another branch is v10-ready. +- Implement AP metadata, subscribe issuance/verification, resource registration, + bound expiring single-use tickets, and subscription/context persistence. +- Implement self-jwt event issuance and AP validation of typ/dwk/issuer/audience/ + expiry/subscription, using the same discovered key for JWT and HTTP signature. + Preserve and verify the actual payload bytes under the chosen digest profile. +- Atomically validate quota, persist the delivery/outbox and update uses before + 202. Include remaining_uses when required; implement specified errors and + restart-safe delivery under Q5/Q6. Do not count a failed durable write as success. +- Implement agent-side issuer signature/audience/expiry/context validation and + deduplication under the recorded interpretation. Provide one explicit local + AP-agent transport; do not label it a standardized endpoint. +- Connect Bookings protected AsyncAPI ticket issuance, resource subscription, + MockAgentProvider routing and a runnable EventAgent. Add a public-subscription + case and bounded/unlimited quota tests even if the primary demo is single-shot. +- Also expose the Events lifecycle as a discoverable runnable scenario in both + GuidedTour and SampleApp, with corresponding Playwright specs. Review whether + the resource's Events behavior serves its single purpose clearly; retaining + Bookings is a deliberate teaching/design choice, not a requirement to keep + adding every future capability to that resource. Phase 12 checks this choice + and the completeness of the scenarios against the capability inventory. + +### Definition of Done + +- [x] No EventToken cnf; unknown typ, wrong AP/resource/agent, expired/future claims, + missing eid, mismatched HTTP key and tampered payload fail as appropriate. +- [x] Ticket reuse, wrong-agent redemption and concurrent redemption fail safely. +- [x] Concurrent max_uses cannot overrun; persistence failure never yields 202; + restart preserves accepted events and quotas. +- [x] Agent never acts on expired/mismatched/unverified events; duplicate behavior + follows the recorded spec interpretation without invented wire fields. +- [x] Public and protected AsyncAPI/R3 flows work end to end with captured headers. +- [x] New Events tests run in the solution and CI; complete sample/e2e and build pass. + +Final evidence (2026-09-09): Release solution 1843/1843 tests (core 865, +conformance 777, R3 142, Events 59), zero failures/skips. Release and `make build` +pass with zero warnings/errors; Events NuGet packing succeeds. Fresh-service +full browser suite passes 55 tests, with one environment-gated Keycloak test +skipped and no failures/flakiness. Both Events pages pass public desktop and +protected work-account mobile flows. Standalone EventAgent completes all six +actual HTTP steps. See the Phase 10 completion ledger in +[implementation-log.md](implementation-log.md) for paths, provider obligations, +recurring-event ambiguity, local transport and remaining environmental limits. + +## Phase 11 - public API alignment and fluent convenience builders + +Depends on Phases 1-10, so the complete new runtime surface is available to +review. Runs before security closure and the frozen-surface sample/docs sweep. +The owner requested this phase after the resource-managed Inbox changed from +pseudonymous hwk to agent JWTs and its examples exposed manual refresher wiring. +See the implementation log's resource-managed revisit entry; the sample flow +decision is not closed merely because Phase 3 tests passed. + +Target: protocol [L2420](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2420) +and [L2422](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2422) +(`#keying-material`), [L2055](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2055) +(`#account-binding`), Signature Keys +[L957](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L957) +(JWKS URI Discovery) and +[L1021](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1021) +(Direct JWKS). These name protocol concepts, not required .NET method names. + +Phase rule: restore the established fluent/convenience style without restoring +obsolete wire formats, compatibility aliases, implicit trust bypasses or hidden +authorization parties. A simpler API must preserve validation and explicit policy. + +### Implementation Decisions + +- [x] Autonomous full Phase 11 alignment authorized on 2026-09-09, preserving + the 1920-test baseline and all 56 browser cases. No delegates, commits or + branch changes. Retain JWT resource-managed access, expose enrollment setup, + and audit the complete public delta against ba768f1. See the implementation log. + +### Events Hardening Verification + +- [x] Bind subscribe subjects to the issuing AP before public/ticket registration. +- [x] Persist AP enrollment ownership, require body-bound proof, and make the + sample namespace provider-assigned with signed idempotent reenrollment. +- [x] Bound serialized inbox pages to 1 MiB with indexed SQL and owner-scoped ack. +- [x] Recover completed notify retries from durable owner/account-bound receipts; + prove EventDemoSession recovery after a lost successful HTTP response. +- [x] Final Release build/tests and fresh no-retry browser gates, including the + separately configured live Keycloak case, recorded in the implementation log. + +### Responsibilities and files + +- Rescan the complete migration diff against implementation baseline `ba768f1`, + including added/changed public methods, overloads, constructors, option types, + DI registrations, endpoint mappers and required context inputs. Extend the + inventory after later fixes; do not limit it to the three phases already done. + Record `spec concept | existing entry point | new low-level contract | chosen + fluent API | ownership/defaults | callers/snippets | validation` in this folder. +- Map the new behavior onto [AAuthClientBuilder](../../../src/AAuth/AAuthClientBuilder.cs), + [EnrolledBuilder](../../../src/AAuth/EnrolledBuilder.cs), + [SelfIssuingBuilder](../../../src/AAuth/SelfIssuingBuilder.cs) and + [BootstrapBuilder](../../../src/AAuth/BootstrapBuilder.cs), plus server/DI and + companion entry points. Reuse suitable APIs; add a layer or forwarding method + only where it removes necessary caller plumbing or fills a real composition gap. + Start from the directly checked resource-managed API map under research F29; + its current EnrolledBuilder can reach flow options via WithInteractionHandling + but lacks a direct WithResourceManagedAccess forwarder. Review composition + intentionally rather than forcing callers to reorder unrelated options. +- Separate Signature-Key schemes (`hwk`, `jkt-jwt`, `jwks_uri`, `jwks`, `jwt`, + `self-jwt`) from the four resource access modes (identity-based, + resource-managed, PS-asserted, federated). Distinguish agent enrollment/key + refresh, agent/auth/subscribe/event tokens and opaque AAuth-Access credentials. + A scheme choice must not silently select an authorization topology. +- Revisit the Inbox example in both primary apps. Record whether it demonstrates + conformant AAuth resource-managed access with an agent token or a separately + labeled generic pseudonymous signing example; do not silently call them the + same flow. Show where the agent token comes from, whether enrollment is setup + or an on-demand call, and which network parties participate at each stage. + No PS/AS token exchange should be introduced into the two-party resource flow. +- Replace manual refresher/HttpClient construction in ordinary enrolled-client + examples with the established Enrolled/RefreshingFrom/WithKeyStore style where + appropriate. Ensure resource-managed access and interaction options compose + through that builder, with correct key/token lifetime and disposable ownership. + Keep an explicit fixed-token low-level path for already-held valid credentials; + do not invent a builder name in a snippet before it exists and is tested. +- Review `From(EnrollResult)` defaults and overrides: it currently selects jwks + when a key URL is available although its comment still says jwks_uri. Decide + the default from the intended agent use case and actual enrollment/token data, + not merely the presence of a URL. Test explicit scheme overrides after refresh + configuration and prevent ambiguous or surprising precedence. +- Map verified issuance/expiry and reserved-claim contracts, admitted discovery, + consent/pending APIs, delegation/sub-agents, issuer-qualified revocation, + account selection, R3 vocabulary/proposal/audit and Events subscription/delivery + contracts into ergonomic public entry points. Preserve mandatory verified + context; do not make new required inputs optional simply to shorten examples. +- Align public naming, XML comments, diagnostics and capability terminology with + the spec. Avoid describing self-issued agent-token provisioning as self-jwt + signing, direct jwks as metadata discovery, or opaque access tokens as JWTs. +- Update all compiled callers and both samples' embedded code, explanatory + text, numbered steps and visuals together. Use equivalent intent expressed + through one consistent high-level builder style; retain low-level examples only + when their explicit purpose is teaching that layer. +- Run an adversarial API review for naming, defaults, builder composition, + disposal/lifetime, hidden network calls and security-policy equivalence. Resolve + findings and repeat before freezing the surface for Phases 12-13. + +### Definition of Done + +- [x] The complete public-API inventory maps every migration-introduced layer + to an existing convenience method, tested new method, or justified low-level API. +- [x] The Inbox agent-token/pseudonymous distinction has an explicit recorded + ruling and both apps show credential provenance and actual parties accurately. +- [x] Enrolled and self-issued builders compose the supported flow options; + client setup does not require avoidable manual service/handler construction. +- [x] Scheme/default/override tests verify emitted carriers and no unintended + PS/AS call; lifecycle tests verify refresh, cancellation and resource ownership. +- [x] Simplified APIs retain required trust, expiry, key/account and consent checks. +- [x] Public names, comments, snippets and sample flow labels use spec terminology; + obsolete aliases and misleading From/enrollment defaults are gone. +- [x] Updated snippets compile/run and both apps' flow/browser checks pass. +- [x] Full solution tests/build pass and the last API review has no unresolved + in-scope findings; decisions and deviations are logged. + +Verified 2026-09-09: Release 1967/1967 tests (core 913, conformance 777, +R3 206, Events 71), no skips/failures; Release and `make build` zero warnings +or errors. Final fresh-service browser gate: 55 stub cases plus the separately +configured live Keycloak case, all 56 executed successfully with retries=0 and +no flakiness. Exact snippet compilation covers 17 templates. The complete +[API map](api-surface-map.md) inventories 182 changed public-source files +(154 SDK, 28 sample runtime), +697/-143 declarations against ba768f1, with no +unmapped files. The [log](implementation-log.md) records failed checks/repairs, +ownership and two-key rulings, screenshots and phase boundaries. This does not +mark Phase 12 security closure or Phase 13 documentation finalization complete. + +## Phase 12 - cross-cutting security and conformance closure + +Findings: all P1/P2 findings plus the research coverage limits. Depends on Phases +1-11. Target: protocol [L1488](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1488) +(mission presentation), [L1490](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1490) +(no mission dereference), and [L2507](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2507) +(`#freshness-and-replay`), plus each finding's canonical references. + +Phase rule: satisfy the normative baseline; do not invent hardening MUSTs. + +### Implementation Decisions + +- [x] Full Phase 12 authorized on 2026-09-09, including retrospective runnable + capability coverage in both apps, selective single-purpose resources and + requirement ledgers. Preserve prior migration work and fluent APIs; no + commits, branch changes, nested delegation or vendor edits. Decisions and + verification are appended to the implementation log as they occur. + +### Responsibilities and files + +- Independently sweep MUST/MUST NOT/reject requirements across core, R3 and + Events, recording implemented, inapplicable, unsupported-optional, ambiguous, + and unresolved cases in the requirement-to-test ledger. +- Close remaining governance coverage: permission/audit/interaction ownership, + unknown/terminated missions, consent association, exact mission bytes and echo, + no resource/AS mission dereference, and account-aware prior approvals. +- Exercise mixed challenge sequences: claims, clarification, approval, payment, + user interaction, cancellation, expiry, slow_down and retry-after. Test redirect + admission and new-token replacement, not only final 200 responses. +- Validate resource-managed agent/key/account binding, token refresh, replay + isolation, secret-safe diagnostics, untrusted metadata/display sanitization, + and real sample configuration rather than helper-only tests. +- Review the configured durable stores and injected HTTP/policy callbacks against + their contracts. Record missing guarantees instead of claiming SDK control of + arbitrary application implementations. + +### Capability scenarios and resource simplicity + +This is an implementation gate before Phase 13, not only a documentation audit. +Apply the owner's 2026-09-09 scenario requirement retrospectively to capabilities +already implemented in Phases 1-11 as well as any additions from review repairs. + +- Build a capability-to-scenario matrix from the migration diff, the research + findings, and [api-surface-map.md](api-surface-map.md): + `capability | existing/new flow | GuidedTour entry | SampleApp entry | resource + purpose | Playwright specs | evidence/gap`. Name the actual pages/flow selectors + and assertions; do not treat unrelated success tests as coverage. +- Include Events public/protected subscriptions and delivery, account selection, + direct and parent-mediated/chained authorization, AS clarification, and other + new user-facing capabilities. Record internal hardening separately with its + negative tests; it does not need an artificial new UI scenario. Optional + capabilities excluded by the approved scope remain explicitly excluded. +- Extend an existing flow if it already teaches the capability without confusing + its actors or purpose. Otherwise add the simplest discoverable scenario to + both apps, with actual SDK/network behavior, setup, expected outcome and a + meaningful rejection or recovery case. Do not substitute simulated output + or a standalone EventAgent run for either app's scenario. +- Review [existing resource examples](../../../samples/MockResourceServers/) + before choosing a backend. Record one sentence describing the resource's + single purpose and why reuse or a new resource best preserves that example. + Keep endpoint handlers, metadata, authorization and domain state easy to read; + move reusable protocol mechanics into existing SDK facilities rather than + copying them into the example. Supporting operations may belong to one use + case; single-purpose does not mean one endpoint or one signing scheme. +- When a new resource is justified, add a minimal project alongside the existing + resources. Wire its project into [AAuth.slnx](../../../AAuth.slnx), shared sample + configuration/explicit loopback policy, [Makefile](../../../Makefile), and the + [Playwright webServer setup](../../../tests/e2e/playwright.config.ts). + Follow existing lifecycle, deterministic reset and isolated-state patterns. + Do not provision a new external service unless the capability requires it. +- Add specs under [GuidedTour tests](../../../samples/GuidedTour/playwright-tests/) + and [SampleApp tests](../../../samples/SampleApp/playwright-tests/), reusing + [shared helpers](../../../tests/e2e/helpers/). Assert the new flow is reachable, + executes its actual protocol steps, exposes the expected claims/headers or + events, and handles the selected failure/recovery branch. Check numbered-step, + sequence-visual and embedded-snippet associations and reset/repeated execution. + Add narrowly scoped API tests for concurrency or crash cases not suited to UI. +- Validate affected flows at desktop and narrow viewports, then run both full + browser projects on fresh services. Ensure the existing CI entry point picks + up all new specs. Append resource-selection decisions and each gap's resolution + to the implementation log; repeat this matrix check after adversarial repairs. + +### Definition of Done + +- [x] Every normative area has an explicit ledger disposition and test evidence + or documented deployment responsibility; no unexplained MUST gap remains. +- [x] Every in-scope new user-facing capability maps to a real scenario in both + apps, with uncovered capabilities implemented rather than silently deferred. +- [x] Resource choices are documented, selective and single-purpose; new resource + source remains a comprehensible example following existing project patterns. +- [x] Every new flow has passing Playwright coverage in both app projects, + including meaningful protocol assertions and a failure or recovery branch. +- [x] New resources/scenarios start, reset and run through the existing demo, + solution, test harness and CI entry points without extra manual setup. +- [x] High-stakes R findings are directly reproduced/rechecked and resolved. +- [x] Threat-oriented tests pass without breaking existing positive controls. +- [x] Core/R3/Events/solution tests and both policy-mode e2e runs pass. + +Final evidence (2026-09-09): 2069 Release tests; clean Release build; 21 exact +snippet templates; full fresh stub browsers 67 passed/one live-only skip; full +fresh live Keycloak browsers 68 passed/no skips. Both browser gates have zero +unexpected/flaky results and retries=0. The eight owner-supplied findings and +the callback/recovery gate have no remaining open in-scope finding. Historical +failed/interrupted runs remain in the append-only log. Deployment obligations +and unsupported optional capabilities remain explicit in the ledger; Phase 13 +is not closed by this evidence. + +## Phase 13 - frozen-surface samples, snippets and docs sweep + +Findings: F29-F31 and every user-facing change. Depends on Phase 12; compiled +consumer fixes have already happened in their owning phases. +Target: protocol [L2420](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2420) +(`#keying-material`) and interop profile +[L9](../../../aauth-spec/v10/interop-demo-profile.md#L9) through its five surfaces. + +Phase rule: describe only the final v10 API and supported capabilities, not legacy aliases. + +### Implementation Decisions + +- [x] Full Phase 13 writes authorized 2026-09-09. Exhaustive discovered snippet + coverage replaces the representative-only requirement below. Reuse Roslyn; + classify external templates explicitly; preserve useful instructional content. + No commits/branch changes. No delegation is this worker's constraint, not an + owner prohibition on the separate Phase 14 review. See the append-only log. + +### Responsibilities and files + +- Inventory every surface in the research ownership map. Cover root/package/ + sample READMEs, docs index/concepts/glossary, all signing/server/workflow/ + advanced/reference docs, GuidedTour CodeSnippets/TourSession/Razor content, + SampleApp pages and both Playwright suites. Record `file | finding | edit | check`. +- Use the completed Phase 12 capability-to-scenario matrix to check every new + page/flow, any new resource's README and code examples, navigation entries, + numbered steps, sequence visuals and embedded snippets. The sweep must not + declare coverage complete while either app lacks a required runnable scenario. +- Separate generic HTTP Signature Keys demos from four AAuth access modes in + routes, policy, headings and diagrams. Ensure getting-started teaches a valid + agent-token path and labels generic signing examples accurately. +- Replace old algorithm/error/action/revocation/carrier snippets. Add account, + EventAgent/AsyncAPI, AS clarification, strict egress, consent session and + supported-capability guidance. Keep hardware-attestation claims honest. +- Compile or explicitly classify every discovered fenced and string-literal example through + the existing sample/test infrastructure. Compare displayed exchanges against + captured runtime wire output, including negative responses. +- Prioritize both [SampleApp](../../../samples/SampleApp/) and + [GuidedTour](../../../samples/GuidedTour/). For every changed flow, record + `flow | changed step | SampleApp surface | GuidedTour surface | validation`. + Reconcile numbered instructions and cross-references, actor lanes, arrows, + decision branches, polling loops, highlights and navigation with runtime order. + Show local checks as local decisions rather than invented network requests. +- Inventory embedded snippets in [CodeSnippets.cs](../../../samples/GuidedTour/CodeSnippets.cs), + [TourSession.cs](../../../samples/GuidedTour/TourSession.cs), + [GuidedTour Razor components](../../../samples/GuidedTour/Components/) and + [SampleApp pages](../../../samples/SampleApp/Components/Pages/). Include raw, + interpolated and multiline strings; inline pre/code blocks; displayed C#, + JSON, JWT and HTTP examples; and copy/download variants where present. + Update signatures, parameters, headers, claims, comments and step references, + not only the live calls. Each snippet must describe the same flow and public + API as its associated step and payload inspector. +- Compile/run complete C# snippets through focused tests or sample harnesses; + wrap fragments with their declared imports/setup. Parse and assert JSON/HTTP + examples against the current contract and captured wire output. For intentional + placeholders or pseudocode, record that classification and check the surrounding + contract explicitly. A successful sample build does not validate code in strings. +- Run five interop surfaces, including a real four-party sub-agent flow with + distinct parent/child keys. Add local hermetic checks; distinguish externally + unavailable live endpoints from failure/success. +- Only after runtime gates pass, update SDK-target wording in root/package docs, + [SPEC-VERSION](../../../aauth-spec/SPEC-VERSION.md) and + [CHANGELOG](../../../aauth-spec/CHANGELOG.md). Preserve historical entries and + all vendored snapshot bytes. Explicitly document remaining optional exclusions. + +### Definition of Done + +- [x] Every ownership-map surface has a recorded disposition, not only grep hits. +- [x] Every scenario/resource introduced for capability coverage has aligned + instructional content and links to the existing demo/test setup. +- [x] No stale executable wire shape remains except deliberate rejection fixtures. +- [x] Snippets compile/run; displayed bodies/headers match actual v10 behavior. +- [x] Every affected embedded snippet in both apps has a recorded validation + result or an explicit illustrative-placeholder classification; no stale API, + wire shape, comment or numbered-step reference remains. +- [x] Both apps' numbered steps, sequence visuals, displayed/copied snippets and + payloads agree with the implemented flow, including consent, clarification, + immediate grants, retries, denial and cancellation where applicable. +- [x] Both Playwright suites check affected step navigation, approval/polling + transitions and displayed snippet/payload associations, not only final success. + Desktop and narrow-viewport visual checks cover labels, arrows, loops, + highlights, clipping and overlap. +- [x] Docs links and anchors resolve; examples do not mislabel generic signing as AAuth. +- [x] Full-stack fresh-server e2e and all interop surfaces have recorded results. +- [x] Version/capability claims match the implemented and verified scope. + +Completed 2026-09-09. [Surface inventory](docs-surface-map.md): 161 files, +615 blocks, including 261 exact compiled C# blocks, 33 source-checked API +excerpts, five explicit external templates, 32 dynamic displays and 162 inline +Razor labels/expressions. The remaining blocks have individual format/runtime +dispositions; they are not all described as compiled programs. All 80 docs +test cases pass. Final Release: 2128 tests, zero failed/skipped, build zero +warnings/errors. Full fresh stub browsers: 67 passed/one live-only skip; +live Keycloak: 68 passed/no skips; retries=0 and no unexpected/flaky results. +Local S1-S5 evidence and partial external LiveWhoAmITest results are recorded in +the [ledger](conformance-ledger.md) and append-only log. External scoped +authorization returned person_token_required and is not claimed as a pass. +All 26 vendored snapshot files match HEAD byte-for-byte. Phases 14 and 15 remain +open; this phase is not an independent adversarial review. + +Final authorization-repair checkpoint (2026-09-09): seven source-review findings +have code/regression evidence in the append-only log. Release passes 2160 tests; +full browsers pass 71 stub plus one live-only skip and 72 live with no skips, +retries=0. The four added Documents cases execute resource permission before PS +consent in both apps. Current inventories cover 169 files/617 documentation +blocks and 197 public-source files (+777/-149 declarations). This continuation +is implementation, not the independent review below; its checkboxes stay open. + +## Phase 14 - independent internal review + +Depends on Phase 13. Give a fresh read-only subagent the final diff, immutable +v10 sources, research, this plan, implementation log and requirement-to-test +ledger. Require severity-graded findings with reverified source lines, including +negative requirements, optional-capability boundaries, samples and docs. + +Phase rule: no compatibility exception or spec interpretation is implicit. + +### Implementation Decisions + +- [x] 2026-09-09: Repair confirmed review findings using independently signed + malformed-token tests and shared structural validation before trusted contexts. + Apply required payload claims to built-in AAuth profiles, not arbitrary JWT + types; registered companion verifiers retain their policy hook. Require the + verified PS metadata role before core AS exchange or pending policy evaluation. + Preserve previous repairs; no delegation, commits, or branch changes. Repeat + Release, documentation inventories, and zero-retry stub/live browser gates. + Independent review remains pending; these repairs do not close Phase 14. + +- [x] 2026-09-09: Reject duplicate JWT members structurally; use policy-aware + host-only agent-domain validation throughout actor contexts; preserve live + factories in refresh-only clients and cancellation before token publication; + support explicit R3 JSON null values without treating missing values as null. + Correct per-agent JWKS/DI documentation and sample identities/consent mappings. + Final implementation evidence: 2637 Release tests, clean build, 93 snippet + checks, full fresh browsers (71 stub plus one live-only skip; 72 live), + retries=0. Retain failed gate history and the optional bootstrap convenience + limitation. This is not an independent pass; all Phase 14 DoD boxes stay open. + +- [x] 2026-09-09: Complete the remaining guarded body/JWT parsing and typed + credential-error repairs from the 2637-test checkpoint. PS/core AS/R3 AS + reject malformed credentials before policy, audit, or document fetch; pending + replacement and claims paths reject invalid shapes without changing state. + Correct cached issuer discovery and conditional IAAuthKey resource-key docs; + compare every property/constructor-parameter table row in both reference pages + against source. Release passes 2859 tests, snippets/source checks pass 96, + fresh full stub passes 71 plus one live-only skip, and live passes 72, all + with zero retries. Only the parent is authorized to commit/push after final + gates and fresh review; this worker performs neither. Independent review and + all Phase 14 DoD checkboxes remain open. + +- [x] 2026-09-09: Repair the 2859-checkpoint claims regression with strict raw + JSON parsing shared across contexts and credential validation only for token + requests or matching clarification updated_request actions. Trusted pending + status controls dispatch; policy-requested action and credential-like names + remain ordinary claims. Preserve reserved-name and invalid-shape guards. + Correct adjacent replay, proactive endpoint and IAAuthKey documentation/XML; + extend the source table checker to token-issuance PS options. Focused HTTP + tests pass 286; snippets/source/link tests pass 103. Full Release passes 2911 + tests with a clean build; fresh browsers pass 71 stub plus one live-only skip + and 72 live, all with zero retries or unexpected/flaky results. API and docs + inventories are current. Parent-only commit/push authorization does not close + independent review; no delegation or branch changes are authorized. + +### Definition of Done + +- [x] Every review finding has a recorded disposition and supporting evidence. +- [x] Approved fixes have focused regression tests and rerun affected gates. +- [x] Material architectural changes receive another independent review. +- [x] Independent review checks the capability-to-scenario matrix, both apps' + new-flow Playwright coverage, and resource purpose/readability, not only SDK code. +- [x] Release solution tests, explicit R3/Events suites, stub/Keycloak e2e, + snippet checks, links, and the requirement ledger are complete. +- [x] Unavailable external live interop is explicitly reported, with local + captured-wire evidence; no blanket full-conformance claim hides it. +- [x] All changes remain uncommitted for owner inspection unless requested otherwise. + +Closed 2026-09-09 after fresh read-only acceptance of signing/discovery/API, +authorization/claims dispatch, R3/Events/storage and instructional surfaces. +Reported findings were repaired and their affected sets reviewed again; the +last applicable independent passes have zero unresolved in-scope findings. +This is a bounded source-review result, not proof of correctness of arbitrary +host policies, stores or transports. The owner authorized commit/push after +completion; the premature worker publication is recorded as a deviation. + +## Phase 15 - final documentation alignment gate + +After all adversarial review repairs, repeat the Phase 13 inventory against the +final code, with SampleApp and GuidedTour as primary acceptance surfaces. Recheck +embedded snippets, numbered steps, sequence visuals, copied examples, API docs, +configuration, README version/capability claims and all affected browser tests. +Record results in the implementation log. Any behavior-changing correction +reopens the affected tests and logical area's independent review. + +### Definition of Done + +- [x] Final code and all instructional surfaces agree; no stale step or snippet remains. +- [x] The final capability matrix has no uncovered in-scope user-facing feature + in either app, including additions from review fixes. +- [x] Links, snippet checks and both apps' visual/browser checks pass. +- [x] Every logical area's last adversarial pass has zero unresolved in-scope findings. +- [x] Runtime and documentation validation results and limitations are recorded honestly. + +Final verification: 2913 Release tests (1469 core, 1079 conformance, 290 R3, +75 Events), zero failed/skipped; clean make build; explicit make unit/conformance +and R3/Events gates pass. All 105 documentation/source/link checks pass, with +current API and documentation inventories. The final runtime's fresh browser +reports contain 71 stub passes plus the expected live-only skip and 72 live +Keycloak passes, zero unexpected/flaky/global errors and retries=0. Subsequent +changes are documentation, XML comments and two documentation regressions only; +the browser evidence remains applicable and is not claimed as newly rerun. +The parent inspected saved Documents/Events desktop/mobile captures. All +vendored snapshot directories remain identical to the migration baseline. + +External full authorization still returns `person_token_required`; local S1-S5 +checks and successful Keycloak tests do not establish external interoperability. +Other declared optional and production-provider limitations remain in the +conformance ledger. No unresolved in-scope finding is hidden by those limits. + +## Finding-to-phase traceability + +| Findings | Owning phases | +|---|---| +| F01-F07 | 3; discovery dependencies in 4; API alignment in 11; cross-cutting review in 12 | +| F08-F09 | 4 | +| F10 | 2; context propagation checked in 5-6 | +| F11 | 1 | +| F12-F15 | 5 | +| F16 | 7 | +| F17-F18 | 6 | +| F19 | 2 (reserved claims), 6 (upstream and actor checks) | +| F20 | 6 | +| F21 | 8; R3 and Events integration in 9-10 | +| F22-F26 | 9; fetch admission in 4; Q4 in 0 | +| F27 | 10 | +| F28 | 0 (dispositions), 3 (self-jwt/jwks), 10 (Events consumer) | +| F29-F30 | Compiled consumers in owning phases; API/flow alignment in 11; final sweep in 13 | +| F31 | 1/3 (bootstrap shared behavior), 10 (AP integration), 11 (API), 13 (documentation) | +| Owner-requested API simplification and Inbox flow revisit | 11, with documentation gates in 13/15 | +| New-capability scenarios, selective single-purpose resources and Playwright | Owning feature phases; coverage implementation in 12; docs/review gates in 13-15 | +| Coverage limits and all negative requirements | 12 and independent review 14 | + +## Out of scope + +These are proposed dispositions subject to Phase 0, not silent omissions. + +| Item | Reason and required boundary | +|---|---| +| Compatibility aliases, old-wire fallbacks | Explicit alpha/spec-accuracy constraint | +| SDK implementation during this documentation task | Research and planning only; approval gate precedes code | +| Rewriting old plans or vendored source | Historical records and immutable citation baseline | +| X.509 and cached-assertion implementations | Optional under Q1; reject/advertise accurately and document exclusion, not partial stubs | +| New JOSE algorithm families beyond supported Ed25519/ES256 | Algorithm agility does not require implementing every registered algorithm; unknown selected keys fail cleanly | +| Platform-native attestors and all AP-agent push transports | Bootstrap guidance and Events transport are implementation-specific; retain hooks and one complete local transport | +| Payment settlement engine | External protocol/provider responsibility; payment challenge/control-flow handling remains in scope | +| General recurring-event semantics invented beyond the draft | Q5 requires a ruling; support only what can be described/tested without inventing standard wire fields | +| Production-specific identity provider and database deployment | Supply explicit contracts and runnable sample providers; operational deployment remains application-owned | +| Automatic branch merge, package publication, git commit | Requires separate owner authorization | \ No newline at end of file diff --git a/.agent/plans/2026-09-08-aauth-v10-spec-migration/research.md b/.agent/plans/2026-09-08-aauth-v10-spec-migration/research.md new file mode 100644 index 00000000..2f69e3ef --- /dev/null +++ b/.agent/plans/2026-09-08-aauth-v10-spec-migration/research.md @@ -0,0 +1,798 @@ +# Research - AAuth v10 repository conformance + +## Status and scope + +Research date: 2026-09-08. This initiative audits the current repository against +the complete v10 specification family, not only the changes since draft-09. +It covers the core SDK, R3, Events, tests, runnable samples, embedded examples, +and documentation. Baseline: commit `0144eb1` on `v09-spec-migration`. +Implementation has not begun. + +Spec accuracy takes precedence over backward compatibility. The intended alpha +cutover has one current wire format and public API, without legacy aliases or +dual-format parsing. Earlier migration decisions remain historical records; +their exclusions are not automatically exclusions for this initiative. + +## Evidence baseline + +The reference snapshot is [aauth-spec/v10](../../../aauth-spec/v10/), pinned to +upstream commit `9dee49fbf49074d1460d0a7c0670bf355aef5e1e`. +The published protocol is +[draft-hardt-oauth-aauth-protocol-10](https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/10/) +(2026-08-06). Companion source files come from the same pinned snapshot; +HTTP Signature Keys is the published draft-08 text. + +Implementation-file citations in the original findings describe the recorded +research baseline, not code replaced during migration. Read that baseline in +git when checking a historical implementation claim. Dated updates identify +current observations; canonical vendored spec-line citations remain unchanged. + +The moving upstream editor's copy is not the conformance baseline. Source-line +citations below refer to the vendored files; stable section anchors are recorded +where available. Publication metadata is separate from stale source-frontmatter +dates. + +## Research method + +Read-only reviewers examine distinct requirement groups, including negative +requirements and samples/documentation. Findings distinguish confirmed defects, +missing optional capabilities, deployment policy, and unresolved spec questions. +The primary reviewer rechecks high-stakes findings directly against the cited +requirement and the controlling implementation. Existing plans and memories are +leads, not evidence of present behavior. + +No SDK or sample changes are part of this research task. The implementation plan +is derived from this evidence inventory and cross-area synthesis. An independent +review of both documents checked high-stakes findings and phase coverage; its +no-claims federation consent finding is incorporated into F17 and Phase 6. + +## Executive assessment + +Changing the version label, algorithm constant, and error JSON is insufficient. +There are pre-existing authentication, consent, delegation, and interaction-state +defects as well as draft-10 changes. Several existing tests preserve the old +behavior rather than independently establish conformance. + +The most consequential findings are unverified JWT types being reported as +verified (F05), pending-route identity gaps (F12), claims release without honoring +the PS consent decision (F17), code-only sample approval bypassing Keycloak +(F14), and missing agent-expiry ceilings (F10). Those findings are code-path +observations, not claims of a tested remote exploit. + +Events is not implemented in the tracked source on this branch. Directories +named `AAuth.Events`, `AAuth.Events.Tests`, and `EventAgent` contain leftover build +artifacts, not active projects. Another local branch, +`feat/aauth-events-implementation`, is a potential source of reusable work, not +evidence that this branch implements Events. + +### Classification and verification + +- P1: security/trust-boundary or major authorization correctness defect +- P2: wire incompatibility, missing required validation, or workflow defect +- P3: documentation, configuration, or unsupported optional capability +- D: primary reviewer directly reread the controlling implementation and spec +- R: focused read-only reviewer inspected the implementation; target citations + are checked here, but the complete implementation path was not reread here + +R findings are explicitly reported evidence, not independently reproduced bugs. +The first broad reviewer pass included incorrect lines and overclaims. A focused +second pass replaced those claims. In particular, optional features are not +universal MUSTs; the AS does not mint policy-expanded scope merely because a +policy can return claims; scope-narrowing and structured confirmation-key checks +already exist; and a replay cache is optional under [P2507]. + +### Canonical source map + +| Source | Immutable local text | Canonical publication or source | +|---|---|---| +| Protocol draft-10, P citations | [Protocol](../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md) | [IETF draft-10](https://www.ietf.org/archive/id/draft-hardt-oauth-aauth-protocol-10.txt) | +| Signature Keys draft-08, S citations | [Signature Keys](../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt) | [IETF draft-08](https://www.ietf.org/archive/id/draft-hardt-httpbis-signature-key-08.txt) | +| R3 draft-01, R citations | [R3](../../../aauth-spec/v10/draft-hardt-aauth-r3.md) | [Pinned source](https://github.com/dickhardt/AAuth/blob/9dee49fbf49074d1460d0a7c0670bf355aef5e1e/draft-hardt-aauth-r3.md) | +| Events draft-00, E citations | [Events](../../../aauth-spec/v10/draft-hardt-aauth-events.md) | [Pinned source](https://github.com/dickhardt/AAuth/blob/9dee49fbf49074d1460d0a7c0670bf355aef5e1e/draft-hardt-aauth-events.md) | +| Bootstrap draft-02 | [Bootstrap L113](../../../aauth-spec/v10/draft-hardt-aauth-bootstrap.md#L113), What Bootstrapping Is Not | [Pinned source](https://github.com/dickhardt/AAuth/blob/9dee49fbf49074d1460d0a7c0670bf355aef5e1e/draft-hardt-aauth-bootstrap.md) | +| Interop profile | [Profile L9](../../../aauth-spec/v10/interop-demo-profile.md#L9), Surface 1 onward | [Pinned source](https://github.com/dickhardt/AAuth/blob/9dee49fbf49074d1460d0a7c0670bf355aef5e1e/interop-demo-profile.md) | + +P/S/R/E citation labels include the exact local line number. Markdown source +lines do not equal rendered IETF text lines. Signature Keys citations use the +published text's actual lines, including page breaks. The source commit, rather +than a moving `latest` frontmatter value, identifies the companion revision. + +## Signing, discovery, and errors + +### F01 - Algorithm identifiers and JWK validation + +P2, D; v10 change. [P2409] and [P2412] (`#signature-algorithms`) require an +explicit fully specified `alg` and rejection of key/algorithm disagreement. +[P2515] (`#jwks-discovery`) requires independent selection of the matching key. +[AAuthKey L19](../../../src/AAuth/Crypto/AAuthKey.cs#L19) names Ed25519 as +`EdDSA`; [L98](../../../src/AAuth/Crypto/AAuthKey.cs#L98) exports no `alg`. +[KeyFactory L18](../../../src/AAuth/Crypto/KeyFactory.cs#L18) dispatches by +`kty`/`crv`, not a validated algorithm. The ECDSA import/export path has the same +missing-algorithm contract. A constant rename alone leaves invalid JWKs accepted. +Key thumbprints must remain RFC 7638 thumbprints, not hashes of the expanded JWK. + +### F02 - Existing hwk wire format is not the standard scheme + +P2, D; pre-existing, plus the new required algorithm member. [S641], [S647], +and [S660] (Section 3.4) define inline `kty`, `crv`, `x`, and `alg` parameters, +with `y` for EC; [S690] applies the algorithm constraint. +[SignatureKeyHeader L49](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs#L49) +instead emits `jkt` plus base64url JSON `jwk`; +[SignatureKeyParser L136](../../../src/AAuth/HttpSig/SignatureKeyParser.cs#L136) +expects that private format. Local signer/verifier agreement hides interop +failure. Providers, bootstrap refresh, snippets, and tests share the defect. + +### F03 - jwks_uri is implemented as a different discovery scheme + +P2, D; pre-existing. [S964] (Section 3.6) requires `id`, `dwk`, and `kid`, then +metadata issuer verification and JWKS discovery at [S975] and [S979]. +[S1021] defines the separate +direct-fetch `jwks` scheme. [SignatureKeyHeader L60](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs#L60) +uses `uri`/`kid`; [DefaultSignatureKeyResolver L63](../../../src/AAuth/HttpSig/DefaultSignatureKeyResolver.cs#L63) +fetches that URI directly. Reusing this behavior under the name `jwks_uri` is +not conformant. Server identity must come from the scheme's verified identifier, +not be guessed by stripping the key URL. Q2 addresses contradictory protocol +examples, not the unambiguous Signature Keys definition. + +### F04 - ES256 support does not reach jwt confirmation-key parsing + +P2, D; pre-existing supported-feature inconsistency. [P2405] +(`#signature-algorithms`) recommends ES256; the middleware advertises it at +[L46](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L46). +However, [SignatureKeyParser L123](../../../src/AAuth/HttpSig/SignatureKeyParser.cs#L123) +and its legacy `Parse` overload use `AAuthKey.FromJwk`, restricted to Ed25519. +The generic key interface and ECDSA implementation exist; JWT carrier parsing +and endpoint key types do not consistently use them. This is not a requirement +to add every JOSE algorithm, but advertised supported algorithms must work. + +### F05 - Issuer verification can be claimed without verification + +P1, D; pre-existing. [S1160] (Section 3.8) rejects unexpected JWT types and +[S1186] requires JWT signature verification before using delegated key authority; +[P2479] (`#verification`) specifies key-resolution failures. +[Middleware L229](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L229) +verifies agent/auth tokens only, skips other types, then reports +`IssuerVerified=true` for any `jwt` carrier when the option is enabled at +[L277](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L277). +An attacker-controlled confirmation key can prove possession without proving +the asserted issuer. Endpoint policy may still reject that type, so this is not +a claim that every resource is bypassable. Future subscribe-token support must +not inherit this behavior. Verification success needs an explicit typed result. + +### F06 - Signature parameter and delegation-lifetime checks + +P2, D; pre-existing. [P2505] (`#freshness-and-replay`) says `expires`, when +present, MUST be honored. [AAuthVerifier L244](../../../src/AAuth/HttpSig/AAuthVerifier.cs#L244) +ignores it. Ignoring signature `alg` is correct for v10 [P2467]; ignoring +`expires` and a conflicting `keyid` is not the same rule ([P2469]). +[S789] and [S917] (Section 3.5) require naming-JWT `iat`/`exp` validation. +[DefaultSignatureKeyResolver L140](../../../src/AAuth/HttpSig/DefaultSignatureKeyResolver.cs#L140) +defers it to middleware, which only checks an `exp` that happens to exist at +[L202](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L202). +Missing expiry and future issuance need explicit rejection, including AP refresh. + +### F07 - Verification error taxonomy and negotiation are obsolete + +P2, D; v10 plus pre-existing parsing behavior. [P2475] (`#verification`) +orders checks and [P2478] defines `unsupported_scheme`; [P2487] pins AAuth +signature failures to 401 and [P2489] excludes signature headers on 403. +[Middleware L128](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L128) +classifies exception messages and emits the removed `supported_algorithms` +member rather than `Accept-Signature-Alg` ([S2997], Document History; +[S1953], Section 5.4.1, SHOULD send the header with unsupported_algorithm). +[SignatureKeyHeader L119](../../../src/AAuth/HttpSig/SignatureKeyHeader.cs#L119) +assumes a single literal `sig` dictionary member and throws `FormatException`, +outside that catch. [S430] and [S437] define label consistency and multiple +signatures. Malformed/unsupported input must yield defined errors, not 500s; +unselected schemes must not poison an otherwise valid selected signature. + +### F08 - Egress admission and exact identifiers are incomplete + +P1, D; pre-existing. [P2521] (`#jwks-discovery`) and [S2372] (Section 7.3) +require admitted HTTPS fetches with size/time limits, redirect constraints, +destination-address checks, DNS-rebinding defense, and cross-origin policy. +[MetadataClient L74](../../../src/AAuth/Discovery/MetadataClient.cs#L74) and +[JwksClient L101](../../../src/AAuth/Discovery/JwksClient.cs#L101) fetch +caller-influenced URLs without those controls. Metadata issuer checking exists; +it is not SSRF admission. R3's narrower same-origin/IP-literal checks are useful +but not a complete reusable network policy. [P2529] and [P2548] (Server +Identifiers) also require strict identifier syntax and exact comparison. +[PS routing L339](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L339) +uses case-insensitive, slash-trimmed comparison. Production policy and explicit +loopback-only development exceptions need separate contracts (Q3). + +### F09 - JWKS floor is not enforced across all fetch paths + +P2, D; pre-existing. [P2517] (`#jwks-discovery`) requires caching and at most +one fetch per minute; it recommends stale-on-error/backoff and bounded age. +[JwksClient L58](../../../src/AAuth/Discovery/JwksClient.cs#L58) fetches on a +cold/expired cache independently of the refresh floor. Concurrent callers can +all enter it; failed attempts do not update a shared attempt timestamp. The +unknown-kid/same-kid refresh helpers and default one-minute interval already +exist and should be retained, with shared per-URI concurrency and failure state. + +### F10 - Auth-token expiry can exceed the agent token + +P1, D; pre-existing. [P1344] explicitly bounds auth `exp` by the agent token's +`exp`, separately from the one-hour ceiling at [P1708]. +[AuthTokenBuilder L152](../../../src/AAuth/Tokens/AuthTokenBuilder.cs#L152) +computes `iat + Lifetime`; [PS mint L249](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L249) +and [AS mint L245](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs#L245) +have no agent-expiry input. Pending state also needs the verified ceiling, +including parent/sub-agent and upstream contexts. A resource receiving only an +auth token cannot independently discover an absent associated-agent expiry; +issuance is the directly observable enforcement point, not an invented token lookup. + +### F11 - Problem details require a coordinated producer/consumer cutover + +P2, D; draft-09 requirement still unmet. [P2304], [P2306], and [P2309] +(`#error-response-format`) specify `application/problem+json`, required `error`, +optional `detail`, and no reliance on `type` for AAuth decisions. +[RevocationEndpoint L62](../../../src/AAuth/Server/RevocationEndpoint.cs#L62) +emits `error_description`; ordinary PS/AS `Results.Json` errors default to +`application/json`. [TokenExchangeClient L201](../../../src/AAuth/Agent/TokenExchangeClient.cs#L201) +and [AccessServerClient L439](../../../src/AAuth/Access/AccessServerClient.cs#L439) +read the legacy description. R3/governance/resource-managed helpers also produce +errors. Bootstrap HTTP APIs are app-defined, so normalizing their bodies is an +SDK consistency decision, not a normative Bootstrap requirement (F31). + +## Authorization, interactions, and delegation + +### F12 - PS pending operations do not establish the request owner safely + +P1, D; pre-existing. [P2825] (`#pending-url-security`) requires identity +verification on every poll. [PS L224](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L224) +installs `SignatureOnly`; [L354](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L354) +fetches a pending entry without checking the poller's identity. POST/DELETE use +[RequesterMatches L1054](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L1054), +which compares a carrier `sub` rather than verified issuer/key-bound ownership. +A known pending URL can be polled by another signer; a forged same-sub carrier +can pass the mutation guard. Disclosed auth tokens remain bound to the original +key. Token-endpoint verification does not repair later pending-route checks. + +### F13 - Clarification dispatch and replacement semantics are incomplete + +P2, D; action is draft-09, replacement validation is pre-existing. +[P1054] (`#agent-response-to-clarification`) requires explicit `action` and 400 +for missing/unknown values. [P1099] requires the replacement resource token's +issuer, agent, and key binding to match the original context. +[PS L429](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L429) dispatches +by payload presence; a supplied replacement is logged and discarded, not +validated or substituted. [ClarificationExchange](../../../src/AAuth/Agent/ClarificationExchange.cs) +and [TourSession L5003](../../../samples/GuidedTour/TourSession.cs#L5003) emit +actionless answers. AS claims POSTs exist, but AS clarification production and +resumption are an additional optional capability ([P1546]), not already implemented. + +### F14 - Browser sample decisions treat correlation codes as authorization + +P1, D; pre-existing. [P2136] (`#interaction-code-format`) says the code alone +MUST NOT authorize a decision. [Federated sample L173](../../../samples/MockAccessServers/Federated/Program.cs#L173) +registers code-only approval unconditionally and [L189](../../../samples/MockAccessServers/Federated/Program.cs#L189) +marks it allowed without the configured Keycloak policy. The route disables +antiforgery. PS [L887](../../../samples/MockPersonServer/Program.cs#L887) and the +R3 consent helper also use demo code-only approval. Local demo identity shortcuts +must be explicit and isolated; they cannot bypass the real Keycloak flow. The +local PS exemption at [P2863] requires OS-controlled access, not merely a localhost URL. + +### F15 - Consent code and pending lifecycles are not uniform + +P2, R; pre-existing. [P2132], [P2134], [P2138], [P2140], and [P2142] +(`#interaction-code-format`) require normalization, single use, bounded failed +attempts, and expiry. [P2826] requires a terminal pending URL to return 410 on +later polls. [PS store L234](../../../src/AAuth/Person/IPersonPendingStore.cs#L234) +and [AS store L151](../../../src/AAuth/Access/IAccessPendingStore.cs#L151) look up +raw code strings; expiry eviction loses the distinction between expired and +unknown. The PS allowed branch [L392](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L392) +remints on repeated polls. Actual consent routes do not use the normalization +helper or a failed-attempt limiter. Resource-managed stores have separate +normalization/atomic-consumption controls; that does not prove PS/AS correctness. +Browser code consumption and the authenticated decision session are distinct +states, so single use must not prevent legitimate approval after page arrival. + +### F16 - Revocation keys and authorization context are incomplete + +P1, D; v10 pair/routing change. [P2361], [P2363], [P2382], and [P2393] +(`#token-revocation`) define `(iss,jti)`, 404 for unknown pairs, and authorized +issuer/trusted-PS revocation. [RevocationEndpoint L78](../../../src/AAuth/Server/RevocationEndpoint.cs#L78) +reads only `jti`, then always returns success. [Middleware L172](../../../src/AAuth/Server/Verification/AAuthVerificationMiddleware.cs#L172) +also queries by bare `jti`. Deny-by-default revoker configuration already exists, +so the earlier claim that any issuer can revoke any token is too broad. Once +authorized, a revoker still operates in a shared unqualified namespace. Replay +state must stay per-request; changing it to token single-use would break legitimate +reuse. AP-to-PS cascade behavior at [P2390] needs explicit routing and issuance records. + +### F17 - Four-party claims release ignores the PS consent outcome + +P1, D; pre-existing. [P934] (`#ps-response`) requires the PS to handle +consent in both access cases. [PS L939](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L939) +calls the asserter, then unconditionally returns a `ClaimsResponse`, substituting +`pairwise-sub` when needed. It never branches on `Deny` or `NeedsConsent`, unlike +the three-party path. AS policy still decides whether to mint, but it may receive +claims and approve despite the PS's contrary decision. Consent gating belongs +before claims release, not only before final token delivery. + +The callback is also the only federated asserter invocation. If the AS grants +immediately, or after interaction without requesting claims, the client reaches +[delivery L248](../../../src/AAuth/Access/AccessServerClient.cs#L248) without +invoking it, and the [PS L960](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L960) +marks the grant allowed. PS consent determination must therefore be independent +of AS claims negotiation. Prior consent can satisfy it; always showing a prompt +is not required. Fixing only the callback leaves this no-claims path untouched. + +### F18 - Federation loses sub-agent and delegation context + +P1, D/R; pre-existing. [P1511] (PS-to-AS Token Request) specifies child binding +and parent recording. [P1574] (Auth Token Delivery) validates both immediate and +nested actors; [P1870] (`#sub-agents`) defines the parent's position. +[PS L341](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L341) omits the +sub-agent parameter when choosing federation; [L718](../../../src/AAuth/Person/AAuthPersonServerEndpoints.cs#L718) +also retains an upstream actor without adding the parent wrapper in the combined +case. The AS [L315](../../../src/AAuth/Access/AAuthAccessServerEndpoints.cs#L315) +does not process forwarded upstream context. The response validator's context +check [L113](../../../src/AAuth/Tokens/AuthTokenResponseValidator.cs#L113) is +optional, incomplete for the immediate actor, and not populated by the PS request. +Ordinary three-party sub-agent key binding exists and must not regress. + +### F19 - Upstream validation and reserved-claim boundaries need tightening + +P2, R; pre-existing structural gap, with a v10 actor prohibition. +[P1770] (`#upstream-token-verification`) requires Auth Token Verification; +[P1751] and [P1753] require confirmation structure and `sub` or `scope`. +[UpstreamTokenValidator L219](../../../src/AAuth/Tokens/UpstreamTokenValidator.cs#L219) +uses generic JWT verification without all those checks. Trust and audience +checks exist. [P1809] (`#directed-sub-chaining`) prohibits person +identifiers inside `act`; [ActChainBuilder L32](../../../src/AAuth/Tokens/ActChainBuilder.cs#L32) +clones upstream objects and [L55](../../../src/AAuth/Tokens/ActChainBuilder.cs#L55) +only checks agent presence/depth. Direct top-level upstream `sub` copying was +not found. [AuthTokenBuilder L211](../../../src/AAuth/Tokens/AuthTokenBuilder.cs#L211) +blocks only already-populated extra claims, allowing unset reserved fields such +as `act` or `mission` through `AdditionalClaims`. That last issue is an API guard +defect; protocol impact depends on the inserted value, not arbitrary overwrite of `iss`. + +### F20 - Resource scope vocabulary is not validated at issuance + +P2, R; pre-existing. [P2041] (`#scopes`) restricts resource scopes to published +`scope_descriptions` and identity scopes to the PS's `scopes_supported`. +[Challenge middleware L206](../../../src/AAuth/Server/Challenge/AAuthChallengeMiddleware.cs#L206) +passes configured scopes into [ResourceTokenBuilder L127](../../../src/AAuth/Tokens/ResourceTokenBuilder.cs#L127) +without a vocabulary check. This permits invalid configuration, not proof that +every sample issues invalid scopes. Existing auth-scope subset checks remain +valuable. The AS mint uses `requestedScope`, so a policy returning broader claims +does not establish the scope-escalation allegation from the first review. + +### F21 - Account binding is an unsupported end-to-end capability + +P3 capability, D; v10 addition. [P2055] and [P2057] (`#account-binding`) +describe optional account selection and its propagation through resource/auth +tokens; [R378] and [R380] define R3 carriage and human-readable display. +[ResourceTokenBuilder](../../../src/AAuth/Tokens/ResourceTokenBuilder.cs), +[AuthTokenBuilder](../../../src/AAuth/Tokens/AuthTokenBuilder.cs), and +[R3Document](../../../src/AAuth.R3/Model/R3Document.cs) have no typed account +contract. Generic additional claims are not end-to-end support. Selection, +pending state, token caches, consent/prior grants, refresh, enforcement, and +R3 proposals must distinguish accounts once this capability is enabled. +Absence in a single-account deployment is not itself a vulnerability. + +## R3, Events, and bootstrap + +### F22 - Vocabulary and discovery models exclude valid shapes + +P3 capability, R; pre-existing plus Gateway in v10. [R179] requires Gateway +`service`/`operationId`; [R218] requires GraphQL `operation`/`type`; +[R236], [R257], and [R275] describe optional AsyncAPI/WSDL/OData members. +[R3Operation L74](../../../src/AAuth.R3/Model/R3Operation.cs#L74) requires one +string-valued member. MCP/OpenAPI/gRPC and minimal forms of other vocabularies +fit; it is incorrect to say six vocabularies are wholly absent. +[R3Metadata L11](../../../src/AAuth.R3/R3Metadata.cs#L11) only accepts string +discovery values, excluding the Gateway map at [R161]. The full-v10 plan defaults +to modeling all eight vocabularies while preserving third-party vocabulary extensibility. + +### F23 - Operation identity matching ignores vocabulary and member names + +P2, D/R; pre-existing. [R316] requires the advertised vocabulary; [R620] +requires authoritative operation validation; [R624] requires grant enforcement. +[Bookings L407](../../../samples/MockResourceServers/Bookings/Program.cs#L407) +checks only `operation.Id`, accepting another vocabulary or arbitrary member +with a known identifier. [R3Grant L28](../../../src/AAuth.R3/Model/R3Grant.cs#L28) +and [R3Enforcement L42](../../../src/AAuth.R3/R3Enforcement.cs#L42) also compare +bare identifiers. Qualified identity must travel through request, proposal, +grant, and execution, especially where two Gateway services reuse an operationId. + +### F24 - Bookings assumes one fixed grant policy + +P2, R; pre-existing. [R542] and [R624] distinguish unconditional grant, +conditional challenge, and rejection. [Bookings L165](../../../samples/MockResourceServers/Bookings/Program.cs#L165) +and [L189](../../../samples/MockResourceServers/Bookings/Program.cs#L189) reject +conditional search/hold grants instead of challenging; +[L214](../../../samples/MockResourceServers/Bookings/Program.cs#L214) assumes +confirmation requires proposal-retry verification even for an unconditional +grant. Current matching sample policy can hide these cases. Parameter/hash +checking itself exists and must remain mandatory on actual proposal retries +([R590], Per-Call Proposals). + +### F25 - R3 auditing can silently be disabled + +> Update (2026-09): Phase 9 removes the no-op audit default and requires an +> explicit sink. NuGet availability for Microsoft.Data.Sqlite 10.0.11 was verified +> from its flat-container nuspec before installation. The sample uses a FULL-sync +> SQLite transaction for token identity/hash plus audit metadata; endpoint, +> rollback, concurrent-write and reopen tests pass. Pending consent remains +> volatile and is not presented as crash-durable. See the Phase 9 implementation +> log for the release boundary and recovery semantics. The finding below records +> the pre-implementation state. + +P2, R; pre-existing. [R616] (Audit Log Integrity) requires audit entries +atomically with issuance. [R3AccessTokenEndpoint L60](../../../src/AAuth.R3/R3AccessTokenEndpoint.cs#L60) +awaits audit before returning a token, and pending mint-once protection exists. +However, the default [L569](../../../src/AAuth.R3/R3AccessTokenEndpoint.cs#L569) +is a no-op sink ([R3Audit L39](../../../src/AAuth.R3/R3Audit.cs#L39)). No-op +auditing cannot satisfy the requirement. Transactional or equivalent durable +semantics remain a deployment contract; absence of a database transaction alone +does not prove failure. Tests already cover audit failure and concurrent mint-once. + +### F26 - R3 document readership is a specification decision + +P3 ambiguity, R. [R446] says both PS and AS fetch R3 documents, whereas [R602] +(`#r3-document-access-restriction`) requires rejecting requests not signed by the resource's AS. +[Bookings L28](../../../samples/MockResourceServers/Bookings/Program.cs#L28) +allows both configured PS and AS; [R3DocumentEndpoint L41](../../../src/AAuth.R3/R3DocumentEndpoint.cs#L41) +does verify an explicit trust predicate. Neither blanket unrestricted-access +nor blanket AS-only compliance is accurate. Q4 records a default without +silently relaxing this requirement. [R393] and [R612] require served-byte hashes; +the default store/fetch path already preserves them, while custom callbacks are +trusted contracts and need documented verification obligations. + +### F27 - Events requires a complete companion implementation + +P3 capability, D inventory; optional until supported. [E198] (`#ap-metadata`) +conditions `event_endpoint` on Events support. No tracked project, token builder, +router, subscription store, or EventAgent exists on this branch. The complete +capability boundaries are: + +| Boundary | Exact requirement | Current state | +|---|---|---| +| AP metadata and subscribe tokens | [E198], [E214], [E277] (`#ap-metadata`, `#subscribe-token`) | No runtime implementation | +| Public/protected registration | [E294], [E304], [E603] (`#subscription-registration`, `#protected-subscriptions`) | No registration or bound single-use tickets | +| Event token and self-jwt | [E368], [E415] (`#event-token`, `#event-delivery`) | Missing scheme and typed verifier | +| Routing, quota, durable acceptance | [E418], [E421], [E424] (`#event-delivery`) | No atomic quota/outbox or delivery service | +| Agent verification and context | [E447], [E454] (`#ap-to-agent`) | No event verifier/context mapping | +| AsyncAPI discovery and R3 handoff | [E470], [E493], [R238] (`#event-discovery`, AsyncAPI Vocabulary) | No linked working flow | + +Durable recording before 202 is a MUST, not an in-memory-demo convenience. +AP-to-agent transport is explicitly implementation-specific at [E441]; a polling +or streaming example is a local profile, not a new standard. Q5 covers recurring +event deduplication and Q6 covers persistence. External platform transports and +unspecified subscription-renewal APIs must not be invented as conformance demands. + +### F28 - Optional Signature Keys capabilities need explicit dispositions + +P3 capability, D inventory. [S1021], [S1222], [S1370], and [S1429] define +`jwks`, `self-jwt`, `x509`, and `cached`. The parser supports none of them. +`self-jwt` is necessary for the included Events work ([E368]); direct `jwks` +is a useful separate mode when fixing F03. X.509 and assertion caching are +optional capability choices, not mandatory AAuth access modes. Rejection must +still be correct ([P2478]). Cache implementation would require bounded state, +expiry, cache-miss recovery, and advertisement semantics; a stub is not support. + +### F29 - AAuth access modes and generic signing modes are conflated + +> **Update (2026-09-09):** Phase 11 resolves the runtime/API ruling: retain +> agent-JWT resource-managed access per [P2420]/[P2422] (#keying-material). +> GuidedTour self-issues locally; SampleApp signs AP enrollment then refreshes +> lazily. Generic Profile signing is a separate demonstration, not that access +> mode. The complete baseline-to-current inventory and ownership/default choices +> are in [api-surface-map.md](api-surface-map.md). The earlier seed observations +> below remain historical evidence, not the current API status. + +> **Update (2026-09):** The paragraph below records the pre-implementation +> baseline. Phase 3 changed the Inbox examples to agent JWTs. The owner has +> reopened credential provenance, the pseudonymous example's intended role and +> API ergonomics for explicit review in the new Phase 11; details follow below. + +P2 documentation/sample behavior, D. [P2420] and [P2422] (`#keying-material`) +require agent/auth JWTs for AAuth resource access and restrict pseudonymous +schemes to other contexts. [Identity workflow L15](../../../docs/workflows/identity-based-access.md#L15) +teaches `hwk`, `jkt-jwt`, or `jwks_uri` as identity-based AAuth access. +[TourSession L2581](../../../samples/GuidedTour/TourSession.cs#L2581) describes +pseudonymous resource access. Generic signature demonstrations can remain, +but their routes, names, policies, and diagrams must not imply they implement +one of the four AAuth access modes. This is not just a spec-link update. + +#### Resource-managed sample revisit and API map + +The diff against implementation baseline `ba768f1` confirms that the Inbox +examples previously used `UseHwk`. Phase 3 switched the GuidedTour snippet to +`UseJwt(agentToken)` and the SampleApp runtime to explicit enrollment and an +AgentProviderTokenRefresher. These were implementation changes, not pre-existing +setup the user overlooked. The policy rationale is [P2420]/[P2422] +(`#keying-material`): an agent token is the minimum AAuth resource credential. +Resource-managed authorization still occurs at the resource; provisioning an +agent identity does not require PS/AS authorization exchange. Generic +pseudonymous HTTP signing and that AAuth access mode are distinct concepts. + +Current provenance, directly checked on 2026-09-08: + +- [GuidedTour EnsureAgentReadyAsync L1149](../../../samples/GuidedTour/TourSession.cs#L1149) + self-issues with AgentTokenBuilder at + [L1163](../../../samples/GuidedTour/TourSession.cs#L1163), using the tour's own + published identity/key. The resource-managed step calls this helper at + [L2544](../../../samples/GuidedTour/TourSession.cs#L2544); no external AP + enrollment is performed by that helper for this flow. +- [SampleApp EnrollmentService L37](../../../samples/SampleApp/EnrollmentService.cs#L37) + ensures enrollment and intentionally discards the returned agent token. + [Inbox L175](../../../samples/SampleApp/Components/Pages/Inbox.razor#L175) + wires AgentProviderTokenRefresher manually. Its + [RefreshAsync L77](../../../src/AAuth/Agent/AgentProviderTokenRefresher.cs#L77) + obtains the runtime agent token from the AP. The displayed snippet omits this + setup and uses an unexplained `refresher` variable. +- [GuidedTour snippet L220](../../../samples/GuidedTour/CodeSnippets.cs#L220) + assumes `agentToken` is already available. The Inbox server snippet still says + "verify the HTTP signature only" despite the new agent-token verification + policy. Successful browser tests do not establish instructional consistency. + +This is a seed inventory, not a completed rescan of the migration's public API. +The phase-level inventory covers later features as they are implemented. + +| Concept | Current public surface | Observed alignment concern | +|---|---|---| +| Enrolled agent token acquisition | [EnrolledBuilder L43](../../../src/AAuth/EnrolledBuilder.cs#L43): RefreshingFrom/WithKeyStore | Existing fluent style can hide required refresher plumbing without hiding that an AP call occurs | +| Resource-managed access and interaction | [EnrolledBuilder L99](../../../src/AAuth/EnrolledBuilder.cs#L99) forwards WithInteractionHandling to the main builder | No direct WithResourceManagedAccess forwarding; interaction-first chaining can reach the main builder, but natural flow-option composition needs review | +| Low-level refresh | [AgentProviderTokenRefresher L54](../../../src/AAuth/Agent/AgentProviderTokenRefresher.cs#L54) constructor and Create builder | Inbox manually constructs HttpClient and refresher; ownership and repeat-call lifecycle need coverage | +| Enrollment-result defaults | [AAuthClientBuilder L59](../../../src/AAuth/AAuthClientBuilder.cs#L59): From(EnrollResult) | Selects direct jwks when key URL/kid exist; comment says jwks_uri; default ignores intended AAuth agent-token use case | +| JWT carrier vs token purpose | [AAuthClientBuilder L176](../../../src/AAuth/AAuthClientBuilder.cs#L176): UseJwt(string agentToken) | Also used with auth tokens; parameter/comment terminology should not conflate scheme and token type | +| Server discovery vs direct key URL | [AAuthClientBuilder L189](../../../src/AAuth/AAuthClientBuilder.cs#L189): UseJwksUri, UseJwks | Distinct contracts per [S964]/[S975] and [S1021]; names, defaults and snippets must preserve that distinction | +| Self-issued agent vs self-jwt | [SelfIssuingBuilder](../../../src/AAuth/SelfIssuingBuilder.cs) and [UseSelfJwt L201](../../../src/AAuth/AAuthClientBuilder.cs#L201) | Agent provisioning still produces an agent JWT with cnf; self-jwt is a different carrier with no cnf per [E368] | + +The owner requested the convenience/builder style, not restoration of invalid +wire formats. Phase 11 resolves setup presentation and retains separately +labeled generic pseudonymous examples. Enrolled and self-issued flow options +compose directly; From uses the issued JWT, and explicit scheme/refresh +precedence is tested. Mandatory trust, account, expiry and consent context remain +required. Final verification evidence is recorded in the implementation log. + +### F30 - Documentation, fixtures, and snippets preserve obsolete contracts + +P2/P3, D. Requirements are [P2409] (algorithms), [P2304] (errors), [P1054] +(clarification), [P2363] (revocation), [S630]/[S957] (key carriers), and [P2057] +(account propagation). [Error handling L106](../../../docs/advanced/error-handling.md#L106), +[signing overview L10](../../../docs/signing-modes/overview.md#L10), +[CodeSnippets L60](../../../samples/GuidedTour/CodeSnippets.cs#L60), +[TourSession L497](../../../samples/GuidedTour/TourSession.cs#L497), and +[MockAgentProvider README L15](../../../samples/MockAgentProvider/README.md#L15) +encode old wire formats or misleading roles. [AuthTokenStructureTests L55](../../../tests/AAuth.Conformance/AuthTokens/AuthTokenStructureTests.cs#L55) +and [PersonServerMapperTests L479](../../../tests/AAuth.Conformance/Person/PersonServerMapperTests.cs#L479) +preserve old algorithm/action shapes. Compiled samples and embedded strings need +different validation: successful compilation does not check a string-literal demo. +Historical plans and immutable vendored drafts are not rewrite targets. + +### F31 - Bootstrap is informational, but its produced tokens must be valid + +P3 consistency/capability, D/R. [Bootstrap L113](../../../aauth-spec/v10/draft-hardt-aauth-bootstrap.md#L113) +and [L131](../../../aauth-spec/v10/draft-hardt-aauth-bootstrap.md#L131) explicitly +say its ceremony is not normative. Existing enrollment, key storage, attestation +hooks, and single/two-key refresh are useful. Their shared formats inherit +F01-F03/F06; [MockAgentProvider L201](../../../samples/MockAgentProvider/Program.cs#L201) +also duplicates naming-JWT verification. Platform-native attestors are extension +points, not mandatory implementations. Software/file keys must not be described +as hardware-backed. The updated example at +[Bootstrap L255](../../../aauth-spec/v10/draft-hardt-aauth-bootstrap.md#L255) +does not make the current SDK's emitted JWTs compliant by itself. + +## Coverage and preserved behavior + +This is a section-oriented audit with verified findings, not a proof of every +MUST in the draft. Absence of a finding is not a conformance verdict. Unexercised +branches and application-owned policy retain the following explicit boundaries. + +| Area | Evidence/coverage | Remaining uncertainty or preserved control | +|---|---|---| +| Core keys, headers, discovery | F01-F09 | Structured-field edge cases and injected HTTP handlers need adversarial tests | +| Agent/resource/auth JWTs | F10, F18-F21; [P1751] | Existing confirmation structure, key thumbprints, audience and scope subset checks remain; full claim negative matrix still needed | +| Identity, resource-managed, PS-asserted, federated | F12, F17, F18, F29; [P2420] | Resource-managed opaque tokens and signed owner checks exist; test identity/key/account isolation together | +| Challenges, payment, claims, deferred callbacks | F11-F15, F17; [P1543], [P2280] | Payment settlement is external; callback-code mapping exists; retry/backoff/cancellation need mixed-response integration coverage | +| Missions and governance | [P1488], [P1490]; F13, F18, F21 | Mission hash/reference echo and terminated-state paths exist; permission/audit/interaction caller ownership and unknown mission handling remain explicit final-review checks | +| Delegation/sub-agents | F18-F19; [P1511], [P1574], [P1870] | Parent-mediated three-party binding works; combined/federated cases are incomplete | +| Revocation vs request replay | F16; [P2363], [P2507] | Deny-by-default revoker config and per-signature replay exist; no universal token single-use rule | +| R3 content and operations | F22-F26; [R393], [R590], [R616], [R624] | Byte hashes, parameter checks, fail-before-release auditing and pending mint-once are existing controls | +| Events and Bootstrap | F27-F28, F31 | Events source absent on active branch; platform attestation and AP-agent transport are implementation policy | +| Five interop surfaces | [Profile L9](../../../aauth-spec/v10/interop-demo-profile.md#L9), [L45](../../../aauth-spec/v10/interop-demo-profile.md#L45) | Existing mission/R3 examples are not a substitute for four-party parent-mediated sub-agent interoperability | + +### Sample and documentation ownership map + +| Surface | Relevant findings and verification concerns | +|---|---| +| AgentConsole, LiveWhoAmITest | F01-F03, F06, F10, F29; enrollment/refresh and captured-wire interop, not just local mock agreement | +| MissionAgent, Concierge | F10-F13, F18-F21; mission bytes, chained audience, parent actor, pending ownership, cancellation | +| MockAgentProvider | F01-F03, F06, F27, F31; genuine enrollment-key proof, refresh, Events metadata and durable routing | +| MockPersonServer | F10-F21; consent/session separation, federation decisions, pending state and account-scoped grants | +| MockAccessServers/Federated | F03-F11, F14-F21; stub and Keycloak paths, no code-only bypass, claims/delegation validation | +| MockAccessServers/R3 and Bookings | F21-F27; vocabulary identity, conditional/unconditional policy variants, audit, ticket handoff | +| Profile, Calendar, Trips, Wallet, Inbox | F01-F11, F16, F20-F21, F29; all four access modes, scope definitions, ownership and key/account isolation | +| GuidedTour and SampleApp | F13-F15, F21, F27, F29-F30; Razor views, live flows, recorded exchanges, CodeSnippets and Playwright assertions | +| Root/sample/package READMEs and docs index/concepts/glossary | F29-F31; capability matrix, accurate version/roles, no unsupported claims | +| docs/signing-modes and docs/server | F01-F11, F16, F29; actual headers, strict identifiers, trust/egress, revocation and error negotiation | +| docs/workflows | F12-F29; each workflow matches the same compiled scenario, including negative outcomes | +| docs/advanced and docs/reference | F08-F28, F31; governance, key management, attestation limits, configuration, DI, observability without secrets | + +## Toolchain and validation observations + +[AAuth.csproj L4](../../../src/AAuth/AAuth.csproj#L4) targets .NET 10; +[L31](../../../src/AAuth/AAuth.csproj#L31) and +[L43](../../../src/AAuth/AAuth.csproj#L43) use Microsoft.IdentityModel.Tokens +8.18.0 and BouncyCastle.Cryptography 2.6.2. No cryptographic-library replacement +is established as necessary: wire identifiers and validation contracts are the +confirmed issues. [Test props L18](../../../tests/Directory.Build.props#L18) +pins Microsoft.NET.Test.Sdk 17.14.1, xUnit 2.9.3, and its VS runner 3.1.4. + +[Makefile L115](../../../Makefile#L115) runs only core tests for `test-unit`, +and `test-conformance` is a separate project. R3 tests are a third project, not +part of either target. [CI L26](../../../.github/workflows/ci.yml#L26) runs +the solution tests. [Playwright L44](../../../tests/e2e/playwright.config.ts#L44) +defines two UI projects with shared servers; Keycloak is opt-in, and neither +Events nor a new sub-agent interop flow is automatically covered. + +The editor test tool found no tests for the selected C# files. Direct `dotnet test` +was therefore used for AuthTokenStructureTests/PersonServerMapperTests and +ResourceR3Tests/AccessEndpointR3Tests. Quiet invocations returned no summary; +the detailed completion summaries were subsequently checked: + +| Focused baseline | Result | +|---|---| +| AuthTokenStructureTests and PersonServerMapperTests | 37 passed, zero failed | +| ResourceR3Tests and AccessEndpointR3Tests | 25 passed, zero failed | + +Both builds reported zero warnings/errors. These 62 passing existing tests +establish a baseline, not v10 compliance or reproduction of every finding. +No full-solution test run, browser run, live interop, load test, or exploit +reproduction is claimed. + +## Gaps and open questions + +These are proposed defaults for the implementation decision gate, not approved +decisions. Rulings belong in the future implementation log. + +| ID | Question and evidence | Proposed default | +|---|---|---| +| Q1 | Capability breadth: optional Events [E198], all R3 vocabularies [R179], optional schemes [S1370]/[S1429] | Include account binding, all eight R3 models, AS clarification, Events, self-jwt and direct jwks. Defer x509/cached with accurate unsupported-scheme behavior and documented boundaries; do not inherit the old v09 exclusions silently | +| Q2 | Protocol [P2420] profiles agent JWT access, but the PS-to-AS example [P1523] contains obsolete jwks_uri syntax | Use normative Signature Keys [S964]/[S975] for non-agent server signing; keep AAuth agent requests jwt. Record the PS-AS profile interpretation and report the stale example upstream | +| Q3 | Production identifiers/egress [P2529], [P2521] vs existing HTTP localhost demos | Strict production defaults, an explicit development policy limited to configured loopback origins, no global permissive fallback | +| Q4 | R3 PS readership [R446] vs AS-only [R602] | Default resource documents to authenticated designated-AS access; provide an explicitly configured PS evaluation role only with a logged interpretation, pending upstream clarification | +| Q5 | Events uses one eid for a subscription [E229], but deduplicates by eid/iss [E454]; raw body [E389] (`#event-delivery`) vs payload-field privacy text [E625] | Ship a single-shot sample first; enforce the stated deduplication rule, do not invent a wire event-id. Follow delivery-section raw body. Recurring-event semantics require a recorded ruling; expired events never trigger action per [E366] | +| Q6 | Durable acceptance [E424], atomic quota [E421], R3 audit [R616] | Reusable persistent store contracts and a transactional local sample provider; pin any new persistence package only after checking existing branch work and license/runtime support. No in-memory production durability claim | +| Q7 | Browser approval cannot rely on code [P2136] | Authenticated decision session and CSRF protection; stub identity available only in an explicit isolated demo mode; no bypass endpoints in Keycloak mode | +| Q8 | Agent-expiry observability [P1344], federation delivery binding [P1574] | Carry verified ceilings/context through issuer and pending state; no unverifiable resource lookup or invented public claim; reject stale agent context before minting | +| Q9 | Prior Events work exists on another branch; active solution has none | Inspect and selectively reuse verified source, tests, and persistence choices, adapting to v10. Do not merge/cherry-pick an entire branch without approval | +| Q10 | Structured fields and signature extensions [S430], [P2445] | Prefer an existing maintained RFC parser/library where suitable; retain current crypto primitives. Pin a choice only after a small compatibility test for labels, parameter types, escaping, and additional covered components | + +## Synthesis + +The common dependencies are typed verified-token context, admitted discovery, +exact wire models, and state transitions that preserve owner/key/account/expiry. +They cross package boundaries: an Events implementation cannot safely reuse +F05, account support cannot stop at token properties, and R3 Gateway cannot +retain bare-id equality. Compiled samples move with each API change; a final +non-compiled documentation sweep follows the frozen code surface. + +The companion [implementation plan](implementation-plan.md) maps every finding +to a phase, carries the unresolved interpretations through Phase 0, and includes +final independent review of the coverage limits above. + +[P934]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L934 +[P1054]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1054 +[P1099]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1099 +[P1344]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1344 +[P1488]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1488 +[P1490]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1490 +[P1511]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1511 +[P1523]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1523 +[P1543]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1543 +[P1546]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1546 +[P1574]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1574 +[P1708]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1708 +[P1751]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1751 +[P1753]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1753 +[P1770]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1770 +[P1809]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1809 +[P1870]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L1870 +[P2041]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2041 +[P2055]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2055 +[P2057]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2057 +[P2132]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2132 +[P2134]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2134 +[P2136]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2136 +[P2138]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2138 +[P2140]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2140 +[P2142]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2142 +[P2280]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2280 +[P2304]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2304 +[P2306]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2306 +[P2309]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2309 +[P2361]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2361 +[P2363]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2363 +[P2382]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2382 +[P2390]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2390 +[P2393]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2393 +[P2405]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2405 +[P2409]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2409 +[P2412]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2412 +[P2420]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2420 +[P2422]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2422 +[P2445]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2445 +[P2467]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2467 +[P2469]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2469 +[P2475]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2475 +[P2478]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2478 +[P2479]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2479 +[P2487]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2487 +[P2489]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2489 +[P2505]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2505 +[P2507]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2507 +[P2515]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2515 +[P2517]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2517 +[P2521]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2521 +[P2529]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2529 +[P2548]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2548 +[P2825]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2825 +[P2826]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2826 +[P2863]: ../../../aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md#L2863 +[S430]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L430 +[S437]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L437 +[S630]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L630 +[S641]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L641 +[S647]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L647 +[S660]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L660 +[S690]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L690 +[S789]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L789 +[S917]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L917 +[S957]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L957 +[S964]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L964 +[S975]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L975 +[S979]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L979 +[S1021]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1021 +[S1160]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1160 +[S1186]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1186 +[S1953]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1953 +[S1222]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1222 +[S1370]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1370 +[S1429]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L1429 +[S2372]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2372 +[S2997]: ../../../aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt#L2997 +[R161]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L161 +[R179]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L179 +[R218]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L218 +[R236]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L236 +[R238]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L238 +[R257]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L257 +[R275]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L275 +[R316]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L316 +[R378]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L378 +[R380]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L380 +[R393]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L393 +[R446]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L446 +[R542]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L542 +[R590]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L590 +[R602]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L602 +[R612]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L612 +[R616]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L616 +[R620]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L620 +[R624]: ../../../aauth-spec/v10/draft-hardt-aauth-r3.md#L624 +[E198]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L198 +[E214]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L214 +[E229]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L229 +[E277]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L277 +[E294]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L294 +[E304]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L304 +[E366]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L366 +[E368]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L368 +[E389]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L389 +[E415]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L415 +[E418]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L418 +[E421]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L421 +[E424]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L424 +[E441]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L441 +[E447]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L447 +[E454]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L454 +[E470]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L470 +[E493]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L493 +[E603]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L603 +[E625]: ../../../aauth-spec/v10/draft-hardt-aauth-events.md#L625 \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 58808912..6e5846b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,6 +26,9 @@ jobs: - name: Test run: dotnet test AAuth.slnx --no-build -c Release --logger "trx;LogFileName=results.trx" + - name: Events HTTP and persistence gate + run: dotnet test tests/AAuth.Events.Tests/AAuth.Events.Tests.csproj --no-build -c Release + e2e: needs: build runs-on: ubuntu-latest diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a4390778..ea327e7f 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -39,6 +39,7 @@ jobs: run: | dotnet pack src/AAuth/AAuth.csproj -c Release -p:PackageVersion=${{ inputs.version }} -o ./nupkg dotnet pack src/AAuth.R3/AAuth.R3.csproj -c Release -p:PackageVersion=${{ inputs.version }} -o ./nupkg + dotnet pack src/AAuth.Events/AAuth.Events.csproj -c Release -p:PackageVersion=${{ inputs.version }} -o ./nupkg - name: NuGet login (OIDC trusted publishing) if: ${{ inputs.dry-run == false }} diff --git a/AAuth.slnx b/AAuth.slnx index d0b0e44a..fc97cb6c 100644 --- a/AAuth.slnx +++ b/AAuth.slnx @@ -1,7 +1,10 @@ + + + @@ -12,6 +15,8 @@ + + @@ -23,11 +28,16 @@ + + + + + diff --git a/Makefile b/Makefile index b83d8276..f8a60e9a 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,8 @@ TRIPS_PROJECT := samples/MockResourceServers/Trips/Trips.csproj WALLET_PROJECT := samples/MockResourceServers/Wallet/Wallet.csproj INBOX_PROJECT := samples/MockResourceServers/Inbox/Inbox.csproj BOOKINGS_PROJECT := samples/MockResourceServers/Bookings/Bookings.csproj +CATALOG_PROJECT := samples/MockResourceServers/Catalog/Catalog.csproj +DOCUMENTS_PROJECT := samples/MockResourceServers/Documents/Documents.csproj PS_PROJECT := samples/MockPersonServer/MockPersonServer.csproj AP_PROJECT := samples/MockAgentProvider/MockAgentProvider.csproj TOUR_PROJECT := samples/GuidedTour/GuidedTour.csproj @@ -22,6 +24,7 @@ LIVE_PROJECT := samples/LiveWhoAmITest/LiveWhoAmITest.csproj MISSION_PROJECT := samples/MissionAgent/MissionAgent.csproj AS_PROJECT := samples/MockAccessServers/Federated/Federated.csproj R3AS_PROJECT := samples/MockAccessServers/R3/R3.csproj +EVENT_AGENT_PROJECT := samples/EventAgent/EventAgent.csproj PROFILE_URL := http://localhost:5000 CALENDAR_URL := http://localhost:5001 @@ -29,6 +32,8 @@ TRIPS_URL := http://localhost:5002 WALLET_URL := http://localhost:5003 INBOX_URL := http://localhost:5004 BOOKINGS_URL := http://localhost:5005 +CATALOG_URL := http://localhost:5006 +DOCUMENTS_URL := http://localhost:5007 PS_URL := http://localhost:5100 AP_URL := http://localhost:5301 CONCIERGE_URL := http://localhost:5200 @@ -40,6 +45,13 @@ KEYCLOAK_URL := http://localhost:8080 KEYCLOAK_IMAGE := quay.io/keycloak/keycloak:26.0 KEYCLOAK_REALM := samples/MockAccessServers/Federated/keycloak +# Keep draft-10 demo credentials separate from keys created by earlier drafts. +USER_HOME := $(HOME) +USER_DATA_HOME := $(or $(XDG_DATA_HOME),$(USER_HOME)/.local/share) +DEMO_HOME ?= $(USER_DATA_HOME)/aauth-samples/v10/home +DEMO_DOTNET_HOME := $(or $(DOTNET_CLI_HOME),$(USER_HOME)) +DEMO_NUGET_PACKAGES := $(or $(NUGET_PACKAGES),$(USER_HOME)/.nuget/packages) + # AgentConsole persists its enrollment under $LocalApplicationData; the MockAgentProvider # keeps its agent registry in memory, so the cache goes stale whenever the AP restarts. AGENT_CACHE_DIR := $(or $(XDG_DATA_HOME),$(HOME)/.local/share)/aauth-agent-console @@ -69,7 +81,20 @@ endef .DEFAULT_GOAL := help -.PHONY: help build restore test test-unit test-conformance format clean \ +demo demo-mission demo-keycloak ps-consent resources: export AAuth__EnableIsolatedDemoConsent=true +demo demo-mission demo-keycloak: export HOME = $(DEMO_HOME) +demo demo-mission demo-keycloak: export XDG_DATA_HOME = $(DEMO_HOME)/.local/share +demo demo-mission demo-keycloak: export DOTNET_CLI_HOME := $(DEMO_DOTNET_HOME) +demo demo-mission demo-keycloak: export NUGET_PACKAGES := $(DEMO_NUGET_PACKAGES) +demo demo-mission demo-keycloak: demo-state + +.PHONY: demo-state +demo-state: + @mkdir -p "$(DEMO_HOME)" "$(DEMO_HOME)/.local/share" + @chmod 700 "$(DEMO_HOME)" "$(DEMO_HOME)/.local/share" + @echo "Demo state: $(DEMO_HOME) (override with DEMO_HOME=...)" + +.PHONY: help build restore test test-unit test-conformance test-events agent-events format clean \ resources ps ps-consent ap concierge tour sampleapp agent live \ demo demo-mission agent-mission \ keycloak access-server demo-keycloak \ @@ -100,6 +125,12 @@ test-unit: ## Run SDK unit + integration tests only test-conformance: ## Run spec conformance tests only $(DOTNET) test tests/AAuth.Conformance/AAuth.Conformance.csproj +test-events: ## Run Events token, HTTP and persistence tests + $(DOTNET) test tests/AAuth.Events.Tests/AAuth.Events.Tests.csproj + +agent-events: ## Run the single-shot Events agent (ARGS=--protected for account-bound consent) + $(DOTNET) run --project $(EVENT_AGENT_PROJECT) -- $(ARGS) + format: ## Apply dotnet format to the solution $(DOTNET) format $(SOLUTION) @@ -111,7 +142,7 @@ clean: ## dotnet clean + remove bin/ obj/ trees # Individual services & apps # ---------------------------------------------------------------------------- -resources: ## Run the Aria resource servers (Profile :5000, Calendar :5001, Trips :5002, Wallet :5003, Inbox :5004, Bookings :5005) +resources: ## Run the Aria resource servers (Profile :5000 through Documents :5007) @echo "Building services (once) before launch..." @$(DOTNET) build $(SOLUTION) -v q @trap 'trap - INT TERM; echo; echo "Stopping..."; kill 0' INT TERM; \ @@ -121,6 +152,8 @@ resources: ## Run the Aria resource servers (Profile :5000, Calendar :5001, Trip $(DOTNET) run --no-build --project $(WALLET_PROJECT) & \ $(DOTNET) run --no-build --project $(INBOX_PROJECT) & \ $(DOTNET) run --no-build --project $(BOOKINGS_PROJECT) & \ + $(DOTNET) run --no-build --project $(CATALOG_PROJECT) & \ + $(DOTNET) run --no-build --project $(DOCUMENTS_PROJECT) & \ wait ps: ## Run the MockPersonServer (port 5100) @@ -162,6 +195,8 @@ demo: ## Start the full stack + stub Access Server + both UIs (all flows incl. f @echo " Wallet: $(WALLET_URL) (four-party resource server)" @echo " Inbox: $(INBOX_URL) (resource-managed two-party server)" @echo " Bookings: $(BOOKINGS_URL) (R3 reservations resource server)" + @echo " Travel Catalog: $(CATALOG_URL) (service-qualified R3 gateway)" + @echo " Document Release: $(DOCUMENTS_URL) (resource permission before PS consent)" @echo " Concierge: $(CONCIERGE_URL) (mission concierge)" @echo " MockPersonServer: $(PS_URL) (RequireConsent=true)" @echo " MockAgentProvider: $(AP_URL) (agent registry)" @@ -183,6 +218,8 @@ demo: ## Start the full stack + stub Access Server + both UIs (all flows incl. f $(DOTNET) run --no-build --project $(WALLET_PROJECT) & \ $(DOTNET) run --no-build --project $(INBOX_PROJECT) & \ $(DOTNET) run --no-build --project $(BOOKINGS_PROJECT) & \ + $(DOTNET) run --no-build --project $(CATALOG_PROJECT) & \ + $(DOTNET) run --no-build --project $(DOCUMENTS_PROJECT) & \ $(DOTNET) run --no-build --project $(CONCIERGE_PROJECT) & \ $(DOTNET) run --no-build --project $(AP_PROJECT) & \ AccessServer__PolicyProvider=stub AccessServer__RequireConsent=true $(DOTNET) run --no-build --project $(AS_PROJECT) & \ @@ -240,8 +277,13 @@ demo-keycloak: ## Four-party federated demo (both UIs) with the live Keycloak po $(DOTNET) run --no-build --project $(CALENDAR_PROJECT) & \ $(DOTNET) run --no-build --project $(TRIPS_PROJECT) & \ $(DOTNET) run --no-build --project $(WALLET_PROJECT) & \ + $(DOTNET) run --no-build --project $(INBOX_PROJECT) & \ + $(DOTNET) run --no-build --project $(BOOKINGS_PROJECT) & \ + $(DOTNET) run --no-build --project $(CATALOG_PROJECT) & \ + $(DOTNET) run --no-build --project $(DOCUMENTS_PROJECT) & \ + $(DOTNET) run --no-build --project $(R3AS_PROJECT) & \ $(DOTNET) run --no-build --project $(CONCIERGE_PROJECT) & \ - MockPersonServer__RequireConsent=true $(DOTNET) run --no-build --project $(PS_PROJECT) & \ + MockPersonServer__RequireConsent=true MockPersonServer__TrustedAccessServers__0=$(AS_URL) MockPersonServer__TrustedAccessServers__1=$(R3AS_URL) $(DOTNET) run --no-build --project $(PS_PROJECT) & \ $(DOTNET) run --no-build --project $(AP_PROJECT) & \ $(KEYCLOAK_AS_ENV) \ $(DOTNET) run --no-build --project $(AS_PROJECT) & \ diff --git a/README.md b/README.md index bfc0332f..8eb2d508 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# AAuth SDK for .NET +--- +title: AAuth SDK for .NET +description: AAuth SDK for .NET, companion packages and runnable protocol demonstrations. +--- [![CI](https://github.com/aauth-dev/dotnet-samples/actions/workflows/ci.yml/badge.svg)](https://github.com/aauth-dev/dotnet-samples/actions/workflows/ci.yml) [![NuGet](https://img.shields.io/nuget/vpre/AAuth)](https://www.nuget.org/packages/AAuth) @@ -11,7 +14,7 @@ The [AAuth protocol](https://aauth.dev) SDK for .NET — agent-to-resource autho ## What is AAuth? -AAuth is a four-party authorization protocol for AI agents. Every HTTP request carries a cryptographic signature — there are no bearer tokens. See the [protocol spec](aauth-spec/v08/draft-hardt-oauth-aauth-protocol.md) for full details. +AAuth is a four-party authorization protocol for AI agents. Every HTTP request carries a cryptographic signature; protocol tokens are proof-of-possession bound. See the [protocol spec](aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md) for full details. The four parties are: @@ -22,7 +25,13 @@ The four parties are: > **Agent Provider (AP)** is a supporting role that issues `aa-agent+jwt` tokens binding an agent's signing key to its identity. -The SDK supports all four signing modes (`hwk`, `jwks_uri`, `jwt`, `jkt-jwt`), the full three-party challenge/exchange flow (autonomous and deferred user-consent), signature verification middleware, resource & auth token builders, JWKS / metadata discovery, and a Blazor `GuidedTour` walk-through. See the [SDK documentation](docs/) for complete usage guides. +The SDK supports six Signature-Key schemes (`hwk`, `jkt-jwt`, `jwks_uri`, `jwks`, `jwt`, `self-jwt`). AAuth agent requests use `jwt` across all four resource access modes; the other schemes serve server signing, AP ceremonies, Events or explicit generic demonstrations. The SDK includes challenge/exchange flows, verification middleware, token builders, admitted discovery and a Blazor `GuidedTour`. See the [SDK documentation](docs/) for usage guides. + +The [AAuth.Events companion](src/AAuth.Events/README.md) adds subscribe tokens, +`self-jwt` event delivery, durable provider contracts and agent verification. +Run its six-step flow in either app at `/events`, or use `make agent-events` +after starting the stack. See [Events](docs/workflows/events.md) for transport, +persistence and draft limitations. ## Access Modes @@ -30,8 +39,8 @@ AAuth supports four resource access modes. Each adds parties and capabilities, a | Mode | Parties | When to Use | Signing | See it in the demos | |------|---------|-------------|---------|---------------------| -| **Identity-Based** | Agent + Resource | Replacing API keys with cryptographic identity | `hwk` / `jwks_uri` | GuidedTour → [**Identity-based**](http://localhost:5400/tour?flow=Identity); SampleApp → [`/pseudonymous`](http://localhost:5240/pseudonymous) and [`/identified`](http://localhost:5240/identified) | -| **Resource-Managed** (two-party) | Agent + Resource | Resource manages authorization itself (interaction, OAuth/OIDC, internal policy) without an external PS or AS | Any | GuidedTour → [**Resource-Managed (Two-Party)**](http://localhost:5400/tour?flow=ResourceManaged); SampleApp → [`/inbox`](http://localhost:5240/inbox) | +| **Identity-Based** | Agent + Resource | Resource authorizes verified agent identity | `jwt` | Profile `/identified` accepts agent JWT; generic signing demonstrations are separate | +| **Resource-Managed** (two-party) | Agent + Resource | Resource manages authorization without an external PS or AS | `jwt` plus opaque AAuth-Access | GuidedTour → [**Resource-Managed (Two-Party)**](http://localhost:5400/tour?flow=ResourceManaged); SampleApp → [`/inbox`](http://localhost:5240/inbox) | | **PS-Asserted** (three-party) | Agent + Resource + PS | Resource accepts identity claims (`sub`, `email`, `tenant`, `groups`, `roles`) from any Person Server | `jwt` | GuidedTour → [**PS-Asserted (Direct Grant)**](http://localhost:5400/tour?flow=Autonomous) and [**PS-Asserted (Deferred)**](http://localhost:5400/tour?flow=Deferred); SampleApp → [`/calendar`](http://localhost:5240/calendar) and [`/calendar-deferred`](http://localhost:5240/calendar-deferred) | | **Federated** (four-party) | Agent + Resource + PS + AS | Cross-domain access with the resource's own Access Server enforcing policy | `jwt` | GuidedTour → [**Federated (Four-Party)**](http://localhost:5400/tour?flow=Federated); SampleApp → [`/wallet`](http://localhost:5240/wallet). Live Keycloak consent: `make demo-keycloak` | @@ -58,7 +67,10 @@ Step-by-step walk-through showing every HTTP exchange, header, and token claim a ### Sample App — http://localhost:5240 -Self-contained Blazor app with one page per AAuth flow (HWK, JWKS URI, resource-managed Inbox, JWT direct grant, deferred user consent, call-chain multi-agent delegation, four-party federated). +Self-contained Blazor app with AAuth authorization flows and separately labeled +generic signing demonstrations. Both apps include +[Wallet Protocol](docs/workflows/wallet-protocol.md), +[Catalog Gateway](docs/workflows/catalog-gateway.md), account-bound Bookings and Events. ![Sample App](samples/SampleApp/sample-app.png) @@ -85,23 +97,31 @@ dotnet build AAuth.slnx dotnet add package AAuth --prerelease ``` -The simplest mode is **pseudonymous (HWK)** — the agent signs every request with an inline public key. No Agent Provider, no Person Server, no registration. The resource sees a stable key thumbprint it can use for rate-limiting or access control, but doesn't know the agent's identity. +An enrolled agent uses an AP-issued agent JWT and proves possession of its +locally held key. Replace the example HTTPS endpoints with your configured +provider and resource. For the runnable loopback configuration, use the +[sample setup](samples/README.md#network-admission). ```csharp using AAuth.Crypto; using AAuth; -var key = AAuthKey.Generate(); // Ed25519 keypair - -using var client = new AAuthClientBuilder(key) - .UseHwk() // Pseudonymous mode: inline public key in Signature-Key header +var keyStore = FileKeyStore.Default(); +var key = keyStore.LoadOrCreate("my-agent"); +var enrollment = await AAuthClientBuilder.Bootstrap("https://ap.example/enrol") + .WithKey(key).WithKeyStore(keyStore).EnrolAsync(); +using var client = AAuthClientBuilder.Enrolled(key) + .RefreshingFrom("https://ap.example/refresh", enrollment.LocalKeyHandle!) + .WithKeyStore(keyStore) .Build(); var response = await client.GetAsync("https://resource.example/data"); -// Request is signed per RFC 9421 — the resource verifies the signature -// using the public key from the Signature-Key: sig=hwk;jkt="...";jwk="..." header +// Signature-Key: sig=jwt;jwt="" ``` +Generic [HWK signing](docs/signing-modes/pseudonymous-hwk.md) remains available +for explicitly generic Signature Keys endpoints; it is not an AAuth access mode. + ### Three-Party Flow (Agent → Resource → Person Server) The PS-Asserted flow is the primary authorization model. The resource delegates authorization to the agent's Person Server, which prompts the user for consent: @@ -224,7 +244,7 @@ var app = builder.Build(); app.MapAAuthAgentWellKnown(new AAuthAgentMetadataOptions { Issuer = issuer, - SigningKeys = new Dictionary { [Kid] = key }, + SigningKeys = new Dictionary { [Kid] = key }, }); // Build signed client with automatic token refresh and challenge handling @@ -245,7 +265,7 @@ Full SDK documentation lives in [`docs/`](docs/): - [Getting Started](docs/getting-started.md) — install, generate a key, three-party flow deep dive, enrollment models - [Concepts](docs/concepts.md) — the four participants and how the SDK maps to them - [Glossary & Acronyms](docs/glossary.md) — every acronym and short protocol term used across the repo -- [Signing Modes](docs/signing-modes/overview.md) — hwk, jwks_uri, jwt, jkt-jwt +- [Signing Modes](docs/signing-modes/overview.md) - six carriers, distinct from four AAuth access modes - [Workflows](docs/workflows/identity-based-access.md) — identity-based, PS-asserted, federated - [Server Guide](docs/server/verification-middleware.md) — verification middleware, token issuance - [Configuration Reference](docs/reference/configuration.md) @@ -264,21 +284,37 @@ dotnet test tests/AAuth.Conformance # spec conformance suite only |------|-------------| | [src/AAuth/](src/AAuth/) | AAuth SDK library (the NuGet package) | | [docs/](docs/) | SDK documentation — signing modes, workflows, server guides | -| [samples/](samples/) | Sample applications — Profile, Calendar, Trips, Wallet, Inbox resource servers, Concierge, AgentConsole, MockPersonServer, MockAgentProvider, GuidedTour, SampleApp | +| [samples/](samples/) | Seven focused resources including Bookings and Catalog, PS/AS/AP hosts, console agents, GuidedTour and SampleApp | | [tests/](tests/) | Unit, integration, and spec-conformance tests | -| [aauth-spec/](aauth-spec/) | Protocol specifications (drafts 01, 02, and 08) from [dickhardt/AAuth](https://github.com/dickhardt/AAuth) | +| [aauth-spec/](aauth-spec/) | Immutable protocol snapshots 01, 02, 08, 09 and 10 with pinned companion drafts | ## Spec Compatibility -This SDK targets **draft-08** of the AAuth protocol specification: +This SDK targets **draft-10** of the AAuth protocol specification: | Spec | Draft | |------|-------| -| [draft-hardt-oauth-aauth-protocol](aauth-spec/v08/draft-hardt-oauth-aauth-protocol.md) | 08 | -| [draft-hardt-aauth-bootstrap](aauth-spec/v08/draft-hardt-aauth-bootstrap.md) | 01 | -| [draft-hardt-aauth-r3](aauth-spec/v08/draft-hardt-aauth-r3.md) | 00 | - -The protocol tracks IETF **draft-08** ([`aauth-spec/v08/`](aauth-spec/v08/), source commit [`dd2b852`](https://github.com/dickhardt/AAuth/commit/dd2b8524eb8a6beb1a6cd922f285cc8bd0464cd8), 2026-06-25). Earlier draft-02 ([`aauth-spec/v02/`](aauth-spec/v02/)) and draft-01 ([`aauth-spec/v01/`](aauth-spec/v01/)) snapshots are retained for reference. All four resource access modes — including the `AAuth-Access` opaque-token flow (resource-managed, two-party access) — are implemented. See [SPEC-VERSION.md](aauth-spec/SPEC-VERSION.md) and [aauth-spec/CHANGELOG.md](aauth-spec/CHANGELOG.md) for details. +| [AAuth protocol](aauth-spec/v10/draft-hardt-oauth-aauth-protocol.md) | 10 | +| [Bootstrap](aauth-spec/v10/draft-hardt-aauth-bootstrap.md) | 02, informational | +| [Rich Resource Requests](aauth-spec/v10/draft-hardt-aauth-r3.md) | 01 | +| [Events](aauth-spec/v10/draft-hardt-aauth-events.md) | 00, revised | +| [HTTP Signature Keys](aauth-spec/v10/draft-hardt-httpbis-signature-key-08.txt) | 08 | + +The pinned source is commit `9dee49fbf49074d1460d0a7c0670bf355aef5e1e`, +published 2026-08-06. All four access modes, account binding, AS clarification, +issuer-qualified revocation and parent-mediated four-party delegation are +implemented. Optional X.509/cached carriers and third-party login hosting are +not implemented. Platform attestation, production stores/policies and native +push transports remain deployment responsibilities. Events uses single-shot +sample delivery with literal issuer/eid deduplication; recurring-event ambiguity +is not hidden by the supported-carrier claim. + +Local Release and both policy-mode browser gates pass. External whoami identity +access succeeds, but its scoped endpoint returned `person-token` rather than the +pinned `auth-token` challenge; full external authorization interop is not claimed. +See [SPEC-VERSION](aauth-spec/SPEC-VERSION.md), +[snapshot history](aauth-spec/CHANGELOG.md), and the +[conformance dispositions](.agent/plans/2026-09-08-aauth-v10-spec-migration/conformance-ledger.md). ## Contributing diff --git a/aauth-agent-console/aauth:demo@ap.example.json b/aauth-agent-console/aauth:demo@ap.example.json new file mode 100644 index 00000000..6e644541 --- /dev/null +++ b/aauth-agent-console/aauth:demo@ap.example.json @@ -0,0 +1 @@ +{"key_id":"GtR1WdoAqH-5aKu4b4SMQ7nT--gfWslLzUJxE2FzQbM","agent_token_kid":"3754cbeb08c249e8bdde24e3f8acb52c","jwks_uri":"http://localhost:5301/agents/aauth%3Aagent-b420e9f196d5d65029a7f38d435fe30cf94ee8a64282b694fad2549dd6153f5b%40localhost/jwks.json","refresh_endpoint":"http://localhost:5301/refresh"} \ No newline at end of file diff --git a/aauth-spec/CHANGELOG.md b/aauth-spec/CHANGELOG.md index a7511089..2a41bc1f 100644 --- a/aauth-spec/CHANGELOG.md +++ b/aauth-spec/CHANGELOG.md @@ -6,29 +6,60 @@ High-fidelity record of what changed between the vendored AAuth specification snapshots in this repository. Each snapshot is a self-contained folder; see [`SPEC-VERSION.md`](SPEC-VERSION.md) for source commits and metadata. -Entries are grouped by snapshot folder, so every document in a release (protocol, -R3, bootstrap) is listed together and a change to R3 or bootstrap travels with the -protocol version it shipped in. +Entries are grouped by snapshot folder, so every document in a release +(protocol, R3, bootstrap, and companion documents) is listed together and a +companion change travels with the protocol version it shipped in. Section and line references in the **`v02/`** entry point into the draft-02 files under [`v02/`](v02/) (commit `feda56b`); references in the **`v08/`** entry point -into the draft-08 files under [`v08/`](v08/) (commit `dd2b852`). Anchors in -parentheses (e.g. `#sub-agents`) are the spec's own kramdown anchors and are stable -across line shifts. - -| Snapshot | Protocol | Bootstrap | R3 | Source commit | -|---|---|---|---|---| -| [`v01/`](v01/) | draft-01 | draft-01 | draft-00 | `c090879` (2026-05-11) | -| [`v02/`](v02/) | draft-02 | draft-01 (unchanged) | draft-00 (revised) | `feda56b` (2026-06-09) | -| [`v08/`](v08/) | draft-08 | draft-01 (unchanged) | draft-00 (unchanged) | `dd2b852` (2026-06-25) | - -> **The SDK code targets `v02/` (draft-02).** The `v08/` snapshot was vendored -> 2026-06-25 as the latest upstream reference; migrating the SDK to draft-08 is -> tracked separately and has not started. See -> [`SPEC-VERSION.md`](SPEC-VERSION.md). +into the draft-08 files under [`v08/`](v08/) (commit `dd2b852`); references in the +**`v09/`** entry point into the draft-09 files under [`v09/`](v09/) (commit +`90089f8`); references in the **`v10/`** entry point into the draft-10 files under +[`v10/`](v10/) (commit `9dee49f`). Anchors in parentheses (e.g. `#sub-agents`) +are the spec's own kramdown anchors and are stable across line shifts. + +| Snapshot | Protocol | Bootstrap | R3 | Interop profile | Events | Source commit | +|---|---|---|---|---|---|---| +| [`v01/`](v01/) | draft-01 | draft-01 | draft-00 | — | — | `c090879` (2026-05-11) | +| [`v02/`](v02/) | draft-02 | draft-01 (unchanged) | draft-00 (revised) | — | — | `feda56b` (2026-06-09) | +| [`v08/`](v08/) | draft-08 | draft-01 (unchanged) | draft-00 (unchanged) | new | — | `dd2b852` (2026-06-25) | +| [`v09/`](v09/) | draft-09 | draft-01 (unchanged) | draft-00 (revised) | unchanged | draft-00 (new) | `90089f8` (2026-07-05) | +| [`v10/`](v10/) | draft-10 | draft-02 (revised) | draft-01 (revised) | unchanged | draft-00 (revised) | `9dee49f` (2026-08-06) | + +> The SDK code targets `v10/` (draft-10) after the separately verified 2026-09-09 +> migration. The snapshot was vendored 2026-09-08 and remains byte-unchanged. +> All four access modes and local four-party sub-agent scenarios are implemented; +> optional exclusions and incomplete external authorization interop remain explicit. +> See [SPEC-VERSION](SPEC-VERSION.md) and the +> [migration evidence](../.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-log.md). +> Historical per-snapshot entries below describe their original publication state. ## Contents +- [`v10/` — AAuth draft-10 snapshot](#v10--aauth-draft-10-snapshot) + - [Protocol (draft-10)](#protocol-draft-10) + - [1. Fully specified algorithms and keys](#1-fully-specified-algorithms-and-keys) + - [2. Signature verification and errors](#2-signature-verification-and-errors) + - [3. Revocation identity and routing](#3-revocation-identity-and-routing) + - [4. Directed subject handling](#4-directed-subject-handling) + - [5. Account binding](#5-account-binding) + - [R3 (draft-01)](#r3-draft-01) + - [AAuth Events (revised draft-00)](#aauth-events-revised-draft-00) + - [Bootstrap (draft-02)](#bootstrap-draft-02) + - [Interoperability Demo Profile (unchanged)](#interoperability-demo-profile-unchanged) + - [HTTP Signature Keys (draft-08)](#http-signature-keys-draft-08) + - [Author's verbatim changelog (draft-10)](#authors-verbatim-changelog-draft-10) +- [`v09/` — AAuth draft-09 snapshot](#v09--aauth-draft-09-snapshot) + - [Protocol (draft-09)](#protocol-draft-09) + - [1. Clarification response discriminator](#1-clarification-response-discriminator) + - [2. RFC 9457 error responses](#2-rfc-9457-error-responses) + - [3. AAuth Events integration](#3-aauth-events-integration) + - [4. Editorial and implementation-status changes](#4-editorial-and-implementation-status-changes) + - [AAuth Events (new companion draft)](#aauth-events-new-companion-draft) + - [R3 (revised)](#r3-revised) + - [Bootstrap and Interoperability Demo Profile (unchanged)](#bootstrap-and-interoperability-demo-profile-unchanged) + - [HTTP Signature Keys (draft-06)](#http-signature-keys-draft-06) + - [Author's verbatim changelog (draft-09)](#authors-verbatim-changelog-draft-09) - [`v08/` — AAuth draft-08 snapshot](#v08--aauth-draft-08-snapshot) - [Protocol (drafts 03–08)](#protocol-drafts-0308) - [1. Agent-delegation restructure](#1-agent-delegation-restructure) @@ -56,6 +87,301 @@ across line shifts. --- +## `v10/` — AAuth draft-10 snapshot + +The latest upstream snapshot, vendored 2026-09-08 for reference. It bundles +protocol **draft-10** with R3 **draft-01**, Bootstrap **draft-02**, revised AAuth +Events **draft-00**, the unchanged Interoperability Demo Profile, and HTTP +Signature Keys **draft-08**. + +> **The SDK continues to target draft-08.** Draft-09 and draft-10 migrations are +> separate implementation work. + +### Protocol (draft-10) + +Published as IETF +[draft-hardt-oauth-aauth-protocol-10](https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/10/) +(commit `9dee49f`, source frontmatter date 2026-06-17, IETF publication date +2026-08-06). The author's verbatim draft-10 changelog is reproduced below. + +#### 1. Fully specified algorithms and keys + +The HTTP Message Signatures profile now requires algorithms to be explicit and +unambiguous (`#signature-algorithms`, `#keying-material`): + +- Every conveyed or referenced key MUST carry a fully specified `alg`. +- `Ed25519` replaces the deprecated polymorphic `EdDSA`; `none`, symmetric + algorithms, and algorithms prohibited by the JOSE registry MUST NOT be used. +- A verifier MUST reject a key whose `kty` or `crv` disagrees with `alg`. +- Every `cnf.jwk` and every AAuth server key selected from `jwks_uri` follows + these rules. Unselected JWKS members do not need to use supported algorithms. +- The HTTP Signature `alg` parameter MUST NOT be sent and is ignored if present; + the selected key determines the algorithm. + +#### 2. Signature verification and errors + +Verification and error behavior now align with HTTP Signature Keys draft-08 +(`#verification`, `#authentication-errors`): + +- Defined failures include `unsupported_scheme`, `unsupported_algorithm`, + `invalid_key`, `issuer_missing`, and `issuer_mismatch` in addition to existing + signature and JWT errors. +- Signature failures are authentication failures and always use `401`; the + `Signature-Error` header is the machine-readable carrier. +- `unsupported_scheme` and `unsupported_algorithm` can advertise accepted values + through `Accept-Signature-Scheme` and `Accept-Signature-Alg`. +- A `403` means authentication succeeded but authorization failed, so it MUST NOT + carry `Signature-Error` or either `Accept-Signature-*` header. +- Metadata discovery explicitly rejects a missing or mismatched `issuer`. + +The protocol also adds designated-expert instructions for its Requirement, +Capability, and Platform registries (`#designated-expert-instructions`). + +#### 3. Revocation identity and routing + +Token revocation is keyed by the pair `(iss, jti)`, because `jti` is unique only +within an issuer's namespace (`#token-revocation`): + +- Revocation requests carry both `iss` and `jti`; recipients MUST store + revocation state under the pair. +- A PS or AS revokes an auth token at the resource that received it. +- An AP revokes its agent token at the PS's `revocation_endpoint`; the PS denies + later use and should revoke auth tokens issued or provided for that agent. +- Identity-based access cannot always receive that push, so exposure remains + bounded by token lifetime when no resource revocation endpoint is reachable. + +#### 4. Directed subject handling + +Federation rules prevent directed person identifiers from crossing trust +boundaries as if they were globally meaningful: + +- A downstream issuer MUST NOT copy `sub` from an upstream auth token. +- It MAY issue its own directed `sub` only after its own authenticated federation + step maps the person into the downstream resource's namespace. +- Person identifiers MUST NOT appear in `act`; that chain identifies agents. + +#### 5. Account binding + +The new optional `account` parameter distinguishes multiple accounts that the +same person may hold at one resource (`#account-binding`): + +- The authorization request names an account in the resource's own namespace. +- The resource echoes it into the resource token, and the PS or AS copies it into + the auth token. +- The resource enforces the claim per account, and audit records retain the + account covered by the authorization. +- The value selects an existing resource account; it is not an authentication + hint and has no protocol-defined structure. + +### R3 (draft-01) + +R3 advances from draft-00 to draft-01 and incorporates the protocol changes: + +- The R3 document gains optional `account`, copied from the authorization request + and resource token. Its `display` should name the account in terms the person + recognizes rather than exposing an opaque resource identifier. +- Operation identifiers are explicitly scoped to a vocabulary's advertised + discovery endpoint. +- The new `urn:aauth:vocabulary:openapi-gateway` vocabulary qualifies operations + with `(service, operationId)` for multi-service gateways. +- JWT examples use `Ed25519`, include `alg` in `cnf.jwk`, and correct token types + to `aa-resource+jwt` and `aa-auth+jwt`. +- The R3 Vocabulary Registry gains designated-expert instructions. + +### AAuth Events (revised draft-00) + +Events remains draft-00 but changes resource-to-AP delivery to match the +Signature Keys model: + +- Event tokens now use `scheme=self-jwt`: the resource issues the JWT and signs + the HTTP request with the same discoverable JWKS key, so the token has no + `cnf` claim. +- Subscribe-token examples use fully specified `Ed25519` and carry `alg` in + `cnf.jwk`. +- The draft adds open-network and `self-jwt` design rationale and points its + protocol-family references at the Datatracker document pages. + +### Bootstrap (draft-02) + +Bootstrap advances from draft-01 to draft-02. Its token examples replace +`EdDSA` with `Ed25519`, add `alg` to `cnf.jwk`, and reference the protocol through +its Datatracker document page. The enrollment guidance is otherwise unchanged. + +### Interoperability Demo Profile (unchanged) + +`interop-demo-profile.md` is byte-identical to `v09/`. + +### HTTP Signature Keys (draft-08) + +Bumped **draft-06 → draft-08** +([published 2026-08-05](https://datatracker.ietf.org/doc/draft-hardt-httpbis-signature-key/08/)). +Draft-07 was editorial only. Draft-08 is not backward compatible with draft-07 +and includes these implementation-relevant changes: + +- Algorithms now come from required, fully specified JWK `alg` values. `EdDSA`, + `none`, symmetric algorithms, and key/algorithm mismatches are forbidden. +- `Accept-Signature-Scheme` and `Accept-Signature-Alg` replace the `sigkey` + parameter; `supported_algorithms` is removed from `Signature-Error`. +- Covering `signature-key` is now mandatory for signers and verifiers; `exp` is + mandatory for `jwt` and `self-jwt`; malformed JWT rejection and cache limits + become mandatory. +- The new `jwks` scheme directly fetches a JWKS URL that serves as both identity + and key location. Discovery adds `issuer_missing` and `issuer_mismatch` errors. +- Optional assertion caching adds the `cached` scheme, + `Signature-Key-Cache`, and `cache_miss`, with bounded verifier state. +- Unknown schemes and unsupported algorithms have defined negotiation and error + behavior, and selected JWKS keys are validated independently of other members. + +### Author's verbatim changelog (draft-10) + +Reproduced from the Document History section of +[`v10/draft-hardt-oauth-aauth-protocol.md`](v10/draft-hardt-oauth-aauth-protocol.md): + +> **draft-hardt-oauth-aauth-protocol-10** +> +> - Adopted the fully-specified `Ed25519` of [@!RFC9864] in place of the `EdDSA` +> it deprecates. `alg` is REQUIRED and MUST be fully specified; `EdDSA`, `none`, +> and symmetric algorithms MUST NOT be used; a verifier MUST reject a key whose +> `kty` or `crv` disagrees with its `alg`. Addresses issue #57. +> - A `cnf` JWK MUST carry a fully-specified `alg`, as MUST every key at an AAuth +> server's `jwks_uri`. A verifier MUST select the key matching `kid` without +> requiring the other JWKS members to be usable. +> - Aligned verification and error mapping with +> [@!I-D.hardt-httpbis-signature-key]: added `unsupported_scheme`, +> `unsupported_algorithm`, `invalid_key`, `issuer_missing`, and +> `issuer_mismatch`; pinned signature failures to `401`; a `403` MUST NOT carry +> `Signature-Error` or either `Accept-Signature-*` header; the `alg` signature +> parameter MUST NOT be used. +> - Revocation identifies a token by `(iss, jti)`, and recipients key revocation +> state by that pair. An agent provider revokes an agent token at the PS's +> `revocation_endpoint`. Addresses issues #59 and #60. +> - A downstream issuer MUST NOT copy a directed `sub` from an upstream token, +> MAY emit one only from its own authenticated federation step, and MUST NOT +> place a person identifier in `act`. Addresses issue #41. +> - Added the OPTIONAL `account` parameter on the authorization endpoint request, +> echoed in the resource token and copied into the auth token, binding an +> authorization to one of several accounts a resource may hold for the same +> person. Addresses issue #52. + +## `v09/` — AAuth draft-09 snapshot + +The latest upstream snapshot, vendored 2026-07-19 for reference. It bundles +protocol **draft-09** with a revised R3 (**draft-00**), the unchanged bootstrap +(**draft-01**) and Interoperability Demo Profile, the new AAuth Events companion +(**draft-00**), and HTTP Signature Keys **draft-06**. + +> **The SDK continues to target draft-08.** This snapshot is the immutable input +> to the separate draft-09 migration. + +### Protocol (draft-09) + +Published as IETF +[draft-hardt-oauth-aauth-protocol-09](https://datatracker.ietf.org/doc/draft-hardt-oauth-aauth-protocol/09/) +(commit `90089f8`, source frontmatter date 2026-06-17, IETF publication date +2026-07-04). The author's verbatim draft-09 changelog is reproduced below. + +#### 1. Clarification response discriminator + +Clarification-chat POSTs to a pending URL are now explicitly typed +(`#clarification-chat`): + +- The body MUST include `action=clarification_response` when answering the + user's question, or `action=updated_request` when replacing the resource + request. +- A server MUST reject a missing or unrecognized `action` with + `400 Bad Request`. +- Both wire examples now carry the discriminator, removing the draft-08 + inference from whether `clarification_response` or `resource_token` happened + to be present. + +#### 2. RFC 9457 error responses + +The token-endpoint-specific JSON format became a common AAuth problem-details +format (`#error-responses`, `#error-response-format`): + +- Error bodies use RFC 9457 `application/problem+json`. +- The AAuth `error` code remains REQUIRED as an extension member; the standard + `detail` member replaces `error_description`. +- Standard RFC 9457 members MAY be present, but receivers MUST use `error`, not + `type`, to determine AAuth behavior. +- Authorization, interaction, mission-status, token-endpoint, and polling + errors now reference or demonstrate the common format. Authentication failures + continue to use the HTTP Signature Keys `Signature-Error` header. + +#### 3. AAuth Events integration + +The protocol now introduces its Events companion at the core integration points: + +- The protocol overview names asynchronous event delivery through the AP, and + the AP role gains event-router behavior. +- Agent metadata (`#metadata-documents`) gains optional `event_endpoint`, which + is required when an AP supports AAuth Events. +- IANA considerations register the companion's `aa-subscribe+jwt` and + `aa-event+jwt` token types. + +#### 4. Editorial and implementation-status changes + +- Hand-maintained source references for HTTP Signature Keys and Bootstrap were + removed in favor of the references resolved by the publication toolchain; the + citations remain. +- The acknowledgments add Lukas Friman and Sanjay Dalal. + +### AAuth Events (new companion draft) + +`draft-hardt-aauth-events.md` is a new standards-track companion source at +draft-00 (source date 2026-06-24). It defines AP metadata, subscribe tokens, +public and protected registration, event tokens, resource-to-AP delivery, +AP-to-agent routing, and AsyncAPI discovery. It is included because both the +protocol and revised R3 reference it. + +At copy time the Events source was present at the pinned protocol tag but had no +dedicated Git tag or published Datatracker revision. The snapshot therefore pins +the exact companion source from protocol tag +`draft-hardt-oauth-aauth-protocol-09` rather than a moving branch. + +### R3 (revised) + +R3 remains draft-00 but its AsyncAPI vocabulary changed: + +- `action` is now OPTIONAL rather than REQUIRED; when present it is `send` or + `receive`, and event subscriptions use `receive`. +- A granted AsyncAPI subscription operation now hands off registration and + delivery to AAuth Events using a subscription ticket URL and subscribe token. + +### Bootstrap and Interoperability Demo Profile (unchanged) + +- `draft-hardt-aauth-bootstrap.md` remains draft-01 and is byte-identical to + `v08/`. +- `interop-demo-profile.md` is byte-identical to `v08/`. + +### HTTP Signature Keys (draft-06) + +Bumped **draft-05 → draft-06** +([published 2026-07-02](https://datatracker.ietf.org/doc/draft-hardt-httpbis-signature-key/06/)). +Draft-06 adds the `self-jwt` scheme: a self-issued JWT whose issuer and signer +are the same party, using the issuer's discovered JWKS key for both the JWT and +HTTP signature and carrying no `cnf` claim. + +The protocol draft-09 publication resolves its Signature Keys reference to +draft-06. This snapshot intentionally vendors that revision rather than the +newer draft-07. + +### Author's verbatim changelog (draft-09) + +Reproduced from the Document History section of +[`v09/draft-hardt-oauth-aauth-protocol.md`](v09/draft-hardt-oauth-aauth-protocol.md): + +> **draft-hardt-oauth-aauth-protocol-09** +> +> - Clarification chat: added a required `action` discriminator +> (`clarification_response` / `updated_request`) to the agent's POST responses +> on the pending URL, so the response type is explicit rather than inferred +> from key presence. +> - Error responses: adopted RFC 9457 problem details — error bodies use +> `Content-Type: application/problem+json` with the AAuth error code as a +> required `error` extension member; `error_description` replaced by the RFC +> 9457 `detail` member; added token endpoint and polling error examples. + ## `v08/` — AAuth draft-08 snapshot The latest upstream snapshot, vendored 2026-06-25 for reference. It bundles diff --git a/aauth-spec/SPEC-VERSION.md b/aauth-spec/SPEC-VERSION.md index 4046a27f..ca4c90bd 100644 --- a/aauth-spec/SPEC-VERSION.md +++ b/aauth-spec/SPEC-VERSION.md @@ -2,10 +2,10 @@ These spec files were copied from the [AAuth](https://github.com/dickhardt/AAuth) repository for reference while building the .NET samples. They are grouped by the -AAuth protocol draft version under [`v01/`](v01/), [`v02/`](v02/), and -[`v08/`](v08/). Each folder is a self-contained snapshot, so each carries its own -copy of the HTTP Signature Keys draft at the version that snapshot's protocol -references. +AAuth protocol draft version under [`v01/`](v01/), [`v02/`](v02/), +[`v08/`](v08/), [`v09/`](v09/), and [`v10/`](v10/). Each folder is a +self-contained snapshot, so each carries its own copy of the HTTP Signature Keys +draft at the version that snapshot's protocol references. The GitHub repository is the working source we vendor from. The canonical, permanent home is the **IETF Datatracker**, which retains every published revision @@ -13,23 +13,29 @@ permanent home is the **IETF Datatracker**, which retains every published revisi deprecated. Use it as the source of record and fallback: - Datatracker document — -- Per-revision text (example) — +- Per-revision text (example) — The vendored `.md` files are the upstream kramdown source; if the GitHub repo is unavailable, the Datatracker `.txt`/`.html` renderings are the authoritative substitute. -The SDK code now targets **draft-08** ([`v08/`](v08/)) — migrated from draft-02 in -the 2026-06-25 migration (see `.agent/plans/2026-06-25-aauth-v08-spec-migration/`). -All four resource access modes are implemented, including the `AAuth-Access` -opaque-token flow (resource-managed, two-party access), added under -`.agent/plans/2026-06-25-aauth-access-token-flow/`. The runnable four-party -sub-agent (S5) interop demo is deferred, though the parent-mediated code path -is implemented and conformance-tested. - -`v08/` is therefore both the version the SDK conforms to and the latest upstream -snapshot, vendored 2026-06-25. The earlier draft-02 ([`v02/`](v02/)) and draft-01 -([`v01/`](v01/)) snapshots are retained for reference. +The SDK now targets **draft-10** ([`v10/`](v10/)), following the separately +verified migration on 2026-09-09. This includes all four access modes, the +resource-managed opaque credential, accounts, AS clarification, issuer-qualified +revocation, and real four-party parent/worker scenarios in both primary apps. +Signature Keys draft-08, R3 draft-01 and revised Events draft-00 are included; +Bootstrap draft-02 remains informational. No snapshot bytes changed during migration. + +`v10/` remains the latest vendored upstream reference. Earlier snapshots are +historical, not compatibility fallbacks. X.509/cached carriers and third-party +login hosting are unsupported; platform/native transports and production +persistence/policy are deployment responsibilities. External whoami identity +access passed, but scoped access returned `person-token`; external authorization +and the full external mission/sub-agent profile remain unverified. See the +[migration log](../.agent/plans/2026-09-08-aauth-v10-spec-migration/implementation-log.md) +and [conformance ledger](../.agent/plans/2026-09-08-aauth-v10-spec-migration/conformance-ledger.md) +for executed gates and explicit limitations. Historical snapshot entries below +retain their original context. For a high-fidelity record of what changed between snapshots, see [`CHANGELOG.md`](CHANGELOG.md). @@ -138,3 +144,110 @@ draft-08 bundles six published protocol drafts (03 → 08). The headline deltas: - **New `## PS Approval Endpoint Authentication`** section and an implementation-clarity pass (draft-06): `AAuth-Requirement`/`AAuth-Access`/`AAuth-Capabilities` grammar, JWKS same-`kid` refresh, and structured `cnf.jwk` verification ordering. + +## `v09/` — protocol draft-09 + +> This is the latest upstream reference. The SDK continues to target draft-08 +> until the separate draft-09 migration is complete. + +| Field | Value | +|---|---| +| Source repository | | +| Commit | `90089f80eaccccbd22e32e06946e2aa08f7d67fe` | +| Commit date | 2026-07-05 | +| Tagged version | `draft-hardt-oauth-aauth-protocol-09` | +| Source document date | 2026-06-17 | +| IETF publication date | 2026-07-04 | +| IETF draft | | +| Copied on | 2026-07-19 | + +- `draft-hardt-oauth-aauth-protocol.md` — Main AAuth protocol specification + (draft-09). +- `draft-hardt-aauth-bootstrap.md` — Agent bootstrap guidance (draft-01, + byte-identical to `v08/`). +- `draft-hardt-aauth-r3.md` — Rich Resource Requests (R3) specification + (draft-00, revised to integrate AAuth Events subscriptions). +- `interop-demo-profile.md` — Interoperability Demo Profile (informational, + byte-identical to `v08/`). +- `draft-hardt-aauth-events.md` — AAuth Events companion specification + (draft-00, **new** in this snapshot). It is present at the pinned protocol tag + but did not yet have its own published tag or Datatracker revision when copied. +- `draft-hardt-httpbis-signature-key-06.txt` — HTTP Signature Keys + (Internet-Draft, draft-06; bumped from draft-05 in `v08/`). The published + protocol draft-09 resolves its reference to draft-06, so this snapshot keeps + that historical dependency even though a newer revision now exists. Downloaded + 2026-07-19 from + + (Internet-Draft, 2 July 2026 revision). + +### Notable changes since draft-08 + +- Clarification-chat POST bodies now require an `action` discriminator with + `clarification_response` or `updated_request`; missing or unknown values are + rejected with `400 Bad Request`. +- AAuth JSON errors now use RFC 9457 problem details with + `Content-Type: application/problem+json`; `error` remains the required AAuth + extension member and `detail` replaces `error_description`. +- The protocol adds AAuth Events integration: APs can publish an + `event_endpoint`, act as event routers, and recognize the new + `aa-subscribe+jwt` and `aa-event+jwt` token types. +- The new AAuth Events draft defines subscription registration and signed event + delivery through an Agent Provider. R3's AsyncAPI vocabulary now links granted + subscription operations to that protocol and makes its `action` field optional. +- HTTP Signature Keys advances from draft-05 to draft-06, adding the `self-jwt` + scheme for self-issued JWTs. + +## `v10/` — protocol draft-10 + +> This is the latest upstream reference. The SDK continues to target draft-08; +> draft-09 and draft-10 migrations remain separate implementation work. + +| Field | Value | +|---|---| +| Source repository | | +| Commit | `9dee49fbf49074d1460d0a7c0670bf355aef5e1e` | +| Commit date | 2026-08-06 | +| Tagged version | `draft-hardt-oauth-aauth-protocol-10` | +| Source document date | 2026-06-17 | +| IETF publication date | 2026-08-06 | +| IETF draft | | +| Copied on | 2026-09-08 | + +- `draft-hardt-oauth-aauth-protocol.md` — Main AAuth protocol specification + (draft-10). +- `draft-hardt-aauth-bootstrap.md` — Agent bootstrap guidance (draft-02, + revised with fully specified algorithm examples and a Datatracker protocol + reference). +- `draft-hardt-aauth-r3.md` — Rich Resource Requests specification (draft-01, + revised with account binding, operation-identifier scoping, and the OpenAPI + Gateway vocabulary). +- `interop-demo-profile.md` — Interoperability Demo Profile (informational, + byte-identical to `v09/`). +- `draft-hardt-aauth-events.md` — AAuth Events companion specification + (draft-00, revised to use the HTTP Signature Keys `self-jwt` scheme for event + delivery and fully specified algorithms). +- `draft-hardt-httpbis-signature-key-08.txt` — HTTP Signature Keys + (Internet-Draft, draft-08; bumped from draft-06 in `v09/`; draft-07 was + editorial only). Downloaded 2026-09-08 from + + (Internet-Draft, 5 August 2026 revision). + +### Notable changes since draft-09 + +- AAuth keys now require fully specified `alg` identifiers. `Ed25519` replaces + deprecated `EdDSA`; `none`, symmetric algorithms, and key/algorithm mismatches + are rejected. +- Signature verification aligns with HTTP Signature Keys draft-08, including + defined scheme, algorithm, key, and issuer errors; signature failures use + `401`, while a `403` must not carry signature error or negotiation headers. +- Revocation identifies tokens by `(iss, jti)`, including agent-token revocation + by an AP through the PS's revocation endpoint. +- Downstream issuers cannot copy directed `sub` values from upstream tokens or + place person identifiers in `act`. +- The authorization request gains optional `account` binding, propagated through + resource and auth tokens. R3 carries the same value and adds display guidance. +- R3 adds operation-identifier scoping and an OpenAPI Gateway vocabulary. Events + switches resource-to-AP delivery to `self-jwt`; Bootstrap advances to draft-02. +- HTTP Signature Keys draft-08 adds `jwks`, assertion caching, fully specified + algorithm rules, stricter covered-component and expiry requirements, and new + negotiation and error handling. diff --git a/aauth-spec/v09/draft-hardt-aauth-bootstrap.md b/aauth-spec/v09/draft-hardt-aauth-bootstrap.md new file mode 100644 index 00000000..39b27f86 --- /dev/null +++ b/aauth-spec/v09/draft-hardt-aauth-bootstrap.md @@ -0,0 +1,411 @@ +%%% +title = "AAuth Bootstrap Guidance" +abbrev = "AAuth-Bootstrap" +ipr = "trust200902" +area = "Security" +workgroup = "TBD" +keyword = ["agent", "authorization", "bootstrap", "http", "identity"] +category = "info" + +[seriesInfo] +status = "informational" +name = "Internet-Draft" +value = "draft-hardt-aauth-bootstrap-latest" +stream = "IETF" + +date = 2026-05-06T00:00:00Z + +[[author]] +initials = "D." +surname = "Hardt" +fullname = "Dick Hardt" +organization = "Hellō" + [author.address] + email = "dick.hardt@gmail.com" + +%%% + + + + AAuth Protocol + + Hellō + + + + + + + + HTTP Signature Keys + + Hellō + + + + + + + + Web Authentication: An API for accessing Public Key Credentials - Level 3 + + W3C + + + + + + + + Establishing your app's integrity (App Attest) + + Apple + + + + + + + + Play Integrity API + + Google + + + + + + + + Web Cryptography API + + W3C + + + + + + +.# Abstract + +This document provides informational guidance for agent providers (APs) on enrolling agents and issuing AAuth agent tokens defined in [@!I-D.hardt-oauth-aauth-protocol]. It covers per-platform key handling, optional platform attestation, agent identifier strategies, and refresh patterns. The mechanisms described here are not normative protocol — they are common patterns that interoperable AP implementations can adopt or adapt. + +.# Discussion Venues + +*Note: This section is to be removed before publishing as an RFC.* + +Discussion of this document takes place on GitHub at https://github.com/dickhardt/AAuth. Issues, comments, and pull requests are welcome there. Source for this draft is in the same repository. + +{mainmatter} + +# Introduction + +The AAuth Protocol [@!I-D.hardt-oauth-aauth-protocol] establishes that every agent has its own cryptographic identity — an agent identifier of the form `aauth:local@domain`, bound to a signing key, and attested by an agent token issued by an agent provider (AP). The protocol defines the agent token format and how agents present that identity to person servers (PSes), resources, and access servers (ASes). It does not specify how an agent comes to hold an agent token in the first place. That step is **bootstrap**, and it is the subject of this document. + +## What Bootstrapping Is + +Bootstrapping is the AP-side ceremony by which an instance of an agent acquires an agent token. The agent generates a signing key on the device or in the browser where it will run, presents whatever evidence the AP requires (a signed-in account, an attested device, a published JWKS, etc.), and receives an agent token whose `cnf.jwk` is bound to that key and whose `sub` is an `aauth:local@domain` identifier the AP has chosen. + +After bootstrap the agent can participate in AAuth: it can sign HTTP messages per [@!I-D.hardt-httpbis-signature-key], identify itself at resources, and present its agent token to a PS so the user can bind the agent to themselves on first interaction. + +## What Bootstrapping Is Not + +- **Not normative protocol.** This document is informational. The AAuth Protocol does not mandate a specific bootstrap ceremony, and conformance does not depend on the patterns described here. APs are free to use other approaches that produce a valid agent token. +- **Not the user-to-agent binding.** Binding an agent to a person is performed by the PS, lazily, on the agent's first interaction with the PS per the AAuth Protocol. Bootstrap produces an agent identity; the PS attaches that identity to a user. +- **Not authorization.** Bootstrap conveys no scope, no resource permission, and no user identity claims. Those are obtained through the flows defined in the AAuth Protocol after bootstrap. +- **Not one-size-fits-all.** Web, mobile, and self-hosted agents have different threat models and different platform primitives available to them. This document offers patterns appropriate to each, not a single prescribed ceremony. + +## Patterns Covered + +- **Per-platform key handling** — where the agent's signing key lives and how strongly it is protected on web, mobile, and self-hosted deployments; desktop and workload coverage is TBD (#per-platform-keys). +- **Optional platform attestation** — when and why to require WebAuthn, App Attest, or Play Integrity (#optional-attestation). +- **Agent identifier strategies** — how to construct the `sub` claim's local part (#identifier-strategies). +- **Refresh patterns** — issuing fresh agent tokens for renewal (#refresh-patterns). + +Throughout, when this document refers to "the durable key" and "the ephemeral key" it means the keys defined in (#per-platform-keys). The ephemeral key's public part appears in `agent_token.cnf.jwk` and signs HTTP messages from the agent per [@!I-D.hardt-httpbis-signature-key]; the durable key serves as the AP's stable enrollment anchor and signs only at refresh. APs that use a single durable key for all signatures (#per-platform-keys) can read references to "the ephemeral key" as referring to that same durable key. + +# Conventions and Definitions + +{::boilerplate bcp14-tagged} + +This document is informational guidance and does not itself impose normative requirements. Normative requirements relevant to bootstrap are defined in [@!I-D.hardt-oauth-aauth-protocol]; this document references them where helpful but uses lowercase "should" / "must" in its own descriptive prose. + +# Terminology + +Terms defined in [@!I-D.hardt-oauth-aauth-protocol] are used here with the same meaning. In particular: + +- **Agent Provider (AP)** — issues agent tokens. +- **Agent token** — JWT signed by the AP, carrying `iss`, `sub`, `cnf.jwk`, optionally `ps`, and other claims. +- **Person Server (PS)** — represents the person; binds agents to a person on first interaction. + +This document additionally uses: + +- **Durable key** — a signing key whose lifetime is intended to span the agent install (typically the lifetime of an install or browser-storage entry). The durable key is the AP's stable enrollment anchor; it is presented only to the AP at refresh and is not used to sign requests to PSes, resources, or ASes. +- **Ephemeral key** — a signing key generated fresh per agent-token issuance. Its public part appears in `agent_token.cnf.jwk`. The agent uses it to sign HTTP messages for the agent token's lifetime, then discards it on the next refresh. +- **Platform attestation** — a mechanism by which the runtime platform attests to properties of the agent or its key (WebAuthn, Apple App Attest, Google Play Integrity, etc.). + +# Per-Platform Key Handling {#per-platform-keys} + +On web, mobile, and desktop, APs should use a two-key pattern: a **durable key** that serves as the AP's stable enrollment anchor and is presented only to the AP at refresh, plus an **ephemeral key** generated fresh per agent-token issuance whose public part appears in `agent_token.cnf.jwk` and which signs HTTP messages for the agent token's lifetime. Refresh chains the new ephemeral key to the durable key via the `jkt-jwt` scheme [@!I-D.hardt-httpbis-signature-key]; see (#refresh-patterns). + +This pattern bounds the blast radius of an ephemeral-key leak to one agent token's lifetime, narrows the durable key's attack surface to the AP refresh path (it never signs requests to PSes, resources, or ASes), and accommodates hardware-backed durable keys on platforms that have them today and on platforms that may expose them in the future without protocol change. APs may use a single durable key for all signatures where simplicity outweighs these properties — receivers cannot distinguish the two patterns, since they only verify `cnf.jwk` against the HTTP signature. + +Self-hosted agents (#self-hosted-agents) use a single key — the JWKS-published key serves as both the AP signing key and the agent's signing key, since there is no separate AP to refresh against. + +## Web Apps + +The durable key is a non-extractable [@WebCryptoAPI] key generated with `extractable: false` and stored in IndexedDB scoped to the AP's origin. The ephemeral key is also a non-extractable WebCrypto key, regenerated on each refresh and discarded when the next refresh produces its replacement. + +Properties of the durable key: + +- The private key cannot be read or exported by JavaScript, including by code injected via XSS or malicious browser extensions. JS can only ask the browser to sign with it. +- The key is bound to the origin's IndexedDB storage. Clearing site data destroys it; a new enrollment is required. +- No user-verification gesture is required to sign — operations are fast enough for routine signature use. + +Both keys are software-protected (browser sandbox) rather than hardware-protected. The two-key pattern still applies: the durable key signs only the periodic refresh (once per agent-token lifetime), while the ephemeral key signs every HTTP request and rotates on each refresh. APs that want the additional assurance of a WebAuthn ceremony at enrollment time can layer one on top; see (#optional-attestation). If browsers later expose hardware-backed credentials suitable for use as the durable key, the pattern accommodates them with no protocol change. + +## Mobile (iOS and Android) + +The durable key is generated and stored in the platform's hardware-backed keystore: the Secure Enclave on iOS or StrongBox on Android (or the Android Keystore where StrongBox is unavailable). The ephemeral key is a software key in app memory, regenerated on each refresh. + +Properties of the durable key: + +- The private key cannot be exported from the keystore. Cryptographic operations are performed by the keystore on the application's behalf. +- The key is bound to the application install. Reinstalling the app generates a new key and requires re-enrollment. +- The keystore can additionally enforce user authentication (biometric or device passcode) before sign operations, if the AP wants user-presence on each refresh. + +The AP typically also requires an attestation ceremony at enrollment to confirm the durable key is real keystore-bound material rather than software-generated. See (#optional-attestation). Because the durable key signs only at refresh, any per-op cost (keystore round-trip, optional user verification) is incurred at most once per agent-token lifetime, not on every request. + +## Self-Hosted Agents {#self-hosted-agents} + +A self-hosted agent runs under a domain the user controls. The agent publishes its AP metadata document at `/.well-known/aauth-agent.json` per [@!I-D.hardt-oauth-aauth-protocol]; the JWKS itself is hosted at any HTTPS URL referenced by the metadata's `jwks_uri`. The corresponding private key should be hardware-bound where the platform supports it: macOS Keychain (Secure Enclave on supported hardware), Windows TPM, or Linux Secret Service. + +Self-hosted agents act as their own AP — they self-issue agent tokens signed by the JWKS-published key. There is no separate AP to refresh against, so the two-key pattern does not apply: the JWKS-published key serves both as the AP signing key (signing self-issued agent tokens) and as the key whose public part appears in `agent_token.cnf.jwk` (signing HTTP messages). Because the trust anchor is a key the user controls and publishes, no platform attestation step exists. Other parties verify the agent token signature against the published JWKS, exactly as they would for any other AP. + +## Desktop Apps + +TBD. Future revisions will cover key handling for native desktop applications, where the durable key would live in a hardware-backed store (macOS Keychain with Secure Enclave on supported hardware, Windows TPM via CNG, Linux Secret Service / TPM2) and the ephemeral key in process memory, following the same pattern as mobile. + +## Workload + +TBD. Future revisions will cover headless workload identity (e.g., SPIFFE/SPIRE SVIDs, WIMSE workload identity, cloud-platform IMDS attestation), where the trust anchor is platform attestation rather than user interaction. + +# Optional Platform Attestation {#optional-attestation} + +Platform attestation gives the AP cryptographic evidence about the runtime context in which the durable key was generated. It is optional — the AAuth Protocol does not require it. APs choose whether to require attestation based on their threat model. + +Common reasons an AP might require attestation: + +- **Anti-fraud at enrollment.** Distinguishing real user devices from server-side automation. +- **Hardware-binding evidence.** Confirming the durable key is in a Secure Enclave or StrongBox rather than software. +- **App-integrity evidence.** Confirming the agent is the AP's published app, not a modified or repackaged binary. +- **User-presence evidence.** Confirming a real user gesture authorized this enrollment. + +Common reasons an AP might not require attestation: + +- The AP serves a trust posture where AP-side fraud detection is not signal-driven (e.g., paid accounts, invitation-only enrollment). +- The AP wants the broadest possible reach, including environments where attestation is unavailable. +- The deployment is self-hosted, where the user is the trust anchor. + +## WebAuthn (Web Apps) + +[@WebAuthn] provides user-verification and a hardware-rooted credential on web. APs that require it perform a registration ceremony at enrollment and an assertion ceremony at later sensitive operations. The credential is stored in the user's authenticator (TPM, Secure Enclave, security key, or platform syncing fabric). + +Tradeoffs: + +- Provides user-verification (touch, face, PIN) the WebCrypto-only approach lacks. +- Provides hardware-protected key material that cannot be lifted even by a fully compromised browser process. +- UX failure modes exist around cross-Chrome-profile use, embedded webviews, syncing-fabric inconsistencies, and cross-device QR ceremonies. APs that adopt WebAuthn should plan for fallback paths when these fail. + +## App Attest (iOS) + +[@AppAttest] attests to two things: that the durable key was generated in the device's Secure Enclave, and that the request originates from the AP's published app on a genuine Apple device. The AP receives an attestation object at enrollment which it verifies against Apple's attestation root, then accepts subsequent assertions signed by the same enclave key. + +## Play Integrity (Android) + +[@PlayIntegrity] provides a device, app, and account integrity verdict signed by Google. The AP nominates a nonce, the agent invokes the Play Integrity API, and the AP verifies the resulting integrity token. Subsequent assertions can be signed by an Android Keystore (or StrongBox) key that the AP enrolled at the same time. + +## When to Require Attestation + +A practical rule of thumb: + +- **Consumer-grade APs**: optional. Most consumer agent providers do not require attestation; the protocol-level binding at the PS is the security gate. +- **Regulated or high-assurance APs**: usually required. Financial services, healthcare, enterprise SSO providers benefit from attestation as part of their AML/KYC or device-management posture. +- **Multi-tenant APs**: often required at higher tiers. An AP may issue weak agent tokens to free tier users and require attestation for paid or enterprise tier users, surfacing the difference to receivers via AP-defined claims in the agent token. + +# Agent Identifier Strategies {#identifier-strategies} + +The agent token's `sub` is an `aauth:local@domain` identifier. The `domain` part is the AP. The `local` part identifies the agent install at the AP — it must be stable for the lifetime of the install so PSes and other parties can recognize a returning agent. + +APs are free to choose any opaque scheme for the local part: a random string assigned at enrollment, a deterministic derivation from the durable key's thumbprint, a sequential identifier, or a human-readable handle. When deriving from a thumbprint, use the durable key's thumbprint — the ephemeral key rotates on each refresh and is not a stable identifier. Receivers treat the identifier as opaque. + +## Per-Install Identity {#per-install-identity} + +Each install's durable key is the basis for one agent identity. A returning user on a new device is a new agent. This keeps the AP minimal — it has no user-account system, no `(user, durable_jkt)` mappings, and no ability to correlate a single user's activity across their devices. + +Multi-device users will see multiple agent entries in their PS dashboard. Grouping or merging those entries belongs at the PS, which already authenticates the user and is the correct layer for cross-device correlation. Rotation of the durable key produces a new agent identity; rotation of the ephemeral key (on every refresh) does not — the agent's `sub` is stable across ephemeral rotations. PS-side regrouping is the recovery path for durable-key changes. + +# Example Agent Token Claims + +A typical agent token issued by an AP, illustrating the claims described in [@!I-D.hardt-oauth-aauth-protocol] and the identifier strategies in (#identifier-strategies). + +JWT header: + +```json +{ "alg": "EdDSA", "typ": "aa-agent+jwt", "kid": "..." } +``` + +JWT payload: + +```json +{ + "iss": "https://ap.example", + "dwk": "aauth-agent.json", + "sub": "aauth:k7q3p9n2@ap.example", + "ps": "https://ps.example", + "cnf": { "jwk": { "kty": "OKP", "crv": "Ed25519", "x": "..." } }, + "iat": 1746316800, + "exp": 1746320400, + "jti": "..." +} +``` + +# Refresh Patterns {#refresh-patterns} + +Agent token lifetime is the AP's policy re-evaluation cadence — every refresh is the AP's chance to re-check device posture, attestation freshness, and account status before issuing a new token. A typical lifetime is **1 hour**, matching common practice for proof-of-possession-bound access tokens. APs may use shorter lifetimes (e.g., 5–15 minutes) for higher-assurance deployments where attestation must be refreshed often, or longer lifetimes up to the AAuth Protocol's 24-hour ceiling for low-policy-churn deployments where refresh chattiness is undesirable. + +## Two-Key Refresh + +On web, mobile, and desktop, refresh chains the new ephemeral key to the durable key via the `jkt-jwt` scheme [@!I-D.hardt-httpbis-signature-key]: + +1. The agent generates a fresh ephemeral key pair. +2. The agent constructs a JWT signed by the **durable key**, naming the new ephemeral public key. This is the "naming JWT" carried in the `Signature-Key` header under `scheme=jkt-jwt`. +3. The agent signs the refresh request with the **ephemeral key** under [@!RFC9421] HTTP Message Signatures. +4. The AP verifies the durable-key signature on the naming JWT, looks up the enrollment by the durable key's thumbprint, verifies the HTTP signature against the ephemeral public key, applies its policy (device posture, attestation freshness, account status), and returns a new agent token whose `cnf.jwk` is the ephemeral public key. +5. The agent uses the new agent token and ephemeral key for the agent token's lifetime, then discards the ephemeral key on the next refresh. + +Example refresh request: + +```http +POST /refresh HTTP/1.1 +Host: ap.example +Content-Type: application/json +Signature-Input: sig=("@method" "@authority" + "@path" "signature-key");created=1746316800 +Signature: sig=:...ephemeral-key signature bytes...: +Signature-Key: sig=jkt-jwt;jwt="eyJhbGc..." + +{} +``` + +The `jwt` parameter value is a JWT signed by the durable key with payload including the ephemeral public key (typically as `cnf.jwk`) and a `jti` for replay protection. The HTTP signature is produced by the ephemeral key. The AP correlates the two keys via the naming JWT's payload. + +## Single-Key Refresh + +APs that opt for the single-durable pattern (#per-platform-keys) sign the refresh request directly with the durable key under the `hwk` scheme [@!I-D.hardt-httpbis-signature-key]. The AP verifies the signature, looks up the enrollment by the key's thumbprint, and issues a fresh agent token with a new `exp`. The same `cnf.jwk` is carried through; the agent's key is unchanged. + +## Mobile Refresh Specifics + +APs that required platform attestation at enrollment typically do not re-attest on every refresh — the durable-key signature on the naming JWT (or the durable-key HTTP signature in the single-key pattern) is sufficient proof that the same enclave-resident key is making the request. APs that want periodic re-attestation can require a fresh App Attest assertion or Play Integrity verdict on a schedule (e.g., every 30 days) by including a server nonce in the refresh challenge. + +## Self-Hosted Refresh + +Self-hosted agents self-issue agent tokens. There is no separate refresh ceremony — the agent generates a new agent token signed by its JWKS-published key whenever needed. The two-key pattern does not apply (#self-hosted-agents). + +## Key Rotation vs Token Refresh + +Refresh issues a new agent token bound to a fresh ephemeral key (or, in the single-key pattern, to the same durable key). **Durable key rotation** generates a new durable key and is a separate, rare event. Under the per-install identity model (#per-install-identity), a new durable key is a new agent — the PS treats it as new on first interaction, and any cross-device or cross-rotation continuity is handled at the PS by the user. + +# Per-Platform Enrollment Sketches + +This section sketches a typical end-to-end enrollment for each platform. The sketches are illustrative; APs are free to vary them. + +## Web App Enrollment + +1. User logs into the AP through the AP's normal login. +2. Agent (running in the AP's web origin) generates a non-extractable WebCrypto Ed25519 **durable** key and stores its handle in IndexedDB. +3. Agent posts the durable public key to an AP-internal enrollment endpoint, signed by the new key (`hwk` scheme). +4. AP optionally performs a WebAuthn registration and verifies it. +5. AP records `(ap_user, durable_jkt)` and is now ready to issue agent tokens. +6. When the agent needs an agent token directed at PS_X, it generates a fresh **ephemeral** WebCrypto key and calls an AP-internal token-issuance endpoint indicating `ps=PS_X`, signed via `jkt-jwt` chaining the durable key to the ephemeral key (#refresh-patterns). The AP returns an agent token with `sub` derived per the AP's identifier strategy (#identifier-strategies) (using the durable key's thumbprint when derivation is used), `ps = PS_X`, `cnf.jwk` = the ephemeral public key, and any AP-attested claims. + +## Mobile App Enrollment + +1. User signs into the AP through the app's normal login. +2. App generates a **durable** key in the Secure Enclave (iOS) or StrongBox (Android). +3. App initiates platform attestation: App Attest on iOS, Play Integrity on Android. The AP nominates a nonce. +4. App posts the durable public key, the attestation result, and the nonce to an AP-internal enrollment endpoint. +5. AP verifies the attestation against the platform's trust root. +6. AP records `(ap_user, durable_jkt, attestation)` and is ready to issue agent tokens. +7. Token issuance proceeds as in the web app sketch — app generates a fresh ephemeral key per agent token and chains it to the durable key via `jkt-jwt`. + +## Self-Hosted Enrollment + +1. User generates a hardware-bound key on their machine. +2. User publishes an AP metadata document at `/.well-known/aauth-agent.json` per [@!I-D.hardt-oauth-aauth-protocol], with `jwks_uri` pointing to a JWKS containing the public part of that key. +3. The agent self-issues an agent token signed by that key as needed. + +There is no separate enrollment step — publication of the JWKS is the enrollment. + +# Security Considerations + +## Trust in the AP + +Every AP-attested claim in the agent token is only as trustworthy as the AP that signed the token. Receivers should apply policy proportional to their trust in the AP. An unfamiliar AP making strong attestation claims may warrant additional caution at the PS consent screen. + +## Ephemeral Key Compromise + +An ephemeral-key leak — via memory disclosure, in-page attacker, side channel, or similar — exposes only the signatures the agent makes during the current agent token's lifetime. At the recommended 1-hour lifetime, the blast radius is bounded to roughly that window before natural expiry forces replacement. Agents that detect compromise can decline to refresh, aging out the ephemeral key without explicit revocation. This bounding is the primary security argument for the two-key pattern (#per-platform-keys). + +## Durable Key Compromise + +Compromise of the durable key compromises the install's agent identity for the durable key's lifetime. The durable key signs only at refresh and is presented only to the AP, so its attack surface is much narrower than the ephemeral key's — but a successful compromise lets the attacker mint refresh requests indefinitely until the AP revokes the enrollment. APs should detect anomalous refresh patterns and provide a way for users to revoke a durable enrollment. + +A non-extractable WebCrypto durable key cannot be exfiltrated by page-level attackers, but it can be used by them while they hold execution in the page. APs should pair WebCrypto-only enrollment with normal web hygiene (CSP, subresource integrity, dependency review) and should not treat the non-extractable property as a substitute for keeping the page's JavaScript clean. A hardware-backed durable key (Secure Enclave, StrongBox, TPM) cannot be exfiltrated at all, only used in-place — narrowing the threat to malicious code running in the agent application itself. + +## Attestation Replay + +Platform attestation results (App Attest, Play Integrity, WebAuthn ceremonies) should be bound to a server-nominated nonce that is single-use and short-lived (5 minutes is a reasonable upper bound). The AP should verify that the attestation includes the nonce it issued; without this binding, a captured attestation can be replayed across enrollments. + +## Self-Hosted JWKS Key Compromise + +Compromise of the self-hosted JWKS key allows the attacker to mint agent tokens for that user's domain. Users running self-hosted agents should use hardware-backed keys (Secure Enclave / TPM / StrongBox) and rotate the published JWKS if compromise is suspected. + +# Privacy Considerations + +## Identifier Stability and User Tracking + +An agent's `sub` is the same value at every PS the agent contacts, not a per-PS pairwise identifier. A stable `sub` lets each PS reliably re-identify the agent across sessions — that is the intended property — but it also means colluding PSes (or any party with cross-PS telemetry) can correlate the agent's activity across them. Under per-install identity (#per-install-identity), durable-key rotation produces a new `sub`, giving users a natural "fresh start" capability. + +## AP Visibility Into Agent Activity + +The AP that issued an agent token does not see the agent's subsequent traffic to PSes, resources, or ASes (they verify against the AP's published JWKS, not by calling the AP). The AP's view is limited to enrollment and refresh requests. APs should document their data retention practices for those events. + +# IANA Considerations + +This document is informational and registers no new media types, JWT claim names, or metadata fields. + +# Implementation Status + +*Note: This section is to be removed before publishing as an RFC.* + +This section records the status of known implementations of the patterns described in this document at the time of posting of this Internet-Draft, and is based on a proposal described in [@?RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. + +TBD + +# Document History + +*Note: This section is to be removed before publishing as an RFC.* + +- draft-hardt-aauth-bootstrap-01 + - Major rewrite. The document is now informational guidance for AP implementers. The previously-normative PS bootstrap protocol (PS `/bootstrap` endpoint, `bootstrap_token`, bootstrap announcement, agent server [now Agent Provider] `bootstrap_endpoint` / `refresh_endpoint` / `webauthn_endpoint`) has been removed. PS-side binding to a person now happens lazily on the agent's first interaction with the PS per the AAuth Protocol; the bootstrap document covers AP-side enrollment patterns only. + - Removed Agent-Attested Display Values section; the `platform` and `device` parameters are defined and described in the AAuth Protocol. + +- draft-hardt-aauth-bootstrap-00 + - Initial draft. + +# Acknowledgments + +TBD. + +{backmatter} diff --git a/aauth-spec/v09/draft-hardt-aauth-events.md b/aauth-spec/v09/draft-hardt-aauth-events.md new file mode 100644 index 00000000..15abfd98 --- /dev/null +++ b/aauth-spec/v09/draft-hardt-aauth-events.md @@ -0,0 +1,758 @@ +%%% +title = "AAuth Events" +abbrev = "AAuth-Events" +ipr = "trust200902" +area = "Security" +workgroup = "TBD" +keyword = ["agent", "events", "webhooks", "async", "subscribe", "http", "identity"] +category = "standard" + +[seriesInfo] +status = "standard" +name = "Internet-Draft" +value = "draft-hardt-aauth-events-latest" +stream = "IETF" + +date = 2026-06-24T00:00:00Z + +[[author]] +initials = "D." +surname = "Hardt" +fullname = "Dick Hardt" +organization = "Hellō" + [author.address] + email = "dick.hardt@gmail.com" + +%%% + + + + AAuth Protocol + + Hellō + + + + + + + + HTTP Signature Keys + + Hellō + + + Cloudflare + + + + + + + + AAuth Rich Resource Requests (R3) + + Hellō + + + + + + + + AAuth Bootstrap Guidance + + Hellō + + + + + + + + AsyncAPI Specification 3.0.0 + + AsyncAPI Initiative + + + + + + +.# Abstract + +This document defines AAuth Events — an event subscription and delivery mechanism for agents operating under the AAuth Protocol ([@!I-D.hardt-oauth-aauth-protocol]). It specifies the subscribe token that agents use to register callbacks with resources, the event token that resources deliver when events fire, and the delivery path through the Agent Provider (AP). AAuth Events enables agents to receive asynchronous notifications without requiring a public endpoint, using the cryptographic identity established by the AAuth Protocol. + +.# Discussion Venues + +*Note: This section is to be removed before publishing as an RFC.* + +Discussion of this document takes place on GitHub at https://github.com/dickhardt/AAuth. Issues, comments, and pull requests are welcome there. Source for this draft is in the same repository. + +{mainmatter} + +# Introduction + +## Agents Cannot Receive Webhooks + +Agents are often not servers with a routable endpoint. Whether running as a workload, a mobile app, or a single-page application, agents typically cannot receive inbound HTTP connections. Existing event delivery mechanisms — webhooks, WebSub, callback URLs — all assume the receiver is always-on and reachable. This assumption fails for agents that run intermittently, execute behind NAT, or live inside a platform that does not expose inbound HTTP. + +At the same time, many interactions agents initiate are inherently asynchronous. An agent books a medical appointment and needs to know if an earlier slot opens. An agent monitors inventory and needs to know when a product becomes available. An agent submits an order and needs confirmation when it ships. In each case, the agent initiates a synchronous request, the resource accepts it, and then the resource needs to reach back to the agent when something changes — potentially hours or days later. + +Existing approaches each fall short: + +- **Webhooks** require the agent to have a public URL. Agents do not. +- **Polling** is wasteful and imprecise. For time-sensitive events like waitlist slots, polling is too slow and too expensive. +- **Server-Sent Events / WebSocket** require a persistent outbound connection, which conflicts with intermittent agent workloads. +- **Message queues** (SQS, Kafka, RabbitMQ) require shared infrastructure, are not web-standard, and have no standardized subscription protocol across trust domains. + +## The Agent Provider as Inbox + +The AAuth Protocol establishes that every agent has an Agent Provider (AP) — a stable, always-on server that issues the agent's identity token. The AP is already a first-class principal in the AAuth ecosystem: it has its own cryptographic identity, publishes metadata at a well-known URL, and is trusted by all parties that interact with the agent. + +AAuth Events uses the AP as the agent's permanent event inbox. A resource that needs to notify an agent does not need to reach the agent directly — it posts the event to the AP's event endpoint. The AP delivers the event to the agent through whatever mechanism the AP and agent have established. The agent does not need a public URL. The AP is the public URL. + +## What AAuth Events Provides + +- **No public endpoint required**: The AP receives events on the agent's behalf. AP-to-agent delivery is platform-dependent and out of scope for this specification. +- **Cryptographic authorization**: The subscribe token is AP-signed and restricts event delivery to a specific resource. No shared secrets. +- **Agent identity at subscription time**: The resource knows cryptographically which agent subscribed, via the `sub` claim in the subscribe token. +- **Protected and public subscriptions**: Public event channels require only a subscribe token. Protected channels use a pre-authorized subscription URL issued by the resource during a prior authenticated interaction. +- **Event discovery via AsyncAPI**: Resources describe their event channels using AsyncAPI ([@AsyncAPI]) as an AAuth R3 vocabulary ([@!I-D.hardt-aauth-r3]). + +## Relationship to Existing Standards + +AAuth Events builds on the AAuth Protocol ([@!I-D.hardt-oauth-aauth-protocol]) and HTTP Signature Keys ([@!I-D.hardt-httpbis-signature-key]). It provides the transport and subscription mechanisms that AsyncAPI ([@AsyncAPI]) describes: resources use AsyncAPI to document their event channels and payload schemas, while AAuth Events defines how agents subscribe and how events are delivered. + +# Conventions and Definitions + +{::boilerplate bcp14-tagged} + +# Terminology + +Terms defined in [@!I-D.hardt-oauth-aauth-protocol] are used here with the same meaning. In particular: Agent, Agent Provider (AP), Agent Token, Resource, Resource Token, Auth Token, Person Server (PS), Access Server (AS), and HTTP Sig. + +This document additionally uses: + +- **Subscribe Token**: A JWT issued by the AP to the agent, authorizing a specific resource to deliver events to the AP on the agent's behalf. Contains the Event ID and the agent's current signing key. +- **Event ID (eid)**: An opaque, AP-generated identifier that uniquely identifies a subscription at the AP. The agent maps the `eid` to its own context. The `eid` is the correlation key between the subscribe token, the AP's subscription record, and the event token. +- **Event Token**: A JWT issued and signed by the resource when an event fires, addressed to the agent (`aud` = agent identifier), and delivered to the AP's event endpoint. +- **Event Endpoint**: An endpoint published by the AP in its metadata at which resources deliver event tokens. +- **Subscription Ticket**: An opaque, short-lived value returned by a resource in response to an authenticated interaction, pre-authorizing a subsequent subscription registration call. Used when subscription to a protected channel requires prior authenticated context. + +# Protocol Overview + +AAuth Events involves four phases: setup, subscription registration, event delivery from resource to AP, and event delivery from AP to agent. + +~~~~ ascii-art +Agent AP Resource + | | | + | (1) request | | + | subscribe | | + | token | | + |------------>| | + | | | + | subscribe | | + | token | | + |<------------| | + | | | + | (2) signed request | + | w/ subscribe token | + |------------------------------------->| + | | | + | 200 OK | + |<-------------------------------------| + | | | + | | ... time passes ... | + | | | + | | (3) POST event token. | + | | (+ optional payload) | + | |<-----------------------| + | | | + | | 202 Accepted | + | |----------------------->| + | | | + | (4) event | | + | token + | | + | payload | | + |<------------| | +~~~~ +Figure: AAuth Events Protocol Overview {#fig-overview} + +1. **Subscribe token acquisition (non-normative)**: The agent requests a subscribe token from its AP. The AP generates an `eid`, creates a subscription record, and issues a subscribe token. This interaction is AP-internal and out of scope for this specification. See (#non-normative-ap-agent) for examples. + +2. **Subscription registration**: The agent presents the subscribe token to the resource as the `Signature-Key` JWT on a signed HTTP request to the resource's subscription endpoint. The resource validates the subscribe token, stores the `eid` and the AP's `event_endpoint` (resolved from the AP's metadata), and registers the subscription. + +3. **Event delivery — resource to AP**: When an event fires, the resource issues an event token (a JWT signed by the resource) and POSTs it to the AP's `event_endpoint`, presenting the event token as the `Signature-Key` JWT. The optional request body carries the AsyncAPI-defined payload for the event type. + +4. **Event delivery — AP to agent (non-normative)**: The AP validates the event, looks up the subscription by `eid`, and delivers the event token and any payload to the agent. This step is platform-dependent and out of scope for this specification. See (#non-normative-ap-agent) for examples. + +# AP Metadata {#ap-metadata} + +The AP MUST publish an `event_endpoint` claim in its metadata at `/.well-known/aauth-agent.json` if it supports AAuth Events. The `event_endpoint` is an HTTPS URL at which the AP receives event tokens from resources. + +```json +{ + "issuer": "https://ap.example", + "jwks_uri": "https://ap.example/.well-known/jwks.json", + "event_endpoint": "https://ap.example/events" +} +``` + +The AP MAY update the `event_endpoint` URL at any time. Resources resolve the AP's `event_endpoint` from the AP's metadata (using the `iss` claim in the subscribe token to locate the AP's well-known document) rather than caching it from the subscribe token. + +# Subscribe Token {#subscribe-token} + +## Structure + +A subscribe token is a JWT with `typ: aa-subscribe+jwt`, issued and signed by the AP, with the following claims: + +Header: + +- `alg`: Signing algorithm. EdDSA is RECOMMENDED. Implementations MUST NOT accept `none`. +- `typ`: `aa-subscribe+jwt` +- `kid`: Key identifier (AP's signing key) + +Required payload claims: + +- `iss`: Agent Provider URL. Used by the resource to locate the AP's metadata and `event_endpoint`. +- `dwk`: `aauth-agent.json` — the well-known metadata document name for key discovery ([@!I-D.hardt-httpbis-signature-key]). +- `sub`: Agent identifier. The AAuth agent identifier (`aauth:local@domain`) of the subscribing agent. +- `aud`: Resource URL. The resource that is authorized to deliver events for this subscription. The resource MUST verify that its own URL matches this claim. +- `cnf`: Confirmation claim ([@!RFC7800]) with `jwk` containing the agent's current public signing key. The resource uses this key to verify the HTTP signature on the subscription registration request. +- `eid`: Event ID. An opaque string generated by the AP, unique to the AP. The agent maps the `eid` to its own context (see (#agent-context-mapping)). The resource includes the `eid` in every event token it issues for this subscription. +- `iat`: Issued-at timestamp. +- `exp`: Expiration timestamp. The resource MUST reject subscribe tokens with `exp` in the past. + +Optional payload claims: + +- `max_uses`: A positive integer. If present, the AP MUST NOT accept more than this many event tokens for this `eid`. If absent, the subscription is unlimited. Enforcement is the AP's responsibility; the AP informs the resource of remaining uses in its `202 Accepted` response (see (#event-delivery)). The resource SHOULD track `remaining_uses` to manage subscription state — for example, prompting the agent to re-subscribe when the subscription is exhausted. + +Example subscribe token payload: + +```json +{ + "iss": "https://ap.example", + "dwk": "aauth-agent.json", + "sub": "aauth:k7q3p9n2@ap.example", + "aud": "https://resource.example", + "cnf": { "jwk": { "kty": "OKP", "crv": "Ed25519", "x": "..." } }, + "eid": "evt_8f3k2n9p", + "iat": 1750000000, + "exp": 1750086400, + "max_uses": 1 +} +``` + +## Presentation + +The agent presents the subscribe token as the `Signature-Key` JWT on the subscription registration request, using `scheme=jwt`: + +```http +POST /appointments/waitlist HTTP/1.1 +Host: resource.example +Content-Type: application/json +Signature-Input: sig=("@method" "@authority" + "@path" "signature-key" "content-type");created=1750000000 +Signature: sig=:...signature bytes...: +Signature-Key: sig=jwt; + jwt="eyJhbGciOiJFZERTQSIsInR5cCI6ImFhLXN1Yitqd3QiLCJraWQiOiIuLi4ifQ..." + +{ + "event_types": ["slot.available"] +} +``` + +The subscribe token replaces the agent token as the `Signature-Key` JWT for subscription registration requests. The `cnf.jwk` in the subscribe token provides the key the resource uses to verify the HTTP signature. The subscribe token is structurally analogous to the agent token — both are AP-signed JWTs carrying `cnf.jwk` — distinguished by `typ`. + +## Verification + +The resource MUST verify the subscribe token as follows: + +1. Decode the JWT header. Verify `typ` is `aa-subscribe+jwt`. +2. Verify `dwk` is `aauth-agent.json`. Discover the AP's JWKS via `{iss}/.well-known/{dwk}` per ([@!I-D.hardt-httpbis-signature-key]). Locate the key matching `kid` and verify the JWT signature. +3. Verify `exp` is in the future and `iat` is not in the future. +4. Verify `aud` matches the resource's own URL. +5. Verify `cnf.jwk` matches the key used to sign the HTTP request. +6. Verify `eid` is present and non-empty. + +After verification, the resource stores the subscription record with sufficient information to deliver events — at minimum `{eid, iss}` (the Event ID and the AP's issuer URL). When an event fires, the resource resolves the AP's `event_endpoint` from `{iss}/.well-known/aauth-agent.json` at delivery time, using standard HTTP caching for the well-known document. + +## Agent Context Mapping {#agent-context-mapping} + +The `eid` is the agent's correlation key. The agent maintains a local mapping of `eid` values to internal context — for example, "eid `evt_8f3k2n9p` corresponds to the appointment waitlist for Dr. Smith opened as part of mission `mission_xyz`". This mapping is the agent's own concern and is not defined by this specification. + +# Subscription Registration {#subscription-registration} + +## Public Subscriptions + +For event channels that do not require prior authorization, the agent presents the subscribe token (as the `Signature-Key` JWT) on a signed POST to the resource's subscription endpoint. No additional credential is required. The resource validates the subscribe token per (#subscribe-token) and registers the subscription. + +## Protected Subscriptions {#protected-subscriptions} + +Some event channels require the agent to be authorized before it can register a subscription — for example, subscribing to events for a specific patient's appointments, or events associated with a particular account. In these cases, the resource does not accept subscription registrations from arbitrary agents; only agents that have already been authorized in an earlier interaction may register. + +This specification defines a **pre-authorized subscription URL** pattern for protected subscriptions: + +1. The agent makes an authenticated request to the resource (using an auth token obtained through one of the AAuth Protocol access modes). +2. The resource, if subscription to events is available for the context established by this interaction, returns a **subscription ticket URL** — an HTTPS URL that encodes a short-lived, single-use authorization to register a subscription. The ticket URL is opaque and is valid only for the specific context (agent, operation, and resource state) established in step 1. +3. The agent obtains a subscribe token from its AP. +4. The agent presents the subscribe token (as the `Signature-Key` JWT) on a signed POST to the subscription ticket URL. No additional auth token is required at this step; the authorization is embedded in the URL. The request body MAY include additional parameters as defined by the resource's AsyncAPI channel schema. +5. The resource validates the subscribe token, verifies the ticket in the URL is valid for the calling agent (by checking `sub` in the subscribe token matches the agent that triggered step 1) and has not been used before, and registers the subscription. + +The subscription ticket URL is resource-controlled: the resource issues it, defines its scope and expiry, and enforces its single-use constraint. The ticket is not defined by this specification beyond the pattern above. + +Example response from step 2: + +```json +{ + "status": "unavailable", + "next_available": "2026-08-24", + "waitlist": { + "subscribe_url": "https://resource.example/waitlist/st_9k2m_abc123", + "event_types": ["slot.available"], + "offer_window_seconds": 300 + } +} +``` + +Example subscription registration from step 4: + +```http +POST /waitlist/st_9k2m_abc123 HTTP/1.1 +Host: resource.example +Content-Type: application/json +Signature-Input: sig=("@method" "@authority" + "@path" "signature-key" "content-type");created=1750000000 +Signature: sig=:...signature bytes...: +Signature-Key: sig=jwt; + jwt="eyJhbGciOiJFZERTQSIsInR5cCI6ImFhLXN1Yitqd3QiLCJraWQiOiIuLi4ifQ..." + +{ + "event_types": ["slot.available"] +} +``` + +The HTTP signature covers the request path (including the ticket), cryptographically binding the subscribe token's identity to this specific ticket URL. + +The resource SHOULD include the subscription ticket URL in an AsyncAPI channel parameter ([@AsyncAPI]) so that agents that discover the resource's event capabilities through its AsyncAPI document know to obtain the URL from a prior API response. + +# Event Token {#event-token} + +## Structure + +When an event fires, the resource issues an event token: a JWT signed by the resource with the following claims: + +Header: + +- `alg`: Signing algorithm. EdDSA is RECOMMENDED. +- `typ`: `aa-event+jwt` +- `kid`: Key identifier (resource's signing key) + +Required payload claims: + +- `iss`: Resource URL. +- `dwk`: `aauth-resource.json` — the well-known metadata document name for key discovery ([@!I-D.hardt-httpbis-signature-key]). +- `aud`: Agent identifier (`aauth:local@domain`). The agent MUST verify this matches its own identifier. +- `eid`: Event ID. MUST match the `eid` from the subscribe token for this subscription. The AP uses the `eid` to look up the subscription record and route to the agent. The agent uses the `eid` to look up its local context mapping. +- `iat`: Issued-at timestamp. +- `exp`: Expiration timestamp. The agent MUST NOT act on an event token with `exp` in the past. The meaning of `exp` is event-specific — for time-sensitive events, it encodes the deadline by which the agent must act. + +The event token is the transport and security layer. It carries no event-specific data. Event-specific content is delivered as the POST body alongside the event token (see (#event-delivery)). + +Example event token payload: + +```json +{ + "iss": "https://resource.example", + "dwk": "aauth-resource.json", + "aud": "aauth:k7q3p9n2@ap.example", + "eid": "evt_8f3k2n9p", + "iat": 1750200000, + "exp": 1750200300 +} +``` + +# Event Delivery: Resource to AP {#event-delivery} + +## Request + +When an event fires for an active subscription, the resource posts to the AP's `event_endpoint`, presenting the event token as the `Signature-Key` JWT. The POST body is the AsyncAPI-defined payload for the event type (OPTIONAL — omitted if the event carries no payload): + +```http +POST /events HTTP/1.1 +Host: ap.example +Content-Type: application/json +Signature-Input: sig=("@method" "@authority" + "@path" "signature-key" "content-type" "content-digest");created=1750200000 +Signature: sig=:...resource signing key signature bytes...: +Signature-Key: sig=jwt; + jwt="eyJhbGciOiJFZERTQSIsInR5cCI6ImFhLWV2ZW50K2p3dCIsImtpZCI6Ii4uLiJ9..." + +{ + "event_type": "slot.available", + "slot_time": "2026-07-15T10:00:00Z" +} +``` + +The event token in `Signature-Key` provides the resource's identity (`iss`) and routing and authorization claims (`eid`, `aud`, `exp`). Unlike agent tokens and subscribe tokens, no `cnf.jwk` is needed: the resource has a stable JWKS discoverable from `{iss}/.well-known/{dwk}`, and the AP uses the same key (identified by `kid` in the JWT header) to verify both the JWT signature and the HTTP signature. This is an extension to the `Signature-Key` JWT scheme: when a JWT has `dwk` but no `cnf`, the verifier resolves the HTTP signing key from `{iss}/.well-known/{dwk}` using `kid` rather than from an inline `cnf.jwk`. The request body structure is defined by the resource's AsyncAPI message schema for the event type (see (#event-discovery)). The AP forwards both the event token and the payload body to the agent. + +The resource resolves the AP's `event_endpoint` from `{iss}/.well-known/aauth-agent.json` at delivery time, using standard HTTP caching for the AP's well-known document. + +## AP Validation + +The AP MUST validate the event delivery request as follows: + +1. Extract the event token JWT from the `Signature-Key` header. Verify `typ` is `aa-event+jwt`. +2. Discover the resource's JWKS via `{iss}/.well-known/{dwk}`. Locate the key matching `kid` and verify the JWT signature. +3. Verify the HTTP signature using the same key (matched by `kid`). This applies the `dwk`-without-`cnf` extension to the Signature-Key JWT scheme: the JWT signing key and the HTTP signing key are the same key, discoverable from the resource's well-known document. +4. Look up the subscription record by `eid`. If no active subscription exists for this `eid`, return `404`. +5. Verify `iss` matches the resource recorded at subscription time (the `aud` of the subscribe token for this `eid`). +6. Verify the event token `exp` is in the future. +7. If `max_uses` is set in the subscribe token, verify the use count has not been exceeded. Increment the use count atomically. If the use limit is reached, the AP MAY mark the subscription as complete after delivery. +8. Verify the event token `aud` matches the agent identifier in the subscription record. + +If all checks pass, the AP returns `202 Accepted` and proceeds with delivery to the agent. The AP MUST NOT return `202` before the event has been durably recorded for delivery. If `max_uses` was set in the subscribe token, the AP MUST include a JSON response body with a `remaining_uses` field indicating how many more event tokens the AP will accept for this `eid`: + +```http +HTTP/1.1 202 Accepted +Content-Type: application/json + +{ + "remaining_uses": 0 +} +``` + +When `remaining_uses` is `0`, the subscription is exhausted. The resource SHOULD clean up its subscription record and MAY prompt the agent to re-subscribe on the next interaction. When `max_uses` was not set, the AP returns `202 Accepted` with no body (or an empty JSON object). + +The AP returns `400` for malformed requests, `401` if the resource's HTTP signature cannot be verified, `403` if the resource does not match the subscription's authorized resource, `404` if the `eid` is unknown or the subscription has expired, and `429` if `max_uses` has been exceeded. + +# Event Delivery: AP to Agent {#ap-to-agent} + +How the AP delivers the event token to the agent is platform-dependent and outside the scope of this specification. The AP is the agent's inbox; the internal mechanism is an implementation choice for the AP and agent. + +See (#non-normative-ap-agent) for non-normative examples of AP-to-agent delivery for different platforms. + +## Agent Verification + +Upon receiving an event token (and optional payload) from the AP, the agent MUST: + +1. Decode the JWT header. Verify `typ` is `aa-event+jwt`. +2. Discover the resource's JWKS via `{iss}/.well-known/{dwk}` per ([@!I-D.hardt-httpbis-signature-key]). Verify the JWT signature. +3. Verify `aud` matches the agent's own identifier. +4. Verify `exp` is in the future. If `exp` has passed, the agent SHOULD NOT act on the event (the response window has closed). +5. Look up `eid` in the agent's local context mapping to recover the context associated with this subscription. +6. Deduplicate: if the agent has already processed an event with this `eid` from this `iss`, it SHOULD ignore the duplicate. The `eid` is a natural idempotency key. + +If a payload was included, the agent MAY use it directly. The payload structure is defined by the resource's AsyncAPI message schema for the event type. + +# Event Discovery {#event-discovery} + +Resources describe their event capabilities using AsyncAPI ([@AsyncAPI]) as an AAuth R3 vocabulary ([@!I-D.hardt-aauth-r3]). + +## R3 Vocabulary Identifier + +The vocabulary identifier for AAuth Events is: + +``` +urn:aauth:vocabulary:asyncapi +``` + +Resources that support AAuth Events SHOULD declare this vocabulary in their AAuth resource metadata: + +```json +{ + "issuer": "https://resource.example", + "r3_vocabularies": { + "urn:aauth:vocabulary:openapi": "/openapi.json", + "urn:aauth:vocabulary:asyncapi": "/asyncapi.json" + } +} +``` + +## AsyncAPI Document + +The resource's AsyncAPI document describes: + +- **Channels**: Event streams the agent may subscribe to. Channels MAY use parameterized addresses (e.g., `/waitlist/{subscriptionTicket}`) when the subscription endpoint URL is dynamic (see (#protected-subscriptions)). +- **Operations**: `receive` operations on channels, with the security requirement and message schema. +- **Messages**: The payload schema for each event type. The AsyncAPI payload schema describes the `payload` field in the event delivery POST body (see (#event-delivery)). The AAuth event token envelope (`iss`, `aud`, `eid`, `exp`) is implicit and not part of the AsyncAPI schema. +- **Security schemes**: The AAuth subscribe token security scheme. + +## Security Scheme + +Resources MUST declare the AAuth subscribe token security scheme as follows: + +```yaml +securitySchemes: + aauth_subscribe: + type: http + scheme: aauth-subscribe + description: > + AAuth Subscribe Token (typ: aa-subscribe+jwt), issued by the agent's Agent + Provider, presented as the Signature-Key JWT with HTTP Message Signatures. + See draft-hardt-aauth-events. +``` + +Operations that require only a subscribe token declare: + +```yaml +security: + - aauth_subscribe: [] +``` + +Operations that require a pre-authorized subscription URL (see (#protected-subscriptions)) have no security scheme on the subscription endpoint itself — the subscription ticket in the URL carries the authorization. The resource SHOULD annotate such channels with a description noting that the subscription URL is obtained from a prior authenticated API call. + +## Example AsyncAPI Document + +```yaml +asyncapi: 3.0.0 +info: + title: Appointments Events + version: 1.0.0 + +channels: + waitlistPublic: + address: /appointments/waitlist/public + messages: + slotAvailable: + $ref: '#/components/messages/SlotAvailable' + + waitlistProtected: + address: /appointments/waitlist/{subscriptionTicket} + description: > + Subscription URL returned by POST /appointments when no slot is + immediately available and the calling agent is authorized for + waitlist access. The subscriptionTicket is embedded in the URL + and carries the authorization context. + parameters: + subscriptionTicket: + description: Single-use ticket from the POST /appointments response. + messages: + slotAvailable: + $ref: '#/components/messages/SlotAvailable' + +operations: + subscribePublicWaitlist: + action: receive + channel: + $ref: '#/channels/waitlistPublic' + security: + - aauth_subscribe: [] + + subscribeProtectedWaitlist: + action: receive + channel: + $ref: '#/channels/waitlistProtected' + +components: + messages: + SlotAvailable: + contentType: application/jwt + payload: + type: object + properties: + event_type: + type: string + const: slot.available + slot_time: + type: string + format: date-time + doctor_id: + type: string + required: + - event_type + - slot_time + + securitySchemes: + aauth_subscribe: + type: http + scheme: aauth-subscribe + description: AAuth Subscribe Token as Signature-Key JWT +``` + +# Security Considerations + +## Subscribe Token Scope + +The `aud` claim in the subscribe token restricts which resource may deliver events to the AP for this `eid`. If a resource attempts to deliver events for an `eid` issued to a different resource, the AP MUST reject the request (#event-delivery). This prevents a compromised resource from hijacking another resource's subscription channel. + +## Event Token Forgery + +Event tokens are signed by the resource using the resource's own signing key. The agent verifies the event token against the resource's JWKS ([@!I-D.hardt-httpbis-signature-key]). A party without the resource's private key cannot forge a valid event token. There are no shared secrets in AAuth Events. + +## Replay Prevention + +The AP enforces `max_uses` per `eid` and rejects event tokens with `exp` in the past. The agent additionally deduplicates on `eid` from the same `iss` (#agent-verification). These two layers prevent replay: a captured event token cannot be re-delivered once the AP has tracked its delivery and the agent has processed it. + +## Subscribe Token Replay at Registration + +A subscribe token with a valid `exp` could in principle be presented to the resource's subscription endpoint more than once. The `eid` is the deduplication key: the resource SHOULD reject subscription registration requests for an `eid` it has already registered. Single-use enforcement of the subscription ticket URL (in protected subscriptions) provides an additional constraint. + +## Pre-Authorized Subscription URL Security + +The subscription ticket URL (see (#protected-subscriptions)) encodes authorization from a prior authenticated context. Resources MUST ensure that subscription tickets are: + +- Short-lived (expiry appropriate to the expected delay between issuing and using the ticket). +- Single-use (the resource invalidates the ticket on first successful subscription registration). +- Bound to the agent that triggered the prior interaction (the resource MUST verify that `sub` in the subscribe token matches the agent that established the ticket). + +## AP as Delivery Intermediary + +The AP sees every event token delivered to an agent. The AP validates the event token's `iss`, `aud`, and `eid` claims but does not need to inspect resource-specific payload claims. APs SHOULD document their data retention policies for event tokens. + +## Resource Enumeration + +A resource that exposes its AsyncAPI document publicly reveals what event types it emits. This may be intentional (public API). Resources that wish to restrict event type discovery MAY gate their AsyncAPI document with AAuth authentication. + +# Privacy Considerations + +## Agent Identifier Stability + +The `sub` claim in the subscribe token carries the agent's stable identifier. Resources that receive subscribe tokens can correlate an agent's subscription activity over time. This is the intended property — the resource needs to know which agent subscribed. Agents and APs should be aware that subscription registrations leave a record at the resource. + +## Event Content + +The event token carries no event-specific data — it is the security and routing envelope only. Event-specific content travels in the `payload` field of the POST body (see (#event-delivery)), which is also visible to the AP during routing. Resources SHOULD NOT include sensitive personal data in the payload beyond what is necessary for the agent to evaluate relevance. Sensitive details SHOULD be fetched by the agent from the resource's data API using a current auth token. + +# IANA Considerations + +## JWT Type Values + +This specification defines the following JWT `typ` header parameter values, to be registered in the IANA "JSON Web Token Types" registry: + +- `aa-subscribe+jwt`: AAuth Subscribe Token. +- `aa-event+jwt`: AAuth Event Token. + +## AAuth R3 Vocabulary Identifiers + +This specification defines the following R3 vocabulary identifier: + +- `urn:aauth:vocabulary:asyncapi`: AAuth AsyncAPI event vocabulary. + +# Implementation Status + +*Note: This section is to be removed before publishing as an RFC.* + +TBD + +# Document History + +*Note: This section is to be removed before publishing as an RFC.* + +- draft-hardt-aauth-events-00 + - Initial draft. + +# Acknowledgments + +TBD. + +{backmatter} + +# Design Rationale {#design-rationale} + +This appendix explains the key design decisions in AAuth Events and the alternatives considered. + +## Why the AP Is the Delivery Intermediary + +Agents are workloads, not servers. They spin up, execute, and terminate. They run behind NAT, inside containers, or on mobile devices. They have no stable public endpoint. + +Every existing push delivery mechanism (webhooks, WebSub, CIBA ping/push mode, W3C Web Push) assumes the subscriber has a stable HTTP endpoint. W3C Web Push is the closest analog to what AAuth Events does — it uses a browser push service (Google/Apple/Mozilla) as the subscriber's stable address. AAuth Events uses the AP in this role, with two improvements: the AP already has a trust relationship with the agent (it issued the agent's identity token), and the subscriber's identity is cryptographic (not just an opaque push service subscription). + +The AP-as-inbox pattern mirrors how email works: you do not need to be online when someone sends you mail. The mail server is the stable address. AAuth Events gives agents the same property for event delivery. + +## Why the Subscribe Token Is the Signature-Key JWT + +The subscribe token simultaneously serves two functions: it proves the agent's identity (via `cnf.jwk` + HTTP signature) and registers the subscription (via `eid`, `aud`, `exp`). Presenting it as the `Signature-Key` JWT means a single signed HTTP request to the subscription endpoint accomplishes both without a separate credential or header. + +This is structurally analogous to the agent token — both are AP-signed JWTs with `cnf.jwk`, distinguished by `typ`. The resource's verification path is the same whether it is processing an identity-based request with an agent token or a subscription registration with a subscribe token. + +The alternative — a separate header or body parameter carrying the subscribe token alongside the normal agent token — was rejected because it requires two credentials where the subscribe token alone is sufficient. + +## Why `aud` in the Subscribe Token Is the Resource + +The `aud` claim restricts event delivery authorization to a specific resource. Only the resource named in `aud` may deliver events for this `eid` to the AP. This prevents: + +- A compromised resource from injecting events into another agent's subscription channels. +- The AP from accepting events from unexpected callers. + +The AP enforces this by matching the calling resource (identified by its HTTP signature) against the `aud` in the subscribe token stored in the subscription record. + +## Why `exp` Is the JWT Validity Period, Not the Subscription Lifetime + +Subscription lifetime is a negotiation between the agent and the resource at registration time. The resource has its own policy on maximum subscription duration. These durations can be days or months and are resource-specific. + +The subscribe token's `exp` is the standard JWT validity window — how long the resource may accept this token for registration. Conflating JWT validity with subscription lifetime would either force a very long-lived token (security concern: replay window) or a very short subscription (UX concern: subscriptions expire before they're useful). + +The resource stores the subscription record with whatever lifetime the agent and resource negotiate at registration. The subscribe token is a registration credential, not a subscription policy document. + +## Why `max_uses` Is in the Subscribe Token + +`max_uses` is the AP's throttle on how many event tokens it will accept for a given `eid`. It is AP-enforced, not resource-enforced. Placing it in the subscribe token — which the AP issued and controls — makes it AP-policy without requiring a separate AP configuration step. + +For single-shot events (confirm this reservation), `max_uses: 1` ensures the AP accepts exactly one event. For ongoing subscriptions, `max_uses` is omitted (unlimited). When `max_uses` is absent, there is no sentinel value — absence means unlimited, avoiding any need for a special value such as -1. + +The AP informs the resource of remaining uses in the `202 Accepted` response body after each delivery. The resource SHOULD use `remaining_uses: 0` as the signal to clean up its subscription record and prompt the agent to re-subscribe. This keeps the AP as the enforcement point while giving the resource the state it needs to manage the subscription lifecycle. + +## Why the Event Token Is the Transport Layer, Not the Data Layer + +The event token carries only what is needed for security, routing, and correlation: `iss`, `aud`, `eid`, `exp`. It is the cryptographic layer — the AP uses it to authenticate the resource, look up the subscription, and verify the delivery is authorized. The agent uses it to verify authenticity and look up its context via `eid`. + +Event-specific data travels as a separate `payload` in the same POST body. The AsyncAPI message schema for the event type defines the payload structure. This separation keeps the JWT minimal and avoids embedding event data in a signed-but-not-encrypted envelope. For events where the agent needs full details beyond the payload, it fetches them from the resource's data API using a current auth token. + +## Why `exp` in the Event Token Is the Response Window + +The `exp` claim in the event token defines how long the agent has to respond to the event. Its meaning is event-specific: for a waitlist slot, it is the deadline by which the agent must claim the slot; for a shipping confirmation, it may be a much longer acknowledgment window. + +The AP delivers events in near real-time. If the AP cannot deliver an event before its `exp`, the agent should not act on it (the response window has closed). The agent verifies `exp` before acting. + +## Why Protected Subscriptions Use a Pre-Authorized URL + +For protected event channels, the resource needs to verify that the subscribing agent has been authorized in a prior interaction before accepting the subscription. The naive approach — requiring both an auth token and a subscribe token on the subscription call — is awkward because the two tokens serve different purposes and the auth token conveyance alongside a `Signature-Key` subscribe token has no established AAuth pattern. + +The pre-authorized subscription URL pattern solves this cleanly: authorization is captured in the prior authenticated interaction, and the resource returns a ticket URL that encodes this context. The agent then presents only the subscribe token at the ticket URL. The HTTP signature covers the URL path (including the ticket), binding the subscribe token's identity to this specific authorization context. + +This mirrors established patterns (OAuth authorization codes, S3 presigned URLs) while preserving the AAuth Events invariant: all subscription endpoints accept only the subscribe token as the `Signature-Key` JWT. + +## Why AsyncAPI Is the Discovery Vocabulary + +AsyncAPI is the de facto standard for describing event-driven APIs. It describes channels, message schemas, security requirements, and (via parameterized addresses) dynamic subscription endpoints. The AAuth R3 vocabulary framework already accommodates multiple vocabularies per resource — AsyncAPI sits naturally alongside OpenAPI for synchronous operations. + +The target reader of an AAuth resource's AsyncAPI document is an AAuth-capable agent, not generic AsyncAPI tooling. This means the `aauth_subscribe` security scheme (type: `http`, scheme: `aauth-subscribe`) does not need to be understood by Swagger UI or code generators — it is a declaration for the agent's benefit, interpreted per this specification. + +## Comparison to Existing Patterns + +| | AAuth Events | Webhooks | WebSub | CIBA (ping) | Web Push | +|---|---|---|---|---|---| +| Receiver needs public URL | No | Yes | Yes | Yes | No | +| Caller identity | Cryptographic (resource key) | HMAC shared secret | None | Client creds | Push service | +| Subscriber identity at resource | Agent identifier (`sub`) | None | None | Client ID | Subscription ID | +| Per-operation subscription | Yes | No (account-level) | No | Yes | No | +| General event types | Yes | Yes | Yes | No (auth only) | Yes | +| Standard description format | AsyncAPI (R3) | Proprietary | Atom/RSS | N/A | None | + +# Non-Normative AP-to-Agent Delivery Examples {#non-normative-ap-agent} + +How the AP delivers an event token to an agent is platform-dependent and not specified by this document. The following examples illustrate common patterns, paralleling the approach taken in [@?I-D.hardt-aauth-bootstrap] for agent token acquisition. + +## Workload Agents + +A workload agent (running in a cloud function, container, or batch job) may poll the AP for pending event tokens on startup, using an AP-internal endpoint. The AP acts as a durable inbox — storing event tokens until the workload polls. The workload validates and processes pending events before beginning its primary task. + +## Mobile Agents + +A mobile agent may receive events via the platform's native push notification infrastructure (APNs on iOS, FCM on Android). The AP holds a push token registered by the agent at enrollment time and delivers event tokens to the agent via push notification. The agent wakes on receipt, fetches the full event token from the AP if needed, and processes it. + +## Web Agents + +A web agent with a persistent session may receive events via a server-sent event (SSE) or WebSocket connection that the agent maintains to the AP. The AP streams event tokens over this connection as they arrive. + +## Self-Hosted Agents + +A self-hosted agent may receive events in two ways depending on whether it manages its own AP or delegates to an external one. + +If the agent acts as its own AP ([@?I-D.hardt-aauth-bootstrap]), it may expose an internal event endpoint. Events are delivered directly to this endpoint by the resource — the AP and agent are collocated. + +If the agent uses an external AP service, it maintains an outbound persistent connection (SSE, WebSocket, or a similar mechanism) to the AP's inbox service. The AP delivers event tokens and payloads over this connection as they arrive. The self-hosted agent does not need a public inbound endpoint — the outbound connection to the AP is sufficient. + + diff --git a/aauth-spec/v09/draft-hardt-aauth-r3.md b/aauth-spec/v09/draft-hardt-aauth-r3.md new file mode 100644 index 00000000..72520982 --- /dev/null +++ b/aauth-spec/v09/draft-hardt-aauth-r3.md @@ -0,0 +1,665 @@ +%%% +title = "AAuth Rich Resource Requests (R3)" +abbrev = "AAuth-R3" +ipr = "trust200902" +area = "Security" +workgroup = "TBD" +keyword = ["agent", "authorization", "http", "resource"] + +[seriesInfo] +status = "standard" +name = "Internet-Draft" +value = "draft-hardt-aauth-r3-latest" +stream = "IETF" + +date = 2026-03-24T00:00:00Z + +[[author]] +initials = "D." +surname = "Hardt" +fullname = "Dick Hardt" +organization = "Hellō" + [author.address] + email = "dick.hardt@gmail.com" + +%%% + + + + AAuth Protocol + + Hellō + + + + + + + + AAuth Events + + Hellō + + + + + + +.# Abstract + +This document defines AAuth Rich Resource Requests (R3), an extension to the AAuth Protocol ([@!I-D.hardt-aauth-protocol]) that enables structured, vocabulary-based authorization for resource access. Resources publish R3 documents (content-addressed authorization definitions) and advertise vocabularies describing their operations. Agents request access using those vocabularies. Auth tokens carry granted operations in the same vocabulary format, enabling resources to enforce authorization directly from the token. R3 provides human-displayable context for consent decisions and content-addressed audit provenance via the `r3_s256` hash in auth tokens. + +.# Discussion Venues + +*Note: This section is to be removed before publishing as an RFC.* + +This document is part of the AAuth specification family. Source for this draft and an issue tracker can be found at https://github.com/dickhardt/AAuth. + +{mainmatter} + +# Introduction + +**Status: Exploratory Draft** + +The AAuth Protocol ([@!I-D.hardt-aauth-protocol]) defines resource tokens as the mechanism by which resources declare what authorization is needed to access them, and scope strings as the primary way to express what operations are available. Scopes are sufficient for simple, well-known access patterns but are limited in three respects: + +1. **Human comprehension.** Scope strings like `calendar:write` are not self-describing to users or auth agents making approval decisions. + +2. **Machine precision.** Scopes do not express which specific operations are being authorized or distinguish operations that need per-call approval. + +3. **Audit completeness.** Scopes do not identify which specific version of an authorization definition was in effect at the time of approval. + +R3 addresses these by introducing: + +- **Vocabularies** that describe a resource's operations in terms the agent already understands (MCP tools, OpenAPI operations, gRPC methods, etc.) +- **R3 documents**: structured, content-addressed authorization definitions published by the resource and fetched by the AS +- **Vocabulary-based grants** in auth tokens, so resources can enforce authorization directly from claims they understand + +# Conventions and Definitions + +{::boilerplate bcp14-tagged} + +# Terminology + +- **Vocabulary**: A defined scheme for expressing resource operations. Each vocabulary corresponds to an API description format (MCP, OpenAPI, gRPC, GraphQL, AsyncAPI, WSDL, OData). Resources advertise which vocabularies they support; agents use them to request access. +- **R3 Document**: A JSON document published by a resource, describing the operations it provides and the consequences of granting access. Identified by the SHA-256 hash of its content. Fetched by both the PS (for user consent using `display` fields) and the AS (for policy evaluation using `operations`); not accessible to agents. +- **R3 URI (`r3_uri`)**: A URI identifying an R3 document. Included in a resource token. +- **R3 Hash (`r3_s256`)**: A SHA-256 hash of the R3 document, base64url-encoded without padding. Included alongside `r3_uri` in the resource token and the auth token. + +# Vocabularies + +Resources advertise their supported vocabularies in well-known metadata. Each vocabulary maps to an API description format that agents already know how to discover and parse. + +## Resource Metadata Extensions + +R3 extends the `/.well-known/aauth-resource.json` document defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol]): + +```json +{ + "resource": "https://calendar.example.com", + "r3_vocabularies": { + "urn:aauth:vocabulary:mcp": "https://calendar.example.com/mcp", + "urn:aauth:vocabulary:openapi": "https://calendar.example.com/openapi.json" + } +} +``` + +**`r3_vocabularies`** (OPTIONAL). A JSON object mapping vocabulary URIs to their discovery endpoints. Keys MUST be vocabulary URIs from the `urn:aauth:vocabulary:` namespace for standard vocabularies defined in this document, or third-party URI namespaces for proprietary vocabularies. Values are vocabulary-specific discovery endpoints (the MCP server URL, the OpenAPI spec URL, the gRPC reflection endpoint, etc.). A resource MAY advertise multiple vocabularies simultaneously. + +## Standard Vocabularies + +This document defines seven standard vocabularies. Third parties MAY define additional vocabularies using their own URI namespaces. Each vocabulary defines: the vocabulary URI, the structure of operation requests, how the resource maps operations to R3 documents, and the discovery endpoint. + +Standard vocabularies use the `urn:aauth:vocabulary:` namespace. + +### MCP Vocabulary (`urn:aauth:vocabulary:mcp`) {#mcp-vocabulary} + +For resources that expose an MCP server. The discovery endpoint is the MCP server URL. Agents discover available tool names via MCP tool discovery. + +Each operation entry contains: + +- **`tool`** (REQUIRED). The MCP tool name as advertised by the MCP server's tool discovery. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:mcp", + "operations": [ + { "tool": "create_calendar_event" }, + { "tool": "modify_calendar_event" } + ] +} +``` + +### OpenAPI Vocabulary (`urn:aauth:vocabulary:openapi`) {#openapi-vocabulary} + +For resources that expose an OpenAPI-described HTTP API. The discovery endpoint is the OpenAPI specification URL. Agents discover available operations by fetching and parsing the spec. + +Each operation entry contains: + +- **`operationId`** (REQUIRED). The `operationId` as defined in the OpenAPI specification. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:openapi", + "operations": [ + { "operationId": "createEvent" }, + { "operationId": "updateEvent" } + ] +} +``` + +### gRPC Vocabulary (`urn:aauth:vocabulary:grpc`) {#grpc-vocabulary} + +For resources that expose a gRPC server. The discovery endpoint is the gRPC server reflection endpoint (supporting `grpc.reflection.v1.ServerReflection`) or a hosted `.proto` file URL. + +Each operation entry contains: + +- **`method`** (REQUIRED). The fully qualified gRPC method name in the form `package.ServiceName/MethodName`. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:grpc", + "operations": [ + { "method": "calendar.CalendarService/CreateEvent" }, + { "method": "calendar.CalendarService/UpdateEvent" } + ] +} +``` + +### GraphQL Vocabulary (`urn:aauth:vocabulary:graphql`) {#graphql-vocabulary} + +For resources that expose a GraphQL API. The discovery endpoint is the GraphQL endpoint. Agents discover available operations via GraphQL introspection (`__schema` query). + +Each operation entry contains: + +- **`operation`** (REQUIRED). The GraphQL operation name. MUST be a named query, mutation, or subscription. +- **`type`** (REQUIRED). One of `query`, `mutation`, or `subscription`. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:graphql", + "operations": [ + { "operation": "CreateCalendarEvent", "type": "mutation" }, + { "operation": "GetCalendarEvents", "type": "query" } + ] +} +``` + +### AsyncAPI Vocabulary (`urn:aauth:vocabulary:asyncapi`) {#asyncapi-vocabulary} + +For resources that emit events described by AsyncAPI. The discovery endpoint is the AsyncAPI specification URL. + +- **`operationId`** (REQUIRED). The `operationId` as defined in the AsyncAPI specification. +- **`action`** (OPTIONAL). The AsyncAPI action type: `send` or `receive`. Agents subscribing to events use `receive`. + +When a resource grants an agent an AsyncAPI subscription operation via R3, the actual subscription registration and event delivery use the AAuth Events protocol ([@?I-D.hardt-aauth-events]). The resource issues a subscription ticket URL in response to the authenticated request; the agent then completes subscription registration using a subscribe token per AAuth Events. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:asyncapi", + "operations": [ + { "operationId": "publishCalendarUpdate", "action": "send" }, + { "operationId": "receiveCalendarEvent", "action": "receive" } + ] +} +``` + +### WSDL Vocabulary (`urn:aauth:vocabulary:wsdl`) {#wsdl-vocabulary} + +For resources that expose a SOAP/WSDL-described web service. The discovery endpoint is the WSDL document URL. + +Each operation entry contains: + +- **`operation`** (REQUIRED). The operation name as defined in the WSDL `portType` or `binding`. +- **`service`** (OPTIONAL). The WSDL service name, for disambiguation when multiple services expose the same operation name. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:wsdl", + "operations": [ + { "operation": "CreateCalendarEvent", "service": "CalendarService" } + ] +} +``` + +### OData Vocabulary (`urn:aauth:vocabulary:odata`) {#odata-vocabulary} + +For resources that expose an OData service. The discovery endpoint is the OData service root URL. Agents discover entity sets, functions, and actions via the `$metadata` document. + +Each operation entry contains: + +- **`operation`** (REQUIRED). An entity set name, a bound function (`EntitySet/FunctionName`), or a bound action (`EntitySet/ActionName`). +- **`methods`** (OPTIONAL). An array of HTTP methods for entity set CRUD (e.g., `["GET", "POST"]`). Omitted for bound functions and actions. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:odata", + "operations": [ + { "operation": "Events", "methods": ["GET", "POST", "PATCH"] }, + { "operation": "Events/SendCancellation" } + ] +} +``` + +# Authorization Endpoint Extensions {#authorization-endpoint-extensions} + +R3 extends the authorization endpoint defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol]) with an `r3_operations` request parameter. When an agent wants to declare intended operations using a resource's vocabulary, it includes `r3_operations` in the authorization endpoint request body. + +## Request + +The agent sends `r3_operations` in the authorization endpoint request: + +```http +POST /authorize HTTP/1.1 +Host: calendar.example.com +Content-Type: application/json +Signature-Input: sig=("@method" "@authority" "@path" "signature-key");created=1741824000 +Signature: sig=:...signature bytes...: +Signature-Key: sig=jwt;jwt="eyJhbGc..." + +{ + "r3_operations": { + "vocabulary": "urn:aauth:vocabulary:openapi", + "operations": [ + { "operationId": "createEvent" }, + { "operationId": "updateEvent" } + ] + } +} +``` + +**`r3_operations`** (OPTIONAL). An object containing: + +- **`vocabulary`** (REQUIRED). A URI identifying the vocabulary. MUST be supported by the resource as advertised in `r3_vocabularies`. +- **`operations`** (REQUIRED). An array of operation requests. Structure is vocabulary-specific; see {{mcp-vocabulary}} through {{odata-vocabulary}}. + +When `r3_operations` is present, the resource maps the declared operations to an appropriate R3 document and includes `r3_uri` and `r3_s256` in the resource token. When `r3_operations` is absent, the resource MAY still include R3 claims in the resource token based on its own policy. + +## Response + +The resource returns a resource token as defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol]), extended with R3 claims: + +```json +{ + "resource_token": "eyJhbGciOiJFUzI1NiJ9..." +} +``` + +The resource token contains `r3_uri` and `r3_s256` identifying the R3 document that covers the requested operations. The resource's internal mapping from operations to R3 documents is opaque to the agent. + +## Operations Spanning Multiple Definitions {#operations-spanning-definitions} + +A resource MAY organize its authorization definitions into multiple R3 documents internally — for example, one document per scope or operation group. A single resource token carries exactly one `r3_uri`/`r3_s256` pair, and the resulting auth token therefore pins exactly one R3 document. + +When an agent's `r3_operations` request includes operations that the resource maps to more than one of its internal definitions, the resource MUST compose a single R3 document that covers all of the requested operations and reference that composed document in the resource token: + +- **`operations`** is the union of the requested operations, expressed in the request's vocabulary. +- **`display`** describes the combined access. The resource MAY merge the `display` sections of the underlying definitions (for example, concatenating `implications` and unioning `data_accessed`) or author a purpose-built summary for the combination. + +The composed document is served at a fresh content-addressed `r3_uri` exactly like any other R3 document (see {{content-addressing}}): the resource builds it on the fly and persists the serialized bytes so the hash remains stable across the AS and PS fetches. Because R3 documents are content-addressed, an identical combination of operations reduces to the same hash and MAY be cached and reused across requests. + +This composition is opaque to the agent. The agent sees one `r3_uri`/`r3_s256` in the resource token regardless of how many internal definitions the requested operations were drawn from, and the auth token's `r3_granted` and `r3_conditional` claims express the granted operations against that single composed document. + +# R3 Document {#r3-document} + +An R3 document is a JSON object published by the resource at a URI. It describes the authorization semantics for a class of access: what operations are covered (in vocabulary format), what the access means in human terms, and what consequences it carries. + +The document MUST be served over HTTPS. The resource MUST require a valid HTTP Message Signature on requests to R3 document URIs, and MUST reject requests that are not signed by the resource's AS. Agents cannot fetch R3 documents. + +```json +{ + "version": "2", + "vocabulary": "urn:aauth:vocabulary:mcp", + "operations": [ + { "tool": "create_calendar_event" }, + { "tool": "modify_calendar_event" } + ], + "display": { + "summary": "Create and modify events on your work calendar", + "implications": "Meetings can be scheduled or rescheduled. Existing events can be modified.", + "data_accessed": "Event titles, times, attendees, and descriptions in the work calendar", + "irreversible": "Sent meeting invitations cannot be unsent" + } +} +``` + +## Fields + +**`version`** (RECOMMENDED). A string identifying the version of this R3 document. The combination of `r3_uri` + SHA-256 hash provides content-addressing independent of this field; `version` is for human readability. + +**`vocabulary`** (REQUIRED). The vocabulary URI identifying how operations are expressed. MUST match one of the vocabularies the resource advertises in `r3_vocabularies`. + +**`operations`** (REQUIRED). An array of operations covered by this R3 document, using the vocabulary-specific structure defined in {{mcp-vocabulary}} through {{odata-vocabulary}}. This is the same format used in the agent's `r3_operations` request and in the auth token's `r3_granted` and `r3_conditional` claims. + +**`display`** (RECOMMENDED). Human-readable descriptions of the consequences of granting this access. The resource describes what *it* does, not what the agent intends: + +- `summary` (REQUIRED if `display` present). A short plain-language description suitable for a consent UI or auth agent. +- `implications` (OPTIONAL). Side effects of granting this access: emails sent, records modified, costs incurred. +- `data_accessed` (OPTIONAL). What data becomes visible to the caller. +- `irreversible` (OPTIONAL). Plain-language description of actions that cannot be undone. + +## Content Addressing {#content-addressing} + +The R3 hash (`r3_s256`) is computed as the SHA-256 hash of the bytes of the R3 document as served by the resource, base64url-encoded without padding. + +The resource's serialization is the document. There is no canonicalization step — verifiers hash the bytes received over the wire, not a normalized form. Resources MUST serialize the R3 document once and serve those exact bytes verbatim on every request for the same `r3_uri`. Re-serialization between hash computation and serving (e.g. middleware that parses and re-stringifies JSON, CDN minification, response framework helpers that reorder keys) will produce different bytes and break hash verification. Resources that build R3 documents on the fly SHOULD persist the serialized bytes (e.g. in a key-value store keyed by `r3_uri` or `r3_s256`) rather than re-build the document per request. + +The `r3_s256` hash is the document's identity, not the URI. The AS caches documents by hash. If a resource updates the document at the same URI, existing auth tokens still reference the previous hash (which the AS has cached). New resource tokens reference the new hash. This enables: + +- **Infinite caching by the AS.** A document that verifies against its hash need never be re-fetched. +- **Permanent audit records.** An auth token carrying `r3_s256` identifies the exact authorization semantics that were approved, regardless of subsequent changes at the same URI. + +## Resource Token Extensions + +R3 extends the resource token defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol]) (a JWT with `typ: resource+jwt`) with two additional payload claims. When a resource includes R3 information, it MUST include both. + +Base claims (from AAuth Protocol): +- `iss`: Resource URL +- `dwk`: `aauth-resource.json` +- `aud`: Auth server URL +- `jti`: Unique token identifier +- `agent`: Agent identifier +- `agent_jkt`: JWK Thumbprint of the agent's signing key +- `iat`: Issued at timestamp +- `exp`: Expiration timestamp +- `scope`: Requested scopes (optional) + +R3 extension claims: +- **`r3_uri`** (REQUIRED for R3): The URI where the AS can fetch the R3 document. The AS authenticates itself using an HTTP Message Signature. +- **`r3_s256`** (REQUIRED for R3): The SHA-256 hash of the R3 document at `r3_uri`, base64url-encoded without padding. + +```json +{ + "typ": "resource+jwt", + "alg": "EdDSA", + "kid": "resource-key-1" +} +``` + +```json +{ + "iss": "https://calendar.example.com", + "dwk": "aauth-resource.json", + "aud": "https://as.example.com", + "jti": "rt-8f3a2b", + "agent": "assistant@agent.example", + "agent_jkt": "NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs", + "r3_uri": "https://calendar.example.com/r3/a1b2c3d4", + "r3_s256": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcd", + "iat": 1741824000, + "exp": 1741824300 +} +``` + +Resource tokens MAY include both `scope` (as defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol])) and R3 claims. When both are present, the AS MUST enforce both independently. + +# R3 Processing + +Both the PS and the AS fetch R3 documents, but for different purposes: + +- **The PS** fetches R3 to present the `display` section to the user during consent — summary, implications, data accessed, irreversibility. The PS uses this information to determine whether the request fits the mission scope and to obtain informed user consent. +- **The AS** fetches R3 to evaluate `operations` for policy decisions and to populate `r3_granted` and `r3_conditional` in the auth token. + +Both independently verify `r3_s256` against the fetched document. Because R3 documents are content-addressed, both can cache aggressively by hash. + +## AS Processing + +When the AS receives a resource token containing `r3_uri` and `r3_s256`, it MUST: + +1. Validate the resource token signature per AAuth Protocol ([@!I-D.hardt-aauth-protocol]). +2. Fetch the R3 document at `r3_uri`. The AS MAY use a cached copy if the cache entry was stored with the same `r3_s256` value. +3. Compute the SHA-256 hash of the bytes received and compare it to `r3_s256`. If the hashes do not match, the AS MUST reject the resource token. +4. Record `r3_uri` and `r3_s256` in its audit log alongside the token issuance event, the agent identifier, and the timestamp. +5. Use the `operations` section for policy evaluation. +6. Include `r3_uri`, `r3_s256`, `r3_granted`, and (if applicable) `r3_conditional` in the issued auth token. + +## Caching + +Because R3 documents are content-addressed, the AS MAY cache them by `r3_s256` to avoid redundant fetches. When serving a cached entry, the AS MUST verify that the stored document produces the expected hash. The AS is not required to retain R3 documents beyond their immediate use in token issuance — the AS's audit log records `r3_uri` and `r3_s256`, which is sufficient for later verification by re-fetching. + + +# Auth Token Extensions + +R3 extends the auth token defined in AAuth Protocol ([@!I-D.hardt-aauth-protocol]) (a JWT with `typ: auth+jwt`) with claims for audit provenance and vocabulary-based grants. The resource can enforce authorization directly from these claims. + +Base claims (from AAuth Protocol): +- `iss`: Auth server URL +- `dwk`: `aauth-issuer.json` +- `aud`: Resource URL +- `jti`: Unique token identifier +- `agent`: Agent identifier +- `cnf`: Confirmation claim with `jwk` containing the agent's public key +- `iat`: Issued at timestamp +- `exp`: Expiration timestamp +- `sub`: User identifier (conditional) +- `scope`: Authorized scopes (conditional) + +R3 extension claims: +- **`r3_uri`** (REQUIRED for R3): The URI of the R3 document that was in effect at approval time. +- **`r3_s256`** (REQUIRED for R3): The SHA-256 hash of that R3 document. +- **`r3_granted`** (REQUIRED for R3): Operations the AS fully authorized. The resource serves these immediately. +- **`r3_conditional`** (OPTIONAL): Operations authorized in principle but requiring per-call approval based on the specific parameters the agent provides. + +```json +{ + "typ": "auth+jwt", + "alg": "EdDSA", + "kid": "as-key-1" +} +``` + +```json +{ + "iss": "https://as.example.com", + "dwk": "aauth-issuer.json", + "aud": "https://calendar.example.com", + "jti": "at-9d4c1e", + "agent": "assistant@agent.example", + "sub": "user:alice@example.com", + "cnf": { "jwk": { "kty": "OKP", "crv": "Ed25519", "x": "NzbLsXh8uDCcd..." } }, + "r3_uri": "https://calendar.example.com/r3/a1b2c3d4", + "r3_s256": "aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789abcd", + "r3_granted": { + "vocabulary": "urn:aauth:vocabulary:mcp", + "operations": [ + { "tool": "list_calendar_events" }, + { "tool": "modify_calendar_event" } + ] + }, + "r3_conditional": { + "vocabulary": "urn:aauth:vocabulary:mcp", + "operations": [ + { "tool": "create_calendar_event" } + ] + }, + "iat": 1741824000, + "exp": 1741824900 +} +``` + +**`r3_uri`** and **`r3_s256`** provide audit provenance: a permanent, verifiable record of which R3 document was in effect at approval time. The AS can verify the R3 document by fetching `r3_uri` and checking `r3_s256`. + +**`r3_granted`** and **`r3_conditional`** use the same vocabulary-specific operation format as the R3 document's `operations` field and the agent's `r3_operations` request: + +- **`vocabulary`** (REQUIRED). The vocabulary URI. +- **`operations`** (REQUIRED). An array of operations using the vocabulary-specific structure. The AS MAY narrow the grant to fewer operations than defined in the R3 document. + +The distinction: `r3_granted` operations are fully authorized and the resource serves them. `r3_conditional` operations require the resource to challenge when the agent actually calls. On the challenge the resource builds a **per-call proposal** ({{per-call-proposals}}) — a content-addressed document carrying the specific parameters of the call — and the AS evaluates those concrete parameters before issuing a per-call auth token. + +## Resource Enforcement + +The resource matches each incoming API call against the auth token claims: + +1. **Match in `r3_granted`**: serve the request. +2. **Match in `r3_conditional`**: build a per-call proposal ({{per-call-proposals}}) and return `AAuth-Requirement` with a resource token referencing it. The AS evaluates the specific call against the proposed parameters. +3. **No match**: reject the request. + +No token introspection or R3 document fetch is needed at enforcement time. The resource uses the vocabulary it already understands. + +When `r3_operations` was not used (the agent received the resource token via a 401 rather than the authorization endpoint), the AS populates `r3_granted` and `r3_conditional` based on the operations defined in the R3 document and its own policy. The AS decides which operations to grant outright and which to make conditional. + +# Per-Call Proposals {#per-call-proposals} + +An `r3_conditional` operation is authorized in principle but not for any specific call: the consequences depend on the concrete parameters the agent supplies (who the email is addressed to, how large the payment is, which record is deleted). When the agent invokes such an operation, the resource challenges the call and the AS re-evaluates it against those parameters before issuing a per-call auth token. + +A **per-call proposal** is the document that carries the specifics of that one pending call. It is an R3 document scoped to a single invocation: same structure, same content-addressing ({{content-addressing}}), and the same AS/PS-only fetch restriction as a class R3 document. Reusing content-addressing keeps tokens small — they carry only the `r3_uri`/`r3_s256` reference, never the parameters — and binds the eventual approval to the exact call that was proposed. + +## Proposal Document + +In addition to the R3 document fields ({{r3-document}}), a per-call proposal carries: + +**`operations`** (REQUIRED). The single conditional operation being invoked, in the resource's vocabulary. + +**`parameters`** (REQUIRED). The concrete parameters of the call, machine-readable, for the AS to evaluate and the resource to bind. A large or sensitive value MAY be represented by a digest object in place of the inline value: + +- `s256` (REQUIRED). `BASE64URL(SHA-256(value-bytes))` of the parameter value as it will be presented at call time. +- `excerpt` (OPTIONAL). A short, human-readable excerpt of the value for display. +- `media_type` (OPTIONAL). The media type of the value. + +**`display`** (RECOMMENDED). Per-call human context for the user's approval decision. In addition to the structured fields defined in {{r3-document}}, a proposal's `display` MAY include a `detail` Markdown string. The following sections are RECOMMENDED as a convention (not normative requirements): `## Action`, `## To` / `## Recipient`, `## Details`, `## Content` (excerpt), `## Irreversible`. + +```json +{ + "vocabulary": "urn:aauth:vocabulary:mcp", + "operations": [ { "tool": "send_email" } ], + "parameters": { + "to": "mom@example.com", + "subject": "Dinner Sunday?", + "body": { "s256": "aBcD…", "excerpt": "Hi Mom, are you free…", "media_type": "text/plain" } + }, + "display": { + "summary": "Send an email as you", + "detail": "## Action\nSend an email\n\n## To\nmom@example.com\n\n## Details\nSubject: Dinner Sunday?\n\n## Content\nHi Mom, are you free…" + } +} +``` + +## Flow + +1. **Conditional challenge.** The agent invokes an `r3_conditional` operation. The resource builds the proposal, persists it keyed by its `r3_s256`, and returns `AAuth-Requirement` with a resource token whose `r3_uri`/`r3_s256` reference the proposal. The token carries only the reference, not the parameters. +2. **Approval.** The AS fetches the proposal and evaluates `parameters` per policy; the PS renders `display` for user consent. On approval, the AS issues a per-call auth token that echoes the proposal's `r3_uri`/`r3_s256` and lists the now-approved operation in `r3_granted`. +3. **Enforced retry.** The agent retries the actual call with the per-call auth token. The resource recovers the proposal from its store via `r3_s256` and MUST verify that the agent's actual parameters match the approved proposal. For any parameter represented as a digest, the resource MUST verify that `BASE64URL(SHA-256(presented-value))` equals the stored `s256`. If anything differs, the resource MUST reject the call. An approval to email one recipient cannot be replayed against another. + +## Large and Sensitive Payloads + +Representing a parameter as a digest keeps large or sensitive payloads out of every token and away from the PS: only the `s256` and a short `excerpt` appear in the proposal. The full bytes travel directly from the agent to the resource at call time, where the resource verifies them against the digest. This is also a privacy control — the resource chooses what the PS (and through it, the user-facing surface) sees versus what stays between the agent and the resource. + +Whether the AS or PS additionally *machine-evaluates* `parameters` (for example, auto-denying a payment over a threshold) or treats the proposal as display-for-human-consent only is deployment policy. The parameters are present in the proposal either way, so machine policy can be layered on without a format change. + +# Security Considerations + +## R3 Document Access Restriction + +The AS MUST authenticate itself when fetching `r3_uri` using an HTTP Message Signature as defined in the AAuth Protocol ([@!I-D.hardt-aauth-protocol]). The resource MUST reject requests not signed by its AS. + +This prevents agents from fetching R3 documents by following the `r3_uri` they carry in the resource token. Since a resource has exactly one AS, the resource only needs to recognize signatures from that AS. The agent opacity property (agents carry the hash of a document they cannot read) depends on this restriction. + +## R3 Endpoint Access Control + +The agent opacity property — agents carry the hash of a document they cannot read — depends entirely on the resource correctly restricting access to R3 document endpoints. If the resource fails to require a valid HTTP Message Signature from its AS on R3 document requests, or accepts signatures from keys other than its AS's, agents can fetch and read R3 documents, breaking the opacity guarantee. Implementations MUST treat R3 endpoint access control as a critical security requirement and SHOULD verify this restriction during deployment testing. + +## Hash Verification + +The AS MUST verify `r3_s256` against the fetched document before using it. Failure to verify allows a resource to serve different content than what was hashed in the resource token. + +## Audit Log Integrity + +The AS MUST write audit log entries atomically with token issuance. An auth token issued without a corresponding audit log entry creates an undetectable gap in the observability record. Implementations SHOULD use transactional writes or equivalent mechanisms. + +## Operation Validation + +For all vocabularies, the resource MUST validate declared operations against its authoritative definition (MCP tool list, OpenAPI spec, `.proto` file, GraphQL schema, AsyncAPI spec, WSDL document, or OData `$metadata`) before issuing a resource token. + +## Grant Enforcement + +Resources MUST enforce `r3_granted` and `r3_conditional` claims in auth tokens. Operations in `r3_granted` define fully authorized access. Operations in `r3_conditional` MUST trigger an `AAuth-Requirement` before being served. The resource MUST reject API calls that do not match an operation in either claim. + +# IANA Considerations + +## JWT Claims Registration + +This document requests registration of the following JWT claims in the IANA JSON Web Token Claims registry: + +| Claim | Description | Reference | +|-------|-------------|-----------| +| `r3_uri` | R3 document URI | This document | +| `r3_s256` | R3 document SHA-256 hash | This document | +| `r3_granted` | Fully authorized operations in vocabulary format | This document | +| `r3_conditional` | Conditionally authorized operations requiring per-call approval | This document | + +## R3 Vocabulary Registry + +This specification establishes the AAuth R3 Vocabulary Registry. The initial contents are: + +| Vocabulary URI | Interface Type | Reference | +|----------------|---------------|-----------| +| `urn:aauth:vocabulary:mcp` | MCP server | This document | +| `urn:aauth:vocabulary:openapi` | HTTP/REST | This document | +| `urn:aauth:vocabulary:grpc` | gRPC | This document | +| `urn:aauth:vocabulary:graphql` | GraphQL | This document | +| `urn:aauth:vocabulary:asyncapi` | Event-driven | This document | +| `urn:aauth:vocabulary:wsdl` | SOAP/WSDL | This document | +| `urn:aauth:vocabulary:odata` | OData | This document | + +New values may be registered following the Specification Required policy ([@!RFC8126]). + +# Implementation Status + +*Note: This section is to be removed before publishing as an RFC.* + +This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [@RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. + +There are currently no known implementations. + +# Document History + +*Note: This section is to be removed before publishing as an RFC.* + +- draft-hardt-aauth-r3-00 + - Initial submission + +# Acknowledgments + +The author would like to thank reviewers for their feedback. + +{backmatter} + +# Design Rationale + +## Why Not RAR + +OAuth 2.0 Rich Authorization Requests ([@RFC9396]) defines `authorization_details` as a structured extension to authorization requests. RAR is a natural reference point for this work. R3 deliberately does not use or profile RAR for the following reasons: + +**Directionality.** RAR is client-declared: the agent constructs `authorization_details` and sends it to the AS. The agent defines what it wants. R3 is resource-declared: the resource defines what access it provides and signs that definition. The agent cannot modify or reframe it. This is the opposite directionality, and the security properties depend on it. + +**Agent opacity.** In R3, the R3 document is fetched by the AS directly from the resource, restricted to AS-only access. The agent carries a hash of a document it cannot read. RAR has no equivalent because the client constructs the authorization details and necessarily knows their content. + +**Content addressing.** R3 uses a content-addressed URI plus SHA-256 hash to pin the exact authorization semantics in effect at approval time. An auth token carrying `r3_uri` and `r3_s256` is a permanent, verifiable record. RAR carries no equivalent versioning or integrity guarantee. + +**Audit trail.** The AS records `r3_uri` in its audit log, creating a durable reference to the exact R3 document version. This is not possible with RAR's inline `authorization_details` structure. + +RAR and R3 are complementary. RAR remains appropriate for client-declared authorization detail. R3 addresses the resource-declared case that RAR was not designed for. + +# Vocabulary Summary + +| Vocabulary URI | Interface Type | Operation Identifier | Discovery Mechanism | +|----------------|---------------|---------------------|---------------------| +| `urn:aauth:vocabulary:mcp` | MCP server | Tool name | MCP tool discovery | +| `urn:aauth:vocabulary:openapi` | HTTP/REST | `operationId` | OpenAPI spec URL | +| `urn:aauth:vocabulary:grpc` | gRPC | `package.Service/Method` | Server reflection or `.proto` URL | +| `urn:aauth:vocabulary:graphql` | GraphQL | Operation name | GraphQL introspection | +| `urn:aauth:vocabulary:asyncapi` | Event-driven | `operationId` | AsyncAPI spec URL | +| `urn:aauth:vocabulary:wsdl` | SOAP/WSDL | Operation name | WSDL document URL | +| `urn:aauth:vocabulary:odata` | OData | Entity set or bound operation | `$metadata` URL | + +# Comparison with RAR + +| Property | RAR ([@RFC9396]) | R3 | +|----------|---------------|----| +| Who declares | Client (agent) | Resource | +| Direction | Client -> AS | Resource -> AS (via agent carrier) | +| Agent visibility | Agent constructs the detail | Agent carries opaque token | +| Versioning | None | Content-addressed URI + hash | +| Audit trail | Inline in request | `r3_uri` recorded by AS | +| Human display | Not specified | `display` section in R3 document | +| Irreversibility signal | Not specified | `display.irreversible` field | diff --git a/aauth-spec/v09/draft-hardt-httpbis-signature-key-06.txt b/aauth-spec/v09/draft-hardt-httpbis-signature-key-06.txt new file mode 100644 index 00000000..028f8f24 --- /dev/null +++ b/aauth-spec/v09/draft-hardt-httpbis-signature-key-06.txt @@ -0,0 +1,2184 @@ + + + + +HTTP D. Hardt +Internet-Draft Hellō +Intended status: Standards Track T. Meunier +Expires: 3 January 2027 Cloudflare + 2 July 2026 + + + HTTP Signature Keys + draft-hardt-httpbis-signature-key-06 + +Abstract + + This document defines two HTTP header fields and one Accept-Signature + parameter for use with HTTP Message Signatures as defined in RFC + 9421. The Signature-Key request header distributes public keys used + to verify signatures, with six initial key distribution schemes: + pseudonymous inline keys (hwk), self-issued key delegation via JWK + Thumbprint JWTs (jkt-jwt), identified signers with JWKS URI discovery + (jwks_uri), JWT-based delegation (jwt), self-issued JWTs (self-jwt), + and X.509 certificate chains (x509). The sigkey parameter extends + Accept-Signature (RFC 9421 Section 5) to indicate the type of + Signature-Key the server requires. The Signature-Error response + header provides structured error information when signature + verification fails. Together, these mechanisms enable flexible trust + models ranging from privacy-preserving pseudonymous verification to + horizontally-scalable delegated authentication and PKI-based identity + chains. + +Discussion Venues + + _Note: This section is to be removed before publishing as an RFC._ + + Source for this draft and an issue tracker can be found at + https://github.com/dickhardt/signature-key + (https://github.com/dickhardt/signature-key). + +Status of This Memo + + 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/. + + + + + + +Hardt & Meunier Expires 3 January 2027 [Page 1] + +Internet-Draft Signature-Keys July 2026 + + + 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 3 January 2027. + +Copyright Notice + + 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. + +Table of Contents + + 1. Conventions and Definitions . . . . . . . . . . . . . . . . . 3 + 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 + 3. Signature-Key HTTP Request Header . . . . . . . . . . . . . . 5 + 3.1. Label Consistency . . . . . . . . . . . . . . . . . . . . 6 + 3.2. Multiple Signatures . . . . . . . . . . . . . . . . . . . 6 + 3.3. Header Web Key (hwk) . . . . . . . . . . . . . . . . . . 6 + 3.4. JKT JWT Self-Issued Key Delegation (jkt-jwt) . . . . . . 8 + 3.5. JWKS URI Discovery (jwks_uri) . . . . . . . . . . . . . . 11 + 3.6. JWT Confirmation Key (jwt) . . . . . . . . . . . . . . . 12 + 3.7. Self-Issued JWT (self-jwt) . . . . . . . . . . . . . . . 14 + 3.8. X.509 Certificates (x509) . . . . . . . . . . . . . . . . 16 + 4. Accept-Signature sigkey Parameter . . . . . . . . . . . . . . 17 + 4.1. Parameter Definition . . . . . . . . . . . . . . . . . . 17 + 4.2. Label Binding . . . . . . . . . . . . . . . . . . . . . . 18 + 4.3. Response Status Codes . . . . . . . . . . . . . . . . . . 19 + 4.4. sigkey Semantics . . . . . . . . . . . . . . . . . . . . 19 + 4.4.1. jkt . . . . . . . . . . . . . . . . . . . . . . . . . 19 + 4.4.2. uri . . . . . . . . . . . . . . . . . . . . . . . . . 20 + 4.4.3. x509 . . . . . . . . . . . . . . . . . . . . . . . . 20 + 4.5. Incremental Adoption . . . . . . . . . . . . . . . . . . 20 + 4.6. Coexistence with WWW-Authenticate . . . . . . . . . . . . 21 + 4.7. Examples . . . . . . . . . . . . . . . . . . . . . . . . 21 + 4.8. Client Processing . . . . . . . . . . . . . . . . . . . . 22 + 5. Signature-Error HTTP Response Header . . . . . . . . . . . . 22 + 5.1. Header Structure . . . . . . . . . . . . . . . . . . . . 22 + + + +Hardt & Meunier Expires 3 January 2027 [Page 2] + +Internet-Draft Signature-Keys July 2026 + + + 5.2. Response Body . . . . . . . . . . . . . . . . . . . . . . 23 + 5.3. Access Denied . . . . . . . . . . . . . . . . . . . . . . 23 + 5.4. Error Codes . . . . . . . . . . . . . . . . . . . . . . . 23 + 5.4.1. unsupported_algorithm . . . . . . . . . . . . . . . . 23 + 5.4.2. invalid_signature . . . . . . . . . . . . . . . . . . 24 + 5.4.3. invalid_input . . . . . . . . . . . . . . . . . . . . 24 + 5.4.4. invalid_request . . . . . . . . . . . . . . . . . . . 24 + 5.4.5. invalid_key . . . . . . . . . . . . . . . . . . . . . 24 + 5.4.6. unknown_key . . . . . . . . . . . . . . . . . . . . . 25 + 5.4.7. invalid_jwt . . . . . . . . . . . . . . . . . . . . . 25 + 5.4.8. expired_jwt . . . . . . . . . . . . . . . . . . . . . 25 + 6. Security Considerations . . . . . . . . . . . . . . . . . . . 25 + 6.1. Key Validation . . . . . . . . . . . . . . . . . . . . . 25 + 6.2. Caching and Performance . . . . . . . . . . . . . . . . . 26 + 6.3. Scheme-Specific Risks . . . . . . . . . . . . . . . . . . 26 + 6.4. Algorithm Selection . . . . . . . . . . . . . . . . . . . 28 + 6.5. Signature-Key Integrity . . . . . . . . . . . . . . . . . 28 + 7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 28 + 7.1. Pseudonymity vs. Identity . . . . . . . . . . . . . . . . 29 + 7.2. Key Discovery Tracking . . . . . . . . . . . . . . . . . 29 + 7.3. JWT Contents . . . . . . . . . . . . . . . . . . . . . . 29 + 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 + 8.1. HTTP Field Name Registration . . . . . . . . . . . . . . 30 + 8.2. Signature-Key Scheme Registry . . . . . . . . . . . . . . 30 + 8.2.1. Registration Procedure . . . . . . . . . . . . . . . 30 + 8.2.2. Initial Registry Contents . . . . . . . . . . . . . . 31 + 8.2.3. Registration Template . . . . . . . . . . . . . . . . 31 + 8.3. HTTP Signature Metadata Parameters . . . . . . . . . . . 31 + 8.4. URN Sub-namespace Registration . . . . . . . . . . . . . 32 + 8.5. Signature Error Code Registry . . . . . . . . . . . . . . 32 + 8.5.1. Initial Registry Contents . . . . . . . . . . . . . . 32 + 9. Document History . . . . . . . . . . . . . . . . . . . . . . 33 + 10. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 34 + 11. References . . . . . . . . . . . . . . . . . . . . . . . . . 34 + 11.1. Normative References . . . . . . . . . . . . . . . . . . 34 + 11.2. Informative References . . . . . . . . . . . . . . . . . 36 + Appendix A. Design Rationale . . . . . . . . . . . . . . . . . . 36 + A.1. Why jwks_uri Instead of Inline JWKS? . . . . . . . . . . 36 + A.2. Why a Separate Header? . . . . . . . . . . . . . . . . . 37 + A.3. Why Schemes Instead of Just a Key and Key ID? . . . . . . 38 + A.4. Why Strings Instead of Byte Sequences for hwk? . . . . . 38 + Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 38 + +1. Conventions and Definitions + + {::boilerplate bcp14-tagged} + + + + + +Hardt & Meunier Expires 3 January 2027 [Page 3] + +Internet-Draft Signature-Keys July 2026 + + +2. Introduction + + HTTP Message Signatures [RFC9421] provides a powerful mechanism for + creating and verifying digital signatures over HTTP messages. To + verify a signature, the verifier needs the signer's public key. + While RFC 9421 defines signature creation and verification + procedures, it intentionally leaves key distribution to application + protocols, recognizing that different deployments have different + trust requirements. + + This document defines: + + * *Signature-Key* (Signature-Key HTTP Request Header (#signature- + key-http-request-header)) — a request header that distributes + public keys for HTTP Message Signature verification. The header + supports six schemes, each designed for different trust models and + operational requirements: + + 1. *Header Web Key (hwk)* - Self-contained public keys for + pseudonymous verification + 2. *JKT JWT (jkt-jwt)* - Self-issued key delegation via JWK + Thumbprint JWTs ("jacket jot") + 3. *JWKS URI (jwks_uri)* - Identified signers with key discovery + via metadata + 4. *JWT (jwt)* - Delegated keys embedded in signed JWTs for + horizontal scale + 5. *Self-Issued JWT (self-jwt)* - Self-signed JWTs where the + signer and issuer are the same party + 6. *X.509 (x509)* - Certificate-based verification with PKI trust + chains + + Additional schemes may be defined through the IANA registry + established by this document. + + * *sigkey* (Accept-Signature sigkey Parameter (#accept-signature- + sigkey-parameter)) — a parameter for the Accept-Signature header + ([RFC9421], Section 5) that indicates the type of Signature-Key + the server requires. This extends RFC 9421's existing mechanism + for requesting signatures rather than defining a new header. + + * *Signature-Error* (Signature-Error HTTP Response Header + (#signature-error-http-response-header)) — a response header that + provides structured error information when signature verification + fails, enabling clients to diagnose and correct signing issues. + + The Signature-Key header works in conjunction with the Signature- + Input and Signature headers defined in RFC 9421, using matching + labels to correlate signature metadata with keying material. + + + +Hardt & Meunier Expires 3 January 2027 [Page 4] + +Internet-Draft Signature-Keys July 2026 + + +3. Signature-Key HTTP Request Header + + The Signature-Key header provides the public key or key reference + needed to verify an HTTP Message Signature. It is a Structured Field + Dictionary [RFC8941] keyed by signature label, where each member + describes how to obtain the verification key for the corresponding + signature. + + *Format:* + + Signature-Key: