@serfab/cadre-core 1.16.0 → 1.17.0

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 (199) hide show
  1. package/README.md +1 -1
  2. package/dist/bootstrap-peer-store-file.js +1 -1
  3. package/dist/bootstrap-peer-store.d.ts +1 -1
  4. package/dist/bootstrap-peer-store.js +4 -4
  5. package/dist/cadre-invite-protocol.d.ts +55 -138
  6. package/dist/cadre-invite-protocol.js +94 -449
  7. package/dist/cadre-invite-protocol.js.map +1 -1
  8. package/dist/cadre-join-request.d.ts +15 -2
  9. package/dist/cadre-join-request.js +22 -3
  10. package/dist/cadre-join-request.js.map +1 -1
  11. package/dist/cadre-node.d.ts +530 -247
  12. package/dist/cadre-node.js +1046 -525
  13. package/dist/cadre-node.js.map +1 -1
  14. package/dist/control-authorization.d.ts +36 -14
  15. package/dist/control-authorization.js +20 -3
  16. package/dist/control-authorization.js.map +1 -1
  17. package/dist/control-cohort.d.ts +22 -23
  18. package/dist/control-cohort.js +24 -24
  19. package/dist/control-cohort.js.map +1 -1
  20. package/dist/control-database.d.ts +416 -136
  21. package/dist/control-database.js +757 -378
  22. package/dist/control-database.js.map +1 -1
  23. package/dist/control-protocol-guard.d.ts +5 -4
  24. package/dist/control-protocol-guard.js +6 -3
  25. package/dist/control-protocol-guard.js.map +1 -1
  26. package/dist/control-schema-version.d.ts +80 -0
  27. package/dist/control-schema-version.js +203 -0
  28. package/dist/control-schema-version.js.map +1 -0
  29. package/dist/control-schema.d.ts +45 -5
  30. package/dist/control-schema.js +254 -70
  31. package/dist/control-schema.js.map +1 -1
  32. package/dist/control-write-retry.d.ts +5 -5
  33. package/dist/control-write-retry.js +10 -8
  34. package/dist/control-write-retry.js.map +1 -1
  35. package/dist/delegate-admission.d.ts +13 -0
  36. package/dist/delegate-admission.js +27 -0
  37. package/dist/delegate-admission.js.map +1 -1
  38. package/dist/ed25519-key.d.ts +10 -7
  39. package/dist/ed25519-key.js +23 -20
  40. package/dist/ed25519-key.js.map +1 -1
  41. package/dist/edge-node/config.d.ts +122 -0
  42. package/dist/edge-node/config.js +199 -0
  43. package/dist/edge-node/config.js.map +1 -0
  44. package/dist/edge-node/dissolve.d.ts +95 -0
  45. package/dist/edge-node/dissolve.js +184 -0
  46. package/dist/edge-node/dissolve.js.map +1 -0
  47. package/dist/edge-node/edge-join.d.ts +44 -0
  48. package/dist/edge-node/edge-join.js +227 -0
  49. package/dist/edge-node/edge-join.js.map +1 -0
  50. package/dist/edge-node/edge-node.d.ts +295 -0
  51. package/dist/edge-node/edge-node.js +704 -0
  52. package/dist/edge-node/edge-node.js.map +1 -0
  53. package/dist/edge-node/index.d.ts +18 -0
  54. package/dist/edge-node/index.js +18 -0
  55. package/dist/edge-node/index.js.map +1 -0
  56. package/dist/edge-node/join-credential.d.ts +11 -0
  57. package/dist/edge-node/join-credential.js +11 -0
  58. package/dist/edge-node/join-credential.js.map +1 -0
  59. package/dist/edge-node/lazy-raw-storage.d.ts +40 -0
  60. package/dist/edge-node/lazy-raw-storage.js +134 -0
  61. package/dist/edge-node/lazy-raw-storage.js.map +1 -0
  62. package/dist/edge-node/node-local.d.ts +60 -0
  63. package/dist/edge-node/node-local.js +58 -0
  64. package/dist/edge-node/node-local.js.map +1 -0
  65. package/dist/edge-node/options.d.ts +83 -0
  66. package/dist/edge-node/options.js +110 -0
  67. package/dist/edge-node/options.js.map +1 -0
  68. package/dist/edge-node/owner-grant.d.ts +41 -0
  69. package/dist/edge-node/owner-grant.js +38 -0
  70. package/dist/edge-node/owner-grant.js.map +1 -0
  71. package/dist/edge-node/platform.d.ts +140 -0
  72. package/dist/edge-node/platform.js +12 -0
  73. package/dist/edge-node/platform.js.map +1 -0
  74. package/dist/edge-node/strand-move.d.ts +115 -0
  75. package/dist/edge-node/strand-move.js +223 -0
  76. package/dist/edge-node/strand-move.js.map +1 -0
  77. package/dist/edge-node/strands.d.ts +28 -0
  78. package/dist/edge-node/strands.js +60 -0
  79. package/dist/edge-node/strands.js.map +1 -0
  80. package/dist/index.d.ts +16 -7
  81. package/dist/index.js +26 -7
  82. package/dist/index.js.map +1 -1
  83. package/dist/joined-strand-store.d.ts +3 -3
  84. package/dist/joined-strand-store.js +3 -3
  85. package/dist/joined-strand-store.js.map +1 -1
  86. package/dist/key-store.d.ts +9 -4
  87. package/dist/key-store.js +9 -4
  88. package/dist/key-store.js.map +1 -1
  89. package/dist/machine-removal.d.ts +19 -39
  90. package/dist/machine-removal.js +24 -98
  91. package/dist/machine-removal.js.map +1 -1
  92. package/dist/member-redemption.d.ts +250 -0
  93. package/dist/member-redemption.js +485 -0
  94. package/dist/member-redemption.js.map +1 -0
  95. package/dist/owner-anchor-sync.d.ts +4 -4
  96. package/dist/owner-anchor-sync.js +16 -15
  97. package/dist/owner-anchor-sync.js.map +1 -1
  98. package/dist/owner-grant-protocol.d.ts +247 -0
  99. package/dist/owner-grant-protocol.js +330 -0
  100. package/dist/owner-grant-protocol.js.map +1 -0
  101. package/dist/owner-key-export.d.ts +70 -0
  102. package/dist/owner-key-export.js +279 -0
  103. package/dist/owner-key-export.js.map +1 -0
  104. package/dist/owner-key-flows.d.ts +55 -0
  105. package/dist/owner-key-flows.js +60 -0
  106. package/dist/owner-key-flows.js.map +1 -0
  107. package/dist/owner-key-store.d.ts +31 -0
  108. package/dist/owner-key-store.js +81 -0
  109. package/dist/owner-key-store.js.map +1 -0
  110. package/dist/owner-keys.d.ts +78 -0
  111. package/dist/owner-keys.js +133 -0
  112. package/dist/owner-keys.js.map +1 -0
  113. package/dist/owner-signer.d.ts +54 -0
  114. package/dist/owner-signer.js +51 -0
  115. package/dist/owner-signer.js.map +1 -0
  116. package/dist/peer-authorization.d.ts +83 -18
  117. package/dist/peer-authorization.js +123 -53
  118. package/dist/peer-authorization.js.map +1 -1
  119. package/dist/provider/rent-node.js +1 -1
  120. package/dist/provider/rent-node.js.map +1 -1
  121. package/dist/seed-bootstrap.d.ts +131 -109
  122. package/dist/seed-bootstrap.js +260 -248
  123. package/dist/seed-bootstrap.js.map +1 -1
  124. package/dist/seed-trust-policy.js +4 -4
  125. package/dist/strand-addr-protocol.d.ts +4 -1
  126. package/dist/strand-addr-protocol.js +8 -2
  127. package/dist/strand-addr-protocol.js.map +1 -1
  128. package/dist/strand-cohort.d.ts +3 -0
  129. package/dist/strand-cohort.js.map +1 -1
  130. package/dist/strand-database.d.ts +1 -0
  131. package/dist/strand-database.js +3 -0
  132. package/dist/strand-database.js.map +1 -1
  133. package/dist/strand-first-sync-gate.d.ts +4 -3
  134. package/dist/strand-first-sync-gate.js +4 -3
  135. package/dist/strand-first-sync-gate.js.map +1 -1
  136. package/dist/strand-instance-manager.d.ts +1 -1
  137. package/dist/strand-membership-writer.d.ts +13 -2
  138. package/dist/strand-membership-writer.js +52 -16
  139. package/dist/strand-membership-writer.js.map +1 -1
  140. package/dist/strand-move.d.ts +6 -5
  141. package/dist/strand-move.js +31 -30
  142. package/dist/strand-move.js.map +1 -1
  143. package/dist/strand-peer-redial.js +2 -3
  144. package/dist/strand-peer-redial.js.map +1 -1
  145. package/dist/types.d.ts +286 -103
  146. package/dist/types.js.map +1 -1
  147. package/package.json +11 -2
  148. package/src/bootstrap-peer-store-file.ts +44 -44
  149. package/src/bootstrap-peer-store.ts +214 -214
  150. package/src/cadre-invite-protocol.ts +652 -1052
  151. package/src/cadre-join-request.ts +24 -3
  152. package/src/cadre-node.ts +1166 -541
  153. package/src/control-authorization.ts +47 -14
  154. package/src/control-cohort.ts +127 -128
  155. package/src/control-database.ts +940 -456
  156. package/src/control-protocol-guard.ts +7 -4
  157. package/src/control-schema-version.ts +251 -0
  158. package/src/control-schema.ts +265 -70
  159. package/src/control-write-retry.ts +569 -567
  160. package/src/delegate-admission.ts +37 -0
  161. package/src/ed25519-key.ts +174 -171
  162. package/src/edge-node/config.ts +277 -0
  163. package/src/edge-node/dissolve.ts +251 -0
  164. package/src/edge-node/edge-join.ts +319 -0
  165. package/src/edge-node/edge-node.ts +1045 -0
  166. package/src/edge-node/index.ts +59 -0
  167. package/src/edge-node/join-credential.ts +16 -0
  168. package/src/edge-node/lazy-raw-storage.ts +178 -0
  169. package/src/edge-node/node-local.ts +84 -0
  170. package/src/edge-node/options.ts +179 -0
  171. package/src/edge-node/owner-grant.ts +63 -0
  172. package/src/edge-node/platform.ts +151 -0
  173. package/src/edge-node/strand-move.ts +270 -0
  174. package/src/edge-node/strands.ts +72 -0
  175. package/src/index.ts +886 -789
  176. package/src/joined-strand-store.ts +4 -4
  177. package/src/key-store.ts +10 -4
  178. package/src/machine-removal.ts +26 -111
  179. package/src/member-redemption.ts +642 -0
  180. package/src/owner-anchor-sync.ts +19 -18
  181. package/src/owner-grant-protocol.ts +532 -0
  182. package/src/owner-key-export.ts +348 -0
  183. package/src/owner-key-flows.ts +109 -0
  184. package/src/owner-key-store.ts +85 -0
  185. package/src/owner-keys.ts +178 -0
  186. package/src/owner-signer.ts +94 -0
  187. package/src/peer-authorization.ts +558 -488
  188. package/src/provider/rent-node.ts +1 -1
  189. package/src/seed-bootstrap.ts +301 -312
  190. package/src/seed-trust-policy.ts +4 -4
  191. package/src/strand-addr-protocol.ts +547 -538
  192. package/src/strand-cohort.ts +4 -0
  193. package/src/strand-database.ts +3 -0
  194. package/src/strand-first-sync-gate.ts +4 -3
  195. package/src/strand-instance-manager.ts +1 -1
  196. package/src/strand-membership-writer.ts +61 -16
  197. package/src/strand-move.ts +45 -36
  198. package/src/strand-peer-redial.ts +2 -3
  199. package/src/types.ts +304 -103
