p2party 0.14.2 → 0.14.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +230 -30
  2. package/docs/getting-started.md +15 -0
  3. package/docs/protocol-v4-security.md +40 -0
  4. package/docs/references.md +28 -8
  5. package/docs/session-api.md +10 -2
  6. package/lib/api/signalingServerApi.d.ts +13 -2
  7. package/lib/api/webrtc/applyIceConfiguration.d.ts +9 -0
  8. package/lib/api/webrtc/dataChannelHandler.d.ts +10 -0
  9. package/lib/api/webrtc/deleteRoomData.d.ts +13 -0
  10. package/lib/api/webrtc/disconnectFromAllRoomsQuery.d.ts +2 -1
  11. package/lib/api/webrtc/disconnectFromRoomQuery.d.ts +2 -1
  12. package/lib/api/webrtc/disconnectQuery.d.ts +2 -1
  13. package/lib/api/webrtc/iceRepair.d.ts +3 -1
  14. package/lib/api/webrtc/index.d.ts +2 -1
  15. package/lib/api/webrtc/interfaces.d.ts +37 -0
  16. package/lib/api/webrtc/negotiationLock.d.ts +24 -0
  17. package/lib/api/webrtc/pendingOffer.d.ts +29 -0
  18. package/lib/api/webrtc/rebindDeadline.d.ts +61 -0
  19. package/lib/api/webrtc/remoteTransportChange.d.ts +142 -0
  20. package/lib/api/webrtc/retiredRemoteTransports.d.ts +70 -0
  21. package/lib/api/webrtc/roomEdgeBudget.d.ts +10 -0
  22. package/lib/api/webrtc/setDescriptionQuery.d.ts +8 -1
  23. package/lib/api/webrtc/settleOnClose.d.ts +36 -0
  24. package/lib/blindRendezvous/admissionInput.d.ts +11 -0
  25. package/lib/blindRendezvous/admissionPolicy.d.ts +217 -0
  26. package/lib/blindRendezvous/canonicalSchema.d.ts +139 -0
  27. package/lib/blindRendezvous/carrierEnvelope.d.ts +105 -0
  28. package/lib/blindRendezvous/coreReduce.d.ts +199 -0
  29. package/lib/blindRendezvous/derivations.d.ts +381 -0
  30. package/lib/blindRendezvous/identityHelloAdmission.d.ts +89 -0
  31. package/lib/blindRendezvous/identityHelloAdmissionPersistence.d.ts +133 -0
  32. package/lib/blindRendezvous/identityHelloHistoricalEvidence.d.ts +52 -0
  33. package/lib/blindRendezvous/identityHelloOpen.d.ts +167 -0
  34. package/lib/blindRendezvous/identityHelloTrial.d.ts +271 -0
  35. package/lib/blindRendezvous/localAdmissibleProject.d.ts +101 -0
  36. package/lib/blindRendezvous/localPresenceKeyBinding.d.ts +108 -0
  37. package/lib/blindRendezvous/localStableIdentityCustody.d.ts +46 -0
  38. package/lib/blindRendezvous/normativeKernel.d.ts +222 -0
  39. package/lib/blindRendezvous/operation.d.ts +137 -0
  40. package/lib/blindRendezvous/operationPayload.d.ts +134 -0
  41. package/lib/blindRendezvous/pairBootstrapSuite.d.ts +93 -0
  42. package/lib/blindRendezvous/pairCrypto.d.ts +122 -0
  43. package/lib/blindRendezvous/pairLedger.d.ts +154 -0
  44. package/lib/blindRendezvous/pairOpenBudget.d.ts +67 -0
  45. package/lib/blindRendezvous/pairOpenReservation.d.ts +157 -0
  46. package/lib/blindRendezvous/pairPlaintext.d.ts +240 -0
  47. package/lib/blindRendezvous/pairStepEnvelope.d.ts +60 -0
  48. package/lib/blindRendezvous/plannerState.d.ts +61 -0
  49. package/lib/blindRendezvous/projections.d.ts +71 -0
  50. package/lib/blindRendezvous/publicWindow.d.ts +330 -0
  51. package/lib/blindRendezvous/retainedOperationStore.d.ts +187 -0
  52. package/lib/blindRendezvous/roomInviteV2.d.ts +92 -0
  53. package/lib/blindRendezvous/roomPolicyV4.d.ts +90 -0
  54. package/lib/blindRendezvous/schemas.d.ts +221 -0
  55. package/lib/blindRendezvous/storeDescriptor.d.ts +160 -0
  56. package/lib/cryptography/aeadWasm.d.ts +18 -0
  57. package/lib/cryptography/byteInput.d.ts +12 -0
  58. package/lib/cryptography/carrierAead.d.ts +23 -0
  59. package/lib/cryptography/chacha20poly1305.d.ts +7 -0
  60. package/lib/cryptography/fips202.d.ts +10 -0
  61. package/lib/cryptography/hpke.d.ts +84 -0
  62. package/lib/cryptography/hpkeSuite.d.ts +39 -0
  63. package/lib/cryptography/hybridKem.d.ts +42 -0
  64. package/lib/cryptography/hybridKemSuite.d.ts +22 -0
  65. package/lib/cryptography/interfaces.d.ts +3 -0
  66. package/lib/cryptography/mlkem.d.ts +27 -1
  67. package/lib/cryptography/mnemonic.d.ts +65 -1
  68. package/lib/cryptography/ownedEd25519KeyMaterial.d.ts +27 -0
  69. package/lib/cryptography/webCryptoSha256.d.ts +20 -0
  70. package/lib/cryptography/x25519.d.ts +18 -0
  71. package/lib/cryptography/xchacha20poly1305.d.ts +7 -0
  72. package/lib/db/api.d.ts +6 -3
  73. package/lib/db/identityEd25519ClientBoundary.d.ts +13 -0
  74. package/lib/db/src/getDB.d.ts +2 -2
  75. package/lib/db/types.d.ts +52 -4
  76. package/lib/db.worker.js +1 -1
  77. package/lib/handlers/coverChannelRegistry.d.ts +22 -0
  78. package/lib/handlers/edgeTeardownFollowUp.d.ts +35 -0
  79. package/lib/handlers/handleChallenge.d.ts +2 -1
  80. package/lib/handlers/handleConnectToPeer.d.ts +1 -1
  81. package/lib/handlers/handleHandshake.d.ts +2 -6
  82. package/lib/handlers/handleSendMessage.d.ts +60 -7
  83. package/lib/handlers/handleWebSocketMessage.d.ts +1 -1
  84. package/lib/handlers/handshakeCore.d.ts +2 -7
  85. package/lib/handlers/handshakeFrame.d.ts +25 -0
  86. package/lib/handlers/ratchetGateWait.d.ts +13 -0
  87. package/lib/handlers/reconcile.d.ts +24 -0
  88. package/lib/handlers/requestRoom.d.ts +30 -0
  89. package/lib/handlers/roomResponse.d.ts +53 -0
  90. package/lib/index.d.ts +99 -12
  91. package/lib/index.js +1 -1
  92. package/lib/index.min.js +1 -1
  93. package/lib/index.mjs +1 -1
  94. package/lib/libcrypto.provenance.json +5 -5
  95. package/lib/libcrypto.wasm +0 -0
  96. package/lib/middleware/roomListenerMiddleware.d.ts +4 -1
  97. package/lib/reducers/commonSlice.d.ts +3 -2
  98. package/lib/reducers/keyPairSlice.d.ts +3 -6
  99. package/lib/reducers/roomSlice.d.ts +81 -5
  100. package/lib/reducers/signalingServerSlice.d.ts +3 -2
  101. package/lib/session.d.ts +6 -3
  102. package/lib/session.js +1 -1
  103. package/lib/session.mjs +1 -1
  104. package/lib/store.d.ts +4 -2
  105. package/lib/utils/constants.d.ts +12 -0
  106. package/lib/utils/correlationId.d.ts +4 -0
  107. package/lib/utils/identityRestore.d.ts +108 -0
  108. package/lib/utils/interfaces.d.ts +25 -6
  109. package/lib/utils/roomConnectAdmission.d.ts +15 -0
  110. package/lib/utils/roomLeaveCoordinator.d.ts +38 -0
  111. package/lib/utils/roomRequestCoordinator.d.ts +104 -0
  112. package/lib/utils/roomRosterReconciler.d.ts +83 -0
  113. package/lib/utils/sdpFingerprint.d.ts +6 -0
  114. package/lib/utils/signalingAttemptLifecycle.d.ts +33 -0
  115. package/lib/utils/signalingAuth.d.ts +21 -2
  116. package/lib/utils/signalingBounds.d.ts +6 -0
  117. package/lib/utils/signalingFrame.d.ts +21 -0
  118. package/lib/utils/signalingHeartbeatWatchdog.d.ts +45 -0
  119. package/lib/utils/signalingIngressQueue.d.ts +49 -0
  120. package/lib/utils/signalingPeerRequestDebouncer.d.ts +13 -0
  121. package/lib/utils/signalingRoomLifecycle.d.ts +7 -0
  122. package/lib/utils/signalingRoomOperationLifecycle.d.ts +14 -0
  123. package/lib/utils/signalingServerBoundary.d.ts +11 -0
  124. package/lib/utils/terminalSettlement.d.ts +53 -0
  125. package/lib/utils/transportIdentity.d.ts +5 -0
  126. package/package.json +1 -1
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Pair-bootstrap HPKE and established-flight AEAD (Section 4.11).
3
+ *
4
+ * This module owns only cryptographic sealing/opening and exact transcript
5
+ * binding. It deliberately does not own one-use routing-tag consumption,
6
+ * predecessor/dependency state, identity/admission decisions, persistence, or
7
+ * SDP dispatch. Those effectful gates consume this module's authenticated
8
+ * output and must commit their state before exposing it to WebRTC.
9
+ */
10
+ import type { LibCrypto } from "../cryptography/libcrypto";
11
+ import type { RoomPqMode } from "../roomPolicy";
12
+ import type { OperationPayloadClassV1 } from "./operation";
13
+ import type { PairBootstrapInfoV1, PairFlightSlotV1, PairOuterBindingV1, PairOuterPrebindingV1, PairPlaintextV1 } from "./pairPlaintext";
14
+ import type { PairStepEnvelopeV1 } from "./pairStepEnvelope";
15
+ export declare class PairCryptoError extends Error {
16
+ readonly name: string;
17
+ constructor(message: string);
18
+ }
19
+ /**
20
+ * A bootstrap plaintext authenticated under one HPKE info value but carrying
21
+ * another identity-flight kind. Recipients may classify this exact
22
+ * peer-authenticated protocol fault without parsing an error message.
23
+ */
24
+ export declare class PairBootstrapPlaintextKindError extends PairCryptoError {
25
+ readonly name = "PairBootstrapPlaintextKindError";
26
+ constructor();
27
+ }
28
+ export type PairBootstrapOuterFieldsV1 = Omit<PairOuterPrebindingV1, "bootstrapHeaderHash" | "nonce">;
29
+ export interface PairBootstrapSealOptionsV1 {
30
+ readonly module: LibCrypto;
31
+ readonly recipientHybridKemPublicKey: Uint8Array;
32
+ /** RoomRoot for HELLO or the validated HelloRoot for ACCEPT. */
33
+ readonly psk: Uint8Array;
34
+ readonly bootstrapInfo: PairBootstrapInfoV1;
35
+ readonly outerFields: PairBootstrapOuterFieldsV1;
36
+ readonly roomPqMode: RoomPqMode;
37
+ /**
38
+ * Called only after the HPKE header, one-use tag, and exact outer binding
39
+ * exist, allowing the stable identity signature to cover that binding.
40
+ */
41
+ readonly createSignedPlaintext: (binding: PairOuterBindingV1) => PairPlaintextV1 | Promise<PairPlaintextV1>;
42
+ }
43
+ export interface PairBootstrapSealResultV1 {
44
+ readonly envelope: PairStepEnvelopeV1;
45
+ readonly binding: PairOuterBindingV1;
46
+ readonly plaintext: PairPlaintextV1;
47
+ /**
48
+ * HelloRoot or AcceptRoot. The caller owns these bytes and must wipe them
49
+ * after deriving/persisting the next protected state.
50
+ */
51
+ readonly bootstrapRoot: Uint8Array;
52
+ }
53
+ /**
54
+ * Seal one HELLO or ACCEPT. Normal encapsulation always uses the hybrid KEM's
55
+ * CSPRNG path; deterministic conformance hooks are intentionally unreachable
56
+ * from this protocol API.
57
+ */
58
+ export declare const sealPairBootstrapV1: (options: PairBootstrapSealOptionsV1) => Promise<PairBootstrapSealResultV1>;
59
+ export interface PairBootstrapOpenOptionsV1 {
60
+ readonly module: LibCrypto;
61
+ readonly recipientHybridKemSecretKey: Uint8Array;
62
+ readonly psk: Uint8Array;
63
+ readonly bootstrapInfo: PairBootstrapInfoV1;
64
+ readonly prebinding: PairOuterPrebindingV1;
65
+ readonly envelope: PairStepEnvelopeV1;
66
+ readonly operationPayloadClass: OperationPayloadClassV1;
67
+ readonly roomPqMode: RoomPqMode;
68
+ /**
69
+ * The trusted pair-state layer verifies the stable transcript signature,
70
+ * identity/commitment binding, exact presences, and state-owned slot before
71
+ * the bootstrap root is released.
72
+ */
73
+ readonly validateAuthenticatedPlaintext: (binding: PairOuterBindingV1, plaintext: PairPlaintextV1) => void | Promise<void>;
74
+ }
75
+ export interface PairBootstrapOpenResultV1 {
76
+ readonly binding: PairOuterBindingV1;
77
+ readonly plaintext: PairPlaintextV1;
78
+ readonly bootstrapRoot: Uint8Array;
79
+ }
80
+ /**
81
+ * Try one budgeted HELLO/ACCEPT receiver key and expected info candidate.
82
+ *
83
+ * A routing-tag or HPKE authentication mismatch is `null` (not this
84
+ * candidate). Authenticated noncanonical/invalid pair plaintext throws and
85
+ * must be accounted as a rejected pair attempt by the caller.
86
+ */
87
+ export declare const openPairBootstrapV1: (options: PairBootstrapOpenOptionsV1) => Promise<PairBootstrapOpenResultV1 | null>;
88
+ export interface SealPairStepOptionsV1 {
89
+ readonly module: LibCrypto;
90
+ /** EstablishedPairRoot before promotion, one-use PqSlotSecret afterwards. */
91
+ readonly baseSecret: Uint8Array;
92
+ readonly expectedSlot: PairFlightSlotV1;
93
+ readonly prebinding: PairOuterPrebindingV1;
94
+ readonly plaintext: PairPlaintextV1;
95
+ readonly roomPqMode: RoomPqMode;
96
+ }
97
+ export interface SealPairStepResultV1 {
98
+ readonly envelope: PairStepEnvelopeV1;
99
+ readonly binding: PairOuterBindingV1;
100
+ readonly plaintext: PairPlaintextV1;
101
+ }
102
+ /** Seal one non-HPKE pair flight under the exact suite-1 DRY construction. */
103
+ export declare const sealPairStepV1: (options: SealPairStepOptionsV1) => Promise<SealPairStepResultV1>;
104
+ export interface OpenPairStepOptionsV1 {
105
+ readonly module: LibCrypto;
106
+ readonly baseSecret: Uint8Array;
107
+ /** One member of the closed candidate-slot set selected by pair state. */
108
+ readonly expectedSlot: PairFlightSlotV1;
109
+ readonly prebinding: PairOuterPrebindingV1;
110
+ readonly envelope: PairStepEnvelopeV1;
111
+ readonly operationPayloadClass: OperationPayloadClassV1;
112
+ readonly roomPqMode: RoomPqMode;
113
+ }
114
+ export interface OpenPairStepResultV1 {
115
+ readonly binding: PairOuterBindingV1;
116
+ readonly plaintext: PairPlaintextV1;
117
+ }
118
+ /**
119
+ * Try one state-selected established-flight slot. A tag/authentication
120
+ * mismatch is `null`; authenticated slot/body/padding disagreement throws.
121
+ */
122
+ export declare const openPairStepV1: (options: OpenPairStepOptionsV1) => Promise<OpenPairStepResultV1 | null>;
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Pure accepted-slot ledger for pair-private operations.
3
+ *
4
+ * This boundary starts only after pair opening has authenticated an operation
5
+ * and checked its state-derived inner slot. Invalid tag/AEAD trials therefore
6
+ * never consume a slot or routing tag here. Persistence, budgets, pair-machine
7
+ * state, WebRTC effects, and response publication remain outside this module.
8
+ *
9
+ * The coordinate deliberately excludes `kind`: two authenticated kinds at
10
+ * the same edge/endpoint/direction/sequence coordinate are a fork. Consumed
11
+ * routing tags and retained fork-stall evidence are projections of entries,
12
+ * never separately mutable state. The pair machine separately owns overall
13
+ * edge status, including non-fork failures and causal expiry.
14
+ */
15
+ import type { PairAuthorChainPrefixEvidenceV1 } from "./coreReduce";
16
+ import type { PairStepKindV1 } from "./pairPlaintext";
17
+ declare const pairAcceptedSlotLedgerBrand: unique symbol;
18
+ /** Process-local immutable ledger handle. Persist only its canonical snapshot. */
19
+ export interface PairAcceptedSlotLedgerV1 {
20
+ readonly [pairAcceptedSlotLedgerBrand]: true;
21
+ }
22
+ export interface PairAcceptedSlotCoordinateV1 {
23
+ readonly pairEdgeId: Uint8Array;
24
+ readonly endpointPresenceOperationIds: readonly [Uint8Array, Uint8Array];
25
+ readonly direction: 0 | 1;
26
+ readonly pairSequence: bigint;
27
+ }
28
+ /**
29
+ * Structural input for the post-authentication boundary.
30
+ *
31
+ * Production pair ingress must construct this only from its opaque successful
32
+ * open result. This ledger owns and validates the shape but does not itself
33
+ * prove pair AEAD, signatures, bindings, or operation-ID derivation.
34
+ */
35
+ export interface PairSlotAcceptanceCandidateV1 {
36
+ readonly coordinate: PairAcceptedSlotCoordinateV1;
37
+ readonly kind: PairStepKindV1;
38
+ readonly acceptedOperationId: Uint8Array;
39
+ readonly exactOperationBytes: Uint8Array;
40
+ readonly acceptedLogicalWindow: bigint;
41
+ readonly retainThroughLogicalWindow: bigint;
42
+ readonly routingTag: Uint8Array;
43
+ readonly authorChainPrefix: readonly PairAuthorChainPrefixEvidenceV1[];
44
+ readonly cachedExactResponse: Uint8Array | null;
45
+ }
46
+ export interface PairAcceptedSlotEntryV1 extends PairSlotAcceptanceCandidateV1 {
47
+ readonly version: 1;
48
+ /**
49
+ * A null cached response is durable only for a locally denied
50
+ * IDENTITY_HELLO or terminal PAIR_CHECKPOINT. The former still reserves its
51
+ * authenticated slot so a later conflicting HELLO cannot win by arrival.
52
+ */
53
+ readonly cachedExactResponse: Uint8Array | null;
54
+ /**
55
+ * Bytewise-lowest two distinct authenticated IDs observed at this
56
+ * coordinate. These are a bounded fork-evidence index; the validated outer
57
+ * operation store remains the SSOT for the referenced signed bytes.
58
+ */
59
+ readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array] | null;
60
+ }
61
+ /** Durable, deeply owned structural representation. */
62
+ export interface PairAcceptedSlotLedgerSnapshotV1 {
63
+ readonly version: 1;
64
+ readonly entries: readonly PairAcceptedSlotEntryV1[];
65
+ }
66
+ export type PairAcceptedSlotTransitionV1 = {
67
+ readonly result: "accepted";
68
+ readonly ledger: PairAcceptedSlotLedgerV1;
69
+ } | {
70
+ readonly result: "replay";
71
+ /** Exact cached bytes are freshly owned by this result. */
72
+ readonly cachedExactResponse: Uint8Array | null;
73
+ /** Replay is a no-op and preserves handle identity. */
74
+ readonly ledger: PairAcceptedSlotLedgerV1;
75
+ } | {
76
+ readonly result: "fork";
77
+ readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array];
78
+ readonly ledger: PairAcceptedSlotLedgerV1;
79
+ } | {
80
+ readonly result: "edge-stalled";
81
+ readonly ledger: PairAcceptedSlotLedgerV1;
82
+ };
83
+ /**
84
+ * Read-only classification at the authenticated pair-slot boundary.
85
+ *
86
+ * `unoccupied` is deliberately not called `accepted`: no durable entry or
87
+ * fork proof exists until `recordAcceptedPairSlotV1` succeeds.
88
+ */
89
+ export type AuthenticatedPairSlotPreviewV1 = {
90
+ readonly result: "unoccupied";
91
+ } | {
92
+ readonly result: "replay";
93
+ /** Exact cached bytes are freshly owned by this result. */
94
+ readonly cachedExactResponse: Uint8Array | null;
95
+ } | {
96
+ readonly result: "fork";
97
+ readonly forkProofOperationIds: readonly [Uint8Array, Uint8Array];
98
+ } | {
99
+ readonly result: "edge-stalled";
100
+ };
101
+ export declare class PairLedgerError extends Error {
102
+ readonly name = "PairLedgerError";
103
+ constructor(message: string);
104
+ }
105
+ /** Create the unique empty ledger value. */
106
+ export declare const createEmptyPairAcceptedSlotLedgerV1: () => PairAcceptedSlotLedgerV1;
107
+ /** Deep-copy the complete state for the durable transaction adapter. */
108
+ export declare const snapshotPairAcceptedSlotLedgerV1: (ledger: PairAcceptedSlotLedgerV1) => PairAcceptedSlotLedgerSnapshotV1;
109
+ /** Canonical durable bytes for one genuine process-local ledger. */
110
+ export declare const encodePairAcceptedSlotLedgerV1: (ledger: PairAcceptedSlotLedgerV1) => Uint8Array;
111
+ /**
112
+ * Strict structural reconstruction boundary.
113
+ *
114
+ * This restores ledger shape and invariants, not cryptographic provenance.
115
+ * The durable pair transaction must revalidate exact accepted operation bytes
116
+ * and pair state before using a restored ledger for protocol effects.
117
+ */
118
+ export declare const restorePairAcceptedSlotLedgerV1: (snapshotValue: unknown) => PairAcceptedSlotLedgerV1;
119
+ /**
120
+ * Strict canonical durable-byte reconstruction.
121
+ *
122
+ * This restores structural ledger invariants only. The trusted pair
123
+ * transaction must still revalidate the retained signed operation bytes
124
+ * before the restored handle can authorize protocol effects.
125
+ */
126
+ export declare const decodePairAcceptedSlotLedgerV1: (encoded: Uint8Array) => PairAcceptedSlotLedgerV1;
127
+ /**
128
+ * Classify one fully authenticated candidate without creating any durable
129
+ * entry, fork proof, consumed-tag projection, or replacement ledger handle.
130
+ *
131
+ * A new IDENTITY_HELLO may be previewed with a null cached response so the
132
+ * caller can run admission and construct that response. The subsequent record
133
+ * call revalidates the candidate and requires the exact response atomically.
134
+ */
135
+ export declare const previewAuthenticatedPairSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => AuthenticatedPairSlotPreviewV1;
136
+ export declare const recordAcceptedPairSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => PairAcceptedSlotTransitionV1;
137
+ /**
138
+ * Persist a stable-signature-valid HELLO that current local policy denies.
139
+ *
140
+ * Denial sends no sensitive response, so an exact replay remains a null
141
+ * response. Reserving the authenticated slot is nevertheless load-bearing:
142
+ * a later byte-different HELLO at the same coordinate is a fork rather than
143
+ * an arrival-order winner. Only the trusted admission transaction may call
144
+ * this after its sole policy kernel returns deny.
145
+ */
146
+ export declare const recordDeniedIdentityHelloSlotV1: (ledger: PairAcceptedSlotLedgerV1, candidateValue: PairSlotAcceptanceCandidateV1) => PairAcceptedSlotTransitionV1;
147
+ /** True exactly while retained fork evidence stalls this edge. */
148
+ export declare const pairEdgeIsStalledV1: (ledger: PairAcceptedSlotLedgerV1, pairEdgeId: Uint8Array) => boolean;
149
+ /**
150
+ * Canonical unique routing-tag projection. There is intentionally no
151
+ * separately persisted consumed-tag collection.
152
+ */
153
+ export declare const consumedPairRoutingTagsV1: (ledger: PairAcceptedSlotLedgerV1) => readonly Uint8Array[];
154
+ export {};
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Pure durable pair-open work-budget reducer.
3
+ *
4
+ * The effectful transaction layer derives one charge from a genuine active
5
+ * PAIR_STEP, calls this reducer, compare-and-swaps the returned row together
6
+ * with the exact Core/pair-state revisions, and only then mints a one-use
7
+ * cryptographic trial capability. This module deliberately cannot authorize
8
+ * crypto work by itself.
9
+ */
10
+ export interface PairOpenBudgetCoordinateV1 {
11
+ readonly localRoomId: string;
12
+ readonly localPresenceOperationId: Uint8Array;
13
+ readonly budgetLogicalWindow: bigint;
14
+ }
15
+ export interface PairOpenBudgetSnapshotV1 {
16
+ readonly version: 1;
17
+ readonly coordinate: PairOpenBudgetCoordinateV1;
18
+ readonly budgetRevision: bigint;
19
+ readonly reservedTrialCount: number;
20
+ readonly reservedEnvelopeBytes: bigint;
21
+ readonly saturated: boolean;
22
+ }
23
+ /**
24
+ * Higher layers derive this from an opaque active-operation handle. In
25
+ * particular, `completeEnvelopeBytes` is the exact validated fixed payload
26
+ * length and is never a transport- or caller-reported estimate.
27
+ */
28
+ export interface PairOpenBudgetChargeV1 {
29
+ readonly localRoomId: string;
30
+ readonly localPresenceOperationId: Uint8Array;
31
+ readonly capturedReferenceWindow: bigint;
32
+ readonly completeEnvelopeBytes: number;
33
+ }
34
+ export interface PairOpenBudgetLimitsV1 {
35
+ readonly maxPairOpenTrialsPerPresenceWindow: number;
36
+ readonly maxPairOpenBytesPerPresenceWindow: number;
37
+ }
38
+ export type PairOpenBudgetTransitionV1 = {
39
+ readonly result: "prepared";
40
+ /** Must be durably committed before any cryptographic work begins. */
41
+ readonly next: PairOpenBudgetSnapshotV1;
42
+ } | {
43
+ readonly result: "saturated";
44
+ /**
45
+ * Non-null on the first saturation (or a new-window reset) and must be
46
+ * committed. Null means the persisted row was already sticky-saturated.
47
+ */
48
+ readonly next: PairOpenBudgetSnapshotV1 | null;
49
+ };
50
+ export declare class PairOpenBudgetError extends Error {
51
+ readonly name = "PairOpenBudgetError";
52
+ constructor(message: string);
53
+ }
54
+ /**
55
+ * Apply one actual expensive-trial charge.
56
+ *
57
+ * Equal/older captured windows reuse the durable counters. Only a strictly
58
+ * newer captured Core reference window resets them, and reset plus charge is
59
+ * represented by one replacement row. Repeating crypto work repeats charge.
60
+ */
61
+ export declare const reducePairOpenBudgetV1: (previousValue: PairOpenBudgetSnapshotV1 | null, chargeValue: PairOpenBudgetChargeV1, limitsValue: PairOpenBudgetLimitsV1) => PairOpenBudgetTransitionV1;
62
+ /** Strictly own and validate one row read from durable storage. */
63
+ export declare const validatePairOpenBudgetSnapshotV1: (value: unknown) => PairOpenBudgetSnapshotV1;
64
+ /** Canonical durable bytes after complete structural and reachability checks. */
65
+ export declare const encodePairOpenBudgetSnapshotV1: (value: unknown) => Uint8Array;
66
+ /** Strictly restore and own one canonical durable budget row. */
67
+ export declare const decodePairOpenBudgetSnapshotV1: (bytes: Uint8Array) => PairOpenBudgetSnapshotV1;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * Effectful pair-open budget reservation boundary.
3
+ *
4
+ * The pure reducer in pairOpenBudget.ts describes the next durable row. This
5
+ * module is the only bridge from that structural transition to permission for
6
+ * one expensive identity-HELLO open: it derives every coordinate and fence
7
+ * from opaque provenance, commits the exact row with one storage CAS, and only
8
+ * then mints an object-identity capability.
9
+ *
10
+ * The storage adapter treats canonical rows as opaque bytes. An IndexedDB
11
+ * implementation performs compare + optional replacement in one readwrite
12
+ * transaction over the Core, receiver-key, and budget stores and resolves
13
+ * "committed" only after `transaction.oncomplete`. No cryptography or other
14
+ * promise is awaited while that transaction is live.
15
+ */
16
+ import type { ActivePairOperationCandidateV1 } from "./coreReduce";
17
+ import type { ExpectedIdentityHelloTrialV1 } from "./identityHelloTrial";
18
+ import type { PairOpenBudgetLimitsV1 } from "./pairOpenBudget";
19
+ /** Storage subject shared by the Core, receiver-key, and budget lookups. */
20
+ export interface PairOpenBudgetSubjectV1 {
21
+ readonly localRoomId: string;
22
+ readonly localPresenceOperationId: Uint8Array;
23
+ }
24
+ /**
25
+ * Exact durable budget-row state. `absent` is distinct from malformed, empty,
26
+ * or deleted-and-recreated bytes.
27
+ */
28
+ export type ExactPairOpenBudgetRowV1 = {
29
+ readonly kind: "absent";
30
+ } | {
31
+ readonly kind: "present";
32
+ readonly exactBytes: Uint8Array;
33
+ };
34
+ export interface PairOpenReservationCasRequestV1 {
35
+ readonly subject: PairOpenBudgetSubjectV1;
36
+ /** Exact canonical Core bytes, not only `operationsDigest` or a revision. */
37
+ readonly expectedExactCoreStateBytes: Uint8Array;
38
+ /**
39
+ * Exact canonical HELLO-time Core bytes identifying the complete retained
40
+ * historical evidence view. This may intentionally differ from the current
41
+ * Core fence for a delayed HELLO.
42
+ *
43
+ * The durable row selected by this fence owns the exact presence operations
44
+ * and author prefixes for every observed presence in that Core view. An
45
+ * adapter must conflict if the row or any of that complete evidence is no
46
+ * longer retained.
47
+ */
48
+ readonly expectedExactEvidenceCoreStateBytes: Uint8Array;
49
+ /**
50
+ * Exact revision at the subject's receiver-key row. Revisions must never be
51
+ * reused after replacement or retirement, so deletion cannot create ABA.
52
+ */
53
+ readonly expectedReceiverKeyRecordRevision: bigint;
54
+ /** Exact prior bytes (or exact absence), never revision-only equality. */
55
+ readonly expectedBudgetRow: ExactPairOpenBudgetRowV1;
56
+ readonly budgetMutation: {
57
+ /** A sticky saturated row is still fenced, but needs no rewrite. */
58
+ readonly kind: "keep";
59
+ } | {
60
+ /** Canonical prepared or newly saturated replacement bytes. */
61
+ readonly kind: "replace";
62
+ readonly exactNextBytes: Uint8Array;
63
+ };
64
+ }
65
+ export type PairOpenReservationCasResultV1 = {
66
+ readonly status: "committed";
67
+ /**
68
+ * Exact row visible at commit. For `keep`, this is the prior row; for
69
+ * `replace`, this is the replacement. The service verifies this echo.
70
+ */
71
+ readonly exactBudgetRowBytes: Uint8Array;
72
+ } | {
73
+ readonly status: "conflict";
74
+ /**
75
+ * Adapters compare in this order: current Core, historical evidence
76
+ * view, receiver key, then budget row. The first mismatch determines
77
+ * this closed result.
78
+ */
79
+ readonly fence: "core" | "historical-evidence" | "receiver-key" | "budget";
80
+ };
81
+ /**
82
+ * Minimal byte-store port. Implementations own all input before retaining it
83
+ * and return fresh bytes; this module additionally snapshots every boundary.
84
+ */
85
+ export interface PairOpenReservationStorePortV1 {
86
+ /**
87
+ * Read the one current budget row for this room/presence subject. This read
88
+ * need not share a transaction with the later CAS: the exact returned bytes
89
+ * become the CAS fence.
90
+ */
91
+ readExactBudgetRow(subject: PairOpenBudgetSubjectV1): Promise<ExactPairOpenBudgetRowV1>;
92
+ /**
93
+ * In one atomic transaction, compare exact current Core bytes, the complete
94
+ * exact historical-evidence view, receiver-key record revision, and exact
95
+ * budget row/absence, then apply the requested mutation.
96
+ *
97
+ * If physical budget keys include `budgetLogicalWindow`, a replacement that
98
+ * advances the window deletes the old key and writes the new key in this
99
+ * same transaction.
100
+ */
101
+ compareAndSwap(request: PairOpenReservationCasRequestV1): Promise<PairOpenReservationCasResultV1>;
102
+ }
103
+ declare const reservedIdentityHelloOpenBrand: unique symbol;
104
+ /**
105
+ * One process-local permission for one already charged HELLO open.
106
+ *
107
+ * It intentionally exposes no structural fields. Spread, structured clone,
108
+ * persistence, or a type assertion cannot reproduce its WeakMap provenance.
109
+ */
110
+ export interface ReservedIdentityHelloOpenV1 {
111
+ readonly [reservedIdentityHelloOpenBrand]: true;
112
+ }
113
+ export type ReserveIdentityHelloOpenResultV1 = {
114
+ readonly kind: "reserved";
115
+ readonly capability: ReservedIdentityHelloOpenV1;
116
+ } | {
117
+ readonly kind: "saturated";
118
+ readonly condition: "pair-control-DoS/stalled";
119
+ } | {
120
+ readonly kind: "retry";
121
+ readonly reason: "budget-conflict";
122
+ } | {
123
+ readonly kind: "stale";
124
+ readonly reason: "core-changed" | "historical-evidence-changed" | "receiver-key-changed";
125
+ };
126
+ export interface PairOpenReservationServiceV1 {
127
+ /**
128
+ * Perform one read/reduce/CAS attempt. Budget contention is returned to the
129
+ * deterministic pair scheduler; this method never spins or reorders trials.
130
+ */
131
+ reserveIdentityHelloOpen(candidate: ActivePairOperationCandidateV1, trial: ExpectedIdentityHelloTrialV1): Promise<ReserveIdentityHelloOpenResultV1>;
132
+ }
133
+ export declare class PairOpenReservationError extends Error {
134
+ readonly name = "PairOpenReservationError";
135
+ constructor(message: string);
136
+ }
137
+ /**
138
+ * Create the trusted effectful boundary around one concrete storage adapter.
139
+ *
140
+ * The adapter and validated local resource policy are captured once; callers
141
+ * cannot supply a transition, charge, coordinate, fence, or commit result per
142
+ * trial.
143
+ */
144
+ export declare const createPairOpenReservationServiceV1: (port: PairOpenReservationStorePortV1, limits: PairOpenBudgetLimitsV1) => PairOpenReservationServiceV1;
145
+ /**
146
+ * Consume one exact reservation before any trial-secret transfer or KEM work.
147
+ *
148
+ * Deletion is synchronous and precedes return, so reentrancy and a second
149
+ * attempt cannot reuse the capability. The returned value is the opaque
150
+ * candidate privately stored at reservation time; the gated trial-secret
151
+ * transfer compares it to the candidate sealed inside the trial. No
152
+ * structural transition or secret-bearing snapshot is returned.
153
+ *
154
+ * @internal
155
+ */
156
+ export declare const consumeReservedIdentityHelloOpenV1: (capability: ReservedIdentityHelloOpenV1, trial: ExpectedIdentityHelloTrialV1) => ActivePairOperationCandidateV1;
157
+ export {};