@opengeni/contracts 0.39.0 → 0.44.1

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 (130) hide show
  1. package/dist/atlassian.d.ts +278 -0
  2. package/dist/atlassian.js +55 -0
  3. package/dist/atlassian.js.map +1 -0
  4. package/dist/chunk-52SGB2QO.js +688 -0
  5. package/dist/chunk-52SGB2QO.js.map +1 -0
  6. package/dist/{chunk-7JZMI22I.js → chunk-5UDNP7AO.js} +34 -2
  7. package/dist/chunk-5UDNP7AO.js.map +1 -0
  8. package/dist/chunk-BVGIYW7D.js +11 -0
  9. package/dist/chunk-BVGIYW7D.js.map +1 -0
  10. package/dist/chunk-CADSX6UN.js +1145 -0
  11. package/dist/chunk-CADSX6UN.js.map +1 -0
  12. package/dist/chunk-D2HKF2EF.js +1460 -0
  13. package/dist/chunk-D2HKF2EF.js.map +1 -0
  14. package/dist/chunk-FJBG5E4O.js +194 -0
  15. package/dist/chunk-FJBG5E4O.js.map +1 -0
  16. package/dist/chunk-H5BVCZKF.js +382 -0
  17. package/dist/chunk-H5BVCZKF.js.map +1 -0
  18. package/dist/chunk-LSB7GRLG.js +779 -0
  19. package/dist/chunk-LSB7GRLG.js.map +1 -0
  20. package/dist/chunk-MYBZRDTY.js +340 -0
  21. package/dist/chunk-MYBZRDTY.js.map +1 -0
  22. package/dist/chunk-RIY7GYQS.js +1204 -0
  23. package/dist/chunk-RIY7GYQS.js.map +1 -0
  24. package/dist/chunk-TZ6YEYN4.js +386 -0
  25. package/dist/chunk-TZ6YEYN4.js.map +1 -0
  26. package/dist/chunk-VA22KRHS.js +15177 -0
  27. package/dist/chunk-VA22KRHS.js.map +1 -0
  28. package/dist/chunk-Y3MLSLB4.js +392 -0
  29. package/dist/chunk-Y3MLSLB4.js.map +1 -0
  30. package/dist/chunk-YRKRZ6OF.js +134 -0
  31. package/dist/chunk-YRKRZ6OF.js.map +1 -0
  32. package/dist/company-profile.d.ts +629 -0
  33. package/dist/document-artifact-commands.d.ts +282 -0
  34. package/dist/document-artifact-commands.js +54 -0
  35. package/dist/document-artifact-commands.js.map +1 -0
  36. package/dist/document-artifact-query.d.ts +2 -0
  37. package/dist/document-artifact-query.js +54 -0
  38. package/dist/document-artifact-query.js.map +1 -0
  39. package/dist/editable-artifact-binary.d.ts +56 -0
  40. package/dist/editable-artifact-causal-frontier.d.ts +12 -0
  41. package/dist/editable-artifact-causal-frontier.js +18 -0
  42. package/dist/editable-artifact-causal-frontier.js.map +1 -0
  43. package/dist/editable-artifact-codec-registry.d.ts +48 -0
  44. package/dist/editable-artifact-codec-registry.js +20 -0
  45. package/dist/editable-artifact-codec-registry.js.map +1 -0
  46. package/dist/editable-artifact-committed-transaction.d.ts +35 -0
  47. package/dist/editable-artifact-committed-transaction.js +19 -0
  48. package/dist/editable-artifact-committed-transaction.js.map +1 -0
  49. package/dist/editable-artifact-live.d.ts +276 -0
  50. package/dist/editable-artifact-live.js +907 -0
  51. package/dist/editable-artifact-live.js.map +1 -0
  52. package/dist/editable-artifact-serialized-commit.d.ts +53 -0
  53. package/dist/editable-artifact-serialized-commit.js +26 -0
  54. package/dist/editable-artifact-serialized-commit.js.map +1 -0
  55. package/dist/editable-artifact-versions.d.ts +6 -0
  56. package/dist/editable-artifact-versions.js +11 -0
  57. package/dist/editable-artifact-versions.js.map +1 -0
  58. package/dist/editable-artifacts.d.ts +46 -0
  59. package/dist/editable-artifacts.js +236 -0
  60. package/dist/editable-artifacts.js.map +1 -0
  61. package/dist/event-preview.d.ts +7 -7
  62. package/dist/google-drive.d.ts +114 -2
  63. package/dist/google-drive.js +70 -14
  64. package/dist/google-drive.js.map +1 -1
  65. package/dist/image-generation.d.ts +70 -0
  66. package/dist/index.d.ts +5180 -329
  67. package/dist/index.js +1173 -40
  68. package/dist/interaction.d.ts +6895 -0
  69. package/dist/mcp-receipts.d.ts +96 -0
  70. package/dist/memory-slack-delivery.d.ts +397 -0
  71. package/dist/presentation-artifact-commands.d.ts +349 -0
  72. package/dist/presentation-artifact-commands.js +66 -0
  73. package/dist/presentation-artifact-commands.js.map +1 -0
  74. package/dist/presentation-artifact-query.d.ts +2 -0
  75. package/dist/presentation-artifact-query.js +66 -0
  76. package/dist/presentation-artifact-query.js.map +1 -0
  77. package/dist/retained-output.d.ts +83 -6
  78. package/dist/sandbox-snapshots.d.ts +9 -0
  79. package/dist/scoped-knowledge.d.ts +14 -13
  80. package/dist/slack-bot-scopes.d.ts +4 -0
  81. package/dist/slack-bot-scopes.js +3 -1
  82. package/dist/spreadsheet-artifact-commands.d.ts +101 -0
  83. package/dist/spreadsheet-artifact-commands.js +27 -0
  84. package/dist/spreadsheet-artifact-commands.js.map +1 -0
  85. package/dist/spreadsheet-artifact-date.d.ts +4 -0
  86. package/dist/spreadsheet-artifact-query.d.ts +120 -0
  87. package/dist/spreadsheet-artifact-query.js +48 -0
  88. package/dist/spreadsheet-artifact-query.js.map +1 -0
  89. package/dist/tool-catalog.d.ts +576 -0
  90. package/dist/video-generation.d.ts +532 -0
  91. package/dist/video-generation.js +51 -0
  92. package/dist/video-generation.js.map +1 -0
  93. package/dist/workspace-learning-policy.d.ts +208 -0
  94. package/package.json +61 -1
  95. package/src/atlassian.ts +160 -0
  96. package/src/company-profile.ts +306 -0
  97. package/src/document-artifact-commands.ts +1709 -0
  98. package/src/document-artifact-query.ts +2 -0
  99. package/src/editable-artifact-binary.ts +396 -0
  100. package/src/editable-artifact-causal-frontier.ts +154 -0
  101. package/src/editable-artifact-codec-registry.ts +261 -0
  102. package/src/editable-artifact-committed-transaction.ts +478 -0
  103. package/src/editable-artifact-live.ts +1379 -0
  104. package/src/editable-artifact-serialized-commit.ts +494 -0
  105. package/src/editable-artifact-versions.ts +8 -0
  106. package/src/editable-artifacts.ts +473 -0
  107. package/src/event-preview.ts +6 -6
  108. package/src/google-drive.ts +68 -15
  109. package/src/image-generation.ts +106 -0
  110. package/src/index.ts +2535 -282
  111. package/src/interaction.ts +2292 -0
  112. package/src/mcp-receipts.ts +281 -0
  113. package/src/memory-slack-delivery.ts +183 -0
  114. package/src/presentation-artifact-commands.ts +2035 -0
  115. package/src/presentation-artifact-query.ts +2 -0
  116. package/src/retained-output.ts +248 -8
  117. package/src/sandbox-snapshots.ts +28 -1
  118. package/src/scoped-knowledge.ts +18 -4
  119. package/src/slack-bot-scopes.ts +34 -1
  120. package/src/spreadsheet-artifact-commands.ts +999 -0
  121. package/src/spreadsheet-artifact-date.ts +21 -0
  122. package/src/spreadsheet-artifact-query.ts +1411 -0
  123. package/src/tool-catalog.ts +334 -0
  124. package/src/video-generation.ts +394 -0
  125. package/src/workspace-learning-policy.ts +233 -0
  126. package/dist/chunk-7JZMI22I.js.map +0 -1
  127. package/dist/chunk-PCTCJEAF.js +0 -10799
  128. package/dist/chunk-PCTCJEAF.js.map +0 -1
  129. package/dist/secret-redaction.d.ts +0 -40
  130. package/src/secret-redaction.ts +0 -364
