@noeos/verification-engine 0.0.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 (184) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +201 -0
  3. package/NOTICE +11 -0
  4. package/README.md +7 -0
  5. package/dist/cjs/api/engine.js +271 -0
  6. package/dist/cjs/api/types.js +10 -0
  7. package/dist/cjs/chains/chain-builder.js +541 -0
  8. package/dist/cjs/chains/duplicate-detector.js +208 -0
  9. package/dist/cjs/chains/verify-chain.js +656 -0
  10. package/dist/cjs/contracts/generated.js +512 -0
  11. package/dist/cjs/contracts/schema-assets.js +6 -0
  12. package/dist/cjs/contracts/vector-assets.js +6 -0
  13. package/dist/cjs/domain/algorithm-id.js +5 -0
  14. package/dist/cjs/domain/byte-view.js +7 -0
  15. package/dist/cjs/domain/chain.js +3 -0
  16. package/dist/cjs/domain/diagnostic.js +6 -0
  17. package/dist/cjs/domain/digest.js +37 -0
  18. package/dist/cjs/domain/duplicate-policy.js +3 -0
  19. package/dist/cjs/domain/evidence.js +10 -0
  20. package/dist/cjs/domain/identifiers.js +52 -0
  21. package/dist/cjs/domain/json-value.js +3 -0
  22. package/dist/cjs/domain/limits.js +24 -0
  23. package/dist/cjs/domain/operation-result.js +19 -0
  24. package/dist/cjs/domain/position.js +16 -0
  25. package/dist/cjs/domain/protocol-version.js +5 -0
  26. package/dist/cjs/domain/rule.js +3 -0
  27. package/dist/cjs/domain/stream.js +3 -0
  28. package/dist/cjs/domain/version.js +16 -0
  29. package/dist/cjs/evidence/digest-evidence.js +22 -0
  30. package/dist/cjs/evidence/evidence-parser.js +288 -0
  31. package/dist/cjs/framing/frame-builders.js +124 -0
  32. package/dist/cjs/framing/frame-encoder.js +238 -0
  33. package/dist/cjs/framing/frame-parser.js +173 -0
  34. package/dist/cjs/framing/frame-types.js +3 -0
  35. package/dist/cjs/hashing/hash-adapter.js +90 -0
  36. package/dist/cjs/hashing/hash-frame.js +16 -0
  37. package/dist/cjs/index.js +16 -0
  38. package/dist/cjs/normalization/byte-sink.js +70 -0
  39. package/dist/cjs/normalization/jcs-profile.js +154 -0
  40. package/dist/cjs/normalization/normalize.js +56 -0
  41. package/dist/cjs/normalization/profile-registry.js +66 -0
  42. package/dist/cjs/normalization/profile.js +3 -0
  43. package/dist/cjs/normalization/raw-bytes-profile.js +27 -0
  44. package/dist/cjs/package.json +3 -0
  45. package/dist/cjs/profiles.js +9 -0
  46. package/dist/cjs/records/record-service.js +278 -0
  47. package/dist/cjs/rules/rule-set.js +211 -0
  48. package/dist/cjs/schemas.js +6 -0
  49. package/dist/cjs/validation/algorithm-validation.js +12 -0
  50. package/dist/cjs/validation/diagnostic-collector.js +159 -0
  51. package/dist/cjs/validation/digest-validation.js +48 -0
  52. package/dist/cjs/validation/identifier-validation.js +33 -0
  53. package/dist/cjs/validation/json-text-parser.js +297 -0
  54. package/dist/cjs/validation/json-value-validation.js +155 -0
  55. package/dist/cjs/validation/limit-validation.js +75 -0
  56. package/dist/cjs/validation/object-inspection.js +60 -0
  57. package/dist/cjs/validation/position-validation.js +13 -0
  58. package/dist/cjs/validation/result-helpers.js +9 -0
  59. package/dist/cjs/validation/utf8-validation.js +69 -0
  60. package/dist/cjs/validation/version-validation.js +31 -0
  61. package/dist/cjs/vectors.js +6 -0
  62. package/dist/esm/api/engine.js +266 -0
  63. package/dist/esm/api/types.js +4 -0
  64. package/dist/esm/chains/chain-builder.js +536 -0
  65. package/dist/esm/chains/duplicate-detector.js +204 -0
  66. package/dist/esm/chains/verify-chain.js +652 -0
  67. package/dist/esm/contracts/generated.js +509 -0
  68. package/dist/esm/contracts/schema-assets.js +2 -0
  69. package/dist/esm/contracts/vector-assets.js +2 -0
  70. package/dist/esm/domain/algorithm-id.js +2 -0
  71. package/dist/esm/domain/byte-view.js +4 -0
  72. package/dist/esm/domain/chain.js +2 -0
  73. package/dist/esm/domain/diagnostic.js +3 -0
  74. package/dist/esm/domain/digest.js +32 -0
  75. package/dist/esm/domain/duplicate-policy.js +2 -0
  76. package/dist/esm/domain/evidence.js +7 -0
  77. package/dist/esm/domain/identifiers.js +45 -0
  78. package/dist/esm/domain/json-value.js +2 -0
  79. package/dist/esm/domain/limits.js +21 -0
  80. package/dist/esm/domain/operation-result.js +15 -0
  81. package/dist/esm/domain/position.js +12 -0
  82. package/dist/esm/domain/protocol-version.js +2 -0
  83. package/dist/esm/domain/rule.js +2 -0
  84. package/dist/esm/domain/stream.js +2 -0
  85. package/dist/esm/domain/version.js +12 -0
  86. package/dist/esm/evidence/digest-evidence.js +19 -0
  87. package/dist/esm/evidence/evidence-parser.js +281 -0
  88. package/dist/esm/framing/frame-builders.js +114 -0
  89. package/dist/esm/framing/frame-encoder.js +234 -0
  90. package/dist/esm/framing/frame-parser.js +170 -0
  91. package/dist/esm/framing/frame-types.js +2 -0
  92. package/dist/esm/hashing/hash-adapter.js +84 -0
  93. package/dist/esm/hashing/hash-frame.js +12 -0
  94. package/dist/esm/index.js +5 -0
  95. package/dist/esm/normalization/byte-sink.js +66 -0
  96. package/dist/esm/normalization/jcs-profile.js +151 -0
  97. package/dist/esm/normalization/normalize.js +52 -0
  98. package/dist/esm/normalization/profile-registry.js +62 -0
  99. package/dist/esm/normalization/profile.js +2 -0
  100. package/dist/esm/normalization/raw-bytes-profile.js +24 -0
  101. package/dist/esm/profiles.js +6 -0
  102. package/dist/esm/records/record-service.js +270 -0
  103. package/dist/esm/rules/rule-set.js +206 -0
  104. package/dist/esm/schemas.js +2 -0
  105. package/dist/esm/validation/algorithm-validation.js +9 -0
  106. package/dist/esm/validation/diagnostic-collector.js +154 -0
  107. package/dist/esm/validation/digest-validation.js +43 -0
  108. package/dist/esm/validation/identifier-validation.js +27 -0
  109. package/dist/esm/validation/json-text-parser.js +294 -0
  110. package/dist/esm/validation/json-value-validation.js +152 -0
  111. package/dist/esm/validation/limit-validation.js +71 -0
  112. package/dist/esm/validation/object-inspection.js +54 -0
  113. package/dist/esm/validation/position-validation.js +10 -0
  114. package/dist/esm/validation/result-helpers.js +6 -0
  115. package/dist/esm/validation/utf8-validation.js +63 -0
  116. package/dist/esm/validation/version-validation.js +26 -0
  117. package/dist/esm/vectors.js +2 -0
  118. package/dist/types/api/engine.d.ts +8 -0
  119. package/dist/types/api/types.d.ts +124 -0
  120. package/dist/types/chains/chain-builder.d.ts +42 -0
  121. package/dist/types/chains/duplicate-detector.d.ts +18 -0
  122. package/dist/types/chains/verify-chain.d.ts +9 -0
  123. package/dist/types/contracts/generated.d.ts +442 -0
  124. package/dist/types/contracts/schema-assets.d.ts +2 -0
  125. package/dist/types/contracts/vector-assets.d.ts +2 -0
  126. package/dist/types/domain/algorithm-id.d.ts +4 -0
  127. package/dist/types/domain/byte-view.d.ts +1 -0
  128. package/dist/types/domain/chain.d.ts +43 -0
  129. package/dist/types/domain/diagnostic.d.ts +23 -0
  130. package/dist/types/domain/digest.d.ts +12 -0
  131. package/dist/types/domain/duplicate-policy.d.ts +26 -0
  132. package/dist/types/domain/evidence.d.ts +100 -0
  133. package/dist/types/domain/identifiers.d.ts +29 -0
  134. package/dist/types/domain/json-value.d.ts +6 -0
  135. package/dist/types/domain/limits.d.ts +13 -0
  136. package/dist/types/domain/operation-result.d.ts +12 -0
  137. package/dist/types/domain/position.d.ts +8 -0
  138. package/dist/types/domain/protocol-version.d.ts +2 -0
  139. package/dist/types/domain/rule.d.ts +34 -0
  140. package/dist/types/domain/stream.d.ts +5 -0
  141. package/dist/types/domain/version.d.ts +8 -0
  142. package/dist/types/evidence/digest-evidence.d.ts +4 -0
  143. package/dist/types/evidence/evidence-parser.d.ts +8 -0
  144. package/dist/types/framing/frame-builders.d.ts +40 -0
  145. package/dist/types/framing/frame-encoder.d.ts +6 -0
  146. package/dist/types/framing/frame-parser.d.ts +4 -0
  147. package/dist/types/framing/frame-types.d.ts +27 -0
  148. package/dist/types/hashing/hash-adapter.d.ts +12 -0
  149. package/dist/types/hashing/hash-frame.d.ts +6 -0
  150. package/dist/types/index.d.ts +8 -0
  151. package/dist/types/normalization/byte-sink.d.ts +19 -0
  152. package/dist/types/normalization/jcs-profile.d.ts +3 -0
  153. package/dist/types/normalization/normalize.d.ts +11 -0
  154. package/dist/types/normalization/profile-registry.d.ts +26 -0
  155. package/dist/types/normalization/profile.d.ts +22 -0
  156. package/dist/types/normalization/raw-bytes-profile.d.ts +2 -0
  157. package/dist/types/profiles.d.ts +8 -0
  158. package/dist/types/records/record-service.d.ts +38 -0
  159. package/dist/types/rules/rule-set.d.ts +13 -0
  160. package/dist/types/schemas.d.ts +2 -0
  161. package/dist/types/validation/algorithm-validation.d.ts +3 -0
  162. package/dist/types/validation/diagnostic-collector.d.ts +24 -0
  163. package/dist/types/validation/digest-validation.d.ts +6 -0
  164. package/dist/types/validation/identifier-validation.d.ts +6 -0
  165. package/dist/types/validation/json-text-parser.d.ts +4 -0
  166. package/dist/types/validation/json-value-validation.d.ts +4 -0
  167. package/dist/types/validation/limit-validation.d.ts +4 -0
  168. package/dist/types/validation/object-inspection.d.ts +11 -0
  169. package/dist/types/validation/position-validation.d.ts +3 -0
  170. package/dist/types/validation/result-helpers.d.ts +3 -0
  171. package/dist/types/validation/utf8-validation.d.ts +5 -0
  172. package/dist/types/validation/version-validation.d.ts +9 -0
  173. package/dist/types/vectors.d.ts +2 -0
  174. package/package.json +61 -0
  175. package/schemas/chain-summary.v1.schema.json +156 -0
  176. package/schemas/diagnostic.v1.schema.json +107 -0
  177. package/schemas/link-evidence.v1.schema.json +165 -0
  178. package/schemas/record-evidence.v1.schema.json +91 -0
  179. package/schemas/vector-set.v1.schema.json +52 -0
  180. package/vectors/evidence.json +26 -0
  181. package/vectors/framing.json +136 -0
  182. package/vectors/hashing.json +58 -0
  183. package/vectors/invalid.json +56 -0
  184. package/vectors/manifest.json +46 -0