@@ -1,15 +1,39 @@
1
+ import { Parser } from '@quereus/quereus';
1
2
  /**
2
- * Embedded control schema for cross-platform compatibility.
3
+ * The version of the declared control schema, carried in the schema text as the
4
+ * {@link CONTROL_SCHEMA_VERSION_TAG} tag on the `OwnerKey` table. A warm start compares
5
+ * it with the version the store records before applying anything
6
+ * (`control-schema-version.ts`, which also says why that is the version the store was
7
+ * created under).
3
8
  *
4
- * This is the authoritative runtime copy of the CadreControl authorization
5
- * schema. It is duplicated from `schemas/control.qsql` so that React Native and
6
- * other filesystem-less environments get the schema without a runtime file read.
9
+ * When it changes, what a new version may change, and the fixture each version keeps:
10
+ * docs/architecture.md → "Control schema changes and incompatible stores", enforced by
11
+ * `control-schema-versions.spec.ts`.
12
+ */
13
+ export const CONTROL_SCHEMA_VERSION = 3;
14
+ /**
15
+ * The first control schema version whose fixture is kept, and the oldest a store can be
16
+ * migrated from. Stores that record no version (written by 1.16.0 and earlier) are not
17
+ * migrated; docs/architecture.md says why.
18
+ */
19
+ export const CONTROL_SCHEMA_BASELINE_VERSION = 3;
20
+ /** The `OwnerKey` table tag that records {@link CONTROL_SCHEMA_VERSION} in the schema and in every store. */
21
+ export const CONTROL_SCHEMA_VERSION_TAG = 'sereus.controlSchemaVersion';
22
+ /**
23
+ * The `declare schema CadreControl { … }` statement, with its header comment.
24
+ *
25
+ * Together with {@link APPLY_CONTROL_SCHEMA} this is the authoritative runtime copy of
26
+ * the CadreControl authorization schema ({@link CONTROL_SCHEMA}). It is duplicated from
27
+ * `schemas/control.qsql` so that React Native and other filesystem-less environments
28
+ * get the schema without a runtime file read. Held apart from the apply because
29
+ * `ControlDatabase.loadSchema` declares, checks the pending changes, and only then
30
+ * applies.
7
31
  *
8
32
  * The two copies MUST stay identical — `control-schema-drift.spec.ts` fails the
9
33
  * build if they drift. Any edit here must be mirrored in `schemas/control.qsql`
10
34
  * and vice versa.
11
35
  */
