@attested-intelligence/aga-mcp-server 2.0.1 → 2.2.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 (241) hide show
  1. package/README.md +197 -124
  2. package/SECURITY.md +59 -0
  3. package/dist/adapters/openclaw.d.ts +43 -0
  4. package/dist/adapters/openclaw.d.ts.map +1 -0
  5. package/dist/adapters/openclaw.js +86 -0
  6. package/dist/adapters/openclaw.js.map +1 -0
  7. package/dist/core/bundle.d.ts +9 -2
  8. package/dist/core/bundle.d.ts.map +1 -1
  9. package/dist/core/bundle.js +16 -2
  10. package/dist/core/bundle.js.map +1 -1
  11. package/dist/core/identity.d.ts +19 -10
  12. package/dist/core/identity.d.ts.map +1 -1
  13. package/dist/core/identity.js +45 -11
  14. package/dist/core/identity.js.map +1 -1
  15. package/dist/core/portal.d.ts +10 -1
  16. package/dist/core/portal.d.ts.map +1 -1
  17. package/dist/core/portal.js +16 -12
  18. package/dist/core/portal.js.map +1 -1
  19. package/dist/core/types.d.ts +29 -2
  20. package/dist/core/types.d.ts.map +1 -1
  21. package/dist/crypto/index.d.ts +5 -6
  22. package/dist/crypto/index.d.ts.map +1 -1
  23. package/dist/crypto/index.js +5 -6
  24. package/dist/crypto/index.js.map +1 -1
  25. package/dist/crypto/sign.d.ts +2 -0
  26. package/dist/crypto/sign.d.ts.map +1 -1
  27. package/dist/crypto/sign.js +6 -0
  28. package/dist/crypto/sign.js.map +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/index.js.map +1 -1
  31. package/dist/middleware/governance.d.ts +7 -1
  32. package/dist/middleware/governance.d.ts.map +1 -1
  33. package/dist/middleware/governance.js +18 -11
  34. package/dist/middleware/governance.js.map +1 -1
  35. package/dist/proxy/evaluator.d.ts +14 -0
  36. package/dist/proxy/evaluator.d.ts.map +1 -0
  37. package/dist/proxy/evaluator.js +141 -0
  38. package/dist/proxy/evaluator.js.map +1 -0
  39. package/dist/proxy/index.d.ts +22 -0
  40. package/dist/proxy/index.d.ts.map +1 -0
  41. package/dist/proxy/index.js +230 -0
  42. package/dist/proxy/index.js.map +1 -0
  43. package/dist/proxy/profiles.d.ts +16 -0
  44. package/dist/proxy/profiles.d.ts.map +1 -0
  45. package/dist/proxy/profiles.js +43 -0
  46. package/dist/proxy/profiles.js.map +1 -0
  47. package/dist/proxy/server.d.ts +106 -0
  48. package/dist/proxy/server.d.ts.map +1 -0
  49. package/dist/proxy/server.js +389 -0
  50. package/dist/proxy/server.js.map +1 -0
  51. package/dist/proxy/stdio-bridge.d.ts +42 -0
  52. package/dist/proxy/stdio-bridge.d.ts.map +1 -0
  53. package/dist/proxy/stdio-bridge.js +142 -0
  54. package/dist/proxy/stdio-bridge.js.map +1 -0
  55. package/dist/proxy/types.d.ts +36 -0
  56. package/dist/proxy/types.d.ts.map +1 -0
  57. package/dist/proxy/types.js +11 -0
  58. package/dist/proxy/types.js.map +1 -0
  59. package/dist/proxy/verify.d.ts +29 -0
  60. package/dist/proxy/verify.d.ts.map +1 -0
  61. package/dist/proxy/verify.js +183 -0
  62. package/dist/proxy/verify.js.map +1 -0
  63. package/dist/server.d.ts +7 -3
  64. package/dist/server.d.ts.map +1 -1
  65. package/dist/server.js +342 -214
  66. package/dist/server.js.map +1 -1
  67. package/dist/storage/sqlite.js +6 -6
  68. package/independent-verifier/README.md +31 -0
  69. package/independent-verifier/package.json +18 -0
  70. package/independent-verifier/verify.ts +211 -0
  71. package/package.json +97 -71
  72. package/src/adapters/openclaw.ts +125 -0
  73. package/src/core/artifact.ts +45 -0
  74. package/src/core/attestation.ts +33 -0
  75. package/src/core/behavioral.ts +132 -0
  76. package/src/core/bundle.ts +45 -0
  77. package/src/core/chain.ts +72 -0
  78. package/src/core/checkpoint.ts +22 -0
  79. package/src/core/delegation.ts +146 -0
  80. package/src/core/disclosure.ts +32 -0
  81. package/src/core/identity.ts +62 -0
  82. package/src/core/index.ts +14 -0
  83. package/src/core/portal.ts +117 -0
  84. package/src/core/quarantine.ts +16 -0
  85. package/src/core/receipt.ts +33 -0
  86. package/src/core/subject.ts +11 -0
  87. package/src/core/types.ts +285 -0
  88. package/src/crypto/hash.ts +33 -0
  89. package/src/crypto/index.ts +5 -0
  90. package/src/crypto/merkle.ts +43 -0
  91. package/src/crypto/salt.ts +18 -0
  92. package/src/crypto/sign.ts +42 -0
  93. package/src/crypto/types.ts +19 -0
  94. package/src/index.ts +12 -0
  95. package/src/middleware/governance.ts +95 -0
  96. package/src/middleware/index.ts +1 -0
  97. package/src/proxy/evaluator.ts +176 -0
  98. package/src/proxy/index.ts +259 -0
  99. package/src/proxy/profiles.ts +48 -0
  100. package/src/proxy/server.ts +499 -0
  101. package/src/proxy/stdio-bridge.ts +171 -0
  102. package/src/proxy/types.ts +40 -0
  103. package/src/proxy/verify.ts +202 -0
  104. package/src/server.ts +435 -0
  105. package/src/storage/index.ts +3 -0
  106. package/src/storage/interface.ts +21 -0
  107. package/src/storage/memory.ts +27 -0
  108. package/src/storage/sqlite.ts +45 -0
  109. package/src/tools/README.md +13 -0
  110. package/src/utils/canonical.ts +14 -0
  111. package/src/utils/constants.ts +3 -0
  112. package/src/utils/timestamp.ts +12 -0
  113. package/src/utils/uuid.ts +2 -0
  114. package/dist/context.d.ts +0 -39
  115. package/dist/context.d.ts.map +0 -1
  116. package/dist/context.js +0 -113
  117. package/dist/context.js.map +0 -1
  118. package/dist/core/measurement.d.ts +0 -16
  119. package/dist/core/measurement.d.ts.map +0 -1
  120. package/dist/core/measurement.js +0 -18
  121. package/dist/core/measurement.js.map +0 -1
  122. package/dist/crypto/canonicalize.d.ts +0 -7
  123. package/dist/crypto/canonicalize.d.ts.map +0 -1
  124. package/dist/crypto/canonicalize.js +0 -21
  125. package/dist/crypto/canonicalize.js.map +0 -1
  126. package/dist/crypto/keys.d.ts +0 -10
  127. package/dist/crypto/keys.d.ts.map +0 -1
  128. package/dist/crypto/keys.js +0 -19
  129. package/dist/crypto/keys.js.map +0 -1
  130. package/dist/prompts/drift-analysis.d.ts +0 -13
  131. package/dist/prompts/drift-analysis.d.ts.map +0 -1
  132. package/dist/prompts/drift-analysis.js +0 -43
  133. package/dist/prompts/drift-analysis.js.map +0 -1
  134. package/dist/prompts/governance-report.d.ts +0 -7
  135. package/dist/prompts/governance-report.d.ts.map +0 -1
  136. package/dist/prompts/governance-report.js +0 -26
  137. package/dist/prompts/governance-report.js.map +0 -1
  138. package/dist/prompts/nccoe-demo.d.ts +0 -14
  139. package/dist/prompts/nccoe-demo.d.ts.map +0 -1
  140. package/dist/prompts/nccoe-demo.js +0 -47
  141. package/dist/prompts/nccoe-demo.js.map +0 -1
  142. package/dist/resources/cosai-mapping.d.ts +0 -24
  143. package/dist/resources/cosai-mapping.d.ts.map +0 -1
  144. package/dist/resources/cosai-mapping.js +0 -127
  145. package/dist/resources/cosai-mapping.js.map +0 -1
  146. package/dist/resources/crypto-primitives.d.ts +0 -3
  147. package/dist/resources/crypto-primitives.d.ts.map +0 -1
  148. package/dist/resources/crypto-primitives.js +0 -52
  149. package/dist/resources/crypto-primitives.js.map +0 -1
  150. package/dist/resources/sample-bundle.d.ts +0 -6
  151. package/dist/resources/sample-bundle.d.ts.map +0 -1
  152. package/dist/resources/sample-bundle.js +0 -58
  153. package/dist/resources/sample-bundle.js.map +0 -1
  154. package/dist/resources/specification.d.ts +0 -3
  155. package/dist/resources/specification.d.ts.map +0 -1
  156. package/dist/resources/specification.js +0 -161
  157. package/dist/resources/specification.js.map +0 -1
  158. package/dist/tools/create-artifact.d.ts +0 -25
  159. package/dist/tools/create-artifact.d.ts.map +0 -1
  160. package/dist/tools/create-artifact.js +0 -85
  161. package/dist/tools/create-artifact.js.map +0 -1
  162. package/dist/tools/delegate-subagent.d.ts +0 -18
  163. package/dist/tools/delegate-subagent.d.ts.map +0 -1
  164. package/dist/tools/delegate-subagent.js +0 -50
  165. package/dist/tools/delegate-subagent.js.map +0 -1
  166. package/dist/tools/disclose-claim.d.ts +0 -14
  167. package/dist/tools/disclose-claim.d.ts.map +0 -1
  168. package/dist/tools/disclose-claim.js +0 -23
  169. package/dist/tools/disclose-claim.js.map +0 -1
  170. package/dist/tools/export-bundle.d.ts +0 -8
  171. package/dist/tools/export-bundle.d.ts.map +0 -1
  172. package/dist/tools/export-bundle.js +0 -25
  173. package/dist/tools/export-bundle.js.map +0 -1
  174. package/dist/tools/full-lifecycle.d.ts +0 -16
  175. package/dist/tools/full-lifecycle.d.ts.map +0 -1
  176. package/dist/tools/full-lifecycle.js +0 -121
  177. package/dist/tools/full-lifecycle.js.map +0 -1
  178. package/dist/tools/generate-receipt.d.ts +0 -16
  179. package/dist/tools/generate-receipt.d.ts.map +0 -1
  180. package/dist/tools/generate-receipt.js +0 -31
  181. package/dist/tools/generate-receipt.js.map +0 -1
  182. package/dist/tools/get-chain.d.ts +0 -14
  183. package/dist/tools/get-chain.d.ts.map +0 -1
  184. package/dist/tools/get-chain.js +0 -45
  185. package/dist/tools/get-chain.js.map +0 -1
  186. package/dist/tools/get-portal-state.d.ts +0 -8
  187. package/dist/tools/get-portal-state.d.ts.map +0 -1
  188. package/dist/tools/get-portal-state.js +0 -15
  189. package/dist/tools/get-portal-state.js.map +0 -1
  190. package/dist/tools/init-chain.d.ts +0 -10
  191. package/dist/tools/init-chain.d.ts.map +0 -1
  192. package/dist/tools/init-chain.js +0 -13
  193. package/dist/tools/init-chain.js.map +0 -1
  194. package/dist/tools/measure-behavior.d.ts +0 -12
  195. package/dist/tools/measure-behavior.d.ts.map +0 -1
  196. package/dist/tools/measure-behavior.js +0 -29
  197. package/dist/tools/measure-behavior.js.map +0 -1
  198. package/dist/tools/measure-subject.d.ts +0 -15
  199. package/dist/tools/measure-subject.d.ts.map +0 -1
  200. package/dist/tools/measure-subject.js +0 -106
  201. package/dist/tools/measure-subject.js.map +0 -1
  202. package/dist/tools/quarantine-status.d.ts +0 -8
  203. package/dist/tools/quarantine-status.d.ts.map +0 -1
  204. package/dist/tools/quarantine-status.js +0 -16
  205. package/dist/tools/quarantine-status.js.map +0 -1
  206. package/dist/tools/revoke-artifact.d.ts +0 -13
  207. package/dist/tools/revoke-artifact.d.ts.map +0 -1
  208. package/dist/tools/revoke-artifact.js +0 -24
  209. package/dist/tools/revoke-artifact.js.map +0 -1
  210. package/dist/tools/rotate-keys.d.ts +0 -13
  211. package/dist/tools/rotate-keys.d.ts.map +0 -1
  212. package/dist/tools/rotate-keys.js +0 -39
  213. package/dist/tools/rotate-keys.js.map +0 -1
  214. package/dist/tools/server-info.d.ts +0 -8
  215. package/dist/tools/server-info.d.ts.map +0 -1
  216. package/dist/tools/server-info.js +0 -23
  217. package/dist/tools/server-info.js.map +0 -1
  218. package/dist/tools/set-verification-tier.d.ts +0 -11
  219. package/dist/tools/set-verification-tier.d.ts.map +0 -1
  220. package/dist/tools/set-verification-tier.js +0 -31
  221. package/dist/tools/set-verification-tier.js.map +0 -1
  222. package/dist/tools/start-monitoring.d.ts +0 -12
  223. package/dist/tools/start-monitoring.d.ts.map +0 -1
  224. package/dist/tools/start-monitoring.js +0 -17
  225. package/dist/tools/start-monitoring.js.map +0 -1
  226. package/dist/tools/trigger-measurement.d.ts +0 -15
  227. package/dist/tools/trigger-measurement.d.ts.map +0 -1
  228. package/dist/tools/trigger-measurement.js +0 -86
  229. package/dist/tools/trigger-measurement.js.map +0 -1
  230. package/dist/tools/verify-artifact.d.ts +0 -13
  231. package/dist/tools/verify-artifact.d.ts.map +0 -1
  232. package/dist/tools/verify-artifact.js +0 -6
  233. package/dist/tools/verify-artifact.js.map +0 -1
  234. package/dist/tools/verify-bundle.d.ts +0 -13
  235. package/dist/tools/verify-bundle.d.ts.map +0 -1
  236. package/dist/tools/verify-bundle.js +0 -6
  237. package/dist/tools/verify-bundle.js.map +0 -1
  238. package/dist/types.d.ts +0 -261
  239. package/dist/types.d.ts.map +0 -1
  240. package/dist/types.js +0 -8
  241. package/dist/types.js.map +0 -1
