@fluxpointstudios/orynq-sdk-process-trace 0.1.0 → 0.3.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.
- package/dist/index.cjs +574 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +573 -9
- package/dist/index.d.ts +573 -9
- package/dist/index.js +562 -9
- package/dist/index.js.map +1 -1
- package/package.json +15 -1
- package/src/__tests__/bundle.test.ts +82 -0
- package/src/__tests__/governance-round4.test.ts +149 -0
- package/src/__tests__/governance.test.ts +382 -0
- package/src/__tests__/hardening-round2.test.ts +173 -0
- package/src/__tests__/hardening-round3.test.ts +208 -0
- package/src/__tests__/model-manifest.test.ts +136 -0
- package/src/__tests__/types.test.ts +8 -2
- package/src/bundle.ts +199 -5
- package/src/governance.ts +711 -0
- package/src/index.ts +69 -0
- package/src/model-manifest.ts +0 -0
- package/src/rolling-hash.ts +15 -6
- package/src/trace-builder.ts +68 -2
- package/src/types.ts +192 -1
package/src/index.ts
CHANGED
|
@@ -52,6 +52,11 @@ export type {
|
|
|
52
52
|
ObservationEvent,
|
|
53
53
|
ErrorTraceEvent,
|
|
54
54
|
CustomEvent,
|
|
55
|
+
GovernanceAttestationEvent,
|
|
56
|
+
GovernanceSignatureScheme,
|
|
57
|
+
GovernanceEip712Binding,
|
|
58
|
+
ToolReceiptEvent,
|
|
59
|
+
ToolReceiptScheme,
|
|
55
60
|
TraceEvent,
|
|
56
61
|
TraceEventKind,
|
|
57
62
|
} from "./types.js";
|
|
@@ -90,6 +95,9 @@ export type {
|
|
|
90
95
|
TraceManifest,
|
|
91
96
|
} from "./types.js";
|
|
92
97
|
|
|
98
|
+
// Model manifest types (pre-execution pinning, issue #59)
|
|
99
|
+
export type { ModelManifest } from "./types.js";
|
|
100
|
+
|
|
93
101
|
// Disclosure types
|
|
94
102
|
export type {
|
|
95
103
|
DisclosureMode,
|
|
@@ -214,6 +222,12 @@ export {
|
|
|
214
222
|
countSpansByVisibility,
|
|
215
223
|
} from "./bundle.js";
|
|
216
224
|
|
|
225
|
+
// Bundle verification option types (governance + tool-receipt hooks)
|
|
226
|
+
export type {
|
|
227
|
+
VerifyBundleOptions,
|
|
228
|
+
ToolReceiptVerifyOutcome,
|
|
229
|
+
} from "./bundle.js";
|
|
230
|
+
|
|
217
231
|
// ---------------------------------------------------------------------------
|
|
218
232
|
// Disclosure Exports
|
|
219
233
|
// ---------------------------------------------------------------------------
|
|
@@ -254,6 +268,61 @@ export {
|
|
|
254
268
|
parseChunkContent,
|
|
255
269
|
} from "./manifest.js";
|
|
256
270
|
|
|
271
|
+
// ---------------------------------------------------------------------------
|
|
272
|
+
// Model Manifest Exports (pre-execution pinning, issue #59)
|
|
273
|
+
// ---------------------------------------------------------------------------
|
|
274
|
+
|
|
275
|
+
export {
|
|
276
|
+
// Hash + validation
|
|
277
|
+
computeModelManifestHash,
|
|
278
|
+
validateModelManifest,
|
|
279
|
+
freezeModelManifest,
|
|
280
|
+
|
|
281
|
+
// Framework builders
|
|
282
|
+
manifestFromHuggingFace,
|
|
283
|
+
manifestFromOpenAI,
|
|
284
|
+
manifestFromAnthropic,
|
|
285
|
+
manifestFromCheckpoint,
|
|
286
|
+
} from "./model-manifest.js";
|
|
287
|
+
|
|
288
|
+
export type {
|
|
289
|
+
HuggingFaceManifestOptions,
|
|
290
|
+
OpenAIManifestOptions,
|
|
291
|
+
AnthropicManifestOptions,
|
|
292
|
+
CheckpointManifestOptions,
|
|
293
|
+
} from "./model-manifest.js";
|
|
294
|
+
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
// Governance Attestation Exports (issue #58)
|
|
297
|
+
// ---------------------------------------------------------------------------
|
|
298
|
+
|
|
299
|
+
export {
|
|
300
|
+
// Preimage + helper
|
|
301
|
+
governanceAttestationPreimage,
|
|
302
|
+
addGovernanceAttestation,
|
|
303
|
+
|
|
304
|
+
// Built-in signers (sr25519 / ed25519 via optional @polkadot peer dep)
|
|
305
|
+
createSr25519GovernanceSigner,
|
|
306
|
+
createEd25519GovernanceSigner,
|
|
307
|
+
SS58_PREFIX,
|
|
308
|
+
|
|
309
|
+
// Verification
|
|
310
|
+
verifyGovernanceAttestations,
|
|
311
|
+
createEip712GovernanceVerifier,
|
|
312
|
+
} from "./governance.js";
|
|
313
|
+
|
|
314
|
+
export type {
|
|
315
|
+
GovernanceSigner,
|
|
316
|
+
GovernanceSignContext,
|
|
317
|
+
GovernanceAttestationFields,
|
|
318
|
+
GovernanceVerifier,
|
|
319
|
+
GovernanceVerifyContext,
|
|
320
|
+
SubstrateGovernanceSignerOptions,
|
|
321
|
+
AddGovernanceAttestationOptions,
|
|
322
|
+
GovernanceAttestationSummary,
|
|
323
|
+
VerifyGovernanceOptions,
|
|
324
|
+
} from "./governance.js";
|
|
325
|
+
|
|
257
326
|
// ---------------------------------------------------------------------------
|
|
258
327
|
// Version
|
|
259
328
|
// ---------------------------------------------------------------------------
|
|
Binary file
|
package/src/rolling-hash.ts
CHANGED
|
@@ -284,30 +284,34 @@ function constantTimeCompare(a: string, b: string): boolean {
|
|
|
284
284
|
// -----------------------------------------------------------------------------
|
|
285
285
|
|
|
286
286
|
/**
|
|
287
|
-
* Compute the final root hash from rolling hash and
|
|
287
|
+
* Compute the final root hash from rolling hash, span hashes, and (when pinned)
|
|
288
|
+
* the model-manifest commitment.
|
|
288
289
|
*
|
|
289
290
|
* The root hash is computed as:
|
|
290
|
-
* `H("poi-trace:root:v1|" + rollingHash + "|" + spanHash1 + "|" +
|
|
291
|
+
* `H("poi-trace:root:v1|" + rollingHash + "|" + spanHash1 + "|" + ... [+ "|manifest:" + modelManifestHash])`
|
|
291
292
|
*
|
|
292
293
|
* Spans are sorted by their `spanSeq` field before joining to ensure
|
|
293
|
-
* deterministic ordering.
|
|
294
|
-
*
|
|
294
|
+
* deterministic ordering. Folding `modelManifestHash` in binds the pinned
|
|
295
|
+
* model/data manifest to the committed root (issue #59): swapping the manifest
|
|
296
|
+
* after commitment changes the recomputed root and fails verification.
|
|
295
297
|
*
|
|
296
298
|
* @param rollingHash - The final rolling hash from all events
|
|
297
299
|
* @param spans - Array of trace spans (must have hash field populated)
|
|
300
|
+
* @param modelManifestHash - Optional pre-execution model-manifest commitment to bind
|
|
298
301
|
* @returns Promise resolving to the root hash as a hex string
|
|
299
302
|
*
|
|
300
303
|
* @example
|
|
301
304
|
* ```typescript
|
|
302
305
|
* const rollingHash = await computeRollingHash(events);
|
|
303
|
-
* const rootHash = await computeRootHash(rollingHash, spans);
|
|
306
|
+
* const rootHash = await computeRootHash(rollingHash, spans, run.modelManifestHash);
|
|
304
307
|
*
|
|
305
308
|
* // rootHash can now be published as the trace commitment
|
|
306
309
|
* ```
|
|
307
310
|
*/
|
|
308
311
|
export async function computeRootHash(
|
|
309
312
|
rollingHash: string,
|
|
310
|
-
spans: TraceSpan[]
|
|
313
|
+
spans: TraceSpan[],
|
|
314
|
+
modelManifestHash?: string
|
|
311
315
|
): Promise<string> {
|
|
312
316
|
// Sort spans by spanSeq for deterministic ordering
|
|
313
317
|
const sortedSpans = [...spans].sort((a, b) => a.spanSeq - b.spanSeq);
|
|
@@ -328,6 +332,11 @@ export async function computeRootHash(
|
|
|
328
332
|
input += "|" + spanHashes.join("|");
|
|
329
333
|
}
|
|
330
334
|
|
|
335
|
+
// Bind the pinned model-manifest commitment into the committed root (#59).
|
|
336
|
+
if (modelManifestHash !== undefined && modelManifestHash.length > 0) {
|
|
337
|
+
input += "|manifest:" + modelManifestHash;
|
|
338
|
+
}
|
|
339
|
+
|
|
331
340
|
return sha256StringHex(input);
|
|
332
341
|
}
|
|
333
342
|
|
package/src/trace-builder.ts
CHANGED
|
@@ -59,6 +59,11 @@ import {
|
|
|
59
59
|
computeRootHash,
|
|
60
60
|
} from "./rolling-hash.js";
|
|
61
61
|
import { buildSpanMerkleTree, computeSpanHash } from "./merkle.js";
|
|
62
|
+
import {
|
|
63
|
+
computeModelManifestHash,
|
|
64
|
+
validateModelManifest,
|
|
65
|
+
freezeModelManifest,
|
|
66
|
+
} from "./model-manifest.js";
|
|
62
67
|
|
|
63
68
|
// =============================================================================
|
|
64
69
|
// TRACE CREATION
|
|
@@ -129,6 +134,28 @@ export async function createTrace(opts: CreateTraceOptions): Promise<TraceRun> {
|
|
|
129
134
|
};
|
|
130
135
|
}
|
|
131
136
|
|
|
137
|
+
// -------------------------------------------------------------------------
|
|
138
|
+
// Pre-execution model-manifest pinning (issue #59)
|
|
139
|
+
// -------------------------------------------------------------------------
|
|
140
|
+
const strict = opts.strict ?? false;
|
|
141
|
+
if (strict) {
|
|
142
|
+
run.strict = true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (opts.manifest !== undefined) {
|
|
146
|
+
const manifest = validateModelManifest(opts.manifest);
|
|
147
|
+
// Pin the hash now, BEFORE any event is recorded — this is the enforcement
|
|
148
|
+
// point for "the model was not altered over the run".
|
|
149
|
+
run.modelManifestHash = await computeModelManifestHash(manifest);
|
|
150
|
+
// Freeze the object so any later mutation throws (ESM strict mode). The pin
|
|
151
|
+
// is the hash computed above, not the live object.
|
|
152
|
+
run.modelManifest = freezeModelManifest(manifest);
|
|
153
|
+
} else if (strict) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
"createTrace: strict mode requires a `manifest` to be pinned before execution"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
132
159
|
return run;
|
|
133
160
|
}
|
|
134
161
|
|
|
@@ -531,6 +558,24 @@ export async function finalizeTrace(run: TraceRun): Promise<TraceBundle> {
|
|
|
531
558
|
throw new Error("Trace run is already finalized");
|
|
532
559
|
}
|
|
533
560
|
|
|
561
|
+
// -------------------------------------------------------------------------
|
|
562
|
+
// Pre-execution manifest enforcement (issue #59)
|
|
563
|
+
// -------------------------------------------------------------------------
|
|
564
|
+
if (run.modelManifest === undefined) {
|
|
565
|
+
if (run.strict) {
|
|
566
|
+
throw new Error(
|
|
567
|
+
"finalizeTrace: strict mode requires a model manifest pinned at createTrace() time"
|
|
568
|
+
);
|
|
569
|
+
}
|
|
570
|
+
// Warn-only path for v0.x — surfaces the missing model-immutability guarantee.
|
|
571
|
+
// Becomes a hard error under strict-by-default in v1.0.
|
|
572
|
+
console.warn(
|
|
573
|
+
"[orynq] finalizeTrace: no model manifest was pinned — model/data immutability " +
|
|
574
|
+
"is NOT proven for this trace. Pass `manifest` to createTrace() (and " +
|
|
575
|
+
"`strict: true` to enforce). This will become an error in v1.0."
|
|
576
|
+
);
|
|
577
|
+
}
|
|
578
|
+
|
|
534
579
|
// Close any open spans
|
|
535
580
|
for (const span of run.spans) {
|
|
536
581
|
if (span.status === "running") {
|
|
@@ -551,8 +596,13 @@ export async function finalizeTrace(run: TraceRun): Promise<TraceBundle> {
|
|
|
551
596
|
// Build Merkle tree from spans
|
|
552
597
|
const merkleTree = await buildSpanMerkleTree(run.spans, run.events);
|
|
553
598
|
|
|
554
|
-
// Compute root hash from rolling hash + span hashes
|
|
555
|
-
|
|
599
|
+
// Compute root hash from rolling hash + span hashes, binding the pinned
|
|
600
|
+
// model-manifest commitment into the committed root (#59).
|
|
601
|
+
const rootHash = await computeRootHash(
|
|
602
|
+
run.rollingHash,
|
|
603
|
+
run.spans,
|
|
604
|
+
run.modelManifestHash
|
|
605
|
+
);
|
|
556
606
|
run.rootHash = rootHash;
|
|
557
607
|
|
|
558
608
|
// Create public view
|
|
@@ -567,6 +617,14 @@ export async function finalizeTrace(run: TraceRun): Promise<TraceBundle> {
|
|
|
567
617
|
rootHash,
|
|
568
618
|
};
|
|
569
619
|
|
|
620
|
+
// Surface the pinned model manifest on the bundle (public-safe: hashes only).
|
|
621
|
+
if (run.modelManifestHash !== undefined) {
|
|
622
|
+
bundle.modelManifestHash = run.modelManifestHash;
|
|
623
|
+
}
|
|
624
|
+
if (run.modelManifest !== undefined) {
|
|
625
|
+
bundle.modelManifest = run.modelManifest;
|
|
626
|
+
}
|
|
627
|
+
|
|
570
628
|
return bundle;
|
|
571
629
|
}
|
|
572
630
|
|
|
@@ -649,6 +707,14 @@ function createPublicView(
|
|
|
649
707
|
redactedSpanHashes,
|
|
650
708
|
};
|
|
651
709
|
|
|
710
|
+
// Model-state commitment is public-safe (it is only a hash).
|
|
711
|
+
if (run.modelManifestHash !== undefined) {
|
|
712
|
+
publicView.modelManifestHash = run.modelManifestHash;
|
|
713
|
+
}
|
|
714
|
+
if (run.modelManifest !== undefined) {
|
|
715
|
+
publicView.modelManifest = run.modelManifest;
|
|
716
|
+
}
|
|
717
|
+
|
|
652
718
|
return publicView;
|
|
653
719
|
}
|
|
654
720
|
|
package/src/types.ts
CHANGED
|
@@ -124,6 +124,101 @@ export interface CustomEvent extends BaseTraceEvent {
|
|
|
124
124
|
data: Record<string, unknown>;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Signature scheme used by a governance attestor.
|
|
129
|
+
* - "sr25519" / "ed25519": Substrate/Materios wallets (verified in-package)
|
|
130
|
+
* - "eip712": EVM typed-data signatures (verified via a pluggable verifier)
|
|
131
|
+
*/
|
|
132
|
+
export type GovernanceSignatureScheme = "sr25519" | "ed25519" | "eip712";
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* EIP-712 typed-data binding, required to verify an `eip712` governance
|
|
136
|
+
* signature. Mirrors the shape consumed by viem's `verifyTypedData`.
|
|
137
|
+
*/
|
|
138
|
+
export interface GovernanceEip712Binding {
|
|
139
|
+
domain: Record<string, unknown>;
|
|
140
|
+
types: Record<string, Array<{ name: string; type: string }>>;
|
|
141
|
+
primaryType: string;
|
|
142
|
+
message?: Record<string, unknown>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Governance attestation event — a verifiable, role-scoped sign-off recorded
|
|
147
|
+
* inside a trace (compliance review, release approval, data-steward sign-off).
|
|
148
|
+
*
|
|
149
|
+
* The signature is computed over a canonical, domain-separated preimage of
|
|
150
|
+
* `(runId || role || policyRef || decisionRef || signedAt)` (see
|
|
151
|
+
* `governanceAttestationPreimage`), so an auditor can verify *who* governed a
|
|
152
|
+
* decision without trusting the wrapper that recorded it, and a genuine
|
|
153
|
+
* attestation cannot be replayed into a different trace.
|
|
154
|
+
*
|
|
155
|
+
* Default visibility: "public" (governance provenance is meant to be auditable).
|
|
156
|
+
*/
|
|
157
|
+
export interface GovernanceAttestationEvent extends BaseTraceEvent {
|
|
158
|
+
kind: "governance-attestation";
|
|
159
|
+
/** Governance role; common values plus free-form extension. */
|
|
160
|
+
role: "compliance" | "release-authority" | "data-steward" | (string & {});
|
|
161
|
+
/** Hash or URI of the policy being attested to. */
|
|
162
|
+
policyRef: string;
|
|
163
|
+
/** Hash or id of the decision/event being governed. */
|
|
164
|
+
decisionRef: string;
|
|
165
|
+
/** The signing identity and scheme. */
|
|
166
|
+
attestor: { address: string; signatureScheme: GovernanceSignatureScheme };
|
|
167
|
+
/** Signature over the canonical preimage (hex, optionally `0x`-prefixed). */
|
|
168
|
+
signature: string;
|
|
169
|
+
/** ISO 8601 timestamp; part of the signed preimage. */
|
|
170
|
+
signedAt: string;
|
|
171
|
+
/** EIP-712 binding — required only when `attestor.signatureScheme === "eip712"`. */
|
|
172
|
+
eip712?: GovernanceEip712Binding;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Signature scheme for a tool-call receipt.
|
|
177
|
+
* - "http-message-signatures": RFC 9421 signed HTTP responses
|
|
178
|
+
* - "stripe-webhook" / "github-webhook": SaaS webhook HMAC signatures
|
|
179
|
+
* - "jws": generic JWS/JWT-signed responses
|
|
180
|
+
* - (string): forward-compatible custom schemes
|
|
181
|
+
*/
|
|
182
|
+
export type ToolReceiptScheme =
|
|
183
|
+
| "http-message-signatures"
|
|
184
|
+
| "stripe-webhook"
|
|
185
|
+
| "github-webhook"
|
|
186
|
+
| "jws"
|
|
187
|
+
| (string & {});
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Verifiable tool-call receipt event — proves "the tool actually returned this
|
|
191
|
+
* response", not merely "the agent says the tool returned this response".
|
|
192
|
+
*
|
|
193
|
+
* The wrapper records a signed receipt produced by (or about) the external
|
|
194
|
+
* system; a verifier independently re-checks `receipt.signature` over
|
|
195
|
+
* `receipt.signedPayload` against `receipt.signer`.
|
|
196
|
+
*
|
|
197
|
+
* Default visibility: "private" (responses may contain PII / secrets — only the
|
|
198
|
+
* hashes and signature are needed for verification).
|
|
199
|
+
*/
|
|
200
|
+
export interface ToolReceiptEvent extends BaseTraceEvent {
|
|
201
|
+
kind: "tool-receipt";
|
|
202
|
+
/** Identifier of the tool/endpoint that was called. */
|
|
203
|
+
toolId: string;
|
|
204
|
+
/** Commitment to the request (SHA-256 hex). */
|
|
205
|
+
request: { hash: string };
|
|
206
|
+
/** Commitment to the response, with an optional retained payload. */
|
|
207
|
+
response: { hash: string; payload?: unknown };
|
|
208
|
+
/** The independently-verifiable signed receipt. */
|
|
209
|
+
receipt: {
|
|
210
|
+
scheme: ToolReceiptScheme;
|
|
211
|
+
/** Verifier-resolvable identity: URL, DID, on-chain address, or keyId. */
|
|
212
|
+
signer: string;
|
|
213
|
+
/** Signature bytes (encoding depends on scheme: base64/hex/0x-hex). */
|
|
214
|
+
signature: string;
|
|
215
|
+
/** Canonicalized signed bytes the signature is computed over. */
|
|
216
|
+
signedPayload: string;
|
|
217
|
+
/** Scheme-specific verification material (headers, keyId, components, ...). */
|
|
218
|
+
params?: Record<string, unknown>;
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
127
222
|
/**
|
|
128
223
|
* Discriminated union of all trace event types.
|
|
129
224
|
*/
|
|
@@ -133,7 +228,9 @@ export type TraceEvent =
|
|
|
133
228
|
| DecisionEvent
|
|
134
229
|
| ObservationEvent
|
|
135
230
|
| ErrorTraceEvent
|
|
136
|
-
| CustomEvent
|
|
231
|
+
| CustomEvent
|
|
232
|
+
| GovernanceAttestationEvent
|
|
233
|
+
| ToolReceiptEvent;
|
|
137
234
|
|
|
138
235
|
/**
|
|
139
236
|
* Event kind string literals for type guards.
|
|
@@ -150,6 +247,10 @@ export const DEFAULT_EVENT_VISIBILITY: Record<TraceEventKind, Visibility> = {
|
|
|
150
247
|
observation: "public",
|
|
151
248
|
error: "private",
|
|
152
249
|
custom: "private",
|
|
250
|
+
// Governance provenance is meant to be auditable by third parties.
|
|
251
|
+
"governance-attestation": "public",
|
|
252
|
+
// Tool responses may carry PII/secrets; only hashes + signature are required.
|
|
253
|
+
"tool-receipt": "private",
|
|
153
254
|
};
|
|
154
255
|
|
|
155
256
|
// =============================================================================
|
|
@@ -186,6 +287,41 @@ export interface TraceSpan {
|
|
|
186
287
|
hash?: string;
|
|
187
288
|
}
|
|
188
289
|
|
|
290
|
+
// =============================================================================
|
|
291
|
+
// MODEL MANIFEST (PRE-EXECUTION PINNING)
|
|
292
|
+
// =============================================================================
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Fingerprint of the model/data state used during a trace run.
|
|
296
|
+
*
|
|
297
|
+
* Distinct from {@link TraceManifest} (which describes off-chain *storage*
|
|
298
|
+
* chunks). A `ModelManifest` is pinned at {@link CreateTraceOptions} time —
|
|
299
|
+
* *before* execution — and frozen, so the resulting trace can prove that
|
|
300
|
+
* "neither the data nor the model was altered" for a given inference.
|
|
301
|
+
*
|
|
302
|
+
* Two traces of "the same model" should produce the same `modelManifestHash`,
|
|
303
|
+
* so the field values must be deterministic fingerprints (see the
|
|
304
|
+
* `manifestFrom*` builders).
|
|
305
|
+
*/
|
|
306
|
+
export interface ModelManifest {
|
|
307
|
+
/** Model checkpoint fingerprint, e.g. "sha256:..." */
|
|
308
|
+
modelHash: string;
|
|
309
|
+
/** Tokenizer fingerprint. */
|
|
310
|
+
tokenizerHash?: string;
|
|
311
|
+
/** System-prompt fingerprint. */
|
|
312
|
+
systemPromptHash?: string;
|
|
313
|
+
/** Training-dataset manifest fingerprint. */
|
|
314
|
+
trainingDataManifest?: string;
|
|
315
|
+
/** Producing framework, e.g. "huggingface" | "openai" | "anthropic" | "checkpoint". */
|
|
316
|
+
framework?: string;
|
|
317
|
+
/** Model identifier (e.g. HF repo id, OpenAI/Anthropic model name). */
|
|
318
|
+
modelId?: string;
|
|
319
|
+
/** Revision / snapshot id, when applicable. */
|
|
320
|
+
revision?: string;
|
|
321
|
+
/** Free-form additional fingerprint inputs (hashed into manifestHash). */
|
|
322
|
+
metadata?: Record<string, unknown>;
|
|
323
|
+
}
|
|
324
|
+
|
|
189
325
|
// =============================================================================
|
|
190
326
|
// TRACE RUN
|
|
191
327
|
// =============================================================================
|
|
@@ -218,6 +354,18 @@ export interface TraceRun {
|
|
|
218
354
|
rootHash?: string;
|
|
219
355
|
nextSeq: number;
|
|
220
356
|
nextSpanSeq: number;
|
|
357
|
+
/**
|
|
358
|
+
* Model/data manifest pinned at createTrace() time (frozen). When present,
|
|
359
|
+
* `modelManifestHash` is the cryptographic commitment to it.
|
|
360
|
+
*/
|
|
361
|
+
modelManifest?: ModelManifest;
|
|
362
|
+
/** H("poi-trace:model-manifest:v1|" + canonical(modelManifest)), pinned at creation. */
|
|
363
|
+
modelManifestHash?: string;
|
|
364
|
+
/**
|
|
365
|
+
* Strict-mode flag (pinned at creation). When true, finalizeTrace() throws
|
|
366
|
+
* if no manifest was pinned. Default false (warn-only) for v0.x.
|
|
367
|
+
*/
|
|
368
|
+
strict?: boolean;
|
|
221
369
|
}
|
|
222
370
|
|
|
223
371
|
// =============================================================================
|
|
@@ -301,6 +449,10 @@ export interface TraceBundlePublicView {
|
|
|
301
449
|
redactedSpanHashes: Array<{ spanId: string; hash: string }>;
|
|
302
450
|
redactionPolicyId?: string;
|
|
303
451
|
redactionRulesHash?: string;
|
|
452
|
+
/** Model-state commitment (public-safe: it is only a hash). */
|
|
453
|
+
modelManifestHash?: string;
|
|
454
|
+
/** Pinned model manifest (hashes only — public-safe). */
|
|
455
|
+
modelManifest?: ModelManifest;
|
|
304
456
|
}
|
|
305
457
|
|
|
306
458
|
/**
|
|
@@ -323,6 +475,14 @@ export interface TraceBundle {
|
|
|
323
475
|
merkleRoot: string;
|
|
324
476
|
rootHash: string;
|
|
325
477
|
manifestHash?: string;
|
|
478
|
+
/**
|
|
479
|
+
* Model/data manifest commitment pinned at createTrace() time. Distinct from
|
|
480
|
+
* `manifestHash` (the off-chain storage-manifest hash). Place this in on-chain
|
|
481
|
+
* anchor metadata to make model drift cryptographically detectable.
|
|
482
|
+
*/
|
|
483
|
+
modelManifestHash?: string;
|
|
484
|
+
/** The pinned model manifest (hashes only — public-safe). */
|
|
485
|
+
modelManifest?: ModelManifest;
|
|
326
486
|
signerId?: string;
|
|
327
487
|
signature?: string;
|
|
328
488
|
}
|
|
@@ -449,6 +609,22 @@ export interface TraceVerificationResult {
|
|
|
449
609
|
spanHashesValid: boolean;
|
|
450
610
|
eventHashesValid: boolean;
|
|
451
611
|
sequenceValid: boolean;
|
|
612
|
+
/**
|
|
613
|
+
* Model-manifest pin binding (#59): the pinned manifest hashes to its
|
|
614
|
+
* recorded commitment AND that commitment is folded into the committed
|
|
615
|
+
* root. True when no manifest is pinned (nothing to bind).
|
|
616
|
+
*/
|
|
617
|
+
modelManifestValid?: boolean;
|
|
618
|
+
/**
|
|
619
|
+
* Set only when governance verification is requested via
|
|
620
|
+
* verifyBundle(bundle, { governance }). Undefined means "not checked".
|
|
621
|
+
*/
|
|
622
|
+
governanceValid?: boolean;
|
|
623
|
+
/**
|
|
624
|
+
* Set only when tool-receipt verification is requested via
|
|
625
|
+
* verifyBundle(bundle, { toolReceipts }). Undefined means "not checked".
|
|
626
|
+
*/
|
|
627
|
+
toolReceiptsValid?: boolean;
|
|
452
628
|
};
|
|
453
629
|
}
|
|
454
630
|
|
|
@@ -478,6 +654,17 @@ export interface CreateTraceOptions {
|
|
|
478
654
|
agentId: string;
|
|
479
655
|
description?: string;
|
|
480
656
|
metadata?: Record<string, unknown>;
|
|
657
|
+
/**
|
|
658
|
+
* Model/data manifest to pin *before* execution. Its hash is computed and
|
|
659
|
+
* frozen at createTrace() time; mutating the manifest afterwards throws.
|
|
660
|
+
*/
|
|
661
|
+
manifest?: ModelManifest;
|
|
662
|
+
/**
|
|
663
|
+
* Strict mode. When true, createTrace() requires a `manifest` and
|
|
664
|
+
* finalizeTrace() refuses to finalize an unpinned trace. Default false
|
|
665
|
+
* (warn-only) for v0.x; planned strict-by-default in v1.0.
|
|
666
|
+
*/
|
|
667
|
+
strict?: boolean;
|
|
481
668
|
}
|
|
482
669
|
|
|
483
670
|
/**
|
|
@@ -514,6 +701,10 @@ export const HASH_DOMAIN_PREFIXES = {
|
|
|
514
701
|
node: "poi-trace:node:v1|",
|
|
515
702
|
manifest: "poi-trace:manifest:v1|",
|
|
516
703
|
root: "poi-trace:root:v1|",
|
|
704
|
+
/** Model/data manifest commitment (pre-execution pinning). */
|
|
705
|
+
modelManifest: "poi-trace:model-manifest:v1|",
|
|
706
|
+
/** Governance-attestation signing preimage. */
|
|
707
|
+
governance: "poi-trace:governance:v1|",
|
|
517
708
|
} as const;
|
|
518
709
|
|
|
519
710
|
/**
|