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.
@@ -0,0 +1,106 @@
1
+ # Pactium Examples
2
+
3
+ This directory contains runnable examples demonstrating Pactium's core capabilities. Each example is a standalone `.mjs` file that can be executed directly with Node.js.
4
+
5
+ ## Running Examples
6
+
7
+ ```bash
8
+ # From the project root
9
+ node examples/record-operation.mjs
10
+ node examples/verify-envelope.mjs
11
+ node examples/export-proof-bundle.mjs
12
+ node examples/workspace-projection.mjs
13
+ node examples/licolite-signed-operation.mjs
14
+ ```
15
+
16
+ Examples create a `.pactium` data directory in the working directory. Remove it between runs for a fresh state: `rm -rf .pactium`.
17
+
18
+ ## Learning Path
19
+
20
+ If you're new to Pactium, follow these examples in order:
21
+
22
+ ### 1. Record an Operation
23
+
24
+ **File:** [`record-operation.mjs`](./record-operation.mjs)
25
+
26
+ The simplest end-to-end example. Creates a LicoLite Aspect instance and records a workspace operation with policy evidence and workspace effect evidence, then verifies the resulting envelope.
27
+
28
+ **Concepts introduced:**
29
+ - `createPactium()` instance creation
30
+ - `createLicoLiteAspect()` aspect setup
31
+ - `recordWorkspaceOperation()` high-level API
32
+ - `verifyEnvelope()` verification
33
+ - Proof Envelope structure
34
+
35
+ ### 2. Two-Phase Operation Lifecycle
36
+
37
+ **File:** [`verify-envelope.mjs`](./verify-envelope.mjs)
38
+
39
+ Demonstrates the low-level two-phase operation lifecycle: first record an Operation Intent, then append an Operation Outcome. This is the pattern for operations where you need to track the "in-progress" state.
40
+
41
+ **Concepts introduced:**
42
+ - `beginOperationIntent()` -- declare intent before execution
43
+ - `appendOperationOutcome()` -- declare result after execution
44
+ - Two-envelope lifecycle (intent + outcome)
45
+ - Envelope verification with `checked` details
46
+
47
+ ### 3. Export and Verify a Proof Bundle
48
+
49
+ **File:** [`export-proof-bundle.mjs`](./export-proof-bundle.mjs)
50
+
51
+ Shows how to export a recorded operation as a portable Proof Bundle and verify it independently -- without access to the original Pactium storage.
52
+
53
+ **Concepts introduced:**
54
+ - `exportProofBundle()` -- create portable proof material
55
+ - `verifyProofBundle()` -- standalone verification function
56
+ - Bundle structure (type, hash, content-addressed blocks)
57
+ - Portable/offline verification
58
+
59
+ ### 4. Workspace Projection and Membership Proofs
60
+
61
+ **File:** [`workspace-projection.mjs`](./workspace-projection.mjs)
62
+
63
+ Records operations across multiple workspaces, queries workspace projections, and demonstrates verifiable workspace membership and non-membership proofs.
64
+
65
+ **Concepts introduced:**
66
+ - Multi-workspace operation recording
67
+ - `getWorkspaceProjection()` -- query workspace state
68
+ - `proveWorkspaceMembership()` -- prove event belongs to workspace
69
+ - Non-membership proofs -- prove event does NOT belong to workspace
70
+ - Workspace isolation guarantees
71
+
72
+ ### 5. LicoLite Signed Operations
73
+
74
+ **File:** [`licolite-signed-operation.mjs`](./licolite-signed-operation.mjs)
75
+
76
+ Full LicoLite integration example with Ed25519 signing, critical policy/effect extensions, production evidence policy, and LicoLite-level verification including bundle export.
77
+
78
+ **Concepts introduced:**
79
+ - `createLicoLiteSigner()` -- Ed25519 signing authority
80
+ - `evidencePolicy: "production"` -- fail-closed on missing evidence
81
+ - Critical extensions (policy + workspace effect)
82
+ - LicoLite-level verification (core + signing + extensions)
83
+ - Bundle export through the aspect
84
+
85
+ ## Key Patterns
86
+
87
+ ### Idempotent Recording
88
+
89
+ All examples use `idempotencyKey` and `outcomeIdempotencyKey`. If you re-run an example without clearing the data directory, the second call returns an idempotency replay (existing proof) rather than creating duplicate ledger entries.
90
+
91
+ ### Proof-First API
92
+
93
+ Every write operation returns a Proof Envelope. The envelope is the proof -- it contains or references all material needed to verify that the operation was recorded and the ledger is consistent.
94
+
95
+ ### Error Handling
96
+
97
+ Verification results are returned as structured objects (`{ ok, failures, checked }`), not thrown exceptions. Verification failures include layer, code, severity, and repairability information.
98
+
99
+ ## Next Steps
100
+
101
+ After working through these examples, consult:
102
+
103
+ - [API Reference](../docs/API.md) for complete API documentation
104
+ - [Protocol Specification](../docs/protocols/PROTOCOLS.md) for protocol behavior details
105
+ - [Architecture](../docs/architecture/ARCHITECTURE.md) for system design and data flow
106
+ - [FAQ](../docs/FAQ.md) for common questions
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Example: Export and Verify a Proof Bundle
3
+ *
4
+ * Demonstrates exporting a portable proof bundle from a recorded operation
5
+ * and verifying it without access to local Pactium storage.
6
+ */
7
+ import { createPactium, verifyProofBundle } from "../src/index.js";
8
+
9
+ const pactium = createPactium({ dataDir: "./.pactium" });
10
+
11
+ // Record an operation
12
+ const envelope = await pactium.recordOperation({
13
+ operationId: "workspace.config.update",
14
+ workspaceId: "settings-workspace",
15
+ idempotencyKey: "update-theme-intent",
16
+ outcomeIdempotencyKey: "update-theme-outcome",
17
+ input: { setting: "theme", value: "dark" },
18
+ stateMutations: [
19
+ { key: "settings/theme", value: { mode: "dark", updatedBy: "user-1" } }
20
+ ]
21
+ });
22
+
23
+ console.log("Operation recorded:", envelope.envelopeId);
24
+
25
+ // Export as a portable proof bundle
26
+ const bundle = await pactium.exportProofBundle(envelope);
27
+
28
+ console.log("Bundle exported:");
29
+ console.log(" Type:", bundle.bundleType);
30
+ console.log(" Hash:", bundle.bundleHash);
31
+ console.log(" Blocks:", bundle.index?.length ?? 0, "content-addressed blocks");
32
+
33
+ // Verify the bundle independently (no local storage needed)
34
+ const result = await verifyProofBundle(bundle);
35
+
36
+ console.log(JSON.stringify({
37
+ verified: result.ok,
38
+ bundleHash: result.bundleHash,
39
+ failures: result.failures
40
+ }, null, 2));
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Example: LicoLite Signed Workspace Operation
3
+ *
4
+ * Demonstrates using the LicoLite Aspect with signing enabled,
5
+ * critical policy/effect extensions, and LicoLite-level verification.
6
+ */
7
+ import { createLicoLiteAspect, createLicoLiteSigner } from "../src/aspects/licolite/index.js";
8
+
9
+ // Create a LicoLite Aspect with signing and production evidence policy
10
+ const licolite = createLicoLiteAspect({
11
+ dataDir: "./.pactium",
12
+ evidencePolicy: "production",
13
+ signer: createLicoLiteSigner({
14
+ signerId: "example-signer",
15
+ secret: "example-secret-for-demonstration-only"
16
+ })
17
+ });
18
+
19
+ // Record a workspace operation with full evidence
20
+ const envelope = await licolite.recordWorkspaceOperation({
21
+ operationId: "workspace.asset.upload",
22
+ workspaceId: "media-workspace",
23
+ idempotencyKey: "upload-image-intent",
24
+ outcomeIdempotencyKey: "upload-image-outcome",
25
+ input: {
26
+ filename: "photo.jpg",
27
+ size: 1024000,
28
+ mimeType: "image/jpeg"
29
+ },
30
+ // LicoLite policy evidence (critical extension)
31
+ policyEvidence: {
32
+ decision: "allow",
33
+ rule: "upload-size-limit",
34
+ evaluatedAt: new Date().toISOString()
35
+ },
36
+ // LicoLite workspace effect evidence (critical extension)
37
+ workspaceEffectEvidence: {
38
+ durableRef: "host:storage:media-workspace/photo.jpg",
39
+ effectType: "file-upload",
40
+ byteLength: 1024000
41
+ },
42
+ stateMutations: [
43
+ { key: "assets/photo.jpg", value: { ref: "host:storage:media-workspace/photo.jpg", size: 1024000 } }
44
+ ]
45
+ });
46
+
47
+ console.log("Signed envelope ID:", envelope.envelopeId);
48
+ console.log("Critical extensions:", envelope.criticalExtensions);
49
+
50
+ // LicoLite-level verification (checks core + signing + extensions)
51
+ const result = await licolite.verifyEnvelope(envelope);
52
+
53
+ console.log(JSON.stringify({
54
+ verified: result.ok,
55
+ failures: result.failures
56
+ }, null, 2));
57
+
58
+ // Export as portable bundle for external verification
59
+ const bundle = await licolite.exportProofBundle(envelope);
60
+ const bundleResult = await licolite.verifyBundle(bundle);
61
+
62
+ console.log("\nBundle verification:", bundleResult.ok ? "PASS" : "FAIL");
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Example: Verify a Proof Envelope
3
+ *
4
+ * Demonstrates the two-phase operation lifecycle (intent then outcome)
5
+ * and verifying the resulting proof envelope.
6
+ */
7
+ import { createPactium } from "../src/index.js";
8
+
9
+ const pactium = createPactium({ dataDir: "./.pactium" });
10
+
11
+ // Phase 1: Begin an Operation Intent
12
+ const intentEnvelope = await pactium.beginOperationIntent({
13
+ operationId: "workspace.document.create",
14
+ workspaceId: "docs-workspace",
15
+ idempotencyKey: "create-readme-intent",
16
+ input: { path: "README.md", format: "markdown" }
17
+ });
18
+
19
+ console.log("Intent recorded:", intentEnvelope.factId);
20
+
21
+ // Phase 2: Append the Operation Outcome
22
+ const outcomeEnvelope = await pactium.appendOperationOutcome({
23
+ intentId: intentEnvelope.factId,
24
+ workspaceId: "docs-workspace",
25
+ idempotencyKey: "create-readme-outcome",
26
+ outcome: "success",
27
+ stateMutations: [
28
+ { key: "README.md", value: { content: "# Project\n", format: "markdown" } }
29
+ ]
30
+ });
31
+
32
+ console.log("Outcome recorded:", outcomeEnvelope.factId);
33
+
34
+ // Verify the outcome envelope
35
+ const result = await pactium.verifyEnvelope(outcomeEnvelope);
36
+
37
+ console.log(JSON.stringify({
38
+ verified: result.ok,
39
+ checked: result.checked,
40
+ failures: result.failures
41
+ }, null, 2));
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Example: Workspace Projection and Membership Proof
3
+ *
4
+ * Demonstrates recording multiple operations across workspaces,
5
+ * querying workspace projections, and proving workspace membership.
6
+ */
7
+ import { createPactium } from "../src/index.js";
8
+
9
+ const pactium = createPactium({ dataDir: "./.pactium" });
10
+
11
+ // Record operations in different workspaces
12
+ const envelopeA = await pactium.recordOperation({
13
+ operationId: "workspace.file.write",
14
+ workspaceId: "project-alpha",
15
+ idempotencyKey: "alpha-write-1",
16
+ outcomeIdempotencyKey: "alpha-outcome-1",
17
+ input: { path: "src/main.js" },
18
+ stateMutations: [
19
+ { key: "src/main.js", value: { content: "console.log('alpha')" } }
20
+ ]
21
+ });
22
+
23
+ const envelopeB = await pactium.recordOperation({
24
+ operationId: "workspace.file.write",
25
+ workspaceId: "project-beta",
26
+ idempotencyKey: "beta-write-1",
27
+ outcomeIdempotencyKey: "beta-outcome-1",
28
+ input: { path: "src/index.js" },
29
+ stateMutations: [
30
+ { key: "src/index.js", value: { content: "console.log('beta')" } }
31
+ ]
32
+ });
33
+
34
+ // Query workspace projection for project-alpha
35
+ const projection = await pactium.getWorkspaceProjection("project-alpha");
36
+ console.log("Workspace 'project-alpha' projection:");
37
+ console.log(JSON.stringify(projection, null, 2));
38
+
39
+ // Prove that envelopeA's fact belongs to project-alpha
40
+ const membershipProof = await pactium.proveWorkspaceMembership({
41
+ workspaceId: "project-alpha",
42
+ ledgerEventId: envelopeA.factRef.ledgerEventId
43
+ });
44
+
45
+ console.log("\nMembership proof for envelopeA in project-alpha:");
46
+ console.log(" Member:", membershipProof.member);
47
+
48
+ // Prove that envelopeB's fact does NOT belong to project-alpha
49
+ const nonMembershipProof = await pactium.proveWorkspaceMembership({
50
+ workspaceId: "project-alpha",
51
+ ledgerEventId: envelopeB.factRef.ledgerEventId
52
+ });
53
+
54
+ console.log("\nMembership proof for envelopeB in project-alpha:");
55
+ console.log(" Member:", nonMembershipProof.member);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pactium",
3
- "version": "0.2.0",
4
- "description": "Pactium — the proof-first protocol substrate for LicoLite state recording and recovery.",
3
+ "version": "0.2.1",
4
+ "description": "Proof-first protocol substrate for verifiable operation facts, append-only recovery history, and cryptographic state verification.",
5
5
  "author": "Unka Y.Y.",