12
- export const CONTROL_SCHEMA = `-- A Sereus party's cadre (its nodes) and their participation in strands (networks).
36
+ export const CONTROL_SCHEMA_DECLARATION = `-- A Sereus party's cadre (its nodes) and their participation in strands (networks).
13
37
  --
14
38
  -- Every write is authorized by a check: an owner signs an action-tagged digest of the row
15
39
  -- (cadre-core control-authorization.ts), or a peer signs its own record. Each digest leads
@@ -21,13 +45,14 @@ export const CONTROL_SCHEMA = `-- A Sereus party's cadre (its nodes) and their p
21
45
  -- two digests scoped by the invitation token instead (FormationUsage.Authorized).
22
46
  --
23
47
  -- Rows of the guarded tables (OwnerKey, ValidationKey, Strand, StrandPartyKey, JoinedStrand,
24
- -- JoinRequest, CadrePeer, DeviceToken, CadreInvite) carry a one-off StampId bound into their
25
- -- add and remove digests. \`unique\` holds over live rows only, so a delete retires the stamp
26
- -- into Revocation in the same transaction (RevocationRecorded) and an insert refuses a retired
27
- -- stamp (NotRevoked): the never-expiring add approval cannot re-seat a removed row. A
28
- -- legitimate re-add mints a fresh stamp and a fresh signature. CadreInvite is the one guarded
29
- -- table that is never deleted: its tombstone withdraws the invitation while the row stays,
30
- -- because the rows it admitted prove their membership through it.
48
+ -- JoinRequest, CadrePeer, DeviceToken, CadreInvite, OwnerGrant) carry a one-off StampId bound
49
+ -- into their add and remove digests. \`unique\` holds over live rows only, so a delete retires
50
+ -- the stamp into Revocation in the same transaction (RevocationRecorded) and an insert refuses
51
+ -- a retired stamp (NotRevoked): the never-expiring add approval cannot re-seat a removed row.
52
+ -- A legitimate re-add mints a fresh stamp and a fresh signature. CadreInvite and OwnerGrant
53
+ -- are the two guarded tables that are never deleted: a tombstone there withdraws the
54
+ -- invitation or grant while the row stays, because the rows it admitted prove themselves
55
+ -- through it.
31
56
  --
32
57
  -- A check whose expression evaluates to null passes (SQL three-valued logic), so every
33
58
  -- comparison over a nullable column that is meant to pin a value is written null-safe
@@ -47,12 +72,16 @@ export const CONTROL_SCHEMA = `-- A Sereus party's cadre (its nodes) and their p
47
72
  declare schema CadreControl {
48
73
  -- A key that can authorize control changes. A row is seated one of three ways, told apart
49
74
  -- by the vouch columns: the founding row (all three null), an owner-signed add (VouchOwner
50
- -- and VouchSig pinned to the insert context, VouchUsage null), or an owner-granting
51
- -- invitation redeemed by consent (VouchOwner = the invitation's IssuerKey, VouchSig null,
52
- -- VouchUsage = the CadreInviteUsage row that admitted it). A reader judges the stored proof
53
- -- against its node-local anchor, never against this replicated table.
75
+ -- and VouchSig pinned to the insert context, VouchUsage null), or an owner grant redeemed
76
+ -- by consent (VouchOwner = the grant's IssuerKey, VouchSig null, VouchUsage = the
77
+ -- OwnerGrantUsage row that seated it). A machine invitation (CadreInvite) admits a machine
78
+ -- and never seats a row here: a machine's identity key is never an owner key. A reader
79
+ -- judges the stored proof against its node-local anchor, never against this replicated
80
+ -- table.
54
81
  table OwnerKey (
55
82
  Key text primary key,
83
+ Label text null, -- the user's name for the key ("phone", "paper backup"); bound into the
84
+ -- signed add, so a relayed approval cannot seat the key under another name
56
85
  StampId text unique,
57
86
  VouchOwner text null,
58
87
  VouchSig text null,
@@ -60,6 +89,10 @@ declare schema CadreControl {
60
89
  constraint NotRevoked check on insert (
61
90
  not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = new.StampId)
62
91
  ),
92
+ -- Never empty: the add digest binds coalesce(Label, ''), so an empty label would sign as none.
93
+ constraint LabelLength check (
94
+ Label is null or length(Label) between 1 and 64
95
+ ),
63
96
  -- The tombstone must name the removed row, not just its stamp (Revocation.RowKey).
64
97
  constraint RevocationRecorded check on delete (
65
98
  exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = old.StampId and R.RowKey = old.Key)
@@ -81,29 +114,34 @@ declare schema CadreControl {
81
114
  -- deliberately raw, the one owner read here that ignores Revocation: a machine holding only
82
115
  -- a retired owner row must still be refused a second genesis, or a removed device could
83
116
  -- re-found the party on its own copy. An owner cannot sign its own removal.
84
- -- The consent branch seats an owner with no signature at all: a CadreInviteUsage row
85
- -- written in the same transaction names this exact row (Key and stamp), and the
86
- -- invitation it redeemed grants ownership and was issued by the stored VouchOwner. The
87
- -- invitation is read from committed.CadreInvite, so an invitation cannot be seated and
88
- -- redeemed in one transaction; the usage row carries the liveness conditions.
117
+ -- The consent branch seats an owner with no signature at all: an OwnerGrantUsage row
118
+ -- written in the same transaction names this exact row (Key and stamp), and the grant
119
+ -- it redeemed was issued by the stored VouchOwner and carries the row's label (the
120
+ -- issuer's choice, bound into the grant's signature). The grant is read from its
121
+ -- committed table, so it cannot be seated and redeemed in one transaction; the usage
122
+ -- row carries the liveness conditions.
89
123
  constraint Authorized check on insert, delete (
90
124
  (old.Key is null and (select count(1) from committed.OwnerKey) = 0
91
125
  and new.VouchOwner is null and new.VouchSig is null and new.VouchUsage is null)
92
- or (old.Key is null and exists (select 1 from committed.OwnerKey A where A.Key = context.OwnerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(digest('CadreControl.OwnerKey', 'add', party_id(), new.Key, new.StampId), context.Signature, A.Key, 'ed25519'))
126
+ or (old.Key is null and exists (select 1 from committed.OwnerKey A where A.Key = context.OwnerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(digest('CadreControl.OwnerKey', 'add', party_id(), new.Key, coalesce(new.Label, ''), new.StampId), context.Signature, A.Key, 'ed25519'))
93
127
  and coalesce(new.VouchOwner, '') = context.OwnerKey
94
128
  and coalesce(new.VouchSig, '') = context.Signature
95
129
  and new.VouchUsage is null)
96
130
  or (old.Key is null and new.VouchSig is null and new.VouchUsage is not null
97
131
  and exists (
98
- select 1 from CadreInviteUsage U
132
+ select 1 from OwnerGrantUsage U
99
133
  where U.UsageStampId = new.VouchUsage
100
- and U.PeerKey = new.Key
101
- and U.OwnerStampId = new.StampId
102
- and exists (select 1 from committed.CadreInvite I where I.Key = U.InviteKey and I.GrantsOwner = 1 and I.IssuerKey = new.VouchOwner)
134
+ and U.SeatedKey = new.Key
135
+ and U.SeatedStampId = new.StampId
136
+ and exists (select 1 from committed.OwnerGrant G
137
+ where G.Key = U.GrantKey and G.IssuerKey = new.VouchOwner
138
+ and coalesce(G.Label, '') = coalesce(new.Label, ''))
103
139
  ))
104
140
  or (new.Key is null and exists (select 1 from committed.OwnerKey A where A.Key = context.OwnerKey and A.Key <> old.Key and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(digest('CadreControl.OwnerKey', 'remove', party_id(), old.Key, old.StampId), context.Signature, A.Key, 'ed25519')))
105
141
  )
106
- ) with context (OwnerKey text null, Signature text null);
142
+ -- The tag is the version of this whole schema (cadre-core CONTROL_SCHEMA_VERSION): every edit
143
+ -- to the schema bumps it, and a warm start reads the store's copy before applying anything.
144
+ ) with tags ("${CONTROL_SCHEMA_VERSION_TAG}" = ${CONTROL_SCHEMA_VERSION}) with context (OwnerKey text null, Signature text null);
107
145
 
