/** Privacy-bounded decision-path trace audit for invented telemetry. */ import { createHash } from "node:crypto" const IDENTITY = /^[A-Za-z0-9][A-Za-z0-9_.:/@-]{0,127}$/ const SHA256 = /^[a-f0-9]{64}$/ const STAGES = ["retrieval", "policy", "model", "tool", "response"] as const const STATUSES = ["ok", "blocked", "error"] as const type Stage = (typeof STAGES)[number] type EventStatus = (typeof STATUSES)[number] function assertPlainRecord(value: unknown, keys: readonly string[]): asserts value is Record { if (value === null || typeof value !== "object" || Object.getPrototypeOf(value) !== Object.prototype) { throw new TypeError("exact plain record required") } const actual = Object.keys(value).sort() const expected = [...keys].sort() if (actual.length !== expected.length || actual.some((key, index) => key !== expected[index])) { throw new TypeError("record keys must match the closed schema") } } function identity(value: unknown): string { if (typeof value !== "string" || !IDENTITY.test(value)) { throw new TypeError("exact bounded identity required") } return value } function sha256Text(value: unknown): string { if (typeof value !== "string" || !SHA256.test(value)) { throw new TypeError("exact lowercase SHA-256 required") } return value } function integer(value: unknown, lower: number, upper: number): number { if (typeof value !== "number" || !Number.isSafeInteger(value) || value < lower || value > upper) { throw new TypeError("bounded safe integer required") } return value } function exactBoolean(value: unknown): boolean { if (typeof value !== "boolean") throw new TypeError("exact boolean required") return value } function exactArray(value: unknown, lower: number, upper: number): readonly unknown[] { if (!Array.isArray(value) || Object.getPrototypeOf(value) !== Array.prototype) { throw new TypeError("exact array required") } integer(value.length, lower, upper) return value } function identities(value: unknown, lower: number, upper: number): readonly string[] { const result = exactArray(value, lower, upper).map(identity) if (new Set(result).size !== result.length) throw new TypeError("duplicate identity") return Object.freeze(result) } function oneOf(value: unknown, allowed: readonly T[]): T { if (typeof value !== "string" || !allowed.includes(value as T)) { throw new TypeError("unknown exact-string declaration") } return value as T } function canonicalJson(value: unknown, seen = new Set()): string { if (value === null) return "null" if (typeof value === "string" || typeof value === "boolean") return JSON.stringify(value) if (typeof value === "number") { if (!Number.isFinite(value)) throw new TypeError("non-finite canonical number") return JSON.stringify(value) } if (Array.isArray(value) && Object.getPrototypeOf(value) === Array.prototype) { if (seen.has(value)) throw new TypeError("cyclic canonical value") seen.add(value) const encoded = `[${value.map((item) => canonicalJson(item, seen)).join(",")}]` seen.delete(value) return encoded } if (typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) { if (seen.has(value)) throw new TypeError("cyclic canonical value") seen.add(value) const record = value as Record const encoded = `{${Object.keys(record) .sort() .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key], seen)}`) .join(",")}}` seen.delete(value) return encoded } throw new TypeError("canonical JSON-compatible value required") } export function digest(value: unknown): string { return createHash("sha256").update(canonicalJson(value)).digest("hex") } const CONTRACT_KEYS = [ "scope", "requiredStages", "maxEvents", "maxTotalLatencyMs", "maxTotalCostMicrousd", "allowRawPayloads", "contentId", ] as const export class TraceContract { readonly scope: readonly string[] readonly requiredStages: readonly Stage[] readonly maxEvents: number readonly maxTotalLatencyMs: number readonly maxTotalCostMicrousd: number readonly allowRawPayloads: boolean readonly contentId: string constructor(input: unknown) { assertPlainRecord(input, CONTRACT_KEYS) this.scope = identities(input.scope, 8, 8) const stages = exactArray(input.requiredStages, 1, STAGES.length).map((value) => oneOf(value, STAGES)) if (new Set(stages).size !== stages.length) throw new TypeError("duplicate required stage") this.requiredStages = Object.freeze(stages) this.maxEvents = integer(input.maxEvents, stages.length, 128) this.maxTotalLatencyMs = integer(input.maxTotalLatencyMs, 1, 86_400_000) this.maxTotalCostMicrousd = integer(input.maxTotalCostMicrousd, 0, 1_000_000_000) if (exactBoolean(input.allowRawPayloads)) throw new TypeError("trace contract forbids raw payload capture") this.allowRawPayloads = false if (typeof input.contentId !== "string") throw new TypeError("content digest requires exact string") const expected = digest({ scope: this.scope, requiredStages: this.requiredStages, maxEvents: this.maxEvents, maxTotalLatencyMs: this.maxTotalLatencyMs, maxTotalCostMicrousd: this.maxTotalCostMicrousd, allowRawPayloads: this.allowRawPayloads, }) if (input.contentId && input.contentId !== expected) throw new TypeError("trace contract digest mismatch") this.contentId = expected Object.freeze(this) } } const EVENT_KEYS = [ "scope", "traceId", "sequence", "stage", "versionId", "tenantHash", "inputSha256", "outputSha256", "status", "latencyMs", "costMicrousd", "contentId", ] as const export class DecisionEvent { readonly scope: readonly string[] readonly traceId: string readonly sequence: number readonly stage: Stage readonly versionId: string readonly tenantHash: string readonly inputSha256: string readonly outputSha256: string readonly status: EventStatus readonly latencyMs: number readonly costMicrousd: number readonly contentId: string constructor(input: unknown) { assertPlainRecord(input, EVENT_KEYS) this.scope = identities(input.scope, 8, 8) this.traceId = identity(input.traceId) this.sequence = integer(input.sequence, 1, 4096) this.stage = oneOf(input.stage, STAGES) this.versionId = identity(input.versionId) this.tenantHash = sha256Text(input.tenantHash) this.inputSha256 = sha256Text(input.inputSha256) this.outputSha256 = sha256Text(input.outputSha256) this.status = oneOf(input.status, STATUSES) this.latencyMs = integer(input.latencyMs, 0, 86_400_000) this.costMicrousd = integer(input.costMicrousd, 0, 1_000_000_000) if (typeof input.contentId !== "string") throw new TypeError("content digest requires exact string") const expected = digest({ scope: this.scope, traceId: this.traceId, sequence: this.sequence, stage: this.stage, versionId: this.versionId, tenantHash: this.tenantHash, inputSha256: this.inputSha256, outputSha256: this.outputSha256, status: this.status, latencyMs: this.latencyMs, costMicrousd: this.costMicrousd, }) if (input.contentId && input.contentId !== expected) throw new TypeError("decision event digest mismatch") this.contentId = expected Object.freeze(this) } } const TRACE_KEYS = ["scope", "contractContentId", "traceId", "events", "contentId"] as const export class DecisionTrace { readonly scope: readonly string[] readonly contractContentId: string readonly traceId: string readonly events: readonly DecisionEvent[] readonly contentId: string constructor(input: unknown) { assertPlainRecord(input, TRACE_KEYS) this.scope = identities(input.scope, 8, 8) this.contractContentId = sha256Text(input.contractContentId) this.traceId = identity(input.traceId) const supplied = exactArray(input.events, 1, 128) const events = supplied.map((value) => validateEvent(value)) if (events.some((event) => event.traceId !== this.traceId || !sameStrings(event.scope, this.scope))) { throw new TypeError("event outside decision trace scope") } if (events.some((event, index) => event.sequence !== index + 1)) { throw new TypeError("event sequences must be unique and contiguous") } this.events = Object.freeze(events) if (typeof input.contentId !== "string") throw new TypeError("content digest requires exact string") const expected = digest({ scope: this.scope, contractContentId: this.contractContentId, traceId: this.traceId, events: this.events.map(eventData), }) if (input.contentId && input.contentId !== expected) throw new TypeError("decision trace digest mismatch") this.contentId = expected Object.freeze(this) } } export interface TraceReport { readonly status: "TRACE_COMPLETE" | "TRACE_REVIEW_REQUIRED" readonly eventCount: number readonly stages: readonly Stage[] readonly totalLatencyMs: number readonly totalCostMicrousd: number readonly violations: readonly string[] readonly evidenceId: string readonly claim: "HASHED_LOCAL_TRACE_NOT_PAYLOAD_CAPTURE" } function sameStrings(left: readonly string[], right: readonly string[]): boolean { return left.length === right.length && left.every((value, index) => value === right[index]) } function contractData(contract: TraceContract): Record { return { scope: contract.scope, requiredStages: contract.requiredStages, maxEvents: contract.maxEvents, maxTotalLatencyMs: contract.maxTotalLatencyMs, maxTotalCostMicrousd: contract.maxTotalCostMicrousd, allowRawPayloads: contract.allowRawPayloads, contentId: contract.contentId, } } function eventData(event: DecisionEvent): Record { return { scope: event.scope, traceId: event.traceId, sequence: event.sequence, stage: event.stage, versionId: event.versionId, tenantHash: event.tenantHash, inputSha256: event.inputSha256, outputSha256: event.outputSha256, status: event.status, latencyMs: event.latencyMs, costMicrousd: event.costMicrousd, contentId: event.contentId, } } function traceData(trace: DecisionTrace): Record { return { scope: trace.scope, contractContentId: trace.contractContentId, traceId: trace.traceId, events: trace.events, contentId: trace.contentId, } } function validateContract(value: unknown): TraceContract { if (Object.getPrototypeOf(value) !== TraceContract.prototype) throw new TypeError("concrete trace contract required") return new TraceContract(contractData(value as TraceContract)) } function validateEvent(value: unknown): DecisionEvent { if (Object.getPrototypeOf(value) !== DecisionEvent.prototype) throw new TypeError("concrete decision event required") return new DecisionEvent(eventData(value as DecisionEvent)) } function validateTrace(value: unknown): DecisionTrace { if (Object.getPrototypeOf(value) !== DecisionTrace.prototype) throw new TypeError("concrete decision trace required") return new DecisionTrace(traceData(value as DecisionTrace)) } export function auditDecisionTrace(contractValue: unknown, traceValue: unknown): TraceReport { const contract = validateContract(contractValue) const trace = validateTrace(traceValue) if (!sameStrings(trace.scope, contract.scope) || trace.contractContentId !== contract.contentId) { throw new TypeError("trace belongs to another observability contract") } if (trace.events.length > contract.maxEvents) throw new TypeError("trace exceeds event budget") const observedStages = trace.events.map((event) => event.stage) const violations: string[] = [] const requiredPositions = contract.requiredStages.map((stage) => observedStages.indexOf(stage)) if (requiredPositions.some((position) => position < 0)) violations.push("missing-required-stage") if (contract.requiredStages.some((stage) => observedStages.filter((item) => item === stage).length !== 1)) { violations.push("required-stage-cardinality") } if (requiredPositions.every((position) => position >= 0) && requiredPositions.some((position, index) => index > 0 && position <= requiredPositions[index - 1])) { violations.push("stage-order") } if (trace.events.some((event) => event.status !== "ok")) violations.push("non-ok-stage") const totalLatencyMs = trace.events.reduce((total, event) => total + event.latencyMs, 0) const totalCostMicrousd = trace.events.reduce((total, event) => total + event.costMicrousd, 0) if (totalLatencyMs > contract.maxTotalLatencyMs) violations.push("latency-budget") if (totalCostMicrousd > contract.maxTotalCostMicrousd) violations.push("cost-budget") const status = violations.length === 0 ? "TRACE_COMPLETE" : "TRACE_REVIEW_REQUIRED" const evidenceId = digest({ contract: contract.contentId, trace: trace.contentId, status, violations, latency: totalLatencyMs, cost: totalCostMicrousd, }) return Object.freeze({ status, eventCount: trace.events.length, stages: Object.freeze([...observedStages]), totalLatencyMs, totalCostMicrousd, violations: Object.freeze(violations), evidenceId, claim: "HASHED_LOCAL_TRACE_NOT_PAYLOAD_CAPTURE", }) } export function illustrativeFixture(): { contract: TraceContract; trace: DecisionTrace } { const scope = [ "trace-policy-v1", "retrieval-v3", "policy-v4", "model-v7", "tool-registry-v2", "response-schema-v3", "retention-v1", "fixture-v1", ] const contract = new TraceContract({ scope, requiredStages: STAGES, maxEvents: 8, maxTotalLatencyMs: 600, maxTotalCostMicrousd: 2_000, allowRawPayloads: false, contentId: "", }) const traceId = "trace-support-1042" const tenantHash = digest("tenant-a") const rows: readonly [Stage, string, number, number][] = [ ["retrieval", "retrieval-v3", 40, 0], ["policy", "policy-v4", 15, 0], ["model", "model-v7", 300, 1_200], ["tool", "tool-registry-v2", 90, 200], ["response", "response-schema-v3", 35, 100], ] const events = rows.map(([stage, versionId, latencyMs, costMicrousd], index) => new DecisionEvent({ scope: contract.scope, traceId, sequence: index + 1, stage, versionId, tenantHash, inputSha256: digest({ stage, direction: "input" }), outputSha256: digest({ stage, direction: "output" }), status: "ok", latencyMs, costMicrousd, contentId: "", }), ) const trace = new DecisionTrace({ scope: contract.scope, contractContentId: contract.contentId, traceId, events, contentId: "", }) return { contract, trace } } export function main(): void { const { contract, trace } = illustrativeFixture() const report = auditDecisionTrace(contract, trace) console.log("example=illustrative_only") console.log(`status=${report.status}`) console.log(`events=${report.eventCount};stages=${report.stages.join(",")}`) console.log(`latency_ms=${report.totalLatencyMs};cost_microusd=${report.totalCostMicrousd}`) console.log(`claim=${report.claim}`) } if (import.meta.url === `file://${process.argv[1]}`) main()