@@ -0,0 +1,494 @@
1
+ import { bytesToHex } from "@noble/hashes/utils";
2
+
3
+ import {
4
+ ArtifactBinaryReader,
5
+ ArtifactBinaryWriter,
6
+ EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES,
7
+ EDITABLE_ARTIFACT_BINARY_HEADER_BYTES,
8
+ decodeCountedEnvelope,
9
+ equalBytes,
10
+ fnv1a64,
11
+ strictUtf8,
12
+ } from "./editable-artifact-binary";
13
+ import {
14
+ DOCUMENT_ARTIFACT_COMMAND_MAX_COMMANDS,
15
+ DOCUMENT_ARTIFACT_MAX_STRUCTURAL_COUNTER,
16
+ } from "./document-artifact-commands";
17
+ import {
18
+ EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
19
+ decodeEditableArtifactMutationIntent,
20
+ encodeEditableArtifactMutationIntent,
21
+ hashEditableArtifactMutationIntentBytes,
22
+ type EditableArtifactMutationIntent,
23
+ } from "./editable-artifacts";
24
+ import { editableArtifactCodecFor } from "./editable-artifact-codec-registry";
25
+
26
+ export const EDITABLE_ARTIFACT_SERIALIZED_COMMIT_VERSION = 1 as const;
27
+ export const EDITABLE_ARTIFACT_SERIALIZED_COMMIT_MAX_BYTES = 8 * 1024 * 1024;
28
+ export const EDITABLE_ARTIFACT_NATIVE_RECEIPT_MAX_BYTES = 512 * 1024;
29
+
30
+ const MAGIC = strictUtf8("OGAST001", "serialized commit magic");
31
+ const SHA256_TEXT = /^sha256:[0-9a-f]{64}$/u;
32
+ const STABLE_ID = /^[0-9a-f]{32}$/u;
33
+ const DOCUMENT_RECEIPT_MAGIC = "OGADR001";
34
+ const PRESENTATION_RECEIPT_MAGIC = strictUtf8("OGAPR001", "presentation receipt magic");
35
+ const DOCUMENT_RECEIPT_VERSION = 1;
36
+ const PRESENTATION_RECEIPT_VERSION = 1;
37
+ const DOCUMENT_CREATED_IDS_PER_COMMAND = 7;
38
+ const DOCUMENT_ID_BYTES = 17;
39
+ const PRESENTATION_RECEIPT_BYTES = 32;
40
+ const MODALITY_TAG = Object.freeze({ document: 1, presentation: 2 } as const);
41
+
42
+ export type EditableArtifactSerializedModality = "document" | "presentation";
43
+
44
+ export type EditableArtifactNativeReceiptSummary =
45
+ | Readonly<{
46
+ modality: "document";
47
+ revision: number;
48
+ commandCount: number;
49
+ createdIdCount: number;
50
+ }>
51
+ | Readonly<{
52
+ modality: "presentation";
53
+ revision: number;
54
+ commandCount: number;
55
+ }>;
56
+
57
+ export type EditableArtifactSerializedCommitInput = Readonly<{
58
+ modality: EditableArtifactSerializedModality;
59
+ transactionId: string;
60
+ parentHeadSequence: number;
61
+ resultHeadSequence: number;
62
+ /** Native model revision before applying this non-empty command batch. */
63
+ priorNativeRevision: number;
64
+ priorStateHash: string;
65
+ stateHash: string;
66
+ /** Exact canonical OGATX001 bytes accepted by the server. */
67
+ intentBytes: Uint8Array;
68
+ /** Exact canonical OGADR001 or OGAPR001 bytes returned by the native kernel. */
69
+ nativeReceiptBytes: Uint8Array;
70
+ }>;
71
+
72
+ export type EditableArtifactSerializedCommitSummary = Readonly<{
73
+ commitProtocolVersion: typeof EDITABLE_ARTIFACT_SERIALIZED_COMMIT_VERSION;
74
+ modality: EditableArtifactSerializedModality;
75
+ transactionId: string;
76
+ parentHeadSequence: number;
77
+ resultHeadSequence: number;
78
+ priorNativeRevision: number;
79
+ priorStateHash: string;
80
+ stateHash: string;
81
+ requestHash: string;
82
+ /** Canonical client intent nested in this authoritative commit. */
83
+ intent: EditableArtifactMutationIntent;
84
+ intentBytes: Uint8Array;
85
+ nativeReceiptBytes: Uint8Array;
86
+ nativeReceipt: EditableArtifactNativeReceiptSummary;
87
+ }>;
88
+
89
+ /**
90
+ * Server-only encoder for one authoritative, strictly serialized commit.
91
+ * Client identity remains solely in the exact nested OGATX envelope.
92
+ */
93
+ export function encodeEditableArtifactSerializedCommit(
94
+ input: EditableArtifactSerializedCommitInput,
95
+ ): Uint8Array {
96
+ const normalized = normalizeSerializedCommit(input);
97
+ const payload = new ArtifactBinaryWriter(
98
+ EDITABLE_ARTIFACT_SERIALIZED_COMMIT_MAX_BYTES -
99
+ EDITABLE_ARTIFACT_BINARY_HEADER_BYTES -
100
+ EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES,
101
+ );
102
+ payload.stableId(normalized.transactionId, "serialized transaction id");
103
+ payload.u64(normalized.parentHeadSequence);
104
+ payload.u64(normalized.resultHeadSequence);
105
+ payload.u64(normalized.priorNativeRevision);
106
+ payload.bytes(hashBytes(normalized.priorStateHash));
107
+ payload.bytes(hashBytes(normalized.stateHash));
108
+ payload.u32(normalized.intentBytes.byteLength);
109
+ payload.u32(normalized.nativeReceiptBytes.byteLength);
110
+ payload.bytes(normalized.intentBytes);
111
+ payload.bytes(normalized.nativeReceiptBytes);
112
+
113
+ const payloadBytes = payload.finish();
114
+ const output = new ArtifactBinaryWriter(EDITABLE_ARTIFACT_SERIALIZED_COMMIT_MAX_BYTES);
115
+ output.bytes(MAGIC);
116
+ output.u16(EDITABLE_ARTIFACT_SERIALIZED_COMMIT_VERSION);
117
+ output.u16(0);
118
+ output.u32(MODALITY_TAG[normalized.modality]);
119
+ output.u64(payloadBytes.byteLength);
120
+ output.bytes(payloadBytes);
121
+ output.u64(fnv1a64(output.view()));
122
+ return output.finish();
123
+ }
124
+
125
+ /** Durable modality must be selected before any nested receipt/command decode. */
126
+ export function decodeEditableArtifactSerializedCommit(
127
+ bytes: Uint8Array,
128
+ durableModality: EditableArtifactSerializedModality,
129
+ ): EditableArtifactSerializedCommitSummary {
130
+ assertUnsharedBytes(bytes, "serialized commit");
131
+ const modality = serializedModality(durableModality);
132
+ if (bytes.byteLength > EDITABLE_ARTIFACT_SERIALIZED_COMMIT_MAX_BYTES) {
133
+ throw new RangeError("serialized commit exceeds its byte limit");
134
+ }
135
+ if (
136
+ bytes.byteLength <
137
+ EDITABLE_ARTIFACT_BINARY_HEADER_BYTES + EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES
138
+ ) {
139
+ throw new TypeError("truncated serialized commit envelope");
140
+ }
141
+ const header = new ArtifactBinaryReader(bytes);
142
+ if (!equalBytes(header.bytes(8), MAGIC)) {
143
+ throw new TypeError("invalid serialized commit magic");
144
+ }
145
+ if (header.u16() !== EDITABLE_ARTIFACT_SERIALIZED_COMMIT_VERSION) {
146
+ throw new TypeError("unsupported serialized commit version");
147
+ }
148
+ if (header.u16() !== 0) {
149
+ throw new TypeError("reserved serialized commit flags must be zero");
150
+ }
151
+ if (header.u32() !== MODALITY_TAG[modality]) {
152
+ throw new TypeError("serialized commit modality disagrees with durable artifact");
153
+ }
154
+ const payloadLength = header.u64Safe("serialized commit payload length");
155
+ const expectedLength =
156
+ EDITABLE_ARTIFACT_BINARY_HEADER_BYTES + payloadLength + EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES;
157
+ if (bytes.byteLength < expectedLength) {
158
+ throw new TypeError("truncated serialized commit payload");
159
+ }
160
+ if (bytes.byteLength > expectedLength) {
161
+ throw new TypeError("serialized commit contains trailing bytes");
162
+ }
163
+ const payloadBytes = header.bytes(payloadLength);
164
+ const checksum = header.u64BigInt();
165
+ header.done();
166
+ if (
167
+ checksum !==
168
+ fnv1a64(bytes.subarray(0, bytes.byteLength - EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES))
169
+ ) {
170
+ throw new TypeError("serialized commit checksum does not match");
171
+ }
172
+
173
+ const payload = new ArtifactBinaryReader(payloadBytes);
174
+ const transactionId = payload.stableId("serialized transaction id");
175
+ const parentHeadSequence = payload.u64Safe("serialized parent head sequence");
176
+ const resultHeadSequence = payload.u64Safe("serialized result head sequence");
177
+ const priorNativeRevision = payload.u64Safe("serialized prior native revision");
178
+ const priorStateHash = stateHashText(payload.bytes(32));
179
+ const stateHash = stateHashText(payload.bytes(32));
180
+ const intentLength = payload.count(
181
+ EDITABLE_ARTIFACT_INTENT_MAX_BYTES,
182
+ "serialized intent bytes",
183
+ 1,
184
+ );
185
+ const receiptLength = payload.count(
186
+ EDITABLE_ARTIFACT_NATIVE_RECEIPT_MAX_BYTES,
187
+ "serialized native receipt bytes",
188
+ 1,
189
+ );
190
+ if (payload.remaining !== intentLength + receiptLength) {
191
+ throw new TypeError("serialized commit nested byte lengths are inconsistent");
192
+ }
193
+ const intentBytes = payload.bytes(intentLength).slice();
194
+ const nativeReceiptBytes = payload.bytes(receiptLength).slice();
195
+ payload.done();
196
+
197
+ const normalized = normalizeSerializedCommit({
198
+ modality,
199
+ transactionId,
200
+ parentHeadSequence,
201
+ resultHeadSequence,
202
+ priorNativeRevision,
203
+ priorStateHash,
204
+ stateHash,
205
+ intentBytes,
206
+ nativeReceiptBytes,
207
+ });
208
+ const canonical = encodeEditableArtifactSerializedCommit(normalized);
209
+ if (!equalBytes(bytes, canonical)) {
210
+ throw new TypeError("serialized commit is not canonically encoded");
211
+ }
212
+ return Object.freeze({
213
+ commitProtocolVersion: EDITABLE_ARTIFACT_SERIALIZED_COMMIT_VERSION,
214
+ modality,
215
+ transactionId,
216
+ parentHeadSequence,
217
+ resultHeadSequence,
218
+ priorNativeRevision,
219
+ priorStateHash,
220
+ stateHash,
221
+ requestHash: normalized.requestHash,
222
+ intent: normalized.intent,
223
+ intentBytes,
224
+ nativeReceiptBytes,
225
+ nativeReceipt: normalized.nativeReceipt,
226
+ });
227
+ }
228
+
229
+ export function assertCanonicalEditableArtifactSerializedCommit(
230
+ bytes: Uint8Array,
231
+ durableModality: EditableArtifactSerializedModality,
232
+ ): void {
233
+ decodeEditableArtifactSerializedCommit(bytes, durableModality);
234
+ }
235
+
236
+ type NormalizedSerializedCommit = EditableArtifactSerializedCommitInput &
237
+ Readonly<{
238
+ requestHash: string;
239
+ intent: EditableArtifactMutationIntent;
240
+ nativeReceipt: EditableArtifactNativeReceiptSummary;
241
+ }>;
242
+
243
+ function normalizeSerializedCommit(
244
+ input: EditableArtifactSerializedCommitInput,
245
+ ): NormalizedSerializedCommit {
246
+ const modality = serializedModality(input.modality);
247
+ const transactionId = canonicalStableId(input.transactionId, "serialized transaction id");
248
+ const parentHeadSequence = safeSequence(
249
+ input.parentHeadSequence,
250
+ "serialized parent head sequence",
251
+ );
252
+ const resultHeadSequence = safeSequence(
253
+ input.resultHeadSequence,
254
+ "serialized result head sequence",
255
+ );
256
+ if (resultHeadSequence !== parentHeadSequence + 1) {
257
+ throw new TypeError("serialized commit must advance the durable head exactly once");
258
+ }
259
+ const priorNativeRevision = safeSequence(
260
+ input.priorNativeRevision,
261
+ "serialized prior native revision",
262
+ );
263
+ const priorStateHash = canonicalSha256(input.priorStateHash, "serialized prior state hash");
264
+ const stateHash = canonicalSha256(input.stateHash, "serialized resulting state hash");
265
+ assertUnsharedBytes(input.intentBytes, "serialized intent");
266
+ assertUnsharedBytes(input.nativeReceiptBytes, "serialized native receipt");
267
+ if (
268
+ input.intentBytes.byteLength < 1 ||
269
+ input.intentBytes.byteLength > EDITABLE_ARTIFACT_INTENT_MAX_BYTES
270
+ ) {
271
+ throw new RangeError("serialized intent bytes exceed their limit");
272
+ }
273
+ if (
274
+ input.nativeReceiptBytes.byteLength < 1 ||
275
+ input.nativeReceiptBytes.byteLength > EDITABLE_ARTIFACT_NATIVE_RECEIPT_MAX_BYTES
276
+ ) {
277
+ throw new RangeError("serialized native receipt bytes exceed their limit");
278
+ }
279
+ const intentBytes = input.intentBytes.slice();
280
+ const decodedIntent = decodeEditableArtifactMutationIntent(intentBytes);
281
+ if (!equalBytes(intentBytes, encodeEditableArtifactMutationIntent(decodedIntent))) {
282
+ throw new TypeError("nested serialized intent is not canonical OGATX001");
283
+ }
284
+ if (
285
+ decodedIntent.causalBase.length !== 0 ||
286
+ decodedIntent.selectiveUndoOperationIds.length !== 0
287
+ ) {
288
+ throw new TypeError("serialized commits cannot carry CRDT causality or selective undo");
289
+ }
290
+ if (decodedIntent.observedHeadSequence !== parentHeadSequence) {
291
+ throw new TypeError("serialized intent observed head does not match its parent");
292
+ }
293
+ const descriptor = editableArtifactCodecFor({
294
+ durableModality: modality,
295
+ modelSchemaVersion: decodedIntent.modelSchemaVersion,
296
+ commandProtocolVersion: decodedIntent.commandProtocolVersion,
297
+ });
298
+ descriptor.command.assertCanonical(decodedIntent.commandBytes);
299
+ const commandCount = decodedCommandCount(descriptor.command.decode(decodedIntent.commandBytes));
300
+ if (commandCount < 1) {
301
+ throw new TypeError("serialized commits require a non-empty command batch");
302
+ }
303
+ const nativeReceiptBytes = input.nativeReceiptBytes.slice();
304
+ const nativeReceipt = decodeNativeReceipt(modality, nativeReceiptBytes, commandCount);
305
+ if (modality === "presentation") {
306
+ if (nativeReceipt.revision !== priorNativeRevision + 1) {
307
+ throw new TypeError(
308
+ "presentation receipt must advance its prior native revision exactly once",
309
+ );
310
+ }
311
+ if (stateHash === priorStateHash) {
312
+ throw new TypeError("presentation commit must change its canonical state hash");
313
+ }
314
+ } else if (nativeReceipt.revision === priorNativeRevision) {
315
+ if (stateHash !== priorStateHash) {
316
+ throw new TypeError("document no-op receipt cannot change the canonical state hash");
317
+ }
318
+ } else {
319
+ if (nativeReceipt.revision !== priorNativeRevision + 1) {
320
+ throw new TypeError(
321
+ "document receipt must preserve or advance its prior native revision once",
322
+ );
323
+ }
324
+ if (stateHash === priorStateHash) {
325
+ throw new TypeError("document revision advance must change the canonical state hash");
326
+ }
327
+ }
328
+ const requestHash = hashEditableArtifactMutationIntentBytes(intentBytes);
329
+ return Object.freeze({
330
+ modality,
331
+ transactionId,
332
+ parentHeadSequence,
333
+ resultHeadSequence,
334
+ priorNativeRevision,
335
+ priorStateHash,
336
+ stateHash,
337
+ intentBytes,
338
+ nativeReceiptBytes,
339
+ requestHash,
340
+ intent: decodedIntent,
341
+ nativeReceipt,
342
+ });
343
+ }
344
+
345
+ function decodeNativeReceipt(
346
+ modality: EditableArtifactSerializedModality,
347
+ bytes: Uint8Array,
348
+ expectedCommandCount: number,
349
+ ): EditableArtifactNativeReceiptSummary {
350
+ return modality === "document"
351
+ ? decodeDocumentReceipt(bytes, expectedCommandCount)
352
+ : decodePresentationReceipt(bytes, expectedCommandCount);
353
+ }
354
+
355
+ function decodeDocumentReceipt(
356
+ bytes: Uint8Array,
357
+ expectedCommandCount: number,
358
+ ): Extract<EditableArtifactNativeReceiptSummary, { modality: "document" }> {
359
+ const envelope = decodeCountedEnvelope(
360
+ bytes,
361
+ DOCUMENT_RECEIPT_MAGIC,
362
+ DOCUMENT_RECEIPT_VERSION,
363
+ EDITABLE_ARTIFACT_NATIVE_RECEIPT_MAX_BYTES,
364
+ DOCUMENT_ARTIFACT_COMMAND_MAX_COMMANDS,
365
+ );
366
+ const payload = new ArtifactBinaryReader(envelope.payload);
367
+ const revision = payload.u64Safe("document receipt revision");
368
+ const commandCount = payload.u32();
369
+ if (commandCount !== envelope.count || commandCount !== expectedCommandCount) {
370
+ throw new TypeError("document receipt command count does not match its intent");
371
+ }
372
+ const maximumCreatedIds = commandCount * DOCUMENT_CREATED_IDS_PER_COMMAND;
373
+ const createdIdCount = payload.count(
374
+ maximumCreatedIds,
375
+ "document receipt created ids",
376
+ DOCUMENT_ID_BYTES,
377
+ );
378
+ for (let index = 0; index < createdIdCount; index += 1) {
379
+ const tag = payload.u8();
380
+ if (tag < 1 || tag > 8) {
381
+ throw new TypeError("document receipt contains an invalid id kind");
382
+ }
383
+ payload.u64BigInt();
384
+ const counter = payload.u64BigInt();
385
+ if (counter === 0n || counter > BigInt(DOCUMENT_ARTIFACT_MAX_STRUCTURAL_COUNTER)) {
386
+ throw new TypeError("document receipt contains an invalid id counter");
387
+ }
388
+ }
389
+ payload.done("document receipt contains trailing bytes");
390
+ return Object.freeze({
391
+ modality: "document",
392
+ revision,
393
+ commandCount,
394
+ createdIdCount,
395
+ });
396
+ }
397
+
398
+ function decodePresentationReceipt(
399
+ bytes: Uint8Array,
400
+ expectedCommandCount: number,
401
+ ): Extract<EditableArtifactNativeReceiptSummary, { modality: "presentation" }> {
402
+ if (bytes.byteLength !== PRESENTATION_RECEIPT_BYTES) {
403
+ throw new TypeError(
404
+ bytes.byteLength < PRESENTATION_RECEIPT_BYTES
405
+ ? "truncated presentation receipt"
406
+ : "presentation receipt contains trailing bytes",
407
+ );
408
+ }
409
+ const reader = new ArtifactBinaryReader(bytes);
410
+ if (!equalBytes(reader.bytes(8), PRESENTATION_RECEIPT_MAGIC)) {
411
+ throw new TypeError("invalid presentation receipt magic");
412
+ }
413
+ if (reader.u16() !== PRESENTATION_RECEIPT_VERSION) {
414
+ throw new TypeError("unsupported presentation receipt version");
415
+ }
416
+ if (reader.u16() !== 0) {
417
+ throw new TypeError("reserved presentation receipt flags must be zero");
418
+ }
419
+ const revision = reader.u64Safe("presentation receipt revision");
420
+ const commandCount = reader.u32();
421
+ if (commandCount !== expectedCommandCount) {
422
+ throw new TypeError("presentation receipt command count does not match its intent");
423
+ }
424
+ const checksum = reader.u64BigInt();
425
+ reader.done();
426
+ if (
427
+ checksum !==
428
+ fnv1a64(bytes.subarray(0, bytes.byteLength - EDITABLE_ARTIFACT_BINARY_CHECKSUM_BYTES))
429
+ ) {
430
+ throw new TypeError("presentation receipt checksum does not match");
431
+ }
432
+ return Object.freeze({ modality: "presentation", revision, commandCount });
433
+ }
434
+
435
+ function decodedCommandCount(value: unknown): number {
436
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
437
+ throw new TypeError("serialized command decoder returned an invalid batch");
438
+ }
439
+ const descriptor = Object.getOwnPropertyDescriptor(value, "commands");
440
+ if (!descriptor || !("value" in descriptor) || !Array.isArray(descriptor.value)) {
441
+ throw new TypeError("serialized command decoder returned an invalid batch");
442
+ }
443
+ return descriptor.value.length;
444
+ }
445
+
446
+ function serializedModality(value: unknown): EditableArtifactSerializedModality {
447
+ if (value !== "document" && value !== "presentation") {
448
+ throw new TypeError("serialized commit modality is invalid");
449
+ }
450
+ return value;
451
+ }
452
+
453
+ function canonicalStableId(value: unknown, label: string): string {
454
+ if (typeof value !== "string" || !STABLE_ID.test(value) || /^0+$/u.test(value)) {
455
+ throw new TypeError(`${label} must be a nonzero lowercase 128-bit hexadecimal id`);
456
+ }
457
+ return value;
458
+ }
459
+
460
+ function canonicalSha256(value: unknown, label: string): string {
461
+ if (typeof value !== "string" || !SHA256_TEXT.test(value)) {
462
+ throw new TypeError(`${label} must be canonical sha256 text`);
463
+ }
464
+ return value;
465
+ }
466
+
467
+ function safeSequence(value: unknown, label: string): number {
468
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0) {
469
+ throw new TypeError(`${label} must be a nonnegative safe integer`);
470
+ }
471
+ return value;
472
+ }
473
+
474
+ function hashBytes(value: string): Uint8Array {
475
+ const hex = value.slice("sha256:".length);
476
+ const bytes = new Uint8Array(32);
477
+ for (let index = 0; index < bytes.byteLength; index += 1) {
478
+ bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
479
+ }
480
+ return bytes;
481
+ }
482
+
483
+ function stateHashText(value: Uint8Array): string {
484
+ return `sha256:${bytesToHex(value)}`;
485
+ }
486
+
487
+ function assertUnsharedBytes(value: unknown, label: string): asserts value is Uint8Array {
488
+ if (!(value instanceof Uint8Array)) {
489
+ throw new TypeError(`${label} bytes must be a Uint8Array`);
490
+ }
491
+ if (typeof SharedArrayBuffer !== "undefined" && value.buffer instanceof SharedArrayBuffer) {
492
+ throw new TypeError(`${label} bytes must not use shared mutable memory`);
493
+ }
494
+ }
@@ -0,0 +1,8 @@
1
+ /** Shared durable model version without importing any modality codec. */
2
+ export const EDITABLE_ARTIFACT_MODEL_SCHEMA_VERSION = 1 as const;
3
+
4
+ /** Shared native snapshot version without importing any modality codec. */
5
+ export const EDITABLE_ARTIFACT_SNAPSHOT_VERSION = 1 as const;
6
+
7
+ /** Canonical committed spreadsheet transaction protocol version. */
8
+ export const COMMITTED_TRANSACTION_PROTOCOL_VERSION = 1 as const;