@@ -0,0 +1,202 @@
1
+ /**
2
+ * AGA Gateway Bundle Verifier
3
+ * Verifies Ed25519-SHA256-JCS evidence bundles.
4
+ * Uses ONLY @noble crypto - zero imports from ../core/ or ../crypto/.
5
+ *
6
+ * 5-step verification matching gateway, Python SDK, and browser verifier:
7
+ * 1. Algorithm check
8
+ * 2. Receipt signature verification
9
+ * 3. Chain integrity (previous_receipt_hash linkage)
10
+ * 4. Merkle inclusion proofs
11
+ * 5. Bundle consistency (leaf hashes match receipts)
12
+ *
13
+ * Patent: USPTO App. No. 19/433,835
14
+ * Copyright (c) 2026 Attested Intelligence Holdings LLC
15
+ * SPDX-License-Identifier: MIT
16
+ */
17
+
18
+ import * as ed from '@noble/ed25519';
19
+ import { sha512 } from '@noble/hashes/sha512';
20
+ import { sha256 } from '@noble/hashes/sha256';
21
+ import { bytesToHex, hexToBytes } from '@noble/hashes/utils';
22
+
23
+ // Ed25519 setup
24
+ ed.etc.sha512Sync = (...m: Uint8Array[]) => {
25
+ const total = m.reduce((n, a) => n + a.length, 0);
26
+ const buf = new Uint8Array(total);
27
+ let off = 0;
28
+ for (const a of m) { buf.set(a, off); off += a.length; }
29
+ return sha512(buf);
30
+ };
31
+
32
+ const enc = new TextEncoder();
33
+
34
+ // ── RFC 8785 Canonicalization ────────────────────────────────
35
+
36
+ function deepSortKeys(obj: unknown): unknown {
37
+ if (obj === null || obj === undefined || typeof obj !== 'object') return obj;
38
+ if (Array.isArray(obj)) return obj.map(deepSortKeys);
39
+ const sorted: Record<string, unknown> = {};
40
+ for (const key of Object.keys(obj as Record<string, unknown>).sort()) {
41
+ sorted[key] = deepSortKeys((obj as Record<string, unknown>)[key]);
42
+ }
43
+ return sorted;
44
+ }
45
+
46
+ function canonicalize(obj: unknown): string {
47
+ return JSON.stringify(deepSortKeys(obj));
48
+ }
49
+
50
+ function sha256Hex(data: string): string {
51
+ return bytesToHex(sha256(enc.encode(data)));
52
+ }
53
+
54
+ function merkleNodeHash(leftHex: string, rightHex: string): string {
55
+ const left = hexToBytes(leftHex);
56
+ const right = hexToBytes(rightHex);
57
+ const combined = new Uint8Array(left.length + right.length);
58
+ combined.set(left, 0);
59
+ combined.set(right, left.length);
60
+ return bytesToHex(sha256(combined));
61
+ }
62
+
63
+ // ── Verification result ─────────────────────────────────────
64
+
65
+ export interface GatewayVerificationResult {
66
+ algorithm_valid: boolean;
67
+ receipt_signatures_valid: boolean;
68
+ chain_integrity_valid: boolean;
69
+ merkle_proofs_valid: boolean;
70
+ bundle_consistent: boolean;
71
+ overall_valid: boolean;
72
+ receipts_checked: number;
73
+ algorithm: string;
74
+ error?: string;
75
+ }
76
+
77
+ // ── 5-step verification ─────────────────────────────────────
78
+
79
+ export async function verifyGatewayBundle(bundleJson: string): Promise<GatewayVerificationResult> {
80
+ let bundle: any;
81
+ try {
82
+ bundle = JSON.parse(bundleJson);
83
+ } catch {
84
+ return {
85
+ algorithm_valid: false, receipt_signatures_valid: false,
86
+ chain_integrity_valid: false, merkle_proofs_valid: false,
87
+ bundle_consistent: false, overall_valid: false,
88
+ receipts_checked: 0, algorithm: '', error: 'Invalid JSON',
89
+ };
90
+ }
91
+
92
+ const result: GatewayVerificationResult = {
93
+ algorithm_valid: false, receipt_signatures_valid: false,
94
+ chain_integrity_valid: false, merkle_proofs_valid: false,
95
+ bundle_consistent: false, overall_valid: false,
96
+ receipts_checked: bundle.receipts?.length ?? 0,
97
+ algorithm: bundle.algorithm ?? '',
98
+ };
99
+
100
+ // Step 1: Algorithm
101
+ if (bundle.algorithm !== 'Ed25519-SHA256-JCS') {
102
+ result.error = `unsupported algorithm: ${bundle.algorithm}`;
103
+ return result;
104
+ }
105
+ for (const r of bundle.receipts) {
106
+ if (r.algorithm !== 'Ed25519-SHA256-JCS') {
107
+ result.error = `receipt has wrong algorithm: ${r.algorithm}`;
108
+ return result;
109
+ }
110
+ }
111
+ result.algorithm_valid = true;
112
+
113
+ // Step 2: Receipt signatures
114
+ try {
115
+ for (const receipt of bundle.receipts) {
116
+ const { signature, ...unsigned } = receipt;
117
+ const canonical = canonicalize(unsigned);
118
+ const sig = hexToBytes(signature);
119
+ const pk = hexToBytes(receipt.public_key);
120
+ if (!ed.verify(sig, enc.encode(canonical), pk)) {
121
+ result.error = `Receipt ${receipt.receipt_id} signature failed`;
122
+ return result;
123
+ }
124
+ }
125
+ result.receipt_signatures_valid = true;
126
+ } catch (e) {
127
+ result.error = `signature verification error: ${e}`;
128
+ return result;
129
+ }
130
+
131
+ // Step 3: Chain integrity
132
+ try {
133
+ const receipts = bundle.receipts;
134
+ if (receipts.length > 0 && receipts[0].previous_receipt_hash !== '') {
135
+ result.error = 'First receipt previous_receipt_hash must be empty';
136
+ return result;
137
+ }
138
+ for (let i = 1; i < receipts.length; i++) {
139
+ const expectedHash = sha256Hex(canonicalize(receipts[i - 1]));
140
+ if (receipts[i].previous_receipt_hash !== expectedHash) {
141
+ result.error = `Chain break at receipt ${i}`;
142
+ return result;
143
+ }
144
+ }
145
+ result.chain_integrity_valid = true;
146
+ } catch (e) {
147
+ result.error = `chain integrity error: ${e}`;
148
+ return result;
149
+ }
150
+
151
+ // Step 4: Merkle proofs
152
+ try {
153
+ for (const proof of bundle.merkle_proofs) {
154
+ let currentHash = proof.leaf_hash;
155
+ for (let i = 0; i < proof.siblings.length; i++) {
156
+ if (proof.directions[i] === 'left') {
157
+ currentHash = merkleNodeHash(proof.siblings[i], currentHash);
158
+ } else {
159
+ currentHash = merkleNodeHash(currentHash, proof.siblings[i]);
160
+ }
161
+ }
162
+ if (currentHash !== bundle.merkle_root) {
163
+ result.error = `Merkle proof failed for leaf ${proof.leaf_index}`;
164
+ return result;
165
+ }
166
+ if (proof.merkle_root !== bundle.merkle_root) {
167
+ result.error = `Proof root mismatch at leaf ${proof.leaf_index}`;
168
+ return result;
169
+ }
170
+ }
171
+ result.merkle_proofs_valid = true;
172
+ } catch (e) {
173
+ result.error = `merkle proof error: ${e}`;
174
+ return result;
175
+ }
176
+
177
+ // Step 5: Bundle consistency
178
+ try {
179
+ if (bundle.merkle_proofs.length !== bundle.receipts.length) {
180
+ result.error = 'Proof count != receipt count';
181
+ return result;
182
+ }
183
+ for (let i = 0; i < bundle.receipts.length; i++) {
184
+ const leafHash = sha256Hex(canonicalize(bundle.receipts[i]));
185
+ if (bundle.merkle_proofs[i].leaf_hash !== leafHash) {
186
+ result.error = `Leaf hash mismatch at receipt ${i}`;
187
+ return result;
188
+ }
189
+ if (bundle.merkle_proofs[i].leaf_index !== i) {
190
+ result.error = `Leaf index mismatch at receipt ${i}`;
191
+ return result;
192
+ }
193
+ }
194
+ result.bundle_consistent = true;
195
+ } catch (e) {
196
+ result.error = `consistency error: ${e}`;
197
+ return result;
198
+ }
199
+
200
+ result.overall_valid = true;
201
+ return result;
202
+ }
package/src/server.ts ADDED
@@ -0,0 +1,435 @@
1
+ /**
2
+ * AGA MCP Server. The Portal (ref 150) as an MCP service.
3
+ *
4
+ * V3 NIST-aligned behaviors:
5
+ * 1. Every measurement generates a receipt (match OR mismatch)
6
+ * 2. TTL checked on every measurement (fail-closed)
7
+ * 3. Mid-session revocation via revoke_artifact tool
8
+ * 4. Governance middleware: portal state checked before tool execution
9
+ * 5. Auto-chaining: every operation writes to continuity chain
10
+ */
11
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
12
+ import { z } from 'zod';
13
+ import { generateKeyPair, pkToHex } from './crypto/sign.js';
14
+ import { sha256Str } from './crypto/hash.js';
15
+ import { computeSubjectIdFromString } from './core/subject.js';
16
+ import { performAttestation } from './core/attestation.js';
17
+ import { generateArtifact, hashArtifact } from './core/artifact.js';
18
+ import { Portal } from './core/portal.js';
19
+ import { generateReceipt } from './core/receipt.js';
20
+ import { createGenesisEvent, appendEvent, verifyChainIntegrity } from './core/chain.js';
21
+ import { createCheckpoint, eventInclusionProof } from './core/checkpoint.js';
22
+ import { generateBundle, verifyBundleOffline } from './core/bundle.js';
23
+ import { processDisclosure } from './core/disclosure.js';
24
+ import { initQuarantine, captureInput } from './core/quarantine.js';
25
+ import { MemoryStorage, type AGAStorage } from './storage/index.js';
26
+ import { utcNow } from './utils/timestamp.js';
27
+ import { deriveArtifact } from './core/delegation.js';
28
+ import { createGovernanceWrapper, type ToolHandler } from './middleware/governance.js';
29
+ import { BehavioralMonitor } from './core/behavioral.js';
30
+ import type { EnforcementParams, DisclosurePolicy, QuarantineState, RevocationRecord } from './core/types.js';
31
+
32
+ // ── Default Policies ────────────────────────────────────────────
33
+
34
+ const DEFAULT_ENFORCEMENT: EnforcementParams = {
35
+ measurement_cadence_ms: 1000, ttl_seconds: 3600,
36
+ enforcement_triggers: ['QUARANTINE', 'TERMINATE'],
37
+ re_attestation_required: true,
38
+ measurement_types: ['FILE_SYSTEM_STATE', 'CONFIG_MANIFEST'],
39
+ };
40
+
41
+ const DEFAULT_CLAIMS: DisclosurePolicy = {
42
+ claims_taxonomy: [
43
+ { claim_id: 'identity.name', sensitivity: 'S3_HIGH', substitutes: ['identity.pseudonym', 'identity.org'], inference_risks: [], permitted_modes: ['PROOF_ONLY'] },
44
+ { claim_id: 'identity.pseudonym', sensitivity: 'S2_MODERATE', substitutes: ['identity.org'], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN'] },
45
+ { claim_id: 'identity.org', sensitivity: 'S1_LOW', substitutes: [], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL'] },
46
+ { claim_id: 'identity.age', sensitivity: 'S3_HIGH', substitutes: ['identity.age_range', 'identity.is_adult'], inference_risks: [], permitted_modes: ['PROOF_ONLY'] },
47
+ { claim_id: 'identity.age_range', sensitivity: 'S2_MODERATE', substitutes: ['identity.is_adult'], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL'] },
48
+ { claim_id: 'identity.is_adult', sensitivity: 'S1_LOW', substitutes: [], inference_risks: [], permitted_modes: ['PROOF_ONLY', 'REVEAL_FULL'] },
49
+ ],
50
+ substitution_rules: [],
51
+ };
52
+
53
+ const CLAIM_VALUES: Record<string, unknown> = {
54
+ 'identity.name': 'Alice Johnson', 'identity.pseudonym': 'AJ-7742', 'identity.org': 'Attested Intelligence',
55
+ 'identity.age': 32, 'identity.age_range': '25-34', 'identity.is_adult': true,
56
+ };
57
+
58
+ // ── Server Factory ──────────────────────────────────────────────
59
+
60
+ export async function createAGAServer(): Promise<McpServer> {
61
+ const server = new McpServer({ name: 'aga-mcp-server', version: '0.1.0' });
62
+ const storage: AGAStorage = new MemoryStorage();
63
+ await storage.initialize();
64
+
65
+ const issuerKP = generateKeyPair();
66
+ const portalKP = generateKeyPair();
67
+ const chainKP = generateKeyPair();
68
+ const portal = new Portal();
69
+ let quarantine: QuarantineState | null = null;
70
+ let chainInitialized = false;
71
+
72
+ // ── Auto-chain helper (auto-inits if needed) ──────────────────
73
+ async function autoChain(type: Parameters<typeof appendEvent>[0], payload: unknown) {
74
+ if (!chainInitialized) {
75
+ const genesis = createGenesisEvent(chainKP, sha256Str('AGA Protocol Specification v1.0.0'));
76
+ await storage.storeEvent(genesis);
77
+ chainInitialized = true;
78
+ portal.sequenceCounter = 0;
79
+ portal.lastLeafHash = genesis.leaf_hash;
80
+ }
81
+ const prev = await storage.getLatestEvent();
82
+ if (!prev) throw new Error('Chain initialization failed');
83
+ const event = appendEvent(type, payload, prev, chainKP);
84
+ await storage.storeEvent(event);
85
+ portal.sequenceCounter = event.sequence_number;
86
+ portal.lastLeafHash = event.leaf_hash;
87
+ return event;
88
+ }
89
+
90
+ const j = (x: unknown) => ({ content: [{ type: 'text' as const, text: JSON.stringify(x, null, 2) }] });
91
+
92
+ // ── Governance middleware (NCCoE Section 4: Portal as PEP) ────
93
+ const quarantineRef = { get current() { return quarantine; } };
94
+ const behavioralMonitor = new BehavioralMonitor();
95
+
96
+ function governedTool(
97
+ name: string, description: string, schema: any,
98
+ handler: ToolHandler
99
+ ) {
100
+ const wrap = createGovernanceWrapper(portal, quarantineRef, name, behavioralMonitor);
101
+ server.tool(name, description, schema, wrap(handler));
102
+ }
103
+
104
+ // ══════════════════════════════════════════════════════════════
105
+ // TOOL: get_server_info
106
+ // ══════════════════════════════════════════════════════════════
107
+ server.tool('get_server_info', 'Get AGA server info, public keys, and portal state.', {}, async () => j({
108
+ server: 'AGA MCP Server', version: '0.1.0',
109
+ protocol: 'Attested Governance Artifacts v1.0.0',
110
+ nist_references: ['NIST-2025-0035', 'NCCoE AI Agent Identity'],
111
+ issuer_public_key: pkToHex(issuerKP.publicKey),
112
+ portal_public_key: pkToHex(portalKP.publicKey),
113
+ chain_public_key: pkToHex(chainKP.publicKey),
114
+ chain_initialized: chainInitialized,
115
+ portal_state: portal.state,
116
+ }));
117
+
118
+ // ══════════════════════════════════════════════════════════════
119
+ // TOOL: get_portal_state - V3 RESTORED (was dropped in V2)
120
+ // ══════════════════════════════════════════════════════════════
121
+ server.tool('get_portal_state', 'Get current portal state, loaded artifact info, and enforcement status.', {}, async () => j({
122
+ state: portal.state,
123
+ artifact_loaded: !!portal.artifact,
124
+ sealed_hash: portal.artifact?.sealed_hash ?? null,
125
+ ttl_seconds: portal.artifact?.enforcement_parameters.ttl_seconds ?? null,
126
+ issued_at: portal.artifact?.issued_timestamp ?? null,
127
+ enforcement_triggers: portal.artifact?.enforcement_parameters.enforcement_triggers ?? [],
128
+ sequence_counter: portal.sequenceCounter,
129
+ quarantine_active: quarantine?.active ?? false,
130
+ }));
131
+
132
+ // ══════════════════════════════════════════════════════════════
133
+ // TOOL: init_chain
134
+ // ══════════════════════════════════════════════════════════════
135
+ server.tool('init_chain', 'Initialize continuity chain with genesis event.',
136
+ { specification_hash: z.string().optional() },
137
+ async ({ specification_hash }) => {
138
+ if (chainInitialized) return j({ success: false, error: 'Chain already initialized' });
139
+ const genesis = createGenesisEvent(chainKP, specification_hash ?? sha256Str('AGA Protocol Specification v1.0.0'));
140
+ await storage.storeEvent(genesis);
141
+ chainInitialized = true;
142
+ portal.sequenceCounter = 0;
143
+ portal.lastLeafHash = genesis.leaf_hash;
144
+ return j({ success: true, genesis_event_id: genesis.event_id, genesis_leaf_hash: genesis.leaf_hash });
145
+ }
146
+ );
147
+
148
+ // ══════════════════════════════════════════════════════════════
149
+ // TOOL: attest_subject
150
+ // ══════════════════════════════════════════════════════════════
151
+ server.tool('attest_subject',
152
+ 'Attest subject, generate sealed Policy Artifact. Auto-loads into portal.',
153
+ {
154
+ subject_content: z.string().describe('Content/bytes of the subject'),
155
+ subject_metadata: z.object({ filename: z.string().optional(), version: z.string().optional(), author: z.string().optional(), content_type: z.string().optional() }),
156
+ evidence_items: z.array(z.object({ label: z.string(), content: z.string() })).default([]),
157
+ behavioral_baseline: z.object({
158
+ permitted_tools: z.array(z.string()),
159
+ rate_limits: z.record(z.number()),
160
+ forbidden_sequences: z.array(z.array(z.string())),
161
+ window_ms: z.number(),
162
+ }).optional(),
163
+ },
164
+ async ({ subject_content, subject_metadata, evidence_items, behavioral_baseline }) => {
165
+ const subId = computeSubjectIdFromString(subject_content, subject_metadata);
166
+ const policyRef = sha256Str(JSON.stringify(DEFAULT_ENFORCEMENT));
167
+ const att = performAttestation({ subject_identifier: subId, policy_reference: policyRef, evidence_items });
168
+ if (!att.success || !att.sealed_hash || !att.seal_salt) return j({ success: false, error: att.rejection_reason });
169
+
170
+ const artifact = generateArtifact({
171
+ subject_identifier: subId, policy_reference: policyRef, policy_version: 1,
172
+ sealed_hash: att.sealed_hash, seal_salt: att.seal_salt,
173
+ enforcement_parameters: DEFAULT_ENFORCEMENT, disclosure_policy: DEFAULT_CLAIMS,
174
+ evidence_commitments: att.evidence_commitments, issuer_keypair: issuerKP,
175
+ });
176
+ await storage.storeArtifact(artifact);
177
+
178
+ portal.reset();
179
+ portal.loadArtifact(artifact, pkToHex(issuerKP.publicKey));
180
+ quarantine = null;
181
+ behavioralMonitor.reset();
182
+ if (behavioral_baseline) behavioralMonitor.setBaseline(behavioral_baseline);
183
+
184
+ await autoChain('POLICY_ISSUANCE', { artifact_hash: hashArtifact(artifact), sealed_hash: artifact.sealed_hash });
185
+
186
+ return j({
187
+ success: true, artifact_hash: hashArtifact(artifact), sealed_hash: artifact.sealed_hash,
188
+ subject_identifier: subId, portal_state: portal.state,
189
+ issuer_public_key: pkToHex(issuerKP.publicKey),
190
+ });
191
+ }
192
+ );
193
+
194
+ // ══════════════════════════════════════════════════════════════
195
+ // TOOL: measure_integrity
196
+ // V3: Generates receipt for EVERY measurement (match or mismatch)
197
+ // V3: Checks TTL and revocation (fail-closed)
198
+ // ══════════════════════════════════════════════════════════════
199
+ governedTool('measure_integrity',
200
+ 'Measure subject state, compare to sealed reference. Generates signed receipt for every measurement.',
201
+ {
202
+ subject_content: z.string().describe('Current content of the subject'),
203
+ subject_metadata: z.object({ filename: z.string().optional(), version: z.string().optional(), author: z.string().optional(), content_type: z.string().optional() }),
204
+ },
205
+ async ({ subject_content, subject_metadata }) => {
206
+ if (!portal.artifact) return j({ success: false, error: 'No artifact loaded. Call attest_subject first.' });
207
+ if (portal.state === 'TERMINATED') return j({ success: false, error: 'Portal is terminated. Re-attest required.' });
208
+
209
+ const result = portal.measure(new TextEncoder().encode(subject_content), subject_metadata);
210
+ const artRef = hashArtifact(portal.artifact);
211
+ const currentStr = result.currentBytesHash ? `${result.currentBytesHash}||${result.currentMetaHash}` : 'UNAVAILABLE';
212
+ const sealedStr = `${result.expectedBytesHash}||${result.expectedMetaHash}`;
213
+
214
+ // Determine enforcement action
215
+ let action = null as import('./core/types.js').EnforcementAction | null;
216
+ let driftDesc: string | null = null;
217
+
218
+ if (!result.ttl_ok) {
219
+ driftDesc = 'TTL expired - fail-closed termination';
220
+ action = 'TERMINATE';
221
+ } else if (result.revoked) {
222
+ driftDesc = 'Artifact revoked - fail-closed termination';
223
+ action = 'TERMINATE';
224
+ } else if (!result.match) {
225
+ driftDesc = 'Subject modified - hash mismatch';
226
+ action = portal.artifact.enforcement_parameters.enforcement_triggers[0] ?? 'ALERT_ONLY';
227
+ portal.enforce(action);
228
+ if (action === 'QUARANTINE') quarantine = initQuarantine();
229
+ }
230
+
231
+ // V3: Receipt for EVERY measurement - match or mismatch
232
+ const receipt = generateReceipt({
233
+ subjectId: portal.artifact.subject_identifier, artifactRef: artRef,
234
+ currentHash: currentStr, sealedHash: sealedStr,
235
+ driftDetected: !result.match, driftDescription: driftDesc,
236
+ action, measurementType: portal.artifact.enforcement_parameters.measurement_types.join(','),
237
+ seq: portal.sequenceCounter + 1, prevLeaf: portal.lastLeafHash, portalKP,
238
+ });
239
+ await storage.storeReceipt(receipt);
240
+ await autoChain('INTERACTION_RECEIPT', { receipt_id: receipt.receipt_id, drift_detected: !result.match, enforcement_action: action });
241
+
242
+ return j({
243
+ success: true, match: result.match, drift_detected: !result.match,
244
+ ttl_ok: result.ttl_ok, revoked: result.revoked,
245
+ enforcement_action: action, portal_state: portal.state,
246
+ receipt_id: receipt.receipt_id,
247
+ });
248
+ }
249
+ );
250
+
251
+ // ══════════════════════════════════════════════════════════════
252
+ // TOOL: revoke_artifact - V3 NEW (NCCoE Phase 3b)
253
+ // ══════════════════════════════════════════════════════════════
254
+ governedTool('revoke_artifact',
255
+ 'Revoke an active policy artifact mid-session. Portal terminates on next measurement. (NCCoE Phase 3b)',
256
+ {
257
+ sealed_hash: z.string().describe('Sealed hash of artifact to revoke'),
258
+ reason: z.string().describe('Reason for revocation'),
259
+ },
260
+ async ({ sealed_hash, reason }) => {
261
+ portal.revoke(sealed_hash);
262
+ const record: RevocationRecord = {
263
+ artifact_sealed_hash: sealed_hash, reason,
264
+ revoked_by: pkToHex(issuerKP.publicKey), timestamp: utcNow(),
265
+ };
266
+ await autoChain('REVOCATION', record);
267
+ return j({ success: true, revoked: sealed_hash, portal_state: portal.state, reason });
268
+ }
269
+ );
270
+
271
+ // ══════════════════════════════════════════════════════════════
272
+ // TOOL: verify_chain
273
+ // ══════════════════════════════════════════════════════════════
274
+ server.tool('verify_chain', 'Verify continuity chain integrity.', {}, async () => {
275
+ const events = await storage.getAllEvents();
276
+ if (!events.length) return j({ success: false, error: 'No events in chain' });
277
+ const result = verifyChainIntegrity(events);
278
+ return j({ success: true, chain_valid: result.valid, events_verified: events.length, broken_at: result.brokenAt, error: result.error });
279
+ });
280
+
281
+ // ══════════════════════════════════════════════════════════════
282
+ // TOOL: create_checkpoint
283
+ // ══════════════════════════════════════════════════════════════
284
+ governedTool('create_checkpoint', 'Batch events into Merkle tree, anchor.',
285
+ { anchor_network: z.string().default('local') },
286
+ async ({ anchor_network }) => {
287
+ const lastCP = await storage.getLatestCheckpoint();
288
+ const startSeq = lastCP ? lastCP.batch_end_sequence + 1 : 0;
289
+ const latest = await storage.getLatestEvent();
290
+ if (!latest) return j({ success: false, error: 'No events' });
291
+ const events = await storage.getEvents(startSeq, latest.sequence_number);
292
+ if (!events.length) return j({ success: false, error: 'No new events since last checkpoint' });
293
+ const { checkpoint, payload } = createCheckpoint(events, anchor_network);
294
+ await storage.storeCheckpoint(checkpoint);
295
+ await autoChain('ANCHOR_BATCH', payload);
296
+ return j({ success: true, merkle_root: checkpoint.merkle_root, events_checkpointed: events.length, transaction_id: checkpoint.transaction_id });
297
+ }
298
+ );
299
+
300
+ // ══════════════════════════════════════════════════════════════
301
+ // TOOL: generate_evidence_bundle
302
+ // ══════════════════════════════════════════════════════════════
303
+ governedTool('generate_evidence_bundle', 'Package artifact + receipts + Merkle proofs for offline verification.', {}, async () => {
304
+ const artifact = await storage.getLatestArtifact();
305
+ if (!artifact) return j({ success: false, error: 'No artifact' });
306
+ const cp = await storage.getLatestCheckpoint();
307
+ if (!cp) return j({ success: false, error: 'No checkpoint. Call create_checkpoint first.' });
308
+ const receipts = await storage.getReceiptsByArtifact(hashArtifact(artifact));
309
+ const batchEvents = await storage.getEvents(cp.batch_start_sequence, cp.batch_end_sequence);
310
+ const proofs = receipts
311
+ .filter(r => r.sequence_number >= cp.batch_start_sequence && r.sequence_number <= cp.batch_end_sequence)
312
+ .map(r => eventInclusionProof(batchEvents, r.sequence_number));
313
+ const bundle = generateBundle(artifact, receipts, proofs, cp, portalKP);
314
+ return j({ success: true, bundle, offline_verifiable: true, receipt_count: receipts.length, proof_count: proofs.length });
315
+ });
316
+
317
+ // ══════════════════════════════════════════════════════════════
318
+ // TOOL: verify_bundle_offline (Section J)
319
+ // ══════════════════════════════════════════════════════════════
320
+ governedTool('verify_bundle_offline', 'Verify evidence bundle offline. (Section J)',
321
+ { bundle: z.any(), pinned_public_key: z.string() },
322
+ async ({ bundle, pinned_public_key }) => j({ success: true, verification: verifyBundleOffline(bundle, pinned_public_key) })
323
+ );
324
+
325
+ // ══════════════════════════════════════════════════════════════
326
+ // TOOL: request_claim
327
+ // ══════════════════════════════════════════════════════════════
328
+ governedTool('request_claim', 'Request disclosure of a claim. Auto-substitutes if denied.',
329
+ { claim_id: z.string(), requester_id: z.string().default('anonymous'), mode: z.enum(['PROOF_ONLY', 'REVEAL_MIN', 'REVEAL_FULL']).default('REVEAL_MIN') },
330
+ async ({ claim_id, requester_id, mode }) => {
331
+ const latest = await storage.getLatestEvent();
332
+ const result = processDisclosure(
333
+ { requested_claim_id: claim_id, requester_id, mode, timestamp: utcNow() },
334
+ DEFAULT_CLAIMS, CLAIM_VALUES, 1, latest?.sequence_number ?? 0, portalKP
335
+ );
336
+ if (result.substitution_receipt) await autoChain('SUBSTITUTION', result.substitution_receipt);
337
+ else await autoChain('DISCLOSURE', { claim_id, mode, permitted: result.permitted });
338
+ return j({ success: true, ...result });
339
+ }
340
+ );
341
+
342
+ // ══════════════════════════════════════════════════════════════
343
+ // TOOL: list_claims
344
+ // ══════════════════════════════════════════════════════════════
345
+ server.tool('list_claims', 'List available claims with sensitivity levels.', {}, async () => {
346
+ return j({ claims: DEFAULT_CLAIMS.claims_taxonomy.map(c => ({ claim_id: c.claim_id, sensitivity: c.sensitivity, substitutes: c.substitutes, permitted_modes: c.permitted_modes })) });
347
+ });
348
+
349
+ // ══════════════════════════════════════════════════════════════
350
+ // TOOL: delegate_to_subagent (NCCoE: constrained sub-mandates)
351
+ // ══════════════════════════════════════════════════════════════
352
+ governedTool('delegate_to_subagent',
353
+ 'Derive a constrained policy artifact for a sub-agent. Scope can only diminish, never expand. (NCCoE constrained delegation)',
354
+ {
355
+ enforcement_triggers: z.array(z.string()).describe('Subset of parent enforcement triggers'),
356
+ measurement_types: z.array(z.string()).describe('Subset of parent measurement types'),
357
+ requested_ttl_seconds: z.number().describe('Requested TTL (will be clamped to parent remaining)'),
358
+ delegation_purpose: z.string().describe('Purpose of the delegation'),
359
+ },
360
+ async ({ enforcement_triggers, measurement_types, requested_ttl_seconds, delegation_purpose }) => {
361
+ if (!portal.artifact) return j({ success: false, error: 'No artifact loaded. Call attest_subject first.' });
362
+
363
+ const result = deriveArtifact(portal.artifact, {
364
+ enforcement_triggers: enforcement_triggers as import('./core/types.js').EnforcementAction[],
365
+ measurement_types: measurement_types as import('./core/types.js').MeasurementType[],
366
+ requested_ttl_seconds,
367
+ delegation_purpose,
368
+ }, issuerKP);
369
+
370
+ if (result.success) {
371
+ await autoChain('ATTESTATION', {
372
+ type: 'DELEGATION',
373
+ parent_artifact_hash: result.parent_artifact_hash,
374
+ child_artifact_hash: result.child_artifact_hash,
375
+ effective_ttl: result.effective_ttl_seconds,
376
+ scope_reduction: result.scope_reduction,
377
+ purpose: delegation_purpose,
378
+ });
379
+ }
380
+
381
+ return j(result);
382
+ }
383
+ );
384
+
385
+ // ══════════════════════════════════════════════════════════════
386
+ // TOOL: measure_behavior (NIST-2025-0035)
387
+ // ══════════════════════════════════════════════════════════════
388
+ server.tool('measure_behavior',
389
+ 'Measure behavioral patterns of agent tool usage. Detects unauthorized tools, rate violations, and forbidden sequences. (NIST-2025-0035)',
390
+ {},
391
+ async () => {
392
+ const measurement = behavioralMonitor.measure();
393
+ if (measurement.drift_detected) {
394
+ await autoChain('INTERACTION_RECEIPT', {
395
+ type: 'BEHAVIORAL_DRIFT',
396
+ violations: measurement.violations,
397
+ behavioral_hash: measurement.behavioral_hash,
398
+ });
399
+ }
400
+ return j({
401
+ success: true,
402
+ ...measurement,
403
+ violation_count: measurement.violations.length,
404
+ });
405
+ }
406
+ );
407
+
408
+ // ══════════════════════════════════════════════════════════════
409
+ // TOOL: get_receipts - V3 NEW
410
+ // ══════════════════════════════════════════════════════════════
411
+ server.tool('get_receipts', 'Get all signed receipts, optionally filtered by artifact.',
412
+ { artifact_hash: z.string().optional() },
413
+ async ({ artifact_hash }) => {
414
+ const receipts = artifact_hash
415
+ ? await storage.getReceiptsByArtifact(artifact_hash)
416
+ : await storage.getAllReceipts();
417
+ return j({ count: receipts.length, receipts: receipts.map(r => ({ receipt_id: r.receipt_id, drift_detected: r.drift_detected, enforcement_action: r.enforcement_action, measurement_type: r.measurement_type, timestamp: r.timestamp })) });
418
+ }
419
+ );
420
+
421
+ // ══════════════════════════════════════════════════════════════
422
+ // TOOL: get_chain_events - V3 NEW
423
+ // ══════════════════════════════════════════════════════════════
424
+ server.tool('get_chain_events', 'Get continuity chain events.',
425
+ { start_seq: z.number().optional(), end_seq: z.number().optional() },
426
+ async ({ start_seq, end_seq }) => {
427
+ const events = (start_seq !== undefined && end_seq !== undefined)
428
+ ? await storage.getEvents(start_seq, end_seq)
429
+ : await storage.getAllEvents();
430
+ return j({ count: events.length, events: events.map(e => ({ sequence_number: e.sequence_number, event_type: e.event_type, event_id: e.event_id, timestamp: e.timestamp, leaf_hash: e.leaf_hash.slice(0, 16) + '...' })) });
431
+ }
432
+ );
433
+
434
+ return server;
435
+ }
@@ -0,0 +1,3 @@
1
+ export type { AGAStorage } from './interface.js';
2
+ export { MemoryStorage } from './memory.js';
3
+ export { SQLiteStorage } from './sqlite.js';
@@ -0,0 +1,21 @@
1
+ import type { PolicyArtifact, ContinuityEvent, SignedReceipt, CheckpointReference } from '../core/types.js';
2
+
3
+ export interface AGAStorage {
4
+ initialize(): Promise<void>;
5
+ close(): Promise<void>;
6
+ storeArtifact(a: PolicyArtifact): Promise<void>;
7
+ getArtifact(sealedHash: string): Promise<PolicyArtifact | null>;
8
+ getLatestArtifact(): Promise<PolicyArtifact | null>;
9
+ storeEvent(e: ContinuityEvent): Promise<void>;
10
+ getEvent(seq: number): Promise<ContinuityEvent | null>;
11
+ getEvents(startSeq: number, endSeq: number): Promise<ContinuityEvent[]>;
12
+ getLatestEvent(): Promise<ContinuityEvent | null>;
13
+ getAllEvents(): Promise<ContinuityEvent[]>;
14
+ storeReceipt(r: SignedReceipt): Promise<void>;
15
+ getReceipt(id: string): Promise<SignedReceipt | null>;
16
+ getReceiptsByArtifact(ref: string): Promise<SignedReceipt[]>;
17
+ getAllReceipts(): Promise<SignedReceipt[]>;
18
+ storeCheckpoint(c: CheckpointReference): Promise<void>;
19
+ getLatestCheckpoint(): Promise<CheckpointReference | null>;
20
+ getCheckpoints(): Promise<CheckpointReference[]>;
21
+ }