@@ -0,0 +1,204 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { failure, success } from "../domain/operation-result.js";
3
+ import { createDiagnostic, DiagnosticCollector } from "../validation/diagnostic-collector.js";
4
+ import { inspectPlainObject } from "../validation/object-inspection.js";
5
+ export function createDuplicateDetector(policy, limits) {
6
+ if (policy.kind === "none")
7
+ return new NoneDetector();
8
+ if (policy.kind === "external")
9
+ return new ExternalDetector(policy, limits);
10
+ return new MemoryDetector(policy, limits);
11
+ }
12
+ function observations(value) {
13
+ return Object.freeze([
14
+ Object.freeze({ kind: "record-id", key: value.recordId }),
15
+ Object.freeze({ kind: "content-digest", key: value.contentDigest }),
16
+ Object.freeze({ kind: "link-digest", key: value.linkDigest }),
17
+ Object.freeze({ kind: "fork", key: value.forkKey, value: value.linkDigest }),
18
+ ]);
19
+ }
20
+ export function observedLink(evidence) {
21
+ return Object.freeze({
22
+ recordId: evidence.recordId,
23
+ contentDigest: evidence.contentDigest,
24
+ linkDigest: evidence.linkDigest,
25
+ forkKey: `${evidence.sequenceId}\u0000${String(evidence.position)}\u0000${previousKey(evidence)}`,
26
+ });
27
+ }
28
+ class NoneDetector {
29
+ inspect() {
30
+ return success(Object.freeze([]));
31
+ }
32
+ commit() {
33
+ void 0;
34
+ }
35
+ }
36
+ class ExternalDetector {
37
+ policy;
38
+ limits;
39
+ pending;
40
+ constructor(policy, limits) {
41
+ this.policy = policy;
42
+ this.limits = limits;
43
+ }
44
+ inspect(value) {
45
+ try {
46
+ const result = this.policy.index.observe(observations(value));
47
+ if (!isOperationResult(result)) {
48
+ return failure([
49
+ createDiagnostic("INTERNAL_INVARIANT_BROKEN", "chain", {
50
+ causeCode: "DUPLICATE_INDEX_INVALID",
51
+ }),
52
+ ]);
53
+ }
54
+ if (!result.ok)
55
+ return failure(result.diagnostics);
56
+ if (!isDuplicateObservationList(result.value)) {
57
+ return failure([
58
+ createDiagnostic("INTERNAL_INVARIANT_BROKEN", "chain", {
59
+ causeCode: "DUPLICATE_INDEX_INVALID",
60
+ }),
61
+ ]);
62
+ }
63
+ this.pending = value;
64
+ return success(diagnosticsForDuplicates(result.value, this.limits));
65
+ }
66
+ catch {
67
+ return failure([
68
+ createDiagnostic("INTERNAL_INVARIANT_BROKEN", "chain", {
69
+ causeCode: "DUPLICATE_INDEX_FAILED",
70
+ }),
71
+ ]);
72
+ }
73
+ }
74
+ commit(value) {
75
+ if (this.pending !== value)
76
+ throw new Error("external duplicate transaction mismatch");
77
+ this.pending = undefined;
78
+ }
79
+ }
80
+ class MemoryDetector {
81
+ policy;
82
+ limits;
83
+ recordIds = new Map();
84
+ contents = new Map();
85
+ links = new Map();
86
+ /** A window can retain more than one observation for a fork key. Keep
87
+ * multiplicities so evicting one entry cannot erase another retained fork. */
88
+ forks = new Map();
89
+ queue = [];
90
+ constructor(policy, limits) {
91
+ this.policy = policy;
92
+ this.limits = limits;
93
+ }
94
+ inspect(value) {
95
+ if (this.policy.kind === "full" && this.queue.length >= this.policy.maxRecords) {
96
+ return failure([createDiagnostic("RESOURCE_BUDGET_EXCEEDED", "chain")]);
97
+ }
98
+ const collector = new DiagnosticCollector(this.limits);
99
+ if (this.recordIds.has(value.recordId))
100
+ collector.addCode("RECORD_ID_DUPLICATE", "chain");
101
+ if (this.contents.has(value.contentDigest))
102
+ collector.addCode("CONTENT_DUPLICATE", "chain");
103
+ if (this.links.has(value.linkDigest))
104
+ collector.addCode("LINK_DIGEST_DUPLICATE", "chain");
105
+ if (hasDifferentFork(this.forks.get(value.forkKey), value.linkDigest)) {
106
+ collector.addCode("CHAIN_FORK", "chain");
107
+ }
108
+ return success(collector.finish());
109
+ }
110
+ commit(value) {
111
+ this.queue.push(value);
112
+ increment(this.recordIds, value.recordId);
113
+ increment(this.contents, value.contentDigest);
114
+ increment(this.links, value.linkDigest);
115
+ incrementNested(this.forks, value.forkKey, value.linkDigest);
116
+ if (this.policy.kind === "window" && this.queue.length > this.policy.size) {
117
+ const discarded = this.queue.shift();
118
+ if (discarded === undefined)
119
+ throw new Error("duplicate window invariant broken");
120
+ decrement(this.recordIds, discarded.recordId);
121
+ decrement(this.contents, discarded.contentDigest);
122
+ decrement(this.links, discarded.linkDigest);
123
+ decrementNested(this.forks, discarded.forkKey, discarded.linkDigest);
124
+ }
125
+ }
126
+ }
127
+ function diagnosticsForDuplicates(duplicates, limits) {
128
+ const collector = new DiagnosticCollector(limits);
129
+ for (const duplicate of duplicates) {
130
+ if (duplicate.kind === "record-id")
131
+ collector.addCode("RECORD_ID_DUPLICATE", "chain");
132
+ if (duplicate.kind === "content-digest")
133
+ collector.addCode("CONTENT_DUPLICATE", "chain");
134
+ if (duplicate.kind === "link-digest")
135
+ collector.addCode("LINK_DIGEST_DUPLICATE", "chain");
136
+ if (duplicate.kind === "fork")
137
+ collector.addCode("CHAIN_FORK", "chain");
138
+ }
139
+ return collector.finish();
140
+ }
141
+ function previousKey(value) {
142
+ return value.previous.kind === "none" ? "none" : value.previous.value;
143
+ }
144
+ function increment(values, key) {
145
+ values.set(key, (values.get(key) ?? 0) + 1);
146
+ }
147
+ function decrement(values, key) {
148
+ const count = values.get(key);
149
+ if (count === undefined)
150
+ throw new Error("duplicate counter invariant broken");
151
+ if (count === 1)
152
+ values.delete(key);
153
+ else
154
+ values.set(key, count - 1);
155
+ }
156
+ function hasDifferentFork(values, digest) {
157
+ if (values === undefined)
158
+ return false;
159
+ for (const observedDigest of values.keys())
160
+ if (observedDigest !== digest)
161
+ return true;
162
+ return false;
163
+ }
164
+ function incrementNested(values, key, value) {
165
+ const nested = values.get(key) ?? new Map();
166
+ increment(nested, value);
167
+ values.set(key, nested);
168
+ }
169
+ function decrementNested(values, key, value) {
170
+ const nested = values.get(key);
171
+ if (nested === undefined)
172
+ throw new Error("duplicate fork invariant broken");
173
+ decrement(nested, value);
174
+ if (nested.size === 0)
175
+ values.delete(key);
176
+ }
177
+ function isOperationResult(value) {
178
+ return (typeof value === "object" &&
179
+ value !== null &&
180
+ "ok" in value &&
181
+ (value.ok === true || value.ok === false) &&
182
+ "diagnostics" in value &&
183
+ Array.isArray(value.diagnostics));
184
+ }
185
+ function isDuplicateObservationList(value) {
186
+ return Array.isArray(value) && value.every(isDuplicateObservation);
187
+ }
188
+ function isDuplicateObservation(value) {
189
+ const entries = inspectPlainObject(value);
190
+ if (entries === undefined)
191
+ return false;
192
+ const fields = new Map(entries);
193
+ const kind = fields.get("kind");
194
+ const key = fields.get("key");
195
+ if (kind !== "record-id" &&
196
+ kind !== "content-digest" &&
197
+ kind !== "link-digest" &&
198
+ kind !== "fork")
199
+ return false;
200
+ if (typeof key !== "string")
201
+ return false;
202
+ const observedValue = fields.get("value");
203
+ return observedValue === undefined || typeof observedValue === "string";
204
+ }