@humain/humain-code-contracts 0.3.2
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 +51 -0
- package/README.md +92 -0
- package/dist/index.d.ts +224 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +218 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestration.d.ts +327 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/orchestration.js +307 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/rpc.d.ts +63 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +147 -0
- package/dist/rpc.js.map +1 -0
- package/dist/subagent-progress.d.ts +106 -0
- package/dist/subagent-progress.d.ts.map +1 -0
- package/dist/subagent-progress.js +440 -0
- package/dist/subagent-progress.js.map +1 -0
- package/dist/testing.d.ts +390 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +431 -0
- package/dist/testing.js.map +1 -0
- package/dist/trace-api.d.ts +293 -0
- package/dist/trace-api.d.ts.map +1 -0
- package/dist/trace-api.js +202 -0
- package/dist/trace-api.js.map +1 -0
- package/dist/trace-artifact.d.ts +94 -0
- package/dist/trace-artifact.d.ts.map +1 -0
- package/dist/trace-artifact.js +168 -0
- package/dist/trace-artifact.js.map +1 -0
- package/dist/trace-canonical.d.ts +23 -0
- package/dist/trace-canonical.d.ts.map +1 -0
- package/dist/trace-canonical.js +240 -0
- package/dist/trace-canonical.js.map +1 -0
- package/dist/trace-export.d.ts +94 -0
- package/dist/trace-export.d.ts.map +1 -0
- package/dist/trace-export.js +374 -0
- package/dist/trace-export.js.map +1 -0
- package/dist/trace-http.d.ts +1294 -0
- package/dist/trace-http.d.ts.map +1 -0
- package/dist/trace-http.js +1481 -0
- package/dist/trace-http.js.map +1 -0
- package/dist/trace-payload.d.ts +425 -0
- package/dist/trace-payload.d.ts.map +1 -0
- package/dist/trace-payload.js +1519 -0
- package/dist/trace-payload.js.map +1 -0
- package/dist/trace.d.ts +257 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +1014 -0
- package/dist/trace.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
import { Type } from "typebox";
|
|
2
|
+
import { parseDhArtifact, parseDhEvent } from "./trace.js";
|
|
3
|
+
import { parseDhExportDownload } from "./trace-api.js";
|
|
4
|
+
import { DhContractError, dhCanonicalText, dhDigestInput, parseDhRawJson } from "./trace-canonical.js";
|
|
5
|
+
import { dhStrictDtoParser, parseDhArtifactMetadataView, parseDhEventMetadataView, parseDhExportManifestHeader, parseDhExportManifestPage, } from "./trace-http.js";
|
|
6
|
+
function checkedHash(hash, bytes) {
|
|
7
|
+
const result = hash(bytes);
|
|
8
|
+
if (typeof result !== "string" || !/^[a-f0-9]{64}$/.test(result))
|
|
9
|
+
throw new DhContractError("manifest_integrity");
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
/** Binary hash chain, not a UTF-8 string containing hexadecimal digests. */
|
|
13
|
+
function rootStep(state, shard) {
|
|
14
|
+
const prefix = new TextEncoder().encode("dh.manifest-step/2\0");
|
|
15
|
+
const input = new Uint8Array(prefix.length + 64);
|
|
16
|
+
input.set(prefix);
|
|
17
|
+
for (const [index, digest] of [state.root, shard].entries())
|
|
18
|
+
for (let byte = 0; byte < 32; byte++)
|
|
19
|
+
input[prefix.length + index * 32 + byte] = Number.parseInt(digest.slice(byte * 2, byte * 2 + 2), 16);
|
|
20
|
+
return checkedHash(state.sha256Hex, input);
|
|
21
|
+
}
|
|
22
|
+
export function beginDhExportManifest(headerInput, options) {
|
|
23
|
+
if (typeof options?.sha256Hex !== "function")
|
|
24
|
+
throw new DhContractError("manifest_integrity");
|
|
25
|
+
return {
|
|
26
|
+
header: parseDhExportManifestHeader(headerInput),
|
|
27
|
+
sha256Hex: options.sha256Hex,
|
|
28
|
+
nextShard: 0,
|
|
29
|
+
eventCount: 0,
|
|
30
|
+
artifactCount: 0,
|
|
31
|
+
streamCount: 0,
|
|
32
|
+
omittedArtifactCount: 0,
|
|
33
|
+
lastKey: "",
|
|
34
|
+
root: checkedHash(options.sha256Hex, new TextEncoder().encode("dh.manifest-root/2\0")),
|
|
35
|
+
cursors: new Set(),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/** Retains one last identity and at most 1,024 navigation cursors, never all record IDs. */
|
|
39
|
+
export function acceptDhExportManifestPage(state, input) {
|
|
40
|
+
const page = parseDhExportManifestPage(input), header = state.header, shard = header.shards[state.nextShard];
|
|
41
|
+
if (!shard || page.shardIndex !== state.nextShard || page.entries.length !== shard.recordCount)
|
|
42
|
+
throw new DhContractError("manifest_invalid");
|
|
43
|
+
for (const key of [
|
|
44
|
+
"jobId",
|
|
45
|
+
"generationId",
|
|
46
|
+
"tenantScope",
|
|
47
|
+
"bindingId",
|
|
48
|
+
"cutoff",
|
|
49
|
+
"captureCutoff",
|
|
50
|
+
"contentIncluded",
|
|
51
|
+
"policyRevision",
|
|
52
|
+
])
|
|
53
|
+
if (dhCanonicalText(page[key]) !== dhCanonicalText(header[key]))
|
|
54
|
+
throw new DhContractError("manifest_integrity");
|
|
55
|
+
const { sha256: _hash, nextCursor: _cursor, ...body } = page;
|
|
56
|
+
if (page.sha256 !== shard.sha256 ||
|
|
57
|
+
checkedHash(state.sha256Hex, dhDigestInput("dh.export-shard/2", body)) !== page.sha256)
|
|
58
|
+
throw new DhContractError("manifest_integrity");
|
|
59
|
+
if ((state.nextShard === header.shardCount - 1) !== (page.nextCursor === null) ||
|
|
60
|
+
(page.nextCursor !== null && state.cursors.has(page.nextCursor)))
|
|
61
|
+
throw new DhContractError("manifest_invalid");
|
|
62
|
+
let last = state.lastKey, events = 0, artifacts = 0, streams = 0, omitted = 0;
|
|
63
|
+
for (const entry of page.entries) {
|
|
64
|
+
const key = `${entry.kind}\0${entry.id}`;
|
|
65
|
+
if (key <= last)
|
|
66
|
+
throw new DhContractError("manifest_invalid");
|
|
67
|
+
last = key;
|
|
68
|
+
if (entry.kind === "event")
|
|
69
|
+
events++;
|
|
70
|
+
else if (entry.kind === "stream")
|
|
71
|
+
streams++;
|
|
72
|
+
else {
|
|
73
|
+
artifacts++;
|
|
74
|
+
if (entry.bytes !== "included")
|
|
75
|
+
omitted++;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const root = rootStep(state, page.sha256);
|
|
79
|
+
state.root = root;
|
|
80
|
+
state.lastKey = last;
|
|
81
|
+
state.nextShard++;
|
|
82
|
+
state.eventCount += events;
|
|
83
|
+
state.artifactCount += artifacts;
|
|
84
|
+
state.streamCount += streams;
|
|
85
|
+
state.omittedArtifactCount += omitted;
|
|
86
|
+
if (page.nextCursor !== null)
|
|
87
|
+
state.cursors.add(page.nextCursor);
|
|
88
|
+
return page;
|
|
89
|
+
}
|
|
90
|
+
export function finishDhExportManifest(state) {
|
|
91
|
+
const header = state.header;
|
|
92
|
+
if (state.nextShard !== header.shardCount ||
|
|
93
|
+
state.eventCount !== header.eventCount ||
|
|
94
|
+
state.artifactCount !== header.artifactCount ||
|
|
95
|
+
state.streamCount !== header.streamCount ||
|
|
96
|
+
state.omittedArtifactCount !== header.omittedArtifactCount)
|
|
97
|
+
throw new DhContractError("manifest_invalid");
|
|
98
|
+
if (state.root !== header.manifestSha256)
|
|
99
|
+
throw new DhContractError("manifest_integrity");
|
|
100
|
+
return header;
|
|
101
|
+
}
|
|
102
|
+
// Passive bundle framing. Hashers and sequential reads are supplied by the caller.
|
|
103
|
+
export const DH_BUNDLE_MAGIC = "DH-BUNDLE/1\n";
|
|
104
|
+
const strict = (properties) => Type.Object(properties, { additionalProperties: false });
|
|
105
|
+
const count = Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER });
|
|
106
|
+
const digest = Type.String({ pattern: "^[a-f0-9]{64}$" });
|
|
107
|
+
const job = Type.String({ minLength: 1, maxLength: 256, pattern: "^[A-Za-z0-9_-]+$" });
|
|
108
|
+
function bundleFrameSchema() {
|
|
109
|
+
return strict({
|
|
110
|
+
schema: Type.Literal("dh.bundle-frame/1"),
|
|
111
|
+
kind: Type.Enum([
|
|
112
|
+
"manifest-header",
|
|
113
|
+
"manifest-page",
|
|
114
|
+
"event",
|
|
115
|
+
"artifact-metadata",
|
|
116
|
+
"artifact-bytes",
|
|
117
|
+
"end",
|
|
118
|
+
]),
|
|
119
|
+
id: Type.String({ minLength: 1, maxLength: 256, pattern: "^[\\x20-\\x7e]+$" }),
|
|
120
|
+
sizeBytes: count,
|
|
121
|
+
sha256: digest,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
export const parseDhBundleFrameHeader = dhStrictDtoParser("bundle frame", bundleFrameSchema, (frame) => {
|
|
125
|
+
const bound = frame.kind === "artifact-bytes"
|
|
126
|
+
? 67108864
|
|
127
|
+
: frame.kind === "manifest-header" || frame.kind === "manifest-page"
|
|
128
|
+
? 1048576
|
|
129
|
+
: frame.kind === "end"
|
|
130
|
+
? 4096
|
|
131
|
+
: 65536;
|
|
132
|
+
if (frame.sizeBytes > bound)
|
|
133
|
+
throw new DhContractError("too_large");
|
|
134
|
+
const valid = frame.kind === "event"
|
|
135
|
+
? /^evt_[A-Za-z0-9_-]{8,128}$/.test(frame.id)
|
|
136
|
+
: frame.kind.startsWith("artifact-")
|
|
137
|
+
? /^art_[A-Za-z0-9_-]{8,128}$/.test(frame.id)
|
|
138
|
+
: frame.kind === "manifest-page"
|
|
139
|
+
? /^(?:0|[1-9][0-9]{0,3})$/.test(frame.id) && Number(frame.id) <= 1023
|
|
140
|
+
: /^[A-Za-z0-9_-]{1,256}$/.test(frame.id);
|
|
141
|
+
if (!valid)
|
|
142
|
+
throw new DhContractError("bundle_integrity");
|
|
143
|
+
});
|
|
144
|
+
export const parseDhBundleSeal = dhStrictDtoParser("bundle seal", () => strict({
|
|
145
|
+
schema: Type.Literal("dh.bundle-seal/1"),
|
|
146
|
+
jobId: job,
|
|
147
|
+
generationId: Type.String({ pattern: "^gen_[A-Za-z0-9_-]{8,128}$" }),
|
|
148
|
+
manifestSha256: digest,
|
|
149
|
+
headerSha256: digest,
|
|
150
|
+
eventCount: count,
|
|
151
|
+
artifactCount: count,
|
|
152
|
+
streamCount: count,
|
|
153
|
+
}));
|
|
154
|
+
export function parseDhBundleHeaderLength(bytes) {
|
|
155
|
+
if (!(bytes instanceof Uint8Array) || bytes.byteLength !== 4)
|
|
156
|
+
throw new DhContractError("bundle_integrity");
|
|
157
|
+
const length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, false);
|
|
158
|
+
if (length < 1 || length > 4096)
|
|
159
|
+
throw new DhContractError("bundle_integrity");
|
|
160
|
+
return length;
|
|
161
|
+
}
|
|
162
|
+
export function assertDhExportDownloadBinding(descriptorInput, headerInput, options) {
|
|
163
|
+
const descriptor = parseDhExportDownload(descriptorInput), header = parseDhExportManifestHeader(headerInput);
|
|
164
|
+
if (descriptor.state !== "ready" ||
|
|
165
|
+
typeof options?.sha256Hex !== "function" ||
|
|
166
|
+
descriptor.manifestSha256 !== header.manifestSha256 ||
|
|
167
|
+
descriptor.headerSha256 !== checkedHash(options.sha256Hex, dhDigestInput("dh.export-header/2", header)))
|
|
168
|
+
throw new DhContractError("bundle_integrity");
|
|
169
|
+
return descriptor;
|
|
170
|
+
}
|
|
171
|
+
/** The second page scan is validated against the same sealed root before yielding members. */
|
|
172
|
+
export function beginDhBundleVerification(magic, headerInput, descriptorInput, pages, options) {
|
|
173
|
+
const expected = new TextEncoder().encode(DH_BUNDLE_MAGIC);
|
|
174
|
+
if (!(magic instanceof Uint8Array) ||
|
|
175
|
+
magic.length !== expected.length ||
|
|
176
|
+
magic.some((byte, index) => byte !== expected[index]) ||
|
|
177
|
+
typeof options?.createHasher !== "function")
|
|
178
|
+
throw new DhContractError("bundle_integrity");
|
|
179
|
+
const header = parseDhExportManifestHeader(headerInput), descriptor = assertDhExportDownloadBinding(descriptorInput, header, options);
|
|
180
|
+
const second = beginDhExportManifest(header, options);
|
|
181
|
+
function* members() {
|
|
182
|
+
for (const input of pages) {
|
|
183
|
+
const page = acceptDhExportManifestPage(second, input);
|
|
184
|
+
for (const entry of page.entries)
|
|
185
|
+
if (entry.kind !== "stream")
|
|
186
|
+
yield entry;
|
|
187
|
+
}
|
|
188
|
+
finishDhExportManifest(second);
|
|
189
|
+
}
|
|
190
|
+
const hasher = options.createHasher();
|
|
191
|
+
hasher.update(magic);
|
|
192
|
+
return {
|
|
193
|
+
header,
|
|
194
|
+
descriptor,
|
|
195
|
+
options,
|
|
196
|
+
hasher,
|
|
197
|
+
manifest: beginDhExportManifest(header, options),
|
|
198
|
+
members: members(),
|
|
199
|
+
bytes: magic.length,
|
|
200
|
+
headerRead: false,
|
|
201
|
+
sealed: false,
|
|
202
|
+
failed: false,
|
|
203
|
+
member: undefined,
|
|
204
|
+
pendingBytes: undefined,
|
|
205
|
+
frame: undefined,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function bundleFailure(state) {
|
|
209
|
+
state.failed = true;
|
|
210
|
+
throw new DhContractError("bundle_integrity");
|
|
211
|
+
}
|
|
212
|
+
export function beginDhBundleFrame(state, bytes) {
|
|
213
|
+
if (state.failed ||
|
|
214
|
+
state.sealed ||
|
|
215
|
+
state.frame ||
|
|
216
|
+
!(bytes instanceof Uint8Array) ||
|
|
217
|
+
bytes.length < 1 ||
|
|
218
|
+
bytes.length > 4096)
|
|
219
|
+
bundleFailure(state);
|
|
220
|
+
let frame;
|
|
221
|
+
try {
|
|
222
|
+
frame = parseDhBundleFrameHeader(parseDhRawJson(bytes, { maxBytes: 4096 }));
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
bundleFailure(state);
|
|
226
|
+
}
|
|
227
|
+
const canonical = new TextEncoder().encode(dhCanonicalText(frame));
|
|
228
|
+
if (bytes.length !== canonical.length || bytes.some((byte, index) => byte !== canonical[index]))
|
|
229
|
+
bundleFailure(state);
|
|
230
|
+
let kind, id;
|
|
231
|
+
if (!state.headerRead) {
|
|
232
|
+
kind = "manifest-header";
|
|
233
|
+
id = state.header.jobId;
|
|
234
|
+
}
|
|
235
|
+
else if (state.manifest.nextShard < state.header.shardCount) {
|
|
236
|
+
kind = "manifest-page";
|
|
237
|
+
id = String(state.manifest.nextShard);
|
|
238
|
+
}
|
|
239
|
+
else if (state.pendingBytes) {
|
|
240
|
+
kind = "artifact-bytes";
|
|
241
|
+
id = state.pendingBytes.id;
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
try {
|
|
245
|
+
state.member = state.members.next().value;
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
bundleFailure(state);
|
|
249
|
+
}
|
|
250
|
+
if (state.member) {
|
|
251
|
+
kind = state.member.kind === "event" ? "event" : "artifact-metadata";
|
|
252
|
+
id = state.member.id;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
kind = "end";
|
|
256
|
+
id = state.header.jobId;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (frame.kind !== kind || frame.id !== id)
|
|
260
|
+
bundleFailure(state);
|
|
261
|
+
const length = new Uint8Array(4);
|
|
262
|
+
new DataView(length.buffer).setUint32(0, bytes.length, false);
|
|
263
|
+
state.hasher.update(length);
|
|
264
|
+
state.hasher.update(bytes);
|
|
265
|
+
state.bytes += 4 + bytes.length;
|
|
266
|
+
if (state.bytes + frame.sizeBytes > state.descriptor.sizeBytes)
|
|
267
|
+
bundleFailure(state);
|
|
268
|
+
state.frame = { header: frame, hasher: state.options.createHasher(), bytes: 0 };
|
|
269
|
+
return frame;
|
|
270
|
+
}
|
|
271
|
+
/** No chunk is retained; artifact bytes can be streamed at any caller-selected chunk size. */
|
|
272
|
+
export function acceptDhBundlePayloadChunk(state, bytes) {
|
|
273
|
+
const frame = state.frame;
|
|
274
|
+
if (state.failed || !frame || !(bytes instanceof Uint8Array) || frame.bytes + bytes.length > frame.header.sizeBytes)
|
|
275
|
+
bundleFailure(state);
|
|
276
|
+
frame.hasher.update(bytes);
|
|
277
|
+
state.hasher.update(bytes);
|
|
278
|
+
frame.bytes += bytes.length;
|
|
279
|
+
state.bytes += bytes.length;
|
|
280
|
+
}
|
|
281
|
+
/** Non-byte frames require the caller's bounded raw parse; its canonical raw hash must agree with streamed bytes. */
|
|
282
|
+
export function finishDhBundleFrame(state, recordInput) {
|
|
283
|
+
const frame = state.frame;
|
|
284
|
+
if (state.failed ||
|
|
285
|
+
!frame ||
|
|
286
|
+
frame.bytes !== frame.header.sizeBytes ||
|
|
287
|
+
frame.hasher.digest("hex") !== frame.header.sha256)
|
|
288
|
+
bundleFailure(state);
|
|
289
|
+
const { kind } = frame.header;
|
|
290
|
+
try {
|
|
291
|
+
if (kind === "artifact-bytes") {
|
|
292
|
+
const entry = state.pendingBytes;
|
|
293
|
+
if (!entry ||
|
|
294
|
+
recordInput !== undefined ||
|
|
295
|
+
frame.bytes !== entry.sizeBytes ||
|
|
296
|
+
frame.header.sha256 !== entry.sha256)
|
|
297
|
+
bundleFailure(state);
|
|
298
|
+
state.pendingBytes = undefined;
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
const raw = new TextEncoder().encode(dhCanonicalText(recordInput));
|
|
302
|
+
if (raw.length !== frame.bytes || checkedHash(state.options.sha256Hex, raw) !== frame.header.sha256)
|
|
303
|
+
bundleFailure(state);
|
|
304
|
+
if (kind === "manifest-header") {
|
|
305
|
+
if (dhCanonicalText(parseDhExportManifestHeader(recordInput)) !== dhCanonicalText(state.header))
|
|
306
|
+
bundleFailure(state);
|
|
307
|
+
state.headerRead = true;
|
|
308
|
+
}
|
|
309
|
+
else if (kind === "manifest-page")
|
|
310
|
+
acceptDhExportManifestPage(state.manifest, recordInput);
|
|
311
|
+
else if (kind === "end") {
|
|
312
|
+
finishDhExportManifest(state.manifest);
|
|
313
|
+
const seal = parseDhBundleSeal(recordInput);
|
|
314
|
+
for (const key of [
|
|
315
|
+
"jobId",
|
|
316
|
+
"generationId",
|
|
317
|
+
"manifestSha256",
|
|
318
|
+
"eventCount",
|
|
319
|
+
"artifactCount",
|
|
320
|
+
"streamCount",
|
|
321
|
+
])
|
|
322
|
+
if (seal[key] !== state.header[key])
|
|
323
|
+
bundleFailure(state);
|
|
324
|
+
if (seal.headerSha256 !== state.descriptor.headerSha256)
|
|
325
|
+
bundleFailure(state);
|
|
326
|
+
state.sealed = true;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
const entry = state.member;
|
|
330
|
+
if (!entry || entry.kind === "stream")
|
|
331
|
+
bundleFailure(state);
|
|
332
|
+
const record = kind === "event"
|
|
333
|
+
? entry.representation === "content"
|
|
334
|
+
? parseDhEvent(recordInput)
|
|
335
|
+
: parseDhEventMetadataView(recordInput)
|
|
336
|
+
: entry.representation === "content"
|
|
337
|
+
? parseDhArtifact(recordInput)
|
|
338
|
+
: parseDhArtifactMetadataView(recordInput);
|
|
339
|
+
const id = "artifactId" in record ? record.artifactId : record.eventId;
|
|
340
|
+
if (id !== entry.id ||
|
|
341
|
+
record.generationId !== state.header.generationId ||
|
|
342
|
+
checkedHash(state.options.sha256Hex, dhDigestInput("dh.export-record/1", {
|
|
343
|
+
kind: entry.kind,
|
|
344
|
+
representation: entry.representation,
|
|
345
|
+
record,
|
|
346
|
+
})) !== entry.recordSha256)
|
|
347
|
+
bundleFailure(state);
|
|
348
|
+
if ("streamId" in record && record.streamId !== entry.originStreamId)
|
|
349
|
+
bundleFailure(state);
|
|
350
|
+
if ("tenantScope" in record &&
|
|
351
|
+
dhCanonicalText(record.tenantScope) !== dhCanonicalText(state.header.tenantScope))
|
|
352
|
+
bundleFailure(state);
|
|
353
|
+
if (entry.kind === "artifact") {
|
|
354
|
+
if (!("artifactId" in record) || record.sizeBytes !== entry.sizeBytes || record.sha256 !== entry.sha256)
|
|
355
|
+
bundleFailure(state);
|
|
356
|
+
if (entry.bytes === "included")
|
|
357
|
+
state.pendingBytes = entry;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
catch {
|
|
363
|
+
bundleFailure(state);
|
|
364
|
+
}
|
|
365
|
+
state.frame = undefined;
|
|
366
|
+
}
|
|
367
|
+
/** Publication is permitted only after this succeeds; the library performs no filesystem I/O. */
|
|
368
|
+
export function finishDhBundleVerification(state) {
|
|
369
|
+
if (state.failed || !state.sealed || state.frame || state.bytes !== state.descriptor.sizeBytes)
|
|
370
|
+
bundleFailure(state);
|
|
371
|
+
if (state.hasher.digest("hex") !== state.descriptor.sha256)
|
|
372
|
+
bundleFailure(state);
|
|
373
|
+
}
|
|
374
|
+
//# sourceMappingURL=trace-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-export.js","sourceRoot":"","sources":["../src/trace-export.ts"],"names":[],"mappings":"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","sourcesContent":["import { type Static, Type } from \"typebox\";\nimport { parseDhArtifact, parseDhEvent } from \"./trace.ts\";\nimport { type DhExportDownload, parseDhExportDownload } from \"./trace-api.ts\";\nimport { DhContractError, dhCanonicalText, dhDigestInput, parseDhRawJson } from \"./trace-canonical.ts\";\nimport {\n\ttype DhExportManifestHeader,\n\ttype DhExportManifestPage,\n\ttype DhManifestEntry,\n\tdhStrictDtoParser,\n\tparseDhArtifactMetadataView,\n\tparseDhEventMetadataView,\n\tparseDhExportManifestHeader,\n\tparseDhExportManifestPage,\n} from \"./trace-http.ts\";\n\nexport interface DhExportHashOptions {\n\treadonly sha256Hex: (bytes: Uint8Array) => string;\n}\nexport interface DhExportManifestValidation {\n\treadonly header: DhExportManifestHeader;\n\treadonly sha256Hex: (bytes: Uint8Array) => string;\n\tnextShard: number;\n\teventCount: number;\n\tartifactCount: number;\n\tstreamCount: number;\n\tomittedArtifactCount: number;\n\tlastKey: string;\n\troot: string;\n\treadonly cursors: Set<string>;\n}\nfunction checkedHash(hash: (bytes: Uint8Array) => string, bytes: Uint8Array): string {\n\tconst result = hash(bytes);\n\tif (typeof result !== \"string\" || !/^[a-f0-9]{64}$/.test(result)) throw new DhContractError(\"manifest_integrity\");\n\treturn result;\n}\n/** Binary hash chain, not a UTF-8 string containing hexadecimal digests. */\nfunction rootStep(state: DhExportManifestValidation, shard: string): string {\n\tconst prefix = new TextEncoder().encode(\"dh.manifest-step/2\\0\");\n\tconst input = new Uint8Array(prefix.length + 64);\n\tinput.set(prefix);\n\tfor (const [index, digest] of [state.root, shard].entries())\n\t\tfor (let byte = 0; byte < 32; byte++)\n\t\t\tinput[prefix.length + index * 32 + byte] = Number.parseInt(digest.slice(byte * 2, byte * 2 + 2), 16);\n\treturn checkedHash(state.sha256Hex, input);\n}\nexport function beginDhExportManifest(headerInput: unknown, options: DhExportHashOptions): DhExportManifestValidation {\n\tif (typeof options?.sha256Hex !== \"function\") throw new DhContractError(\"manifest_integrity\");\n\treturn {\n\t\theader: parseDhExportManifestHeader(headerInput),\n\t\tsha256Hex: options.sha256Hex,\n\t\tnextShard: 0,\n\t\teventCount: 0,\n\t\tartifactCount: 0,\n\t\tstreamCount: 0,\n\t\tomittedArtifactCount: 0,\n\t\tlastKey: \"\",\n\t\troot: checkedHash(options.sha256Hex, new TextEncoder().encode(\"dh.manifest-root/2\\0\")),\n\t\tcursors: new Set(),\n\t};\n}\n/** Retains one last identity and at most 1,024 navigation cursors, never all record IDs. */\nexport function acceptDhExportManifestPage(state: DhExportManifestValidation, input: unknown): DhExportManifestPage {\n\tconst page = parseDhExportManifestPage(input),\n\t\theader = state.header,\n\t\tshard = header.shards[state.nextShard];\n\tif (!shard || page.shardIndex !== state.nextShard || page.entries.length !== shard.recordCount)\n\t\tthrow new DhContractError(\"manifest_invalid\");\n\tfor (const key of [\n\t\t\"jobId\",\n\t\t\"generationId\",\n\t\t\"tenantScope\",\n\t\t\"bindingId\",\n\t\t\"cutoff\",\n\t\t\"captureCutoff\",\n\t\t\"contentIncluded\",\n\t\t\"policyRevision\",\n\t] as const)\n\t\tif (dhCanonicalText(page[key]) !== dhCanonicalText(header[key])) throw new DhContractError(\"manifest_integrity\");\n\tconst { sha256: _hash, nextCursor: _cursor, ...body } = page;\n\tif (\n\t\tpage.sha256 !== shard.sha256 ||\n\t\tcheckedHash(state.sha256Hex, dhDigestInput(\"dh.export-shard/2\", body)) !== page.sha256\n\t)\n\t\tthrow new DhContractError(\"manifest_integrity\");\n\tif (\n\t\t(state.nextShard === header.shardCount - 1) !== (page.nextCursor === null) ||\n\t\t(page.nextCursor !== null && state.cursors.has(page.nextCursor))\n\t)\n\t\tthrow new DhContractError(\"manifest_invalid\");\n\tlet last = state.lastKey,\n\t\tevents = 0,\n\t\tartifacts = 0,\n\t\tstreams = 0,\n\t\tomitted = 0;\n\tfor (const entry of page.entries) {\n\t\tconst key = `${entry.kind}\\0${entry.id}`;\n\t\tif (key <= last) throw new DhContractError(\"manifest_invalid\");\n\t\tlast = key;\n\t\tif (entry.kind === \"event\") events++;\n\t\telse if (entry.kind === \"stream\") streams++;\n\t\telse {\n\t\t\tartifacts++;\n\t\t\tif (entry.bytes !== \"included\") omitted++;\n\t\t}\n\t}\n\tconst root = rootStep(state, page.sha256);\n\tstate.root = root;\n\tstate.lastKey = last;\n\tstate.nextShard++;\n\tstate.eventCount += events;\n\tstate.artifactCount += artifacts;\n\tstate.streamCount += streams;\n\tstate.omittedArtifactCount += omitted;\n\tif (page.nextCursor !== null) state.cursors.add(page.nextCursor);\n\treturn page;\n}\nexport function finishDhExportManifest(state: DhExportManifestValidation): DhExportManifestHeader {\n\tconst header = state.header;\n\tif (\n\t\tstate.nextShard !== header.shardCount ||\n\t\tstate.eventCount !== header.eventCount ||\n\t\tstate.artifactCount !== header.artifactCount ||\n\t\tstate.streamCount !== header.streamCount ||\n\t\tstate.omittedArtifactCount !== header.omittedArtifactCount\n\t)\n\t\tthrow new DhContractError(\"manifest_invalid\");\n\tif (state.root !== header.manifestSha256) throw new DhContractError(\"manifest_integrity\");\n\treturn header;\n}\n\n// Passive bundle framing. Hashers and sequential reads are supplied by the caller.\nexport const DH_BUNDLE_MAGIC = \"DH-BUNDLE/1\\n\" as const;\nconst strict = <const T extends Parameters<typeof Type.Object>[0]>(properties: T) =>\n\tType.Object(properties, { additionalProperties: false });\nconst count = Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER });\nconst digest = Type.String({ pattern: \"^[a-f0-9]{64}$\" });\nconst job = Type.String({ minLength: 1, maxLength: 256, pattern: \"^[A-Za-z0-9_-]+$\" });\nfunction bundleFrameSchema() {\n\treturn strict({\n\t\tschema: Type.Literal(\"dh.bundle-frame/1\"),\n\t\tkind: Type.Enum([\n\t\t\t\"manifest-header\",\n\t\t\t\"manifest-page\",\n\t\t\t\"event\",\n\t\t\t\"artifact-metadata\",\n\t\t\t\"artifact-bytes\",\n\t\t\t\"end\",\n\t\t] as const),\n\t\tid: Type.String({ minLength: 1, maxLength: 256, pattern: \"^[\\\\x20-\\\\x7e]+$\" }),\n\t\tsizeBytes: count,\n\t\tsha256: digest,\n\t});\n}\nexport const parseDhBundleFrameHeader = dhStrictDtoParser(\"bundle frame\", bundleFrameSchema, (frame) => {\n\tconst bound =\n\t\tframe.kind === \"artifact-bytes\"\n\t\t\t? 67108864\n\t\t\t: frame.kind === \"manifest-header\" || frame.kind === \"manifest-page\"\n\t\t\t\t? 1048576\n\t\t\t\t: frame.kind === \"end\"\n\t\t\t\t\t? 4096\n\t\t\t\t\t: 65536;\n\tif (frame.sizeBytes > bound) throw new DhContractError(\"too_large\");\n\tconst valid =\n\t\tframe.kind === \"event\"\n\t\t\t? /^evt_[A-Za-z0-9_-]{8,128}$/.test(frame.id)\n\t\t\t: frame.kind.startsWith(\"artifact-\")\n\t\t\t\t? /^art_[A-Za-z0-9_-]{8,128}$/.test(frame.id)\n\t\t\t\t: frame.kind === \"manifest-page\"\n\t\t\t\t\t? /^(?:0|[1-9][0-9]{0,3})$/.test(frame.id) && Number(frame.id) <= 1023\n\t\t\t\t\t: /^[A-Za-z0-9_-]{1,256}$/.test(frame.id);\n\tif (!valid) throw new DhContractError(\"bundle_integrity\");\n});\nexport type DhBundleFrameHeader = Static<ReturnType<typeof bundleFrameSchema>>;\nexport const parseDhBundleSeal = dhStrictDtoParser(\"bundle seal\", () =>\n\tstrict({\n\t\tschema: Type.Literal(\"dh.bundle-seal/1\"),\n\t\tjobId: job,\n\t\tgenerationId: Type.String({ pattern: \"^gen_[A-Za-z0-9_-]{8,128}$\" }),\n\t\tmanifestSha256: digest,\n\t\theaderSha256: digest,\n\t\teventCount: count,\n\t\tartifactCount: count,\n\t\tstreamCount: count,\n\t}),\n);\nexport type DhBundleSeal = ReturnType<typeof parseDhBundleSeal>;\nexport function parseDhBundleHeaderLength(bytes: Uint8Array): number {\n\tif (!(bytes instanceof Uint8Array) || bytes.byteLength !== 4) throw new DhContractError(\"bundle_integrity\");\n\tconst length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0, false);\n\tif (length < 1 || length > 4096) throw new DhContractError(\"bundle_integrity\");\n\treturn length;\n}\nexport function assertDhExportDownloadBinding(\n\tdescriptorInput: unknown,\n\theaderInput: unknown,\n\toptions: DhExportHashOptions,\n): Extract<DhExportDownload, { state: \"ready\" }> {\n\tconst descriptor = parseDhExportDownload(descriptorInput),\n\t\theader = parseDhExportManifestHeader(headerInput);\n\tif (\n\t\tdescriptor.state !== \"ready\" ||\n\t\ttypeof options?.sha256Hex !== \"function\" ||\n\t\tdescriptor.manifestSha256 !== header.manifestSha256 ||\n\t\tdescriptor.headerSha256 !== checkedHash(options.sha256Hex, dhDigestInput(\"dh.export-header/2\", header))\n\t)\n\t\tthrow new DhContractError(\"bundle_integrity\");\n\treturn descriptor;\n}\nexport interface DhBundleHasher {\n\tupdate(bytes: Uint8Array): unknown;\n\tdigest(encoding: \"hex\"): string;\n}\nexport interface DhBundleHashOptions extends DhExportHashOptions {\n\treadonly createHasher: () => DhBundleHasher;\n}\nexport interface DhBundleVerification {\n\treadonly header: DhExportManifestHeader;\n\treadonly descriptor: Extract<DhExportDownload, { state: \"ready\" }>;\n\treadonly options: DhBundleHashOptions;\n\treadonly hasher: DhBundleHasher;\n\treadonly manifest: DhExportManifestValidation;\n\treadonly members: Iterator<DhManifestEntry>;\n\tbytes: number;\n\theaderRead: boolean;\n\tsealed: boolean;\n\tfailed: boolean;\n\tmember: DhManifestEntry | undefined;\n\tpendingBytes: Extract<DhManifestEntry, { kind: \"artifact\" }> | undefined;\n\tframe: { header: DhBundleFrameHeader; hasher: DhBundleHasher; bytes: number } | undefined;\n}\n/** The second page scan is validated against the same sealed root before yielding members. */\nexport function beginDhBundleVerification(\n\tmagic: Uint8Array,\n\theaderInput: unknown,\n\tdescriptorInput: unknown,\n\tpages: Iterable<unknown>,\n\toptions: DhBundleHashOptions,\n): DhBundleVerification {\n\tconst expected = new TextEncoder().encode(DH_BUNDLE_MAGIC);\n\tif (\n\t\t!(magic instanceof Uint8Array) ||\n\t\tmagic.length !== expected.length ||\n\t\tmagic.some((byte, index) => byte !== expected[index]) ||\n\t\ttypeof options?.createHasher !== \"function\"\n\t)\n\t\tthrow new DhContractError(\"bundle_integrity\");\n\tconst header = parseDhExportManifestHeader(headerInput),\n\t\tdescriptor = assertDhExportDownloadBinding(descriptorInput, header, options);\n\tconst second = beginDhExportManifest(header, options);\n\tfunction* members(): Generator<DhManifestEntry> {\n\t\tfor (const input of pages) {\n\t\t\tconst page = acceptDhExportManifestPage(second, input);\n\t\t\tfor (const entry of page.entries) if (entry.kind !== \"stream\") yield entry;\n\t\t}\n\t\tfinishDhExportManifest(second);\n\t}\n\tconst hasher = options.createHasher();\n\thasher.update(magic);\n\treturn {\n\t\theader,\n\t\tdescriptor,\n\t\toptions,\n\t\thasher,\n\t\tmanifest: beginDhExportManifest(header, options),\n\t\tmembers: members(),\n\t\tbytes: magic.length,\n\t\theaderRead: false,\n\t\tsealed: false,\n\t\tfailed: false,\n\t\tmember: undefined,\n\t\tpendingBytes: undefined,\n\t\tframe: undefined,\n\t};\n}\nfunction bundleFailure(state: DhBundleVerification): never {\n\tstate.failed = true;\n\tthrow new DhContractError(\"bundle_integrity\");\n}\nexport function beginDhBundleFrame(state: DhBundleVerification, bytes: Uint8Array): DhBundleFrameHeader {\n\tif (\n\t\tstate.failed ||\n\t\tstate.sealed ||\n\t\tstate.frame ||\n\t\t!(bytes instanceof Uint8Array) ||\n\t\tbytes.length < 1 ||\n\t\tbytes.length > 4096\n\t)\n\t\tbundleFailure(state);\n\tlet frame: DhBundleFrameHeader;\n\ttry {\n\t\tframe = parseDhBundleFrameHeader(parseDhRawJson(bytes, { maxBytes: 4096 }));\n\t} catch {\n\t\tbundleFailure(state);\n\t}\n\tconst canonical = new TextEncoder().encode(dhCanonicalText(frame));\n\tif (bytes.length !== canonical.length || bytes.some((byte, index) => byte !== canonical[index]))\n\t\tbundleFailure(state);\n\tlet kind: DhBundleFrameHeader[\"kind\"], id: string;\n\tif (!state.headerRead) {\n\t\tkind = \"manifest-header\";\n\t\tid = state.header.jobId;\n\t} else if (state.manifest.nextShard < state.header.shardCount) {\n\t\tkind = \"manifest-page\";\n\t\tid = String(state.manifest.nextShard);\n\t} else if (state.pendingBytes) {\n\t\tkind = \"artifact-bytes\";\n\t\tid = state.pendingBytes.id;\n\t} else {\n\t\ttry {\n\t\t\tstate.member = state.members.next().value;\n\t\t} catch {\n\t\t\tbundleFailure(state);\n\t\t}\n\t\tif (state.member) {\n\t\t\tkind = state.member.kind === \"event\" ? \"event\" : \"artifact-metadata\";\n\t\t\tid = state.member.id;\n\t\t} else {\n\t\t\tkind = \"end\";\n\t\t\tid = state.header.jobId;\n\t\t}\n\t}\n\tif (frame.kind !== kind || frame.id !== id) bundleFailure(state);\n\tconst length = new Uint8Array(4);\n\tnew DataView(length.buffer).setUint32(0, bytes.length, false);\n\tstate.hasher.update(length);\n\tstate.hasher.update(bytes);\n\tstate.bytes += 4 + bytes.length;\n\tif (state.bytes + frame.sizeBytes > state.descriptor.sizeBytes) bundleFailure(state);\n\tstate.frame = { header: frame, hasher: state.options.createHasher(), bytes: 0 };\n\treturn frame;\n}\n/** No chunk is retained; artifact bytes can be streamed at any caller-selected chunk size. */\nexport function acceptDhBundlePayloadChunk(state: DhBundleVerification, bytes: Uint8Array): void {\n\tconst frame = state.frame;\n\tif (state.failed || !frame || !(bytes instanceof Uint8Array) || frame.bytes + bytes.length > frame.header.sizeBytes)\n\t\tbundleFailure(state);\n\tframe.hasher.update(bytes);\n\tstate.hasher.update(bytes);\n\tframe.bytes += bytes.length;\n\tstate.bytes += bytes.length;\n}\n/** Non-byte frames require the caller's bounded raw parse; its canonical raw hash must agree with streamed bytes. */\nexport function finishDhBundleFrame(state: DhBundleVerification, recordInput?: unknown): void {\n\tconst frame = state.frame;\n\tif (\n\t\tstate.failed ||\n\t\t!frame ||\n\t\tframe.bytes !== frame.header.sizeBytes ||\n\t\tframe.hasher.digest(\"hex\") !== frame.header.sha256\n\t)\n\t\tbundleFailure(state);\n\tconst { kind } = frame.header;\n\ttry {\n\t\tif (kind === \"artifact-bytes\") {\n\t\t\tconst entry = state.pendingBytes;\n\t\t\tif (\n\t\t\t\t!entry ||\n\t\t\t\trecordInput !== undefined ||\n\t\t\t\tframe.bytes !== entry.sizeBytes ||\n\t\t\t\tframe.header.sha256 !== entry.sha256\n\t\t\t)\n\t\t\t\tbundleFailure(state);\n\t\t\tstate.pendingBytes = undefined;\n\t\t} else {\n\t\t\tconst raw = new TextEncoder().encode(dhCanonicalText(recordInput));\n\t\t\tif (raw.length !== frame.bytes || checkedHash(state.options.sha256Hex, raw) !== frame.header.sha256)\n\t\t\t\tbundleFailure(state);\n\t\t\tif (kind === \"manifest-header\") {\n\t\t\t\tif (dhCanonicalText(parseDhExportManifestHeader(recordInput)) !== dhCanonicalText(state.header))\n\t\t\t\t\tbundleFailure(state);\n\t\t\t\tstate.headerRead = true;\n\t\t\t} else if (kind === \"manifest-page\") acceptDhExportManifestPage(state.manifest, recordInput);\n\t\t\telse if (kind === \"end\") {\n\t\t\t\tfinishDhExportManifest(state.manifest);\n\t\t\t\tconst seal = parseDhBundleSeal(recordInput);\n\t\t\t\tfor (const key of [\n\t\t\t\t\t\"jobId\",\n\t\t\t\t\t\"generationId\",\n\t\t\t\t\t\"manifestSha256\",\n\t\t\t\t\t\"eventCount\",\n\t\t\t\t\t\"artifactCount\",\n\t\t\t\t\t\"streamCount\",\n\t\t\t\t] as const)\n\t\t\t\t\tif (seal[key] !== state.header[key]) bundleFailure(state);\n\t\t\t\tif (seal.headerSha256 !== state.descriptor.headerSha256) bundleFailure(state);\n\t\t\t\tstate.sealed = true;\n\t\t\t} else {\n\t\t\t\tconst entry = state.member;\n\t\t\t\tif (!entry || entry.kind === \"stream\") bundleFailure(state);\n\t\t\t\tconst record =\n\t\t\t\t\tkind === \"event\"\n\t\t\t\t\t\t? entry.representation === \"content\"\n\t\t\t\t\t\t\t? parseDhEvent(recordInput)\n\t\t\t\t\t\t\t: parseDhEventMetadataView(recordInput)\n\t\t\t\t\t\t: entry.representation === \"content\"\n\t\t\t\t\t\t\t? parseDhArtifact(recordInput)\n\t\t\t\t\t\t\t: parseDhArtifactMetadataView(recordInput);\n\t\t\t\tconst id = \"artifactId\" in record ? record.artifactId : record.eventId;\n\t\t\t\tif (\n\t\t\t\t\tid !== entry.id ||\n\t\t\t\t\trecord.generationId !== state.header.generationId ||\n\t\t\t\t\tcheckedHash(\n\t\t\t\t\t\tstate.options.sha256Hex,\n\t\t\t\t\t\tdhDigestInput(\"dh.export-record/1\", {\n\t\t\t\t\t\t\tkind: entry.kind,\n\t\t\t\t\t\t\trepresentation: entry.representation,\n\t\t\t\t\t\t\trecord,\n\t\t\t\t\t\t}),\n\t\t\t\t\t) !== entry.recordSha256\n\t\t\t\t)\n\t\t\t\t\tbundleFailure(state);\n\t\t\t\tif (\"streamId\" in record && record.streamId !== entry.originStreamId) bundleFailure(state);\n\t\t\t\tif (\n\t\t\t\t\t\"tenantScope\" in record &&\n\t\t\t\t\tdhCanonicalText(record.tenantScope) !== dhCanonicalText(state.header.tenantScope)\n\t\t\t\t)\n\t\t\t\t\tbundleFailure(state);\n\t\t\t\tif (entry.kind === \"artifact\") {\n\t\t\t\t\tif (!(\"artifactId\" in record) || record.sizeBytes !== entry.sizeBytes || record.sha256 !== entry.sha256)\n\t\t\t\t\t\tbundleFailure(state);\n\t\t\t\t\tif (entry.bytes === \"included\") state.pendingBytes = entry;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {\n\t\tbundleFailure(state);\n\t}\n\tstate.frame = undefined;\n}\n/** Publication is permitted only after this succeeds; the library performs no filesystem I/O. */\nexport function finishDhBundleVerification(state: DhBundleVerification): void {\n\tif (state.failed || !state.sealed || state.frame || state.bytes !== state.descriptor.sizeBytes) bundleFailure(state);\n\tif (state.hasher.digest(\"hex\") !== state.descriptor.sha256) bundleFailure(state);\n}\n"]}
|