6
6
  "license": "GPL-3.0-or-later",
7
7
  "repository": {
@@ -12,7 +12,27 @@
12
12
  "url": "https://github.com/Unka-Malloc/Pactium/issues"
13
13
  },
14
14
  "homepage": "https://github.com/Unka-Malloc/Pactium#readme",
15
+ "funding": {
16
+ "type": "github",
17
+ "url": "https://github.com/sponsors/Unka-Malloc"
18
+ },
19
+ "keywords": [
20
+ "merkle",
21
+ "proof",
22
+ "transparency-log",
23
+ "verifiable",
24
+ "prolly-tree",
25
+ "append-only",
26
+ "ledger",
27
+ "cryptographic",
28
+ "operation-ledger",
29
+ "proof-envelope",
30
+ "workspace",
31
+ "protocol",
32
+ "integrity"
33
+ ],
15
34
  "type": "module",
35
+ "sideEffects": false,
16
36
  "main": "./src/index.js",
17
37
  "types": "./src/index.d.ts",
18
38
  "exports": {
@@ -25,7 +45,8 @@
25
45
  "types": "./src/aspects/licolite/index.d.ts",
26
46
  "import": "./src/aspects/licolite/index.js",
27
47
  "default": "./src/aspects/licolite/index.js"
28
- }
48
+ },
49
+ "./package.json": "./package.json"
29
50
  },
