pactium 0.2.0 → 0.2.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.
- package/CHANGELOG.md +150 -0
- package/README.md +362 -39
- package/README.zh-CN.md +296 -34
- package/SECURITY.md +87 -4
- package/docs/API.md +698 -0
- package/docs/FAQ.md +189 -0
- package/docs/MIGRATION.md +110 -0
- package/docs/README.md +47 -9
- package/docs/architecture/ARCHITECTURE.md +193 -1
- package/docs/logo.svg +45 -0
- package/examples/README.md +106 -0
- package/examples/export-proof-bundle.mjs +40 -0
- package/examples/licolite-signed-operation.mjs +62 -0
- package/examples/verify-envelope.mjs +41 -0
- package/examples/workspace-projection.mjs +55 -0
- package/package.json +33 -5
- package/src/index.d.ts +1 -1
- package/src/protocol/constants.js +1 -1
package/docs/API.md
ADDED
|
@@ -0,0 +1,698 @@
|
|
|
1
|
+
# Pactium API Reference
|
|
2
|
+
|
|
3
|
+
This document covers the complete public API surface of the `pactium` package.
|
|
4
|
+
|
|
5
|
+
## Entry Points
|
|
6
|
+
|
|
7
|
+
| Export path | Description |
|
|
8
|
+
| --- | --- |
|
|
9
|
+
| `pactium` | Core proof-first protocol API |
|
|
10
|
+
| `pactium/licolite` | LicoLite integration aspect |
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Core API (`pactium`)
|
|
15
|
+
|
|
16
|
+
### `createPactium(options?)`
|
|
17
|
+
|
|
18
|
+
Creates a Pactium instance with full protocol capabilities.
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { createPactium } from "pactium";
|
|
22
|
+
|
|
23
|
+
const pactium = createPactium({
|
|
24
|
+
dataDir: "./.pactium", // Data directory path (default: ~/.pactium)
|
|
25
|
+
inMemory: false, // Use in-memory storage (for testing)
|
|
26
|
+
storage: null // Provide a pre-configured StoragePort
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Returns:** `PactiumCore`
|
|
31
|
+
|
|
32
|
+
The returned instance exposes:
|
|
33
|
+
|
|
34
|
+
| Property | Type | Description |
|
|
35
|
+
| --- | --- | --- |
|
|
36
|
+
| `protocol` | `string` | Protocol identifier (`pactium.v0.2`) |
|
|
37
|
+
| `schema` | `string` | Schema version |
|
|
38
|
+
| `dataDir` | `string` | Resolved data directory path |
|
|
39
|
+
| `storage` | `PactiumStoragePort` | Underlying storage port |
|
|
40
|
+
| `ledger` | `PactiumLedger` | Operation Ledger instance |
|
|
41
|
+
| `indexEngine` | `PactiumIndexEngine` | Verifiable Index Engine instance |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
### Operation Lifecycle
|
|
46
|
+
|
|
47
|
+
#### `pactium.recordOperation(input)`
|
|
48
|
+
|
|
49
|
+
Records a complete operation (intent + outcome) in a single call. This is the high-level convenience API.
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const envelope = await pactium.recordOperation({
|
|
53
|
+
operationId: "workspace.file.write",
|
|
54
|
+
workspaceId: "workspace-a",
|
|
55
|
+
idempotencyKey: "intent-unique-key",
|
|
56
|
+
outcomeIdempotencyKey: "outcome-unique-key",
|
|
57
|
+
input: { path: "file.txt" },
|
|
58
|
+
outcome: "success",
|
|
59
|
+
stateMutations: [
|
|
60
|
+
{ key: "file.txt", value: { content: "data" } }
|
|
61
|
+
]
|
|
62
|
+
});
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Returns:** `PactiumProofEnvelope`
|
|
66
|
+
|
|
67
|
+
#### `pactium.beginOperationIntent(input)`
|
|
68
|
+
|
|
69
|
+
Records an Operation Intent fact. Use this for two-phase operation lifecycle.
|
|
70
|
+
|
|
71
|
+
```js
|
|
72
|
+
const intentEnvelope = await pactium.beginOperationIntent({
|
|
73
|
+
operationId: "workspace.file.write",
|
|
74
|
+
workspaceId: "workspace-a",
|
|
75
|
+
idempotencyKey: "intent-key",
|
|
76
|
+
input: { path: "file.txt" }
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Returns:** `PactiumProofEnvelope` -- The envelope's `factRef` references the intent.
|
|
81
|
+
|
|
82
|
+
#### `pactium.appendOperationOutcome(input)`
|
|
83
|
+
|
|
84
|
+
Records an Operation Outcome fact that closes an existing intent.
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
const outcomeEnvelope = await pactium.appendOperationOutcome({
|
|
88
|
+
intentId: intentEnvelope.factId,
|
|
89
|
+
workspaceId: "workspace-a",
|
|
90
|
+
idempotencyKey: "outcome-key",
|
|
91
|
+
outcome: "success",
|
|
92
|
+
stateMutations: [
|
|
93
|
+
{ key: "file.txt", value: { content: "data" } }
|
|
94
|
+
]
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Returns:** `PactiumProofEnvelope`
|
|
99
|
+
|
|
100
|
+
#### `pactium.lookupOpenIntent(intentId)`
|
|
101
|
+
|
|
102
|
+
Looks up an Operation Intent that does not yet have a corresponding outcome.
|
|
103
|
+
|
|
104
|
+
```js
|
|
105
|
+
const openIntent = await pactium.lookupOpenIntent("intent-id");
|
|
106
|
+
// Returns the intent record or null
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### `pactium.lookupOutcome(intentId)`
|
|
110
|
+
|
|
111
|
+
Looks up the Operation Outcome for a given intent.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const outcome = await pactium.lookupOutcome("intent-id");
|
|
115
|
+
// Returns the outcome record or null
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
### Workspace Projection
|
|
121
|
+
|
|
122
|
+
#### `pactium.getWorkspaceProjection(workspaceId)`
|
|
123
|
+
|
|
124
|
+
Returns the current workspace projection state for a given workspace.
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
const projection = await pactium.getWorkspaceProjection("workspace-a");
|
|
128
|
+
// { workspaceId, nextOrdinal, orderRoot, membershipRoot, order, membership }
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### `pactium.proveWorkspaceMembership(input)`
|
|
132
|
+
|
|
133
|
+
Generates a verifiable proof that a ledger event belongs (or does not belong) to a workspace.
|
|
134
|
+
|
|
135
|
+
```js
|
|
136
|
+
const proof = await pactium.proveWorkspaceMembership({
|
|
137
|
+
workspaceId: "workspace-a",
|
|
138
|
+
ledgerEventId: "ledger-event-id"
|
|
139
|
+
});
|
|
140
|
+
// { member: true/false, proof: { ... } }
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Proof Verification
|
|
146
|
+
|
|
147
|
+
#### `pactium.verifyEnvelope(envelope, options?)`
|
|
148
|
+
|
|
149
|
+
Verifies a Proof Envelope against local proof material.
|
|
150
|
+
|
|
151
|
+
```js
|
|
152
|
+
const result = await pactium.verifyEnvelope(envelope);
|
|
153
|
+
// { ok: true/false, failures: [...], checked: [...] }
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Returns:** `PactiumVerificationResult`
|
|
157
|
+
|
|
158
|
+
#### `verifyProofEnvelope(envelope, options?)`
|
|
159
|
+
|
|
160
|
+
Standalone envelope verification function (does not require a Pactium instance).
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
import { verifyProofEnvelope } from "pactium";
|
|
164
|
+
|
|
165
|
+
const result = await verifyProofEnvelope(envelope, {
|
|
166
|
+
storage: storagePort,
|
|
167
|
+
verifierRegistry: customRegistry
|
|
168
|
+
});
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
#### `verifyProofBundle(bundle, options?)`
|
|
172
|
+
|
|
173
|
+
Verifies a portable Proof Bundle without access to local storage.
|
|
174
|
+
|
|
175
|
+
```js
|
|
176
|
+
import { verifyProofBundle } from "pactium";
|
|
177
|
+
|
|
178
|
+
const result = await verifyProofBundle(bundle, {
|
|
179
|
+
verifyAllBlocks: true // Verify all content-addressed blocks
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
**Returns:** `PactiumVerificationResult & { bundleHash?: string }`
|
|
184
|
+
|
|
185
|
+
#### `pactium.exportProofBundle(envelopeOrId, options?)`
|
|
186
|
+
|
|
187
|
+
Exports an envelope as a portable Proof Bundle.
|
|
188
|
+
|
|
189
|
+
```js
|
|
190
|
+
const bundle = await pactium.exportProofBundle(envelope, {
|
|
191
|
+
format: "indexed"
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**Returns:** `PactiumProofBundle`
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Verification Failures
|
|
200
|
+
|
|
201
|
+
#### `createVerificationFailure(input)`
|
|
202
|
+
|
|
203
|
+
Creates a structured verification failure object.
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
import { createVerificationFailure } from "pactium";
|
|
207
|
+
|
|
208
|
+
const failure = createVerificationFailure({
|
|
209
|
+
layer: "ledger",
|
|
210
|
+
code: "consistency_violation",
|
|
211
|
+
severity: "critical",
|
|
212
|
+
message: "Ledger history diverged",
|
|
213
|
+
repairable: false
|
|
214
|
+
});
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
**Returns:** `PactiumVerificationFailure`
|
|
218
|
+
|
|
219
|
+
| Field | Type | Description |
|
|
220
|
+
| --- | --- | --- |
|
|
221
|
+
| `protocol` | `string` | Protocol identifier |
|
|
222
|
+
| `layer` | `string` | Verification layer (ledger, index, envelope, extension) |
|
|
223
|
+
| `code` | `string` | Machine-readable failure code |
|
|
224
|
+
| `severity` | `string` | Severity level (critical, warning, info) |
|
|
225
|
+
| `message` | `string?` | Human-readable description |
|
|
226
|
+
| `evidenceRef` | `string?` | Reference to failure evidence |
|
|
227
|
+
| `repairable` | `boolean?` | Whether automated repair is possible |
|
|
228
|
+
| `details` | `object?` | Additional structured details |
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### Ledger Transparency Log
|
|
233
|
+
|
|
234
|
+
#### `createLedgerTransparencyLog(options?)`
|
|
235
|
+
|
|
236
|
+
Creates a standalone Ledger Transparency Log instance.
|
|
237
|
+
|
|
238
|
+
```js
|
|
239
|
+
import { createLedgerTransparencyLog } from "pactium";
|
|
240
|
+
|
|
241
|
+
const ledger = createLedgerTransparencyLog({ storage: storagePort });
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
**Returns:** `PactiumLedger`
|
|
245
|
+
|
|
246
|
+
| Method | Description |
|
|
247
|
+
| --- | --- |
|
|
248
|
+
| `ledger.append(entry)` | Append an entry and return `{ head, leafIndex, inclusionProof }` |
|
|
249
|
+
| `ledger.head()` | Return the current `PactiumLedgerHead` |
|
|
250
|
+
| `ledger.entries()` | Return all ledger entries |
|
|
251
|
+
| `ledger.pageEntries({ start, limit })` | Return a paginated slice of entries |
|
|
252
|
+
|
|
253
|
+
#### Proof helpers
|
|
254
|
+
|
|
255
|
+
```js
|
|
256
|
+
import {
|
|
257
|
+
createLedgerInclusionProof,
|
|
258
|
+
verifyLedgerInclusionProof,
|
|
259
|
+
createLedgerConsistencyProof,
|
|
260
|
+
verifyLedgerConsistencyProof,
|
|
261
|
+
createCompactRange,
|
|
262
|
+
ledgerLeafHash,
|
|
263
|
+
ledgerNodeHash,
|
|
264
|
+
emptyTreeHash
|
|
265
|
+
} from "pactium";
|
|
266
|
+
|
|
267
|
+
// Verify that a leaf is included in the ledger at a given size
|
|
268
|
+
const inclusion = createLedgerInclusionProof({ leafIndex, treeSize, hashes });
|
|
269
|
+
const valid = verifyLedgerInclusionProof({ leafHash, treeSize, rootHash, proof: inclusion });
|
|
270
|
+
|
|
271
|
+
// Verify that a smaller ledger is a prefix of a larger one
|
|
272
|
+
const consistency = createLedgerConsistencyProof({ oldSize, newSize, hashes });
|
|
273
|
+
const valid = verifyLedgerConsistencyProof({ oldSize, newSize, oldRoot, newRoot, proof: consistency });
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
### Signed Ledger Heads
|
|
279
|
+
|
|
280
|
+
```js
|
|
281
|
+
import {
|
|
282
|
+
signLedgerHead,
|
|
283
|
+
verifyLedgerHeadSignature,
|
|
284
|
+
advanceTrustedHead,
|
|
285
|
+
createVerifierManifest,
|
|
286
|
+
ledgerHeadSigningPayload
|
|
287
|
+
} from "pactium";
|
|
288
|
+
|
|
289
|
+
// Create a verifier manifest describing the signing authority
|
|
290
|
+
const manifest = createVerifierManifest({
|
|
291
|
+
signerId: "authority-1",
|
|
292
|
+
algorithm: "ed25519",
|
|
293
|
+
publicKey: publicKeyHex
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
// Sign a ledger head
|
|
297
|
+
const signedHead = signLedgerHead(head, { signer, manifest });
|
|
298
|
+
|
|
299
|
+
// Verify signature
|
|
300
|
+
const result = verifyLedgerHeadSignature(signedHead, manifest);
|
|
301
|
+
// { ok: true/false, accepted: signatureCount }
|
|
302
|
+
|
|
303
|
+
// Advance a local trust anchor
|
|
304
|
+
const advanced = advanceTrustedHead({
|
|
305
|
+
lastTrusted: previousHead,
|
|
306
|
+
candidate: newHead,
|
|
307
|
+
consistencyProof: proof
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
### Verifiable Index Engine
|
|
314
|
+
|
|
315
|
+
#### `createVerifiableIndexEngine(options?)`
|
|
316
|
+
|
|
317
|
+
Creates a Verifiable Index Engine instance (Canonical Prolly Tree).
|
|
318
|
+
|
|
319
|
+
```js
|
|
320
|
+
import { createVerifiableIndexEngine } from "pactium";
|
|
321
|
+
|
|
322
|
+
const engine = createVerifiableIndexEngine({
|
|
323
|
+
storage: storagePort,
|
|
324
|
+
domain: "state" // Domain adapter identifier
|
|
325
|
+
});
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**Returns:** `PactiumIndexEngine`
|
|
329
|
+
|
|
330
|
+
| Method | Description |
|
|
331
|
+
| --- | --- |
|
|
332
|
+
| `engine.createIndex(entries?, options?)` | Create an index from initial entries |
|
|
333
|
+
| `engine.put(root, key, value, options?)` | Insert/update a key |
|
|
334
|
+
| `engine.delete(root, key, options?)` | Delete a key |
|
|
335
|
+
| `engine.get(root, key)` | Retrieve a value by key |
|
|
336
|
+
| `engine.prove(root, key)` | Generate a membership/non-membership proof |
|
|
337
|
+
| `engine.verifyProof(proof)` | Verify an index proof |
|
|
338
|
+
| `engine.scan(root, options?)` | Scan keys in range |
|
|
339
|
+
| `engine.prefix(root, keyPrefix?, options?)` | Scan keys by prefix |
|
|
340
|
+
| `engine.diff(leftRoot, rightRoot)` | Compute differences between two roots |
|
|
341
|
+
| `engine.readSnapshot(root)` | Read full index snapshot |
|
|
342
|
+
| `engine.readIndexRoot(root)` | Read index root metadata |
|
|
343
|
+
| `engine.readNode(root)` | Read a single index node |
|
|
344
|
+
|
|
345
|
+
#### `verifyIndexProof(proof)`
|
|
346
|
+
|
|
347
|
+
Standalone index proof verification.
|
|
348
|
+
|
|
349
|
+
```js
|
|
350
|
+
import { verifyIndexProof } from "pactium";
|
|
351
|
+
|
|
352
|
+
const valid = verifyIndexProof(proof);
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
---
|
|
356
|
+
|
|
357
|
+
### Canonical Value Encoding
|
|
358
|
+
|
|
359
|
+
```js
|
|
360
|
+
import {
|
|
361
|
+
canonicalEncode,
|
|
362
|
+
canonicalDecode,
|
|
363
|
+
canonicalString,
|
|
364
|
+
normalizeCanonicalValue
|
|
365
|
+
} from "pactium";
|
|
366
|
+
|
|
367
|
+
// Encode a value to canonical bytes (deterministic)
|
|
368
|
+
const bytes = canonicalEncode({ key: "value", nested: [1, 2, 3] });
|
|
369
|
+
|
|
370
|
+
// Decode canonical bytes back to a value
|
|
371
|
+
const value = canonicalDecode(bytes);
|
|
372
|
+
|
|
373
|
+
// Get the canonical JSON string (sorted keys)
|
|
374
|
+
const str = canonicalString({ b: 2, a: 1 }); // '{"a":1,"b":2}'
|
|
375
|
+
|
|
376
|
+
// Normalize a value to PactiumCanonicalValue
|
|
377
|
+
const normalized = normalizeCanonicalValue(input);
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
The canonical value model is a restricted IPLD/DAG-CBOR-style data model supporting: `null`, `boolean`, `number`, `string`, arrays, and plain objects with string keys.
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
### Protocol Hashing
|
|
385
|
+
|
|
386
|
+
```js
|
|
387
|
+
import {
|
|
388
|
+
protocolHash,
|
|
389
|
+
protocolHashHex,
|
|
390
|
+
cidForBytes,
|
|
391
|
+
cidForCanonical,
|
|
392
|
+
HASH_DOMAINS
|
|
393
|
+
} from "pactium";
|
|
394
|
+
|
|
395
|
+
// Hash with domain separation
|
|
396
|
+
const hash = protocolHash("ledger.leaf", value);
|
|
397
|
+
const hex = protocolHashHex("ledger.node", value);
|
|
398
|
+
|
|
399
|
+
// Content-addressed identifiers
|
|
400
|
+
const cid = cidForBytes(bytes); // "cid:sha256:<hex>"
|
|
401
|
+
const cid = cidForCanonical(value); // Canonical encode then hash
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
---
|
|
405
|
+
|
|
406
|
+
### Storage Port
|
|
407
|
+
|
|
408
|
+
```js
|
|
409
|
+
import { createStoragePort, resolveDataDir, resolveWithin } from "pactium";
|
|
410
|
+
|
|
411
|
+
const storage = createStoragePort({
|
|
412
|
+
dataDir: "./.pactium",
|
|
413
|
+
inMemory: false
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
await storage.initialize();
|
|
417
|
+
|
|
418
|
+
// Content-addressed block storage
|
|
419
|
+
const record = await storage.putBlock(value);
|
|
420
|
+
const block = await storage.getBlock(cid);
|
|
421
|
+
const exists = await storage.hasBlock(cid);
|
|
422
|
+
|
|
423
|
+
// Protocol object storage (scoped key-value)
|
|
424
|
+
await storage.putProtocolObject("ledger", "head", headValue);
|
|
425
|
+
const head = await storage.getProtocolObject("ledger", "head");
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
---
|
|
429
|
+
|
|
430
|
+
### Tracking Cursors and Append Conditions
|
|
431
|
+
|
|
432
|
+
```js
|
|
433
|
+
import {
|
|
434
|
+
createTrackingCursor,
|
|
435
|
+
advanceTo,
|
|
436
|
+
covers,
|
|
437
|
+
samePositionAs,
|
|
438
|
+
verifyTrackingCursor,
|
|
439
|
+
createAppendCondition
|
|
440
|
+
} from "pactium";
|
|
441
|
+
|
|
442
|
+
// Create a cursor tracking ledger position
|
|
443
|
+
const cursor = createTrackingCursor({ position: 0, headHash: rootHash });
|
|
444
|
+
|
|
445
|
+
// Advance to a new position
|
|
446
|
+
const advanced = advanceTo(cursor, 5, { headHash: newRootHash });
|
|
447
|
+
|
|
448
|
+
// Check coverage
|
|
449
|
+
covers(cursor, 3); // true if cursor position >= 3
|
|
450
|
+
|
|
451
|
+
// Append condition for optimistic concurrency
|
|
452
|
+
const condition = createAppendCondition({
|
|
453
|
+
expectedHead: currentHead,
|
|
454
|
+
expectedSize: currentSize
|
|
455
|
+
});
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
### Maintenance and Repair
|
|
461
|
+
|
|
462
|
+
```js
|
|
463
|
+
import { createRepairPlanner, createMaintenanceTaskEngine } from "pactium";
|
|
464
|
+
|
|
465
|
+
// Repair planning from verification failures
|
|
466
|
+
const planner = createRepairPlanner();
|
|
467
|
+
const plan = planner.planRepair(failures);
|
|
468
|
+
// Returns deterministic repair tasks for host execution
|
|
469
|
+
|
|
470
|
+
// Maintenance task engine
|
|
471
|
+
const engine = createMaintenanceTaskEngine({ pactium });
|
|
472
|
+
const result = await engine.run("doctor");
|
|
473
|
+
// { ok: true/false, dataDir, checks: [...] }
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
### Protocol Constants
|
|
479
|
+
|
|
480
|
+
```js
|
|
481
|
+
import {
|
|
482
|
+
PACTIUM_PROTOCOL, // "pactium.v0.2"
|
|
483
|
+
PACTIUM_SCHEMA_VERSION, // "pactium.v0.2.schema.latest"
|
|
484
|
+
PACTIUM_PACKAGE_VERSION, // "0.2.1"
|
|
485
|
+
PACTIUM_INDEX_ENGINE, // "pactium.verifiable-index-engine"
|
|
486
|
+
PACTIUM_INDEX_SPLITTER, // "pactium-cdc-boundary"
|
|
487
|
+
PACTIUM_PROOF_BUNDLE_TYPE, // "pactium.proof-bundle.indexed"
|
|
488
|
+
PACTIUM_BUNDLE_ENCODING, // "pactium.bundle.indexed-record-stream"
|
|
489
|
+
PACTIUM_PROOF_TYPES, // { ledgerInclusion, ledgerConsistency, indexMembership, indexNonMembership }
|
|
490
|
+
PACTIUM_PROTOCOL_PROFILE, // Full protocol parameter matrix
|
|
491
|
+
HASH_DOMAINS // Domain separation constants
|
|
492
|
+
} from "pactium";
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
---
|
|
496
|
+
|
|
497
|
+
## LicoLite Aspect API (`pactium/licolite`)
|
|
498
|
+
|
|
499
|
+
### `createLicoLiteAspect(options?)`
|
|
500
|
+
|
|
501
|
+
Creates a LicoLite Aspect instance with workspace projection and signing defaults.
|
|
502
|
+
|
|
503
|
+
```js
|
|
504
|
+
import { createLicoLiteAspect, createLicoLiteSigner } from "pactium/licolite";
|
|
505
|
+
|
|
506
|
+
const licolite = createLicoLiteAspect({
|
|
507
|
+
pactium: pactiumInstance, // Optional: provide existing instance
|
|
508
|
+
dataDir: "./.pactium", // Or create new instance from dataDir
|
|
509
|
+
evidencePolicy: "production", // "production" | "opportunistic"
|
|
510
|
+
signer: createLicoLiteSigner({
|
|
511
|
+
signerId: "host-signer",
|
|
512
|
+
secret: signingSecret
|
|
513
|
+
})
|
|
514
|
+
});
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Returns:** `LicoLiteAspect`
|
|
518
|
+
|
|
519
|
+
| Property | Type | Description |
|
|
520
|
+
| --- | --- | --- |
|
|
521
|
+
| `protocol` | `string` | LicoLite aspect protocol identifier |
|
|
522
|
+
| `core` | `PactiumCore` | Underlying Pactium instance |
|
|
523
|
+
| `evidencePolicy` | `string` | Evidence policy mode |
|
|
524
|
+
| `workspaceProjectionDefault` | `true` | Workspace projection always enabled |
|
|
525
|
+
| `criticalExtensions` | `string[]` | Required critical extensions |
|
|
526
|
+
| `signer` | `LicoLiteSigner \| null` | Signing authority |
|
|
527
|
+
|
|
528
|
+
---
|
|
529
|
+
|
|
530
|
+
### `createLicoLiteSigner(options)`
|
|
531
|
+
|
|
532
|
+
Creates a signing authority for LicoLite proof envelopes.
|
|
533
|
+
|
|
534
|
+
```js
|
|
535
|
+
import { createLicoLiteSigner } from "pactium/licolite";
|
|
536
|
+
|
|
537
|
+
const signer = createLicoLiteSigner({
|
|
538
|
+
signerId: "my-signer",
|
|
539
|
+
secret: "base64-encoded-secret",
|
|
540
|
+
algorithm: "ed25519" // Default
|
|
541
|
+
});
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
**Returns:** `LicoLiteSigner`
|
|
545
|
+
|
|
546
|
+
| Method | Description |
|
|
547
|
+
| --- | --- |
|
|
548
|
+
| `signer.sign(message)` | Sign a message string |
|
|
549
|
+
| `signer.verify(message, signature)` | Verify a signature |
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
### `licolite.recordWorkspaceOperation(input)`
|
|
554
|
+
|
|
555
|
+
Records a workspace operation with LicoLite policy and workspace effect evidence.
|
|
556
|
+
|
|
557
|
+
```js
|
|
558
|
+
const envelope = await licolite.recordWorkspaceOperation({
|
|
559
|
+
operationId: "workspace.file.write",
|
|
560
|
+
workspaceId: "workspace-a",
|
|
561
|
+
idempotencyKey: "intent-key",
|
|
562
|
+
outcomeIdempotencyKey: "outcome-key",
|
|
563
|
+
input: { path: "file.txt" },
|
|
564
|
+
outcome: "success",
|
|
565
|
+
policyEvidence: { decision: "allow", rule: "write-permitted" },
|
|
566
|
+
workspaceEffectEvidence: { durableRef: "host:asset:file-001" },
|
|
567
|
+
stateMutations: [
|
|
568
|
+
{ key: "file.txt", value: { content: "data" } }
|
|
569
|
+
]
|
|
570
|
+
});
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
The returned envelope includes critical LicoLite extensions for policy and workspace effect evidence.
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
### `licolite.verifyEnvelope(envelope, options?)`
|
|
578
|
+
|
|
579
|
+
LicoLite-level verification that checks core proofs plus:
|
|
580
|
+
- Signature validity
|
|
581
|
+
- Critical extension support
|
|
582
|
+
- Policy extension binding
|
|
583
|
+
- Workspace effect extension binding
|
|
584
|
+
- Workspace projection proof
|
|
585
|
+
|
|
586
|
+
```js
|
|
587
|
+
const result = await licolite.verifyEnvelope(envelope);
|
|
588
|
+
// { ok: true/false, failures: [...] }
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
### `licolite.verifyBundle(bundle, options?)`
|
|
594
|
+
|
|
595
|
+
Verifies a Proof Bundle with LicoLite-level checks.
|
|
596
|
+
|
|
597
|
+
```js
|
|
598
|
+
const result = await licolite.verifyBundle(bundle);
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
603
|
+
### `licolite.planRepair(failures?)`
|
|
604
|
+
|
|
605
|
+
Translates verification failures into deterministic repair tasks.
|
|
606
|
+
|
|
607
|
+
```js
|
|
608
|
+
const plan = licolite.planRepair(result.failures);
|
|
609
|
+
// { tasks: [...], repairable: true/false }
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
### LicoLite Constants
|
|
615
|
+
|
|
616
|
+
```js
|
|
617
|
+
import {
|
|
618
|
+
LICOLITE_ASPECT_PROTOCOL,
|
|
619
|
+
LICOLITE_POLICY_EXTENSION, // "licolite.policy"
|
|
620
|
+
LICOLITE_WORKSPACE_EFFECT_EXTENSION, // "licolite.workspaceEffect"
|
|
621
|
+
LICOLITE_SIGNATURE_EXTENSION, // "licolite.signature"
|
|
622
|
+
LICOLITE_CRITICAL_EXTENSIONS,
|
|
623
|
+
LICOLITE_SUPPORTED_CRITICAL_EXTENSIONS
|
|
624
|
+
} from "pactium/licolite";
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### Evidence Helpers
|
|
628
|
+
|
|
629
|
+
```js
|
|
630
|
+
import {
|
|
631
|
+
licoLitePolicyExtensionValue,
|
|
632
|
+
licoLiteWorkspaceEffectExtensionValue
|
|
633
|
+
} from "pactium/licolite";
|
|
634
|
+
|
|
635
|
+
// Generate policy extension value
|
|
636
|
+
const policyExt = licoLitePolicyExtensionValue({
|
|
637
|
+
decision: "allow",
|
|
638
|
+
rule: "upload-permitted"
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
// Generate workspace effect extension value
|
|
642
|
+
const effectExt = licoLiteWorkspaceEffectExtensionValue({
|
|
643
|
+
durableRef: "host:asset:001",
|
|
644
|
+
effectType: "file-write"
|
|
645
|
+
});
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
---
|
|
649
|
+
|
|
650
|
+
## TypeScript Types
|
|
651
|
+
|
|
652
|
+
All public types are exported from the package entry points:
|
|
653
|
+
|
|
654
|
+
```ts
|
|
655
|
+
import type {
|
|
656
|
+
PactiumCanonicalValue,
|
|
657
|
+
PactiumRecord,
|
|
658
|
+
PactiumDataDirOptions,
|
|
659
|
+
PactiumStoragePort,
|
|
660
|
+
PactiumLedgerHead,
|
|
661
|
+
PactiumProofEnvelope,
|
|
662
|
+
PactiumVerificationFailure,
|
|
663
|
+
PactiumVerificationResult,
|
|
664
|
+
PactiumProofBundle,
|
|
665
|
+
PactiumIndexScanOptions,
|
|
666
|
+
PactiumIndexEngine,
|
|
667
|
+
PactiumLedgerPageOptions,
|
|
668
|
+
PactiumLedgerPage,
|
|
669
|
+
PactiumLedger,
|
|
670
|
+
PactiumCore
|
|
671
|
+
} from "pactium";
|
|
672
|
+
|
|
673
|
+
import type {
|
|
674
|
+
LicoLiteSigner,
|
|
675
|
+
LicoLiteAspect
|
|
676
|
+
} from "pactium/licolite";
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
## Error Handling
|
|
682
|
+
|
|
683
|
+
Pactium does not throw exceptions for verification failures. Instead, verification methods return structured results:
|
|
684
|
+
|
|
685
|
+
```js
|
|
686
|
+
const result = await pactium.verifyEnvelope(envelope);
|
|
687
|
+
|
|
688
|
+
if (!result.ok) {
|
|
689
|
+
for (const failure of result.failures) {
|
|
690
|
+
console.error(`[${failure.layer}] ${failure.code}: ${failure.message}`);
|
|
691
|
+
if (failure.repairable) {
|
|
692
|
+
// Can be addressed by repair planner
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
Protocol errors (invalid arguments, storage failures) throw standard JavaScript `Error` instances.
|