108
146
  -- A key that can validate a strand formation disclosure (FormationUsage.Authorized).
109
147
  table ValidationKey (
@@ -136,9 +174,12 @@ declare schema CadreControl {
136
174
  Id text primary key, -- UUID
137
175
  MemberPrivateKey text null unique, -- the strand's shared read secret; closed strands only
138
176
  Type text, -- 'o' open | 'c' closed: open gates writes in the sApp, only closed gates reads
139
- FounderOwnerKey text null, -- owner key of the machine that published the row, the founding machine
140
- -- (cadre-node.ts launchStrand); null on a consent-seated strand, whose
141
- -- insert carries no signature. Provenance, not content (strandRowMismatches).
177
+ FounderOwnerKey text null, -- the owner key that signed the insert; null on a consent-seated strand,
178
+ -- whose insert carries no signature. Provenance, not content (strandRowMismatches).
179
+ FounderPeerId text null, -- peer id of the machine that runs the founder bootstrap (cadre-node.ts
180
+ -- launchStrand), bound into the signed add; null on a consent-seated strand.
181
+ -- Not pinned to a CadrePeer row: a solo founder publishes before its own
182
+ -- row exists, and only an owner can name it. Provenance, as FounderOwnerKey.
142
183
  StampId text unique,
143
184
  constraint NotRevoked check on insert (
144
185
  not exists (select 1 from Revocation R where R.TableName = 'Strand' and R.StampId = new.StampId)
@@ -149,9 +190,10 @@ declare schema CadreControl {
149
190
  -- The consent branch below carries no signature, so an update rule would let anyone rewrite
150
191
  -- a consent-seated strand.
151
192
  constraint NoUpdate check on update (false),
152
- -- Owner-signed, with FounderOwnerKey pinned to the verified signer; or consent-seated by a
153
- -- FormationUsage row naming this exact row (id and stamp), written in the same transaction
154
- -- (ControlDatabase.redeemInvitation). Binding the stamp is what makes a removal stick:
193
+ -- Owner-signed, with FounderOwnerKey pinned to the verified signer and FounderPeerId bound
194
+ -- into the signature; or consent-seated by a FormationUsage row naming this exact row (id
195
+ -- and stamp), written in the same transaction (ControlDatabase.redeemInvitation). Binding
196
+ -- the stamp is what makes a removal stick:
155
197
  -- the usage row outlives the strand, and keyed on the id alone it would re-authorize an
156
198
  -- unsigned re-seat under a fresh stamp. The consent branch is narrow, each clause closing
157
199
  -- one door:
@@ -164,12 +206,14 @@ declare schema CadreControl {
164
206
  -- A standalone tombstone (no accompanying delete, Revocation.Authorized) lets an owner
165
207
  -- foreclose consent-seating of an id that never existed: owner-only, and ids are random.
166
208
  constraint AuthorizedInsert check on insert (
167
- (exists (select 1 from OwnerKey A where A.Key = context.OwnerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(digest('CadreControl.Strand', 'add', party_id(), new.Id, new.Type, coalesce(new.MemberPrivateKey, ''), new.StampId), context.Signature, A.Key, 'ed25519'))
168
- and new.FounderOwnerKey = context.OwnerKey)
209
+ (exists (select 1 from OwnerKey A where A.Key = context.OwnerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(digest('CadreControl.Strand', 'add', party_id(), new.Id, new.Type, coalesce(new.MemberPrivateKey, ''), new.FounderPeerId, new.StampId), context.Signature, A.Key, 'ed25519'))
210
+ and new.FounderOwnerKey = context.OwnerKey
211
+ and new.FounderPeerId is not null)
169
212
  or (
170
213
  new.Type = 'o'
171
214
  and new.MemberPrivateKey is null
172
215
  and new.FounderOwnerKey is null
216
+ and new.FounderPeerId is null
173
217
  and exists (
174
218
  select 1 from FormationUsage FU
175
219
  where FU.StrandId = new.Id
@@ -623,11 +667,13 @@ declare schema CadreControl {
623
667
  -- convergence is guarded by the integration scenario strand-formation-concurrent-redemption.
624
668
  index FormationUsageByToken on FormationUsage (Token);
625
669
 
626
- -- An owner-signed invitation to join this cadre, redeemable on the owner's behalf by any
627
- -- member machine (ControlDatabase.redeemCadreInvite). The invitation is a keypair, not a
670
+ -- An owner-signed invitation to join this cadre as a machine, redeemable on the owner's
671
+ -- behalf by any member machine (ControlDatabase.redeemCadreInvite). It admits a machine
672
+ -- and grants nothing else; ownership is an OwnerGrant. The invitation is a keypair, not a
628
673
  -- bearer token: the row holds the public half and the holder proves possession by signing
629
- -- with the private half (CadreInviteUsage.InvitePossessed), so the member that redeems it
630
- -- can verify but never redeem it for itself. Rows are never deleted: a device admitted
674
+ -- with the private half (CadreInviteUsage.InvitePossessed), so a member that only relays
675
+ -- it can neither admit a machine of its own choosing with it nor spend its uses. Rows are
676
+ -- never deleted: a device admitted
631
677
  -- through one carries no owner signature of its own, and its membership is the chain
632
678
  -- invitation -> usage -> peer row, verified at read time, so the row must outlive every
633
679
  -- device it admitted. Withdrawing an invitation is an owner-signed Revocation tombstone
@@ -640,7 +686,6 @@ declare schema CadreControl {
640
686
  table CadreInvite (
641
687
  Key text primary key, -- the invitation's ed25519 public key (base64url)
642
688
  PeerId text null, -- the device this invitation is for; null: whoever redeems first designates it
643
- GrantsOwner integer check (GrantsOwner = 0 or GrantsOwner = 1), -- 1: redemption also seats an OwnerKey row
644
689
  ExpiresAt datetime null,
645
690
  TotalUses int null check (TotalUses >= 0),
646
691
  IssuerKey text, -- the owner that signed the row (== insert context.OwnerKey). A reader checks it
@@ -661,7 +706,6 @@ declare schema CadreControl {
661
706
  'CadreControl.CadreInvite', 'add', party_id(),
662
707
  new.Key,
663
708
  coalesce(new.PeerId, ''),
664
- cast(new.GrantsOwner as text),
665
709
  coalesce(cast(new.ExpiresAt as text), ''),
666
710
  coalesce(cast(new.TotalUses as text), ''),
667
711
  new.StampId
@@ -676,8 +720,7 @@ declare schema CadreControl {
676
720
  ) with context (OwnerKey text, Signature text);
677
721
 
678
722
  -- Append-only record of cadre invitation redemptions, one row per redemption: the proof a
679
- -- CadrePeer row (and, for an owner-granting invitation, an OwnerKey row) was admitted by
680
- -- consent rather than by an owner signature.
723
+ -- CadrePeer row was admitted by consent rather than by an owner signature.
681
724
  table CadreInviteUsage (
682
725
  UsageStampId text primary key, -- nonce minted by the redeeming device and signed into both signatures
683
726
  -- below. The primary key: this table never deletes, so the key alone
@@ -691,22 +734,20 @@ declare schema CadreControl {
691
734
  PeerStampId text, -- the CadrePeer.StampId this usage seats: one row incarnation, not a peer id
692
735
  -- forever. Minted by the writer inside the redeeming transaction and not
693
736
  -- signed (FormationUsage.StrandStampId).
694
- OwnerStampId text null, -- the OwnerKey.StampId this usage seats when the invitation grants ownership
695
737
  InviteSig text, -- by the invitation's private key over the 'redeem' digest: proof of possession
696
738
  PeerSig text, -- by PeerKey over the 'consent' digest: the device agreed to join
697
739
  constraint InsertOnly check on update, delete (false),
698
740
  -- The invitation is read from the pre-transaction snapshot, so an invitation cannot be
699
- -- seated and redeemed in one transaction (the OwnerKey consent branch rests on that).
741
+ -- seated and redeemed in one transaction (the CadrePeer consent branch rests on that).
700
742
  -- NOTE: accepted tradeoff — the use cap counts committed usage, so two redeemers racing
701
- -- for a single-use invitation on different machines may both be admitted until merge,
702
- -- and after merge both rows stand (FormationUsage.Authorized), for owner grants too.
703
- -- Serializing would need cross-machine coordination the control plane does not have;
704
- -- the mitigations are the defaults the redemption protocol sets (untargeted owner
705
- -- invitations single-use with a short expiry), the targeted form for owner grants, and
706
- -- the owner seeing the extra owner and removing it. Revisit if the control plane gains
707
- -- a cross-machine sequencer. An issuer removed since issuing takes its outstanding
708
- -- invitations with it (the committed.OwnerKey clause, which a tombstone alone
709
- -- satisfies); devices it already admitted stay members.
743
+ -- for a single-use machine invitation on different machines may both be admitted until
744
+ -- merge, and after merge both rows stand (FormationUsage.Authorized). Serializing would
745
+ -- need cross-machine coordination the control plane does not have; the mitigations are
746
+ -- the single-use default, the targeted form, and the owner seeing the extra machine and
747
+ -- removing it. Revisit if the control plane gains a cross-machine sequencer. The owner
748
+ -- grant's half of this tradeoff is at OwnerGrantUsage.Authorized. An issuer removed
749
+ -- since issuing takes its outstanding invitations with it (the committed.OwnerKey
750
+ -- clause, which a tombstone alone satisfies); devices it already admitted stay members.
710
751
  constraint Authorized check on insert (
711
752
  exists (
712
753
  select 1 from committed.CadreInvite I
@@ -731,33 +772,143 @@ declare schema CadreControl {
731
772
  ),
732
773
  -- Deferred, so the same-transaction peer insert counts: a usage row can never be held in
733
774
  -- reserve to seat a row later (FormationUsage.StrandExists). PeerKey must be the key the
734
- -- peer row stores: a redemption that only completes an already-admitted device with its
735
- -- OwnerKey row (no peer insert to pin it) cannot name a key other than that device's.
775
+ -- peer row stores, so the usage names the admitted machine's own key and no other.
736
776
  constraint PeerExists check (exists (
737
777
  select 1 from CadrePeer P where P.PeerId = new.PeerId and P.StampId = new.PeerStampId and P.PublicKey = new.PeerKey
738
- )),
739
- constraint OwnerExists check (
740
- new.OwnerStampId is null
741
- or exists (select 1 from OwnerKey K where K.Key = new.PeerKey and K.StampId = new.OwnerStampId)
742
- )
778
+ ))
743
779
  ) with context (Now datetime);
744
780
 
745
781
  -- Serves the cap count above and the liveness reads (cadre-core countCadreInviteUsage,
746
782
  -- hasLiveCadreInvite) on an append-only table, as FormationUsageByToken does.
747
783
  index CadreInviteUsageByInvite on CadreInviteUsage (InviteKey);
748
784
 
785
+ -- An owner-signed grant of ownership to whoever holds the grant's private half: it seats an
786
+ -- OwnerKey row for a key the holder generates or already holds, and admits no machine (a
787
+ -- machine is admitted by a CadreInvite; peer identity and ownership are unrelated, so the
788
+ -- row names no peer id). The grant is a keypair as the invitation is: the row holds the
789
+ -- public half, the holder proves possession by signing with the private half
790
+ -- (OwnerGrantUsage.GrantPossessed), and the member machine that writes the redemption can
791
+ -- verify that signature but never produce it, so it cannot seat an owner for itself. Rows
792
+ -- are never deleted: a key seated through one carries no owner signature of its own, and
793
+ -- its proof is the chain grant -> usage -> OwnerKey row, verified at read time, so the row
794
+ -- must outlive every key it seated. Withdrawal is an owner-signed Revocation tombstone over
795
+ -- the row's stamp with the row kept (Revocation.RowIsGone); liveness is read as no
796
+ -- tombstone, unexpired, uses left, issuer still an owner (OwnerGrantUsage.Authorized).
797
+ -- NOTE: expired and withdrawn rows accumulate for the life of the party, as CadreInvite's.
798
+ -- The label is the issuer's: it is bound into the grant's signature and the seated OwnerKey
799
+ -- row must carry it (the grant branch of OwnerKey.Authorized), so a key seated on a fresh
800
+ -- device during recovery needs no naming prompt, and nothing the holder writes names it.
801
+ table OwnerGrant (
802
+ Key text primary key, -- the grant's ed25519 public key (base64url)
803
+ Label text null, -- the label the seated OwnerKey row carries, chosen by the issuer
804
+ ExpiresAt datetime null, -- null: never. The writer defaults to a short expiry; a lifetime with
805
+ -- no end is the issuer's explicit choice (a backup grant)
806
+ TotalUses int null check (TotalUses >= 0),
807
+ IssuerKey text, -- the owner that signed the row (== insert context.OwnerKey); a reader checks
808
+ -- it against its node-local anchor, never against the replicated OwnerKey table
809
+ IssuerSig text, -- that owner's 'add' signature (== insert context.Signature), stored so any
810
+ -- reader can re-verify the row from the holder's copy or the replicated one
811
+ StampId text unique,
812
+ -- A withdrawn grant cannot be re-seated from the signed copy its holder keeps, on any
813
+ -- node that holds the tombstone (schema header for the node that does not).
814
+ constraint NotRevoked check on insert (
815
+ not exists (select 1 from Revocation R where R.TableName = 'OwnerGrant' and R.StampId = new.StampId)
816
+ ),
817
+ -- Never empty, as OwnerKey.LabelLength: the add digest binds coalesce(Label, '').
818
+ constraint LabelLength check (
819
+ Label is null or length(Label) between 1 and 64
820
+ ),
821
+ -- The owner signs the whole row, nullable columns as '' (cadre-core ownerGrantRowFields),
822
+ -- and the stored issuer pair must be the pair verified here, as CadreInvite pins its issuer.
823
+ constraint AuthorizedInsert check on insert (
824
+ exists (select 1 from OwnerKey A where A.Key = context.OwnerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = A.StampId) and verify(
825
+ digest(
826
+ 'CadreControl.OwnerGrant', 'add', party_id(),
827
+ new.Key,
828
+ coalesce(new.Label, ''),
829
+ coalesce(cast(new.ExpiresAt as text), ''),
830
+ coalesce(cast(new.TotalUses as text), ''),
831
+ new.StampId
832
+ ),
833
+ context.Signature, A.Key, 'ed25519'))
834
+ and coalesce(new.IssuerKey, '') = context.OwnerKey
835
+ and coalesce(new.IssuerSig, '') = context.Signature
836
+ ),
837
+ constraint NoUpdate check on update (false),
838
+ -- Never deleted (table comment). Withdrawal is the tombstone alone.
839
+ constraint NoDelete check on delete (false)
840
+ ) with context (OwnerKey text, Signature text);
841
+
842
+ -- Append-only record of owner-grant redemptions, one row per redemption: the proof an
843
+ -- OwnerKey row was seated by consent rather than by an owner signature.
844
+ table OwnerGrantUsage (
845
+ UsageStampId text primary key, -- nonce minted by the holder and signed into both signatures below. The
846
+ -- primary key: this table never deletes, so the key alone makes a nonce
847
+ -- permanent and there is no NotRevoked pair here (CadreInviteUsage).
848
+ GrantKey text, -- the OwnerGrant redeemed
849
+ SeatedKey text, -- the owner key seated (base64url ed25519): the holder's, fresh or already held
850
+ SeatedStampId text, -- the OwnerKey.StampId this usage seats: one row incarnation, not a key
851
+ -- forever. Minted by the writer inside the redeeming transaction and not
852
+ -- signed (CadreInviteUsage.PeerStampId).
853
+ GrantSig text, -- by the grant's private key over the 'redeem' digest: proof of possession
854
+ OwnerSig text, -- by SeatedKey over the 'consent' digest: the holder holds the key it seats
855
+ constraint InsertOnly check on update, delete (false),
856
+ -- The grant is read from the pre-transaction snapshot, so a grant cannot be seated and
857
+ -- redeemed in one transaction (the grant branch of OwnerKey.Authorized rests on that).
858
+ -- NOTE: accepted tradeoff — the use cap counts committed usage, so two holders of one
859
+ -- single-use grant redeeming on different machines may both be seated until merge, and
860
+ -- after merge both rows stand (CadreInviteUsage.Authorized). Serializing would need
861
+ -- cross-machine coordination the control plane does not have; the mitigations are the
862
+ -- defaults the writer sets (single use and a 15-minute expiry, a longer lifetime only
863
+ -- when the user chooses one) and the owner seeing the extra key in the owner-key list
864
+ -- and removing it. Revisit if the control plane gains a cross-machine sequencer. An
865
+ -- issuer removed since issuing takes its outstanding grants with it (the
866
+ -- committed.OwnerKey clause, which a tombstone alone satisfies); keys it already
867
+ -- seated stay owners.
868
+ constraint Authorized check on insert (
869
+ exists (
870
+ select 1 from committed.OwnerGrant G
871
+ where G.Key = new.GrantKey
872
+ and not exists (select 1 from Revocation R where R.TableName = 'OwnerGrant' and R.StampId = G.StampId)
873
+ and (G.ExpiresAt is null or G.ExpiresAt > context.Now)
874
+ and (G.TotalUses is null or G.TotalUses > (select count(1) from committed.OwnerGrantUsage U where U.GrantKey = new.GrantKey))
875
+ and exists (select 1 from committed.OwnerKey K where K.Key = G.IssuerKey and not exists (select 1 from Revocation R where R.TableName = 'OwnerKey' and R.StampId = K.StampId))
876
+ )
877
+ ),
878
+ -- Verified against the grant key itself: the member writing the row can check this
879
+ -- signature but, holding only the public half, cannot produce it.
880
+ constraint GrantPossessed check on insert (
881
+ verify(digest('CadreControl.OwnerGrantUsage', 'redeem', party_id(), new.GrantKey, new.UsageStampId, new.SeatedKey),
882
+ new.GrantSig, new.GrantKey, 'ed25519')
883
+ ),
884
+ -- The holder proves it holds the key being seated (CadreInviteUsage.PeerConsented).
885
+ constraint OwnerConsented check on insert (
886
+ verify(digest('CadreControl.OwnerGrantUsage', 'consent', party_id(), new.GrantKey, new.UsageStampId, new.SeatedKey),
887
+ new.OwnerSig, new.SeatedKey, 'ed25519')
888
+ ),
889
+ -- Deferred, so the same-transaction OwnerKey insert counts: a usage row can never be
890
+ -- held in reserve to seat a row later (CadreInviteUsage.PeerExists).
891
+ constraint SeatedExists check (
892
+ exists (select 1 from OwnerKey K where K.Key = new.SeatedKey and K.StampId = new.SeatedStampId)
893
+ )
894
+ ) with context (Now datetime);
895
+
896
+ -- Serves the cap count above and the liveness reads (cadre-core countOwnerGrantUsage,
897
+ -- listOwnerGrantStatuses) on an append-only table, as CadreInviteUsageByInvite does.
898
+ index OwnerGrantUsageByGrant on OwnerGrantUsage (GrantKey);
899
+
749
900
  -- Append-only retirement record for the stamps of removed rows of every guarded table, with
750
901
  -- the removed row's key. Every append is owner-signed, so the growth surface is the owner
751
902
  -- keys. One singleton marker row, ('Revocation', 'ledger', 'opened'), retires nothing: an
752
903
  -- owner's connected reconcile pass files it (ControlDatabase.openRevocationLedger) so this
753
904
  -- table is never a never-written block, which the storage layer would consult the cohort
754
905
  -- for on every guarded insert and membership lookup. Readers filter on their own guarded
755
- -- TableName, and queryRevocations skips it. A 'CadreInvite' row withdraws an invitation
756
- -- whose row stays (CadreInvite table comment).
906
+ -- TableName, and queryRevocations skips it. A 'CadreInvite' or 'OwnerGrant' row withdraws
907
+ -- an invitation or a grant whose row stays (the table comments).
757
908
  table Revocation (
758
909
  TableName text, -- 'OwnerKey' | 'ValidationKey' | 'Strand' | 'StrandPartyKey' | 'JoinedStrand' |
759
- -- 'JoinRequest' | 'CadrePeer' | 'DeviceToken' | 'CadreInvite', or 'Revocation'
760
- -- for the marker
910
+ -- 'JoinRequest' | 'CadrePeer' | 'DeviceToken' | 'CadreInvite' | 'OwnerGrant', or
911
+ -- 'Revocation' for the marker
761
912
  RowKey text, -- primary key of the removed row
762
913
  StampId text, -- the retired stamp
763
914
  ReissuedAt integer default 0, -- bumped by an owner-signed re-issue so a tombstone committed while the
@@ -785,9 +936,9 @@ declare schema CadreControl {
785
936
  -- counts). Keyed on the stamp, not RowKey: a node that converges on a re-admission before
786
937
  -- the earlier removal's tombstone must still accept that tombstone. Retiring a stamp that
787
938
  -- never existed is harmless: stamps carry 128 random bits (generateStampId). For
788
- -- 'CadreInvite' there is no row-gone test: a tombstone there is a withdrawal, and the
789
- -- row stays (CadreInvite table comment). The last branch admits the marker row and
790
- -- nothing else under 'Revocation'.
939
+ -- 'CadreInvite' and 'OwnerGrant' there is no row-gone test: a tombstone there is a
940
+ -- withdrawal, and the row stays (the table comments). The last branch admits the marker
941
+ -- row and nothing else under 'Revocation'.
791
942
  constraint RowIsGone check on insert (
792
943
  (new.TableName = 'OwnerKey' and not exists (select 1 from OwnerKey K where K.StampId = new.StampId))
793
944
  or (new.TableName = 'CadrePeer' and not exists (select 1 from CadrePeer P where P.StampId = new.StampId))
@@ -798,6 +949,7 @@ declare schema CadreControl {
798
949
  or (new.TableName = 'JoinRequest' and not exists (select 1 from JoinRequest J where J.StampId = new.StampId))
799
950
  or (new.TableName = 'DeviceToken' and not exists (select 1 from DeviceToken D where D.StampId = new.StampId))
800
951
  or (new.TableName = 'CadreInvite')
952
+ or (new.TableName = 'OwnerGrant')
801
953
  or (new.TableName = 'Revocation' and new.RowKey = 'ledger' and new.StampId = 'opened')
802
954
  ),
803
955
  -- Owner-signed over the whole row under its own domain tag, so the delete's 'remove'
@@ -822,8 +974,40 @@ declare schema CadreControl {
822
974
  context.Signature, A.Key, 'ed25519'))
823
975
  )
824
976
  ) with context (OwnerKey text, Signature text);
825
- }
977
+ }`;
978
+ /** The name the control schema is declared under; Quereus compares schema names without regard to case. */
979
+ export const CONTROL_SCHEMA_NAME = 'CadreControl';
980
+ /** The statement that applies {@link CONTROL_SCHEMA_DECLARATION}, run only after the store has been checked against it. */
981
+ export const APPLY_CONTROL_SCHEMA = `apply schema ${CONTROL_SCHEMA_NAME};`;
982
+ /** The whole control schema as `schemas/control.qsql` holds it: the declaration, then the apply. */
983
+ export const CONTROL_SCHEMA = `${CONTROL_SCHEMA_DECLARATION}
826
984
 
827
- apply schema CadreControl;
985
+ ${APPLY_CONTROL_SCHEMA}
828
986
  `;
987
+ /**
988
+ * The declaration statement of a control schema file (`ControlDatabaseConfig.schemaPath`),
989
+ * cut from the file's own text.
990
+ *
991
+ * Refuses a file that is anything other than one `declare schema CadreControl { … }`
992
+ * followed by one plain `apply schema CadreControl` — the shape of {@link CONTROL_SCHEMA}.
993
+ * `loadSchema` runs its own {@link APPLY_CONTROL_SCHEMA} once the store has been checked,
994
+ * so any other statement in the file, or an option on its apply, would be dropped or run
995
+ * unchecked.
996
+ */
997
+ export function controlSchemaFileDeclaration(source) {
998
+ const statements = new Parser().parseAll(source);
999
+ const [declaration, apply] = statements;
1000
+ if (statements.length !== 2
1001
+ || declaration.type !== 'declareSchema' || !isControlSchemaName(declaration.schemaName)
1002
+ || apply.type !== 'applySchema' || !isControlSchemaName(apply.schemaName)
1003
+ || apply.options !== undefined || apply.toVersion !== undefined || apply.withSeed === true
1004
+ || declaration.loc === undefined) {
1005
+ throw new Error(`A control schema file must hold exactly \`declare schema ${CONTROL_SCHEMA_NAME} { … }\` ` +
1006
+ `followed by \`${APPLY_CONTROL_SCHEMA}\`, the shape of schemas/control.qsql.`);
1007
+ }
1008
+ return source.slice(declaration.loc.start.offset, declaration.loc.end.offset);
1009
+ }
1010
+ function isControlSchemaName(name) {
1011
+ return name?.toLowerCase() === CONTROL_SCHEMA_NAME.toLowerCase();
1012
+ }
829
1013
  //# sourceMappingURL=control-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"control-schema.js","sourceRoot":"","sources":["../src/control-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgzB7B,CAAC"}
1
+ {"version":3,"file":"control-schema.js","sourceRoot":"","sources":["../src/control-schema.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ import type { ControlRetryOptions } from './control-retry.js';
31
31
  * TWO policies ship from here, and the split is deliberate: the default
32
32
  * ({@link isRetriableControlWriteFailure}, {@link CONTROL_WRITE_ATTEMPTS}) sits under every
33
33
  * control write, and {@link SCHEMA_INIT_RETRY_POLICY} is opted into by
34
- * `ControlDatabase.loadSchema` alone. The widened one absorbs one extra failure class whose
34
+ * `ControlDatabase.applyControlSchema` alone. The widened one absorbs one extra failure class whose
35
35
  * re-run safety holds for schema DDL and NOT for writes in general; anything added to the default
36
36
  * list must be safe for all ~19 callers.
37
37
  *
@@ -212,7 +212,7 @@ export declare function isUncommittedTransactorAggregate(message: string): boole
212
212
  export declare function isRetriableControlWriteFailure(error: unknown): boolean;
213
213
  /**
214
214
  * {@link isRetriableControlWriteFailure} widened by exactly one class — the self-coordination
215
- * grace refusal ({@link RETRIABLE_SCHEMA_INIT_MATCHERS}) — for `ControlDatabase.loadSchema`.
215
+ * grace refusal ({@link RETRIABLE_SCHEMA_INIT_MATCHERS}) — for `ControlDatabase.applyControlSchema`.
216
216
  *
217
217
  * Opt-in per call site, via {@link SCHEMA_INIT_RETRY_POLICY}. Every other control write keeps the
218
218
  * default classifier untouched.
@@ -230,7 +230,7 @@ export declare function isRetriableSchemaInitFailure(error: unknown): boolean;
230
230
  */
231
231
  export type ControlWriteRetryOptions = ControlRetryOptions;
232
232
  /**
233
- * The one non-default retry policy: `ControlDatabase.loadSchema`'s distributed DDL, which
233
+ * The one non-default retry policy: `ControlDatabase.applyControlSchema`'s distributed DDL, which
234
234
  * additionally absorbs optimystic's self-coordination grace refusal and gets more attempts over a
235
235
  * longer backoff to do it (see {@link SCHEMA_INIT_ATTEMPTS} and
236
236
  * {@link SCHEMA_INIT_RETRY_DELAYS_MS}). Still bounded by the shared
@@ -238,8 +238,8 @@ export type ControlWriteRetryOptions = ControlRetryOptions;
238
238
  *
239
239
  * NOTE: exactly one call site opts in today, and the re-run safety this policy assumes is that
240
240
  * site's, not a general property — `apply schema` is a diff, and a failed apply is unwound whole
241
- * and verified against the pre-apply catalog (full argument at the `loadSchema` call site in
242
- * `control-database.ts`). A second opt-in must re-derive that argument for its own write body
241
+ * and verified against the pre-apply catalog (full argument at the `applyControlSchema` call site
242
+ * in `control-database.ts`). A second opt-in must re-derive that argument for its own write body
243
243
  * first; if this policy ever grows a third consumer, rename it for what the callers share rather
244
244
  * than widening it by default.
245
245
  */
@@ -33,7 +33,7 @@ import { causeChain, chainMessages, retryControlOperation } from './control-retr
33
33
  * TWO policies ship from here, and the split is deliberate: the default
34
34
  * ({@link isRetriableControlWriteFailure}, {@link CONTROL_WRITE_ATTEMPTS}) sits under every
35
35
  * control write, and {@link SCHEMA_INIT_RETRY_POLICY} is opted into by
36
- * `ControlDatabase.loadSchema` alone. The widened one absorbs one extra failure class whose
36
+ * `ControlDatabase.applyControlSchema` alone. The widened one absorbs one extra failure class whose
37
37
  * re-run safety holds for schema DDL and NOT for writes in general; anything added to the default
38
38
  * list must be safe for all ~19 callers.
39
39
  *
@@ -382,14 +382,16 @@ const RETRIABLE_CONTROL_WRITE_MATCHERS = [
382
382
  * failed apply is taken back whole — Quereus unwinds every step it ran and verifies the catalog
383
383
  * against a pre-apply fingerprint — so a re-run emits exactly the DDL the live catalog is missing.
384
384
  * The full argument, including the plugin-side dependency that unwind carries, is at the
385
- * `loadSchema` call site in `control-database.ts`.
385
+ * `applyControlSchema` call site in `control-database.ts`.
386
386
  *
387
387
  * RETRIED DELIBERATELY, not by oversight: the failures Quereus cannot take back. When the unwind
388
388
  * does not complete — an undo statement threw, the post-unwind catalog did not match the pre-apply
389
389
  * fingerprint, that catalog could not be re-collected to check, or a step the differ marks
390
390
  * irreversible because it discards data (dropping a table or a column, narrowing a column's type —
391
- * none of which a `CadreControl` diff generates today) poisoned the journal before it ran, leaving
392
- * nothing unwound — Quereus keeps the failing step's own message, APPENDS the reason the
391
+ * none of which reaches a `CadreControl` apply: a cold store's diff is all creates, and
392
+ * `refuseIncompatibleControlStore` in `control-schema-version.ts` refuses a warm store whose diff
393
+ * holds anything but creates and tag changes before the apply runs) poisoned the journal before it
394
+ * ran, leaving nothing unwound — Quereus keeps the failing step's own message, APPENDS the reason the
393
395
  * schema could not be restored, and carries the original as `cause`. So a transient cause
394
396
  * underneath still matches here, and neither veto ({@link reportsPossiblyStoredWrite},
395
397
  * {@link reportsIndeterminateCommit}) looks for that reason text. Retrying over a partially migrated
@@ -432,7 +434,7 @@ export function isRetriableControlWriteFailure(error) {
432
434
  }
433
435
  /**
434
436
  * {@link isRetriableControlWriteFailure} widened by exactly one class — the self-coordination
435
- * grace refusal ({@link RETRIABLE_SCHEMA_INIT_MATCHERS}) — for `ControlDatabase.loadSchema`.
437
+ * grace refusal ({@link RETRIABLE_SCHEMA_INIT_MATCHERS}) — for `ControlDatabase.applyControlSchema`.
436
438
  *
437
439
  * Opt-in per call site, via {@link SCHEMA_INIT_RETRY_POLICY}. Every other control write keeps the
438
440
  * default classifier untouched.
@@ -466,7 +468,7 @@ function matchesRetriableFailure(error, matchers) {
466
468
  return messages.some(message => matchers.some(matches => matches(message)));
467
469
  }
468
470
  /**
469
- * The one non-default retry policy: `ControlDatabase.loadSchema`'s distributed DDL, which
471
+ * The one non-default retry policy: `ControlDatabase.applyControlSchema`'s distributed DDL, which
470
472
  * additionally absorbs optimystic's self-coordination grace refusal and gets more attempts over a
471
473
  * longer backoff to do it (see {@link SCHEMA_INIT_ATTEMPTS} and
472
474
  * {@link SCHEMA_INIT_RETRY_DELAYS_MS}). Still bounded by the shared
@@ -474,8 +476,8 @@ function matchesRetriableFailure(error, matchers) {
474
476
  *
475
477
  * NOTE: exactly one call site opts in today, and the re-run safety this policy assumes is that
476
478
  * site's, not a general property — `apply schema` is a diff, and a failed apply is unwound whole
477
- * and verified against the pre-apply catalog (full argument at the `loadSchema` call site in
478
- * `control-database.ts`). A second opt-in must re-derive that argument for its own write body
479
+ * and verified against the pre-apply catalog (full argument at the `applyControlSchema` call site
480
+ * in `control-database.ts`). A second opt-in must re-derive that argument for its own write body
479
481
  * first; if this policy ever grows a third consumer, rename it for what the callers share rather
480
482
  * than widening it by default.
481
483
  */
@@ -1 +1 @@
1
- {"version":3,"file":"control-write-retry.js","sourceRoot":"","sources":["../src/control-write-retry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"control-write-retry.js","sourceRoot":"","sources":["../src/control-write-retry.ts"],"names":[],"mappings":"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"}