30
51
  "bin": {
31
52
  "pactium": "bin/pactium.mjs"
@@ -39,7 +60,12 @@
39
60
  "src/",
40
61
  "bin/",
41
62
  "examples/",
63
+ "CHANGELOG.md",
64
+ "docs/logo.svg",
42
65
  "docs/README.md",
66
+ "docs/API.md",
67
+ "docs/FAQ.md",
68
+ "docs/MIGRATION.md",
43
69
  "docs/architecture/",
44
70
  "docs/protocols/",
45
71
  "docs/LICOLITE-ASPECT.md",
@@ -54,16 +80,18 @@
54
80
  },
55
81
  "scripts": {
56
82
  "start": "pactium serve",
83
+ "docs:sync-version": "node scripts/update-published-doc-versions.mjs --write",
57
84
  "test": "node --test tests/pactium/*.test.mjs",
58
85
  "test:coverage": "node --test --experimental-test-coverage '--test-coverage-exclude=bin/**' --test-coverage-exclude=src/http.js --test-coverage-lines=95 --test-coverage-functions=95 --test-coverage-branches=90 tests/pactium/*.test.mjs",
59
86
  "verify": "npm run verify:release",
60
87
  "verify:core": "npm run test:coverage",
88
+ "verify:docs:versions": "node scripts/update-published-doc-versions.mjs --check",
61
89
  "verify:hygiene": "node scripts/verify-pactium-hygiene.mjs",
62
90
  "verify:protocol:gates": "node scripts/verify-protocol-gates.mjs",
63
91
  "verify:package:contents": "node scripts/verify-package-contents.mjs",
64
92
  "verify:release:readiness": "node scripts/verify-release-readiness.mjs",
65
- "verify:release": "npm run verify:hygiene && npm run verify:core && npm run verify:protocol:gates && npm run verify:release:readiness && npm run verify:package:contents && npm run pack:dry-run && npm run publish:dry-run",
93
+ "verify:release": "npm run verify:hygiene && npm run verify:core && npm run verify:protocol:gates && npm run verify:release:readiness && npm run verify:docs:versions && npm run verify:package:contents && npm run pack:dry-run && npm run publish:dry-run",
66
94
  "pack:dry-run": "npm pack --dry-run",
67
- "publish:dry-run": "npm publish --dry-run"
95
+ "publish:dry-run": "node scripts/verify-publish-dry-run.mjs"
68
96
  }
