Delivery proposes durable bind fencing and exact scheduling replay for ADR-0052 second review
Assignment ADR-0052/delivery/002; coordinator 01a0e095-f279-7fd0-a8ef-92ce8f9547fc, host local; participant 01a0ff07-cd25-7490-9008-a734cad7147e. This is Delivery's proposed concrete revision for another owner review, not an accepted ADR, contract amendment or implementation authorization. No other owner's acknowledgment or commitment is asserted. The coordinator remains sole publisher.
Reviewed the four owner positions and updated ADR at canonical commit 33da836a4c73ce5d23fa14eb7485f873c698a0ae. Original source findings remain pinned to Delivery 75589fa499b3c62ef94ef5702d5470c4781a1059, Revenue 5f10755c031897b6598a051f915c6864ee0901e1, Platform audit 8f877adca494d1fd23cc404cf64423d06a35565d, and audit-derived Sales d31ddf1a4bd233c3d4e2714350452de8b7cbc878. Baselines are service-auth v1.7.0, scheduling v1.12.0, credit-reservation-lock v3.4.1 and sales-ordering v2.8.0. Delivery's local coordination clone still reports 2ac56cf; canonical owner positions were read directly, read-only. No refresh or merge of that clone is assumed.
Selected protocol and alternatives
Select Revenue's narrow evidence read PLUS a durable Revenue reservation fence installed before its bind send. A read alone, a signed short-lived resource grant, or an expiring lease is insufficient: release can commit after verification and before Delivery's write. Holding a Revenue database transaction across HTTP is also rejected. This protocol deliberately retains an uncertain fence until Delivery supplies committed or permanent noncommit evidence. It chooses recoverability over freeing a reservation on timeout.
Revenue creates the fence in its own existing close/recovery transaction, so no remote acquire API is proposed. One additional Delivery settlement operation is necessary to safely abandon an attempt whose send or result is uncertain. Without that operation, a fence must remain indefinitely or risk a delayed bind after release. A shared database or distributed transaction is not proposed.
Durable Revenue admission
Before first bind send, Revenue atomically persists the original close admission, order/reservation/lesson association, exact bind business request/key, immutable actor, protocol headers, bind_intent_id (UUID), request fingerprint and monotonic reservation revision. The transaction locks the reservation and enforces a unique active scheduling fence, no conflicting release/closure execution fence, canonical order linkage and lifecycle reserved. Pending funding is allowed; funding is not the bind authority. Resume this same record after a crash before close-response caching; never rerun fresh-ID order/reservation creation to recover it.
The fence binds tenant, Organization, original workload subject, order, reservation, intended lesson, account Person, OrgMarket, window, bind key digest and fingerprint. Every Revenue writer that can invalidate the reservation association or release/consume/forfeit it must serialize against this fence. Refund processing must not invalidate the association under an unresolved bind; Revenue must identify and gate its concrete invalidating writers in review. Acquiring the fence after a competing terminal transition is denied. A conflicting closure that already owns the Revenue execution fence wins and prevents new bind admission. A fence does not expire when a bearer, lease timer, hold TTL or HTTP request expires.
After an exact Delivery committed receipt, Revenue atomically records bound, its receipt reference and revision, and clears only that intent's scheduling fence. After an exact Delivery noncommit settlement, it records noncommitted and clears only that fence. Both transitions use compare-and-set on intent/revision, never a blanket unlock. Response loss or unknown outcome retains the fence. Provider charge/invoice progression requires the agreed committed bind outcome and its normal financial predicates; a historical receipt does not establish current booking readiness.
New interfaces and authority
These are proposed additions requiring explicit Platform, Revenue and Delivery approval, not implicit extensions of the two original policies:
| Method and exact deployed path | Caller subject / audience | Selector and sole scope |
|---|---|---|
POST /api/v1/delivery/v1/lesson-holds/soft |
sales / delivery |
delivery.scheduling.soft-hold.create |
POST /api/v1/delivery/v1/lesson-holds/bind |
system:revenue / delivery |
delivery.scheduling.reservation.bind |
GET /api/v1/reservations/{reservation_id}/scheduling-bind-evidence on Revenue |
system:delivery / revenue |
revenue.reservations.bind-evidence.read |
POST /api/v1/delivery/v1/lesson-holds/bind-settlements |
system:revenue / delivery |
delivery.scheduling.reservation.bind.settle |
No selector grants another row's path. Exact route-param validation and route matching apply; arbitrary prefix/suffix matches fail. Evidence GET query is exactly organization_id, lesson_id, bind_intent_id. Revenue returns only a unique canonical association after access checks. Proposed strict evidence schema is {protocol_version:"1.0", bind_intent_id, tenant_id, organization_id, order_id, reservation_id, lesson_id, credit_account_id, person_id, platform_market_id, window:{start,end}, lifecycle, funding_state, reservation_revision, bind_key_digest, request_fingerprint, fence_state:"pending"|"bound"|"noncommitted", delivery_receipt_ref:null|ReceiptRef, as_of}. Unknown variants or missing identity fields fail closed. Account/market/Person facts are derived, not copied from query fields. Bound/noncommitted evidence is retained for replay checks; only pending fenced evidence authorizes a new transition.
Use Platform's proposed exact production subjects, issuer/JWKS/audiences, output subjects, tnt_sguild, Organization list [org_01900000-0000-7000-8000-000000000001], RS256, UUID jti, nbf=iat, maximum 300-second lifetime and at most 30-second clock tolerance from its first position. Revenue must confirm its production proof subject with actual later exchange evidence. Obtain newly audited authority on every outbound scheduling, evidence and settlement attempt; explicitly override reusable-token caching for these policies. No credentials are persisted. Issuance disablement leaves an already-issued JWT valid for its remaining permitted lifetime/tolerance; immediate disablement would require a separately approved producer mechanism. Do not claim instant revocation.
Delivery commit, replay and settlement
New create/bind attempts carry Scheduling-Protocol-Version: 2.0; Revenue bind also carries immutable Scheduling-Bind-Intent: <UUID>. Existing JSON bodies and Idempotency-Key values remain unchanged. New fingerprints are SHA-256 of compact recursively key-sorted validated JSON {protocol_version, operation, tenant_id, subject, body}. Bind fingerprint additionally includes bind_intent_id. Keys are scoped by verified tenant, Organization and operation, with explicit cross-operation collision rejection in the existing shared key namespace. Hash/digest formats and normalization become normative schemas, not implementation guesses.
On every attempt Delivery verifies JWT and exact route/scope/tenant/Organization before any business cache or remote call. It loads only organization-scoped local resources. Create verifies Participant and matching supplied Person, active canonical Person tenancy before creating a Participant, site visibility/private Person linkage and Service Area coverage, organization-active type and canonical market mapping. Bind compares the Revenue evidence tuple/fingerprint/key digest to the locked Lesson's Organization, Participant Person, market and exact window. Nullable Revenue Participant/type/site fields are not treated as required facts. Missing local market mapping means unverifiable evidence, not a guessed match.
For a new bind, Revenue evidence must show the matching pending durable fence and reserved lifecycle. Delivery's local commit transaction serializes on Lesson, bind-intent/key journal and existing cancellation admission state; rechecks live soft hold, no conflicting reservation binding, no admitted cancellation/closure fence, current eligibility and coach slot, and permanent noncommit tombstone absence. It atomically creates/advances the lock, attaches the Lesson, records the original immutable success receipt and emits exactly one existing hold-created event. It enforces reservation-to-lesson uniqueness. Network evidence reads occur outside the local commit transaction; the persistent Revenue fence, not as_of, prevents invalidation between read and commit.
Receipt replay first checks current service/Organization reach, original command/fingerprint and exact current resource ownership. Bind additionally reads retained Revenue association evidence for that original intent; it need not still be reserved or pending once already committed. Missing or unverifiable current ownership/association prevents disclosure. It then returns the unchanged original success body/status without repeating eligibility, state transitions or events. Create replay similarly checks current exact local ownership without creating a missing Participant. A replayed success is historical receipt evidence, not a claim that the hold is currently unexpired, unbound or eligible. An optional response header Scheduling-Receipt-Replayed: true labels replay without rewriting historical JSON.
If Revenue elects to abandon an uncertain bind, it freezes further sends for that intent and persists a separately keyed settlement request. Proposed settlement JSON is {protocol_version:"1.0", settlement_id:Uuid, bind_intent_id:Uuid, organization_id, reservation_id, lesson_id, bind_key, request_fingerprint}; Idempotency-Key equals settlement_id. Delivery authenticates the separate settle policy and canonical evidence before disclosure or mutation. Under the SAME local serialization/key identity as bind it returns either an immutable exact committed receipt reference, or atomically installs a permanent noncommit tombstone for the original bind intent/key/fingerprint. The tombstone can occupy a never-seen bind identity, so delayed first requests cannot execute. Existing conflicting identity is 409, never overwritten. A delayed bind after settlement returns 409 bind_noncommitted; settlement losing a race to committed bind returns committed, never abort success. Settlement creates no Lesson, lock, cancellation, credit mutation or business event.
Proposed settlement 200 response is {protocol_version:"1.0", settlement_id, bind_intent_id, tenant_id, organization_id, reservation_id, lesson_id, bind_key_digest, request_fingerprint, decision:"committed"|"noncommitted", receipt_ref:null|ReceiptRef, decided_at}. ReceiptRef binds the original intent/fingerprint/key digest and exact Lesson/reservation/lock identity, original lock version, event ID and immutable receipt digest; noncommitted has null receipt. Permanent tombstone and settlement proof survive key-cache eviction. Revenue records the exact authenticated response before clearing its fence; replay the same settlement after response loss. No read miss, HTTP denial or timeout is noncommit proof.
Failure and closure behavior
Invalid/missing/expired JWT or expected-subject/issuer/audience mismatch is 401 UNAUTHENTICATED; insufficient scope is 403 INSUFFICIENT_SCOPE; verified tenant/Organization/resource denial is 403 FORBIDDEN, without disclosing foreign resources. Unknown exchange selector is 400 BAD_REQUEST. Missing canonical association is nondisclosing 404 not_found; contradictory tuple/key/fingerprint is 409 bind_identity_conflict; ambiguous historical evidence is 409 historical_reconciliation_required; unavailable/malformed evidence or eligibility is 503 with no business mutation. Existing new-write eligibility/slot/soft-hold-state 409 reasons remain. Security audit is allowed on denial; business receipts, Participants, locks and events are not.
Revenue release while scheduling fence is unresolved returns a retryable conflict scheduling_bind_pending on the ordinary release interface. Existing ADR-0050 operation reads, request fingerprints, abort/noncommit proofs, generations and receipts retain their current versions/bytes. For an already admitted guarded release, the additional scheduling conflict is represented through its existing pending/blocked assessment mechanism, never a completed release or safe abort; Revenue must ratify the exact reason-code integration. Delivery cancellation admission and bind commit must serialize on the same Lesson authority so cancellation cannot silently lose its fence. Once bind is proven committed, any cancellation uses the existing separately authorized held-resource protocol. Once proven noncommitted, existing release/closure semantics proceed. Neither bind settlement nor scheduling token authorizes cancellation, refunds or closure, and no ADR-0050 key or proof is repurposed.
Durable compatibility, versions and cutover
Retain original command/key/fingerprint/receipt associations and noncommit tombstones durably, with no same-key conversion into a new write after 24 hours. Large receipt payloads may move to immutable storage only if exact bytes remain recoverable. Changed-body replay is 409 before receipt disclosure. Because this changes the published payload-variance/retention behavior, propose sales-scheduling-surface v2.0.0, with a new authoritative scheduling-workload-and-bind-settlement v1.0.0 sub-spec, sections 3/4.1a/4.1b/6.2/7.5/8.5 and exact mounted path map. Do not label this an unqualified compatible minor.
Propose service-auth v1.8.0 for the four isolated additive policies above; credit-reservation-lock v3.5.0 plus scheduling-bind-evidence v1.0.0 sub-spec for fence/evidence/ordinary-release conflict; sales-ordering-surface v2.9.0 for durable bind association journal/recovery and settlement dependency while preserving close bodies and original response schemas. If Revenue finds incompatible close/release response requirements, reclassify those versions before acceptance. These version numbers assume the reviewed baselines remain current. No lock lifecycle state, funding state or credit.* event changes are proposed; discovering such a change requires the ADR-0006 amendment protocol rather than hiding it here.
Do not reinterpret historical commands as new v2 admissions or rewrite bytes/keys/actors/receipts. A separate migration provenance record may bind a historical saved command to producer evidence only after full exact reconciliation. Proven historical success can replay with current auth/resource checks; uncertain or evicted legacy keys remain quarantined, with no new bind/soft-create and no guessed tombstone. A newly introduced settlement cannot certify old noncommit where the complete original association is unavailable. Recovery workers must not silently replace expired soft holds, reservations or keys.
Proposed gated cutover: owners explicitly approve a bounded pause of new scheduling/close admission; inventory pending and historical commands; reconcile/migrate supported exact commands and quarantine ambiguity; implement/deploy issuer and producer guards/fences/settlement with admission still paused; upgrade callers and exercise positive/negative proof; then enable v2 admission together. Legacy unfenced execution and legacy payload-variance replay are disabled explicitly at that cutover, never through a permissive fallback. Owners must set the compatibility/deprecation interval and approve the pause before acceptance. Rollback pauses admission/sends and preserves journals/fences/tombstones; it cannot revert to an unfenced or unauthenticated writer. Existing post-bind compensation authority must be proven separately before close admission resumes.
Admission policy and remaining owner decisions
Coordinator's human-authorized policy choice for second review: after valid admission the immutable command is service-owned. Later initiating-operator membership removal, session expiry or active-Organization switch blocks that human's new admission but does not alone invalidate exact-command recovery. Preserve original actor/request/key; current workload/Organization authority and current resource/business predicates still apply. This is a selected policy, not formal owner approval. Sales proposes enabled exact-Organization owner/admin membership plus accepted Sales app access for NEW admission; Platform/Sales must validate the authoritative permission surface and vocabulary.
Revenue must ratify the durable fence across all invalidating writers, evidence schema/revisions, replay after later lifecycle advancement, ordinary-release and ADR-0050 assessment integration, and association recovery without duplicate charge. Platform must approve the two additional evidence/settle policies and exact production reach. Sales must ratify durable retention/migration and cutover admission. Delivery must validate local shared serialization with closure and full resource/market predicates before acknowledgment. No initiating-operator revocation question remains pending; technical owner disagreements and cutover approval do.
Bounded acceptance checks
Later implementation proof must include: bind/read/release interleavings (release first denies bind admission; fence first blocks release until exact Delivery outcome); lost bind and settlement responses; delayed bind after permanent settlement; crash after Revenue association/fence commit before close cache; and concurrent Delivery cancellation versus bind. Every case must converge to one exact committed outcome or provable noncommit without duplicate Lesson, reservation, lock, order, event or provider charge. Exercise denied receipt disclosure, same-key changed-body, cross-Organization resource, missing/ambiguous association, evidence outage, expired hold, later released/confirmed receipt replay, permanent retention beyond 24 hours, quarantined historical key and cutover rollback. Prove new-human denial and exact admitted recovery after membership removal separately, with service-policy disablement preventing new sends and residual JWT lifetime stated accurately.
This review checked canonical source versions/owner memos, local source behavior and live inbox/ledger only. It ran no runtime tests, listeners, database changes, policy issuance or implementation. No ADR-0052 implementation commitment was found complete. New proposed interfaces, schemas and state reasoning require affected-owner review and later integration evidence; they are not verified runtime behavior. Coordinator publication/indexing/freshness remain pending for this proposed revision.