69
97
  }
package/src/index.d.ts CHANGED
@@ -185,7 +185,7 @@ export interface PactiumCore {
185
185
 
186
186
  export const PACTIUM_PROTOCOL: "pactium.v0.2";
187
187
  export const PACTIUM_SCHEMA_VERSION: "pactium.v0.2.schema.latest";
188
- export const PACTIUM_PACKAGE_VERSION: "0.2.0";
188
+ export const PACTIUM_PACKAGE_VERSION: "0.2.1";
189
189
  export const PACTIUM_INDEX_ENGINE: "pactium.verifiable-index-engine";
190
190
  export const PACTIUM_INDEX_SPLITTER: "pactium-cdc-boundary";
191
191
  export const PACTIUM_PROOF_BUNDLE_TYPE: "pactium.proof-bundle.indexed";
@@ -1,6 +1,6 @@
1
1
  export const PACTIUM_PROTOCOL = "pactium.v0.2";
2
2
  export const PACTIUM_SCHEMA_VERSION = "pactium.v0.2.schema.latest";
3
- export const PACTIUM_PACKAGE_VERSION = "0.2.0";
3
+ export const PACTIUM_PACKAGE_VERSION = "0.2.1";
4
4
  export const PACTIUM_INDEX_ENGINE = "pactium.verifiable-index-engine";
5
5
  export const PACTIUM_INDEX_SPLITTER = "pactium-cdc-boundary";
6
6
  export const PACTIUM_PROOF_BUNDLE_TYPE = "pactium.proof-bundle.indexed";