From c8dfb3f3ba985d98a9f464cef53f12b9623653fc Mon Sep 17 00:00:00 2001 From: sneakocom <192013763+sneakocom@users.noreply.github.com> Date: Tue, 25 Aug 2026 12:55:15 +0000 Subject: [PATCH] feat: validate visible value receipts --- .github/workflows/ci.yml | 1 + ARCHITECTURE.md | 18 + CHANGELOG.md | 12 + README.md | 43 + SPEC.md | 22 +- bin/decision-evidence.js | 46 +- docs/context-firewall-packet-v1.md | 4 +- docs/value-receipt-v1.md | 21 + .../context-firewall-packet-v1/vectors.json | 2689 ++++++++++++++++- package.json | 11 +- src/conformance.js | 7 + src/context-firewall-v1.js | 2 +- src/context-firewall-value.js | 228 ++ src/index.js | 15 + src/value-receipt-v1.js | 245 ++ tests/context-firewall-v1.test.js | 4 + tests/value-receipt-v1.test.js | 248 ++ tools/generate-context-firewall-vectors.js | 5 +- tools/verify-context-firewall-interop.js | 12 +- 19 files changed, 3601 insertions(+), 32 deletions(-) create mode 100644 docs/value-receipt-v1.md create mode 100644 src/context-firewall-value.js create mode 100644 src/value-receipt-v1.js create mode 100644 tests/value-receipt-v1.test.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 745fcdc..af6fb68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,3 +20,4 @@ jobs: - run: npm run lint - run: npm test - run: npm run conformance + - run: npm run determinism diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index b4cdc3d..a63ad24 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -25,3 +25,21 @@ The Context Firewall profile is a separately implemented classifier and receipt auditor. Repository-local tests consume checked-in vectors. The optional cross-repository proof dynamically imports an exact read-only producer checkout only from a development tool, never from the package runtime or normal CI. + +## Visible Value channels + +```text +Context Firewall packet + optional source + | + v +Decision Evidence validation + | + +--> canonical validation JSON (stdout/model channel) + +--> sibling value receipt (API/optional sidecar) + +--> [Decision Evidence] indicator (stderr/operator channel) +``` + +`src/value-receipt-v1.js` enforces generic claim ceilings. +`src/context-firewall-value.js` cross-checks producer receipts against packet +facts and creates the Decision Evidence validation receipt. Neither creates a +runtime package dependency on Context Firewall, Research, or the profiler. diff --git a/CHANGELOG.md b/CHANGELOG.md index cebb0f5..c04cb32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.3.0 - 2026-08-25 + +- Added dependency-free `opsle.value-receipt.v1` validation and strict Context + Firewall receipt cross-checking at producer revision + `953c48f1cfd154d6b7ed10b51b87fe54e4df45f2`. +- Added sibling validation receipts, deterministic sidecars, and named + `[Decision Evidence]` stderr indicators without changing canonical stdout. +- Added exact/observed class, trust, aggregation, counterfactual, tamper, + inconsistency, source-verification, and invalid-state coverage. +- This is conformance evidence, not EXP-001, causal benefit, or proof that a + failure was prevented. + ## 0.2.0 - 2026-08-25 - Added an independent Context Firewall packet-v1 validator and stable API. diff --git a/README.md b/README.md index d310ff7..ab916d4 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,10 @@ A universal event schema, embedding raw logs by default, or expanding fields wit ```js import { + createValidationValueReceipt, validateContextFirewallPacket, + validateContextFirewallValueReceipt, + validateValueReceipt, } from '@opsle/decision-evidence-protocol'; const result = validateContextFirewallPacket( @@ -44,6 +47,17 @@ const result = validateContextFirewallPacket( sourceInput, }, ); + +const producerReceiptResult = validateContextFirewallValueReceipt( + contextFirewallValueReceipt, + packet, +); + +const validationReceipt = createValidationValueReceipt( + packet, + result, + { mechanismRevision }, +); ``` `sourceInput` is optional and uses Context Firewall's public input shape. A @@ -90,12 +104,41 @@ including valid-but-insufficient escalation receipts; callers must inspect `sufficiency`. Exit code 1 means validation failure. Invocation or JSON errors use exit code 2. +Successful validation also emits one stable named operator line on stderr, for +example: + +```text +[Decision Evidence] source-backed packet verified | SUFFICIENT | 7 claims checked +``` + +Canonical stdout remains byte-identical whether or not a full validation receipt +is requested: + +```bash +node ./bin/decision-evidence.js \ + validate-context-firewall \ + --packet packet.json \ + --source-input source.json \ + --mechanism-revision REVISION \ + --value-receipt value-receipt.json +``` + +The producer's separate Context Firewall receipt can be cross-checked against +the packet with `validate-context-firewall-value --receipt ... --packet ...`. +Neither full receipt nor stderr should be merged automatically into compact +decision-relevant model context. + +The Visible Value receipt reports performed checks, trust, sufficiency, +rejections, and escalation. It does not claim token/cost/latency savings, +preserved model correctness, or a failure prevented. + ## Verification ```bash npm run lint npm test npm run conformance +npm run determinism ``` The self-contained conformance corpus contains 24 public-safe vectors: 9 valid diff --git a/SPEC.md b/SPEC.md index 3c0d232..1a57b3b 100644 --- a/SPEC.md +++ b/SPEC.md @@ -36,6 +36,26 @@ The Context Firewall packet-v1 validation profile additionally enforces the normative invariants in [`docs/context-firewall-packet-v1.md`](docs/context-firewall-packet-v1.md). +## Visible Value validation + +Version 0.3.0 validates `opsle.value-receipt.v1` structure and measurement-class +semantics. The Context Firewall value profile independently cross-checks the 11 +producer measurements against the packet rather than trusting their labels. +Byte evidence cannot become a token, cost, latency, correctness, or +failure-prevention claim. `ESTIMATED` and `MODELED` values require inspectable +assumptions; `EXPERIMENTAL` requires controlled comparability evidence; modeled, +experimental, ratio, percent, boolean, and state values are not directly summed. + +Packet validation may produce a sibling Decision Evidence value receipt. It +records validation, classification, evaluated verification claims, source-backed +and hash verification, sufficiency, tamper/inconsistency detection, and raw +escalation. A rejection is directly observed; the receipt never claims a failure +was prevented. + +Canonical validation JSON remains on stdout. One named `[Decision Evidence]` +indicator is written to stderr, and the full receipt is written only to a +caller-requested deterministic sidecar. + ## Failure behavior Missing required authority or evidence fails closed. Unsupported optional data remains explicit and does not silently widen behavior. Implementations must document idempotency, crash consistency, and raw-evidence escalation. @@ -45,5 +65,5 @@ Missing required authority or evidence fails closed. Unsupported optional data r Breaking semantic changes require a new protocol version. New optional fields require evidence that they affect a real decision. The Context Firewall profile supports only evidence packet v1, receipt version -1, test-run input v1, reducer 0.2.0, and TAP-subset policy v1. Unsupported +1, test-run input v1, reducer 0.3.0, and TAP-subset policy v1. Unsupported versions are rejected explicitly; they are not interpreted as compatible. diff --git a/bin/decision-evidence.js b/bin/decision-evidence.js index 6910f8e..8aaa204 100755 --- a/bin/decision-evidence.js +++ b/bin/decision-evidence.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -import { readFile } from 'node:fs/promises'; +import { readFile, writeFile } from 'node:fs/promises'; import process from 'node:process'; import { @@ -7,10 +7,17 @@ import { validateContextFirewallPacket, } from '../src/context-firewall-v1.js'; import { runContextFirewallConformance } from '../src/conformance.js'; +import { + createValidationValueReceipt, + formatDecisionEvidenceIndicator, + validateContextFirewallValueReceipt, +} from '../src/context-firewall-value.js'; function usage() { return [ 'usage: decision-evidence validate-context-firewall [--packet PATH|-] [--source-input PATH]', + ' [--mechanism-revision REV] [--value-receipt PATH]', + ' decision-evidence validate-context-firewall-value --receipt PATH --packet PATH', ' decision-evidence conformance', '', ].join('\n'); @@ -26,12 +33,28 @@ async function readBytes(path) { function parseValidateArgs(args) { let packet = '-'; let sourceInput = null; + let mechanismRevision = null; + let valueReceipt = null; for (let index = 0; index < args.length; index += 1) { if (args[index] === '--packet' && args[index + 1]) packet = args[++index]; else if (args[index] === '--source-input' && args[index + 1]) sourceInput = args[++index]; + else if (args[index] === '--mechanism-revision' && args[index + 1]) mechanismRevision = args[++index]; + else if (args[index] === '--value-receipt' && args[index + 1]) valueReceipt = args[++index]; + else throw new TypeError(`unknown or incomplete argument: ${args[index]}`); + } + return { mechanismRevision, packet, sourceInput, valueReceipt }; +} + +function parseValueArgs(args) { + let packet = null; + let receipt = null; + for (let index = 0; index < args.length; index += 1) { + if (args[index] === '--packet' && args[index + 1]) packet = args[++index]; + else if (args[index] === '--receipt' && args[index + 1]) receipt = args[++index]; else throw new TypeError(`unknown or incomplete argument: ${args[index]}`); } - return { packet, sourceInput }; + if (packet === null || receipt === null) throw new TypeError('--packet and --receipt are required'); + return { packet, receipt }; } async function parseJsonFile(path, label) { @@ -52,6 +75,18 @@ async function main() { process.exitCode = report.conformance === 'PASS' ? 0 : 1; return; } + if (command === 'validate-context-firewall-value') { + const options = parseValueArgs(args); + const packet = await parseJsonFile(options.packet, 'packet'); + const receipt = await parseJsonFile(options.receipt, 'value receipt'); + const result = validateContextFirewallValueReceipt(receipt.value, packet.value); + process.stdout.write(`${canonicalJson(result)}\n`); + process.stderr.write(result.valid + ? '[Decision Evidence] Context Firewall value receipt verified | 11 measurements checked\n' + : `[Decision Evidence] Context Firewall value receipt rejected | ${result.violations.length} violation(s)\n`); + process.exitCode = result.valid ? 0 : 1; + return; + } if (command !== 'validate-context-firewall') { process.stderr.write(usage()); process.exitCode = 2; @@ -66,7 +101,14 @@ async function main() { packetBytes: packet.bytes, sourceInput, }); + if (options.valueReceipt !== null) { + const receipt = createValidationValueReceipt(packet.value, result, { + mechanismRevision: options.mechanismRevision, + }); + await writeFile(options.valueReceipt, `${canonicalJson(receipt)}\n`, 'utf8'); + } process.stdout.write(`${canonicalJson(result)}\n`); + process.stderr.write(`${formatDecisionEvidenceIndicator(result)}\n`); process.exitCode = result.valid ? 0 : 1; } diff --git a/docs/context-firewall-packet-v1.md b/docs/context-firewall-packet-v1.md index b5ef6fc..b21da22 100644 --- a/docs/context-firewall-packet-v1.md +++ b/docs/context-firewall-packet-v1.md @@ -7,7 +7,7 @@ Profile version: Producer contract: `opsle.context-firewall.evidence-packet/v1` at Context Firewall revision -`dd34bd9f681314761f1ca87f339648bf611811f3`. +`953c48f1cfd154d6b7ed10b51b87fe54e4df45f2`. ## What a validated receipt establishes @@ -65,7 +65,7 @@ loose compatibility: - receipt version is exactly 1; - source protocol is exactly test-run input v1; - reducer identity is exactly - `@opsle/context-firewall/test-output` version `0.2.0`; + `@opsle/context-firewall/test-output` version `0.3.0`; - policy revision is exactly `tap-subset-policy/v1`; - source, run, operation, and raw-reference identities are either nonempty strings or `null`, according to packet v1; diff --git a/docs/value-receipt-v1.md b/docs/value-receipt-v1.md new file mode 100644 index 0000000..619f075 --- /dev/null +++ b/docs/value-receipt-v1.md @@ -0,0 +1,21 @@ +# Value receipt v1 profile + +Decision Evidence accepts only `opsle.value-receipt.v1` and enforces the +program-owned Visible Value semantics without importing another repository. + +The generic validator checks required identities, units, measurement classes, +finite values, one delta sign convention, evidence references, source trust, +inspectable estimation/model assumptions, controlled experiment identity, safe +aggregation, and counterfactual claim misuse. + +The Context Firewall profile additionally requires exactly raw/visible/avoided +bytes, an exact non-summable ratio, original/retained/suppressed/ambiguous event +counts, payload ceiling, escalation, and raw-locator state. Every value is +cross-checked against the packet. A structurally valid generic receipt with a +wrong raw-byte value is invalid for this profile. + +Packet validation emits its own sibling receipt with observed validation state +and exact evaluated-claim count. It reports tamper or inconsistency detection, +not failure prevention. Full receipts use API return values or a caller-requested +sidecar; canonical decision JSON remains on stdout and one named operator line +remains on stderr. diff --git a/fixtures/context-firewall-packet-v1/vectors.json b/fixtures/context-firewall-packet-v1/vectors.json index 9849d14..4493d7d 100644 --- a/fixtures/context-firewall-packet-v1/vectors.json +++ b/fixtures/context-firewall-packet-v1/vectors.json @@ -1,5 +1,5 @@ { - "context_firewall_revision": "dd34bd9f681314761f1ca87f339648bf611811f3", + "context_firewall_revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", "invalid_vectors": [ { "id": "missing-required-field", @@ -333,7 +333,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -361,7 +361,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -418,6 +418,301 @@ "data": "TAP version 13\nok 1 - alpha\nok 2 - beta\n1..2\n# tests 2\n# pass 2\n# fail 0\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:a241d570cd2f4cbfc1e3769c3606b21317e78cae1ff298abf69223e09915480d", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:c5f859435187b89c8377b6426bfdf236a50e139fa632274ef08ae0445a64b006", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 104, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 104, + "class": "EXACT", + "delta": 1720, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 1824, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 1824, + "class": "EXACT", + "delta": -1720, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 104, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-1720/104", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 9, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 9, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -491,7 +786,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -519,7 +814,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -578,6 +873,301 @@ "data": "TAP version 13\nnot ok 1 - adds values\n message: expected two\n expected: 2\n actual: 3\n1..1\n# tests 1\n# pass 0\n# fail 1\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:b39c39b5cc00dd7177e6628b3a247967f2d9ad10b24a67f0512bed5321a83e12", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:a5aef42a220e82a4d629e81cadb3d2c14cf00cb383a7ba73abf96fa70261538f", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 152, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 152, + "class": "EXACT", + "delta": 2401, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 2553, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 2553, + "class": "EXACT", + "delta": -2401, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 152, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-2401/152", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 11, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 4, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 7, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -675,7 +1265,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -703,7 +1293,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -761,6 +1351,301 @@ "data": "TAP version 13\nnot ok 1 - first\n message: first broke\nnot ok 2 - second\n message: second broke\nnot ok 3 - third\n message: third broke\n1..3\n# tests 3\n# pass 0\n# fail 3\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:104a99176603c3bb2d387260331e5cb1a199c77f0bc722baecd575dc806e50bc", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:c09851d8d77f5525b9515d5194e690166a6d1d68a368bdc53777e2118f36974c", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 201, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 201, + "class": "EXACT", + "delta": 2772, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 2973, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 2973, + "class": "EXACT", + "delta": -2772, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 201, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-2772/201", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 13, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 6, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 7, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -800,7 +1685,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -828,7 +1713,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -885,6 +1770,301 @@ "data": "TAP version 13\nok 1 - case-0001\nok 2 - case-0002\nok 3 - case-0003\nok 4 - case-0004\nok 5 - case-0005\nok 6 - case-0006\nok 7 - case-0007\nok 8 - case-0008\nok 9 - case-0009\nok 10 - case-0010\nok 11 - case-0011\nok 12 - case-0012\nok 13 - case-0013\nok 14 - case-0014\nok 15 - case-0015\nok 16 - case-0016\nok 17 - case-0017\nok 18 - case-0018\nok 19 - case-0019\nok 20 - case-0020\nok 21 - case-0021\nok 22 - case-0022\nok 23 - case-0023\nok 24 - case-0024\nok 25 - case-0025\nok 26 - case-0026\nok 27 - case-0027\nok 28 - case-0028\nok 29 - case-0029\nok 30 - case-0030\nok 31 - case-0031\nok 32 - case-0032\nok 33 - case-0033\nok 34 - case-0034\nok 35 - case-0035\nok 36 - case-0036\nok 37 - case-0037\nok 38 - case-0038\nok 39 - case-0039\nok 40 - case-0040\nok 41 - case-0041\nok 42 - case-0042\nok 43 - case-0043\nok 44 - case-0044\nok 45 - case-0045\nok 46 - case-0046\nok 47 - case-0047\nok 48 - case-0048\nok 49 - case-0049\nok 50 - case-0050\nok 51 - case-0051\nok 52 - case-0052\nok 53 - case-0053\nok 54 - case-0054\nok 55 - case-0055\nok 56 - case-0056\nok 57 - case-0057\nok 58 - case-0058\nok 59 - case-0059\nok 60 - case-0060\nok 61 - case-0061\nok 62 - case-0062\nok 63 - case-0063\nok 64 - case-0064\nok 65 - case-0065\nok 66 - case-0066\nok 67 - case-0067\nok 68 - case-0068\nok 69 - case-0069\nok 70 - case-0070\nok 71 - case-0071\nok 72 - case-0072\nok 73 - case-0073\nok 74 - case-0074\nok 75 - case-0075\nok 76 - case-0076\nok 77 - case-0077\nok 78 - case-0078\nok 79 - case-0079\nok 80 - case-0080\nok 81 - case-0081\nok 82 - case-0082\nok 83 - case-0083\nok 84 - case-0084\nok 85 - case-0085\nok 86 - case-0086\nok 87 - case-0087\nok 88 - case-0088\nok 89 - case-0089\nok 90 - case-0090\nok 91 - case-0091\nok 92 - case-0092\nok 93 - case-0093\nok 94 - case-0094\nok 95 - case-0095\nok 96 - case-0096\nok 97 - case-0097\nok 98 - case-0098\nok 99 - case-0099\nok 100 - case-0100\nok 101 - case-0101\nok 102 - case-0102\nok 103 - case-0103\nok 104 - case-0104\nok 105 - case-0105\nok 106 - case-0106\nok 107 - case-0107\nok 108 - case-0108\nok 109 - case-0109\nok 110 - case-0110\nok 111 - case-0111\nok 112 - case-0112\nok 113 - case-0113\nok 114 - case-0114\nok 115 - case-0115\nok 116 - case-0116\nok 117 - case-0117\nok 118 - case-0118\nok 119 - case-0119\nok 120 - case-0120\nok 121 - case-0121\nok 122 - case-0122\nok 123 - case-0123\nok 124 - case-0124\nok 125 - case-0125\nok 126 - case-0126\nok 127 - case-0127\nok 128 - case-0128\nok 129 - case-0129\nok 130 - case-0130\nok 131 - case-0131\nok 132 - case-0132\nok 133 - case-0133\nok 134 - case-0134\nok 135 - case-0135\nok 136 - case-0136\nok 137 - case-0137\nok 138 - case-0138\nok 139 - case-0139\nok 140 - case-0140\nok 141 - case-0141\nok 142 - case-0142\nok 143 - case-0143\nok 144 - case-0144\nok 145 - case-0145\nok 146 - case-0146\nok 147 - case-0147\nok 148 - case-0148\nok 149 - case-0149\nok 150 - case-0150\nok 151 - case-0151\nok 152 - case-0152\nok 153 - case-0153\nok 154 - case-0154\nok 155 - case-0155\nok 156 - case-0156\nok 157 - case-0157\nok 158 - case-0158\nok 159 - case-0159\nok 160 - case-0160\nok 161 - case-0161\nok 162 - case-0162\nok 163 - case-0163\nok 164 - case-0164\nok 165 - case-0165\nok 166 - case-0166\nok 167 - case-0167\nok 168 - case-0168\nok 169 - case-0169\nok 170 - case-0170\nok 171 - case-0171\nok 172 - case-0172\nok 173 - case-0173\nok 174 - case-0174\nok 175 - case-0175\nok 176 - case-0176\nok 177 - case-0177\nok 178 - case-0178\nok 179 - case-0179\nok 180 - case-0180\nok 181 - case-0181\nok 182 - case-0182\nok 183 - case-0183\nok 184 - case-0184\nok 185 - case-0185\nok 186 - case-0186\nok 187 - case-0187\nok 188 - case-0188\nok 189 - case-0189\nok 190 - case-0190\nok 191 - case-0191\nok 192 - case-0192\nok 193 - case-0193\nok 194 - case-0194\nok 195 - case-0195\nok 196 - case-0196\nok 197 - case-0197\nok 198 - case-0198\nok 199 - case-0199\nok 200 - case-0200\nok 201 - case-0201\nok 202 - case-0202\nok 203 - case-0203\nok 204 - case-0204\nok 205 - case-0205\nok 206 - case-0206\nok 207 - case-0207\nok 208 - case-0208\nok 209 - case-0209\nok 210 - case-0210\nok 211 - case-0211\nok 212 - case-0212\nok 213 - case-0213\nok 214 - case-0214\nok 215 - case-0215\nok 216 - case-0216\nok 217 - case-0217\nok 218 - case-0218\nok 219 - case-0219\nok 220 - case-0220\nok 221 - case-0221\nok 222 - case-0222\nok 223 - case-0223\nok 224 - case-0224\nok 225 - case-0225\nok 226 - case-0226\nok 227 - case-0227\nok 228 - case-0228\nok 229 - case-0229\nok 230 - case-0230\nok 231 - case-0231\nok 232 - case-0232\nok 233 - case-0233\nok 234 - case-0234\nok 235 - case-0235\nok 236 - case-0236\nok 237 - case-0237\nok 238 - case-0238\nok 239 - case-0239\nok 240 - case-0240\nok 241 - case-0241\nok 242 - case-0242\nok 243 - case-0243\nok 244 - case-0244\nok 245 - case-0245\nok 246 - case-0246\nok 247 - case-0247\nok 248 - case-0248\nok 249 - case-0249\nok 250 - case-0250\nok 251 - case-0251\nok 252 - case-0252\nok 253 - case-0253\nok 254 - case-0254\nok 255 - case-0255\nok 256 - case-0256\nok 257 - case-0257\nok 258 - case-0258\nok 259 - case-0259\nok 260 - case-0260\nok 261 - case-0261\nok 262 - case-0262\nok 263 - case-0263\nok 264 - case-0264\nok 265 - case-0265\nok 266 - case-0266\nok 267 - case-0267\nok 268 - case-0268\nok 269 - case-0269\nok 270 - case-0270\nok 271 - case-0271\nok 272 - case-0272\nok 273 - case-0273\nok 274 - case-0274\nok 275 - case-0275\nok 276 - case-0276\nok 277 - case-0277\nok 278 - case-0278\nok 279 - case-0279\nok 280 - case-0280\nok 281 - case-0281\nok 282 - case-0282\nok 283 - case-0283\nok 284 - case-0284\nok 285 - case-0285\nok 286 - case-0286\nok 287 - case-0287\nok 288 - case-0288\nok 289 - case-0289\nok 290 - case-0290\nok 291 - case-0291\nok 292 - case-0292\nok 293 - case-0293\nok 294 - case-0294\nok 295 - case-0295\nok 296 - case-0296\nok 297 - case-0297\nok 298 - case-0298\nok 299 - case-0299\nok 300 - case-0300\nok 301 - case-0301\nok 302 - case-0302\nok 303 - case-0303\nok 304 - case-0304\nok 305 - case-0305\nok 306 - case-0306\nok 307 - case-0307\nok 308 - case-0308\nok 309 - case-0309\nok 310 - case-0310\nok 311 - case-0311\nok 312 - case-0312\nok 313 - case-0313\nok 314 - case-0314\nok 315 - case-0315\nok 316 - case-0316\nok 317 - case-0317\nok 318 - case-0318\nok 319 - case-0319\nok 320 - case-0320\nok 321 - case-0321\nok 322 - case-0322\nok 323 - case-0323\nok 324 - case-0324\nok 325 - case-0325\nok 326 - case-0326\nok 327 - case-0327\nok 328 - case-0328\nok 329 - case-0329\nok 330 - case-0330\nok 331 - case-0331\nok 332 - case-0332\nok 333 - case-0333\nok 334 - case-0334\nok 335 - case-0335\nok 336 - case-0336\nok 337 - case-0337\nok 338 - case-0338\nok 339 - case-0339\nok 340 - case-0340\nok 341 - case-0341\nok 342 - case-0342\nok 343 - case-0343\nok 344 - case-0344\nok 345 - case-0345\nok 346 - case-0346\nok 347 - case-0347\nok 348 - case-0348\nok 349 - case-0349\nok 350 - case-0350\nok 351 - case-0351\nok 352 - case-0352\nok 353 - case-0353\nok 354 - case-0354\nok 355 - case-0355\nok 356 - case-0356\nok 357 - case-0357\nok 358 - case-0358\nok 359 - case-0359\nok 360 - case-0360\nok 361 - case-0361\nok 362 - case-0362\nok 363 - case-0363\nok 364 - case-0364\nok 365 - case-0365\nok 366 - case-0366\nok 367 - case-0367\nok 368 - case-0368\nok 369 - case-0369\nok 370 - case-0370\nok 371 - case-0371\nok 372 - case-0372\nok 373 - case-0373\nok 374 - case-0374\nok 375 - case-0375\nok 376 - case-0376\nok 377 - case-0377\nok 378 - case-0378\nok 379 - case-0379\nok 380 - case-0380\nok 381 - case-0381\nok 382 - case-0382\nok 383 - case-0383\nok 384 - case-0384\nok 385 - case-0385\nok 386 - case-0386\nok 387 - case-0387\nok 388 - case-0388\nok 389 - case-0389\nok 390 - case-0390\nok 391 - case-0391\nok 392 - case-0392\nok 393 - case-0393\nok 394 - case-0394\nok 395 - case-0395\nok 396 - case-0396\nok 397 - case-0397\nok 398 - case-0398\nok 399 - case-0399\nok 400 - case-0400\nok 401 - case-0401\nok 402 - case-0402\nok 403 - case-0403\nok 404 - case-0404\nok 405 - case-0405\nok 406 - case-0406\nok 407 - case-0407\nok 408 - case-0408\nok 409 - case-0409\nok 410 - case-0410\nok 411 - case-0411\nok 412 - case-0412\nok 413 - case-0413\nok 414 - case-0414\nok 415 - case-0415\nok 416 - case-0416\nok 417 - case-0417\nok 418 - case-0418\nok 419 - case-0419\nok 420 - case-0420\nok 421 - case-0421\nok 422 - case-0422\nok 423 - case-0423\nok 424 - case-0424\nok 425 - case-0425\nok 426 - case-0426\nok 427 - case-0427\nok 428 - case-0428\nok 429 - case-0429\nok 430 - case-0430\nok 431 - case-0431\nok 432 - case-0432\nok 433 - case-0433\nok 434 - case-0434\nok 435 - case-0435\nok 436 - case-0436\nok 437 - case-0437\nok 438 - case-0438\nok 439 - case-0439\nok 440 - case-0440\nok 441 - case-0441\nok 442 - case-0442\nok 443 - case-0443\nok 444 - case-0444\nok 445 - case-0445\nok 446 - case-0446\nok 447 - case-0447\nok 448 - case-0448\nok 449 - case-0449\nok 450 - case-0450\nok 451 - case-0451\nok 452 - case-0452\nok 453 - case-0453\nok 454 - case-0454\nok 455 - case-0455\nok 456 - case-0456\nok 457 - case-0457\nok 458 - case-0458\nok 459 - case-0459\nok 460 - case-0460\nok 461 - case-0461\nok 462 - case-0462\nok 463 - case-0463\nok 464 - case-0464\nok 465 - case-0465\nok 466 - case-0466\nok 467 - case-0467\nok 468 - case-0468\nok 469 - case-0469\nok 470 - case-0470\nok 471 - case-0471\nok 472 - case-0472\nok 473 - case-0473\nok 474 - case-0474\nok 475 - case-0475\nok 476 - case-0476\nok 477 - case-0477\nok 478 - case-0478\nok 479 - case-0479\nok 480 - case-0480\nok 481 - case-0481\nok 482 - case-0482\nok 483 - case-0483\nok 484 - case-0484\nok 485 - case-0485\nok 486 - case-0486\nok 487 - case-0487\nok 488 - case-0488\nok 489 - case-0489\nok 490 - case-0490\nok 491 - case-0491\nok 492 - case-0492\nok 493 - case-0493\nok 494 - case-0494\nok 495 - case-0495\nok 496 - case-0496\nok 497 - case-0497\nok 498 - case-0498\nok 499 - case-0499\nok 500 - case-0500\nok 501 - case-0501\nok 502 - case-0502\nok 503 - case-0503\nok 504 - case-0504\nok 505 - case-0505\nok 506 - case-0506\nok 507 - case-0507\nok 508 - case-0508\nok 509 - case-0509\nok 510 - case-0510\nok 511 - case-0511\nok 512 - case-0512\nok 513 - case-0513\nok 514 - case-0514\nok 515 - case-0515\nok 516 - case-0516\nok 517 - case-0517\nok 518 - case-0518\nok 519 - case-0519\nok 520 - case-0520\nok 521 - case-0521\nok 522 - case-0522\nok 523 - case-0523\nok 524 - case-0524\nok 525 - case-0525\nok 526 - case-0526\nok 527 - case-0527\nok 528 - case-0528\nok 529 - case-0529\nok 530 - case-0530\nok 531 - case-0531\nok 532 - case-0532\nok 533 - case-0533\nok 534 - case-0534\nok 535 - case-0535\nok 536 - case-0536\nok 537 - case-0537\nok 538 - case-0538\nok 539 - case-0539\nok 540 - case-0540\nok 541 - case-0541\nok 542 - case-0542\nok 543 - case-0543\nok 544 - case-0544\nok 545 - case-0545\nok 546 - case-0546\nok 547 - case-0547\nok 548 - case-0548\nok 549 - case-0549\nok 550 - case-0550\nok 551 - case-0551\nok 552 - case-0552\nok 553 - case-0553\nok 554 - case-0554\nok 555 - case-0555\nok 556 - case-0556\nok 557 - case-0557\nok 558 - case-0558\nok 559 - case-0559\nok 560 - case-0560\nok 561 - case-0561\nok 562 - case-0562\nok 563 - case-0563\nok 564 - case-0564\nok 565 - case-0565\nok 566 - case-0566\nok 567 - case-0567\nok 568 - case-0568\nok 569 - case-0569\nok 570 - case-0570\nok 571 - case-0571\nok 572 - case-0572\nok 573 - case-0573\nok 574 - case-0574\nok 575 - case-0575\nok 576 - case-0576\nok 577 - case-0577\nok 578 - case-0578\nok 579 - case-0579\nok 580 - case-0580\nok 581 - case-0581\nok 582 - case-0582\nok 583 - case-0583\nok 584 - case-0584\nok 585 - case-0585\nok 586 - case-0586\nok 587 - case-0587\nok 588 - case-0588\nok 589 - case-0589\nok 590 - case-0590\nok 591 - case-0591\nok 592 - case-0592\nok 593 - case-0593\nok 594 - case-0594\nok 595 - case-0595\nok 596 - case-0596\nok 597 - case-0597\nok 598 - case-0598\nok 599 - case-0599\nok 600 - case-0600\nok 601 - case-0601\nok 602 - case-0602\nok 603 - case-0603\nok 604 - case-0604\nok 605 - case-0605\nok 606 - case-0606\nok 607 - case-0607\nok 608 - case-0608\nok 609 - case-0609\nok 610 - case-0610\nok 611 - case-0611\nok 612 - case-0612\nok 613 - case-0613\nok 614 - case-0614\nok 615 - case-0615\nok 616 - case-0616\nok 617 - case-0617\nok 618 - case-0618\nok 619 - case-0619\nok 620 - case-0620\nok 621 - case-0621\nok 622 - case-0622\nok 623 - case-0623\nok 624 - case-0624\nok 625 - case-0625\nok 626 - case-0626\nok 627 - case-0627\nok 628 - case-0628\nok 629 - case-0629\nok 630 - case-0630\nok 631 - case-0631\nok 632 - case-0632\nok 633 - case-0633\nok 634 - case-0634\nok 635 - case-0635\nok 636 - case-0636\nok 637 - case-0637\nok 638 - case-0638\nok 639 - case-0639\nok 640 - case-0640\nok 641 - case-0641\nok 642 - case-0642\nok 643 - case-0643\nok 644 - case-0644\nok 645 - case-0645\nok 646 - case-0646\nok 647 - case-0647\nok 648 - case-0648\nok 649 - case-0649\nok 650 - case-0650\nok 651 - case-0651\nok 652 - case-0652\nok 653 - case-0653\nok 654 - case-0654\nok 655 - case-0655\nok 656 - case-0656\nok 657 - case-0657\nok 658 - case-0658\nok 659 - case-0659\nok 660 - case-0660\nok 661 - case-0661\nok 662 - case-0662\nok 663 - case-0663\nok 664 - case-0664\nok 665 - case-0665\nok 666 - case-0666\nok 667 - case-0667\nok 668 - case-0668\nok 669 - case-0669\nok 670 - case-0670\nok 671 - case-0671\nok 672 - case-0672\nok 673 - case-0673\nok 674 - case-0674\nok 675 - case-0675\nok 676 - case-0676\nok 677 - case-0677\nok 678 - case-0678\nok 679 - case-0679\nok 680 - case-0680\nok 681 - case-0681\nok 682 - case-0682\nok 683 - case-0683\nok 684 - case-0684\nok 685 - case-0685\nok 686 - case-0686\nok 687 - case-0687\nok 688 - case-0688\nok 689 - case-0689\nok 690 - case-0690\nok 691 - case-0691\nok 692 - case-0692\nok 693 - case-0693\nok 694 - case-0694\nok 695 - case-0695\nok 696 - case-0696\nok 697 - case-0697\nok 698 - case-0698\nok 699 - case-0699\nok 700 - case-0700\nok 701 - case-0701\nok 702 - case-0702\nok 703 - case-0703\nok 704 - case-0704\nok 705 - case-0705\nok 706 - case-0706\nok 707 - case-0707\nok 708 - case-0708\nok 709 - case-0709\nok 710 - case-0710\nok 711 - case-0711\nok 712 - case-0712\nok 713 - case-0713\nok 714 - case-0714\nok 715 - case-0715\nok 716 - case-0716\nok 717 - case-0717\nok 718 - case-0718\nok 719 - case-0719\nok 720 - case-0720\nok 721 - case-0721\nok 722 - case-0722\nok 723 - case-0723\nok 724 - case-0724\nok 725 - case-0725\nok 726 - case-0726\nok 727 - case-0727\nok 728 - case-0728\nok 729 - case-0729\nok 730 - case-0730\nok 731 - case-0731\nok 732 - case-0732\nok 733 - case-0733\nok 734 - case-0734\nok 735 - case-0735\nok 736 - case-0736\nok 737 - case-0737\nok 738 - case-0738\nok 739 - case-0739\nok 740 - case-0740\nok 741 - case-0741\nok 742 - case-0742\nok 743 - case-0743\nok 744 - case-0744\nok 745 - case-0745\nok 746 - case-0746\nok 747 - case-0747\nok 748 - case-0748\nok 749 - case-0749\nok 750 - case-0750\nok 751 - case-0751\nok 752 - case-0752\nok 753 - case-0753\nok 754 - case-0754\nok 755 - case-0755\nok 756 - case-0756\nok 757 - case-0757\nok 758 - case-0758\nok 759 - case-0759\nok 760 - case-0760\nok 761 - case-0761\nok 762 - case-0762\nok 763 - case-0763\nok 764 - case-0764\nok 765 - case-0765\nok 766 - case-0766\nok 767 - case-0767\nok 768 - case-0768\nok 769 - case-0769\nok 770 - case-0770\nok 771 - case-0771\nok 772 - case-0772\nok 773 - case-0773\nok 774 - case-0774\nok 775 - case-0775\nok 776 - case-0776\nok 777 - case-0777\nok 778 - case-0778\nok 779 - case-0779\nok 780 - case-0780\nok 781 - case-0781\nok 782 - case-0782\nok 783 - case-0783\nok 784 - case-0784\nok 785 - case-0785\nok 786 - case-0786\nok 787 - case-0787\nok 788 - case-0788\nok 789 - case-0789\nok 790 - case-0790\nok 791 - case-0791\nok 792 - case-0792\nok 793 - case-0793\nok 794 - case-0794\nok 795 - case-0795\nok 796 - case-0796\nok 797 - case-0797\nok 798 - case-0798\nok 799 - case-0799\nok 800 - case-0800\nok 801 - case-0801\nok 802 - case-0802\nok 803 - case-0803\nok 804 - case-0804\nok 805 - case-0805\nok 806 - case-0806\nok 807 - case-0807\nok 808 - case-0808\nok 809 - case-0809\nok 810 - case-0810\nok 811 - case-0811\nok 812 - case-0812\nok 813 - case-0813\nok 814 - case-0814\nok 815 - case-0815\nok 816 - case-0816\nok 817 - case-0817\nok 818 - case-0818\nok 819 - case-0819\nok 820 - case-0820\nok 821 - case-0821\nok 822 - case-0822\nok 823 - case-0823\nok 824 - case-0824\nok 825 - case-0825\nok 826 - case-0826\nok 827 - case-0827\nok 828 - case-0828\nok 829 - case-0829\nok 830 - case-0830\nok 831 - case-0831\nok 832 - case-0832\nok 833 - case-0833\nok 834 - case-0834\nok 835 - case-0835\nok 836 - case-0836\nok 837 - case-0837\nok 838 - case-0838\nok 839 - case-0839\nok 840 - case-0840\nok 841 - case-0841\nok 842 - case-0842\nok 843 - case-0843\nok 844 - case-0844\nok 845 - case-0845\nok 846 - case-0846\nok 847 - case-0847\nok 848 - case-0848\nok 849 - case-0849\nok 850 - case-0850\nok 851 - case-0851\nok 852 - case-0852\nok 853 - case-0853\nok 854 - case-0854\nok 855 - case-0855\nok 856 - case-0856\nok 857 - case-0857\nok 858 - case-0858\nok 859 - case-0859\nok 860 - case-0860\nok 861 - case-0861\nok 862 - case-0862\nok 863 - case-0863\nok 864 - case-0864\nok 865 - case-0865\nok 866 - case-0866\nok 867 - case-0867\nok 868 - case-0868\nok 869 - case-0869\nok 870 - case-0870\nok 871 - case-0871\nok 872 - case-0872\nok 873 - case-0873\nok 874 - case-0874\nok 875 - case-0875\nok 876 - case-0876\nok 877 - case-0877\nok 878 - case-0878\nok 879 - case-0879\nok 880 - case-0880\nok 881 - case-0881\nok 882 - case-0882\nok 883 - case-0883\nok 884 - case-0884\nok 885 - case-0885\nok 886 - case-0886\nok 887 - case-0887\nok 888 - case-0888\nok 889 - case-0889\nok 890 - case-0890\nok 891 - case-0891\nok 892 - case-0892\nok 893 - case-0893\nok 894 - case-0894\nok 895 - case-0895\nok 896 - case-0896\nok 897 - case-0897\nok 898 - case-0898\nok 899 - case-0899\nok 900 - case-0900\nok 901 - case-0901\nok 902 - case-0902\nok 903 - case-0903\nok 904 - case-0904\nok 905 - case-0905\nok 906 - case-0906\nok 907 - case-0907\nok 908 - case-0908\nok 909 - case-0909\nok 910 - case-0910\nok 911 - case-0911\nok 912 - case-0912\nok 913 - case-0913\nok 914 - case-0914\nok 915 - case-0915\nok 916 - case-0916\nok 917 - case-0917\nok 918 - case-0918\nok 919 - case-0919\nok 920 - case-0920\nok 921 - case-0921\nok 922 - case-0922\nok 923 - case-0923\nok 924 - case-0924\nok 925 - case-0925\nok 926 - case-0926\nok 927 - case-0927\nok 928 - case-0928\nok 929 - case-0929\nok 930 - case-0930\nok 931 - case-0931\nok 932 - case-0932\nok 933 - case-0933\nok 934 - case-0934\nok 935 - case-0935\nok 936 - case-0936\nok 937 - case-0937\nok 938 - case-0938\nok 939 - case-0939\nok 940 - case-0940\nok 941 - case-0941\nok 942 - case-0942\nok 943 - case-0943\nok 944 - case-0944\nok 945 - case-0945\nok 946 - case-0946\nok 947 - case-0947\nok 948 - case-0948\nok 949 - case-0949\nok 950 - case-0950\nok 951 - case-0951\nok 952 - case-0952\nok 953 - case-0953\nok 954 - case-0954\nok 955 - case-0955\nok 956 - case-0956\nok 957 - case-0957\nok 958 - case-0958\nok 959 - case-0959\nok 960 - case-0960\nok 961 - case-0961\nok 962 - case-0962\nok 963 - case-0963\nok 964 - case-0964\nok 965 - case-0965\nok 966 - case-0966\nok 967 - case-0967\nok 968 - case-0968\nok 969 - case-0969\nok 970 - case-0970\nok 971 - case-0971\nok 972 - case-0972\nok 973 - case-0973\nok 974 - case-0974\nok 975 - case-0975\nok 976 - case-0976\nok 977 - case-0977\nok 978 - case-0978\nok 979 - case-0979\nok 980 - case-0980\nok 981 - case-0981\nok 982 - case-0982\nok 983 - case-0983\nok 984 - case-0984\nok 985 - case-0985\nok 986 - case-0986\nok 987 - case-0987\nok 988 - case-0988\nok 989 - case-0989\nok 990 - case-0990\nok 991 - case-0991\nok 992 - case-0992\nok 993 - case-0993\nok 994 - case-0994\nok 995 - case-0995\nok 996 - case-0996\nok 997 - case-0997\nok 998 - case-0998\nok 999 - case-0999\nok 1000 - case-1000\nok 1001 - case-1001\nok 1002 - case-1002\nok 1003 - case-1003\nok 1004 - case-1004\nok 1005 - case-1005\nok 1006 - case-1006\nok 1007 - case-1007\nok 1008 - case-1008\nok 1009 - case-1009\nok 1010 - case-1010\nok 1011 - case-1011\nok 1012 - case-1012\nok 1013 - case-1013\nok 1014 - case-1014\nok 1015 - case-1015\nok 1016 - case-1016\nok 1017 - case-1017\nok 1018 - case-1018\nok 1019 - case-1019\nok 1020 - case-1020\nok 1021 - case-1021\nok 1022 - case-1022\nok 1023 - case-1023\nok 1024 - case-1024\nok 1025 - case-1025\nok 1026 - case-1026\nok 1027 - case-1027\nok 1028 - case-1028\nok 1029 - case-1029\nok 1030 - case-1030\nok 1031 - case-1031\nok 1032 - case-1032\nok 1033 - case-1033\nok 1034 - case-1034\nok 1035 - case-1035\nok 1036 - case-1036\nok 1037 - case-1037\nok 1038 - case-1038\nok 1039 - case-1039\nok 1040 - case-1040\nok 1041 - case-1041\nok 1042 - case-1042\nok 1043 - case-1043\nok 1044 - case-1044\nok 1045 - case-1045\nok 1046 - case-1046\nok 1047 - case-1047\nok 1048 - case-1048\nok 1049 - case-1049\nok 1050 - case-1050\nok 1051 - case-1051\nok 1052 - case-1052\nok 1053 - case-1053\nok 1054 - case-1054\nok 1055 - case-1055\nok 1056 - case-1056\nok 1057 - case-1057\nok 1058 - case-1058\nok 1059 - case-1059\nok 1060 - case-1060\nok 1061 - case-1061\nok 1062 - case-1062\nok 1063 - case-1063\nok 1064 - case-1064\nok 1065 - case-1065\nok 1066 - case-1066\nok 1067 - case-1067\nok 1068 - case-1068\nok 1069 - case-1069\nok 1070 - case-1070\nok 1071 - case-1071\nok 1072 - case-1072\nok 1073 - case-1073\nok 1074 - case-1074\nok 1075 - case-1075\nok 1076 - case-1076\nok 1077 - case-1077\nok 1078 - case-1078\nok 1079 - case-1079\nok 1080 - case-1080\nok 1081 - case-1081\nok 1082 - case-1082\nok 1083 - case-1083\nok 1084 - case-1084\nok 1085 - case-1085\nok 1086 - case-1086\nok 1087 - case-1087\nok 1088 - case-1088\nok 1089 - case-1089\nok 1090 - case-1090\nok 1091 - case-1091\nok 1092 - case-1092\nok 1093 - case-1093\nok 1094 - case-1094\nok 1095 - case-1095\nok 1096 - case-1096\nok 1097 - case-1097\nok 1098 - case-1098\nok 1099 - case-1099\nok 1100 - case-1100\nok 1101 - case-1101\nok 1102 - case-1102\nok 1103 - case-1103\nok 1104 - case-1104\nok 1105 - case-1105\nok 1106 - case-1106\nok 1107 - case-1107\nok 1108 - case-1108\nok 1109 - case-1109\nok 1110 - case-1110\nok 1111 - case-1111\nok 1112 - case-1112\nok 1113 - case-1113\nok 1114 - case-1114\nok 1115 - case-1115\nok 1116 - case-1116\nok 1117 - case-1117\nok 1118 - case-1118\nok 1119 - case-1119\nok 1120 - case-1120\nok 1121 - case-1121\nok 1122 - case-1122\nok 1123 - case-1123\nok 1124 - case-1124\nok 1125 - case-1125\nok 1126 - case-1126\nok 1127 - case-1127\nok 1128 - case-1128\nok 1129 - case-1129\nok 1130 - case-1130\nok 1131 - case-1131\nok 1132 - case-1132\nok 1133 - case-1133\nok 1134 - case-1134\nok 1135 - case-1135\nok 1136 - case-1136\nok 1137 - case-1137\nok 1138 - case-1138\nok 1139 - case-1139\nok 1140 - case-1140\nok 1141 - case-1141\nok 1142 - case-1142\nok 1143 - case-1143\nok 1144 - case-1144\nok 1145 - case-1145\nok 1146 - case-1146\nok 1147 - case-1147\nok 1148 - case-1148\nok 1149 - case-1149\nok 1150 - case-1150\nok 1151 - case-1151\nok 1152 - case-1152\nok 1153 - case-1153\nok 1154 - case-1154\nok 1155 - case-1155\nok 1156 - case-1156\nok 1157 - case-1157\nok 1158 - case-1158\nok 1159 - case-1159\nok 1160 - case-1160\nok 1161 - case-1161\nok 1162 - case-1162\nok 1163 - case-1163\nok 1164 - case-1164\nok 1165 - case-1165\nok 1166 - case-1166\nok 1167 - case-1167\nok 1168 - case-1168\nok 1169 - case-1169\nok 1170 - case-1170\nok 1171 - case-1171\nok 1172 - case-1172\nok 1173 - case-1173\nok 1174 - case-1174\nok 1175 - case-1175\nok 1176 - case-1176\nok 1177 - case-1177\nok 1178 - case-1178\nok 1179 - case-1179\nok 1180 - case-1180\nok 1181 - case-1181\nok 1182 - case-1182\nok 1183 - case-1183\nok 1184 - case-1184\nok 1185 - case-1185\nok 1186 - case-1186\nok 1187 - case-1187\nok 1188 - case-1188\nok 1189 - case-1189\nok 1190 - case-1190\nok 1191 - case-1191\nok 1192 - case-1192\nok 1193 - case-1193\nok 1194 - case-1194\nok 1195 - case-1195\nok 1196 - case-1196\nok 1197 - case-1197\nok 1198 - case-1198\nok 1199 - case-1199\nok 1200 - case-1200\nok 1201 - case-1201\nok 1202 - case-1202\nok 1203 - case-1203\nok 1204 - case-1204\nok 1205 - case-1205\nok 1206 - case-1206\nok 1207 - case-1207\nok 1208 - case-1208\nok 1209 - case-1209\nok 1210 - case-1210\nok 1211 - case-1211\nok 1212 - case-1212\nok 1213 - case-1213\nok 1214 - case-1214\nok 1215 - case-1215\nok 1216 - case-1216\nok 1217 - case-1217\nok 1218 - case-1218\nok 1219 - case-1219\nok 1220 - case-1220\nok 1221 - case-1221\nok 1222 - case-1222\nok 1223 - case-1223\nok 1224 - case-1224\nok 1225 - case-1225\nok 1226 - case-1226\nok 1227 - case-1227\nok 1228 - case-1228\nok 1229 - case-1229\nok 1230 - case-1230\nok 1231 - case-1231\nok 1232 - case-1232\nok 1233 - case-1233\nok 1234 - case-1234\nok 1235 - case-1235\nok 1236 - case-1236\nok 1237 - case-1237\nok 1238 - case-1238\nok 1239 - case-1239\nok 1240 - case-1240\nok 1241 - case-1241\nok 1242 - case-1242\nok 1243 - case-1243\nok 1244 - case-1244\nok 1245 - case-1245\nok 1246 - case-1246\nok 1247 - case-1247\nok 1248 - case-1248\nok 1249 - case-1249\nok 1250 - case-1250\nok 1251 - case-1251\nok 1252 - case-1252\nok 1253 - case-1253\nok 1254 - case-1254\nok 1255 - case-1255\nok 1256 - case-1256\nok 1257 - case-1257\nok 1258 - case-1258\nok 1259 - case-1259\nok 1260 - case-1260\nok 1261 - case-1261\nok 1262 - case-1262\nok 1263 - case-1263\nok 1264 - case-1264\nok 1265 - case-1265\nok 1266 - case-1266\nok 1267 - case-1267\nok 1268 - case-1268\nok 1269 - case-1269\nok 1270 - case-1270\nok 1271 - case-1271\nok 1272 - case-1272\nok 1273 - case-1273\nok 1274 - case-1274\nok 1275 - case-1275\nok 1276 - case-1276\nok 1277 - case-1277\nok 1278 - case-1278\nok 1279 - case-1279\nok 1280 - case-1280\nok 1281 - case-1281\nok 1282 - case-1282\nok 1283 - case-1283\nok 1284 - case-1284\nok 1285 - case-1285\nok 1286 - case-1286\nok 1287 - case-1287\nok 1288 - case-1288\nok 1289 - case-1289\nok 1290 - case-1290\nok 1291 - case-1291\nok 1292 - case-1292\nok 1293 - case-1293\nok 1294 - case-1294\nok 1295 - case-1295\nok 1296 - case-1296\nok 1297 - case-1297\nok 1298 - case-1298\nok 1299 - case-1299\nok 1300 - case-1300\nok 1301 - case-1301\nok 1302 - case-1302\nok 1303 - case-1303\nok 1304 - case-1304\nok 1305 - case-1305\nok 1306 - case-1306\nok 1307 - case-1307\nok 1308 - case-1308\nok 1309 - case-1309\nok 1310 - case-1310\nok 1311 - case-1311\nok 1312 - case-1312\nok 1313 - case-1313\nok 1314 - case-1314\nok 1315 - case-1315\nok 1316 - case-1316\nok 1317 - case-1317\nok 1318 - case-1318\nok 1319 - case-1319\nok 1320 - case-1320\nok 1321 - case-1321\nok 1322 - case-1322\nok 1323 - case-1323\nok 1324 - case-1324\nok 1325 - case-1325\nok 1326 - case-1326\nok 1327 - case-1327\nok 1328 - case-1328\nok 1329 - case-1329\nok 1330 - case-1330\nok 1331 - case-1331\nok 1332 - case-1332\nok 1333 - case-1333\nok 1334 - case-1334\nok 1335 - case-1335\nok 1336 - case-1336\nok 1337 - case-1337\nok 1338 - case-1338\nok 1339 - case-1339\nok 1340 - case-1340\nok 1341 - case-1341\nok 1342 - case-1342\nok 1343 - case-1343\nok 1344 - case-1344\nok 1345 - case-1345\nok 1346 - case-1346\nok 1347 - case-1347\nok 1348 - case-1348\nok 1349 - case-1349\nok 1350 - case-1350\nok 1351 - case-1351\nok 1352 - case-1352\nok 1353 - case-1353\nok 1354 - case-1354\nok 1355 - case-1355\nok 1356 - case-1356\nok 1357 - case-1357\nok 1358 - case-1358\nok 1359 - case-1359\nok 1360 - case-1360\nok 1361 - case-1361\nok 1362 - case-1362\nok 1363 - case-1363\nok 1364 - case-1364\nok 1365 - case-1365\nok 1366 - case-1366\nok 1367 - case-1367\nok 1368 - case-1368\nok 1369 - case-1369\nok 1370 - case-1370\nok 1371 - case-1371\nok 1372 - case-1372\nok 1373 - case-1373\nok 1374 - case-1374\nok 1375 - case-1375\nok 1376 - case-1376\nok 1377 - case-1377\nok 1378 - case-1378\nok 1379 - case-1379\nok 1380 - case-1380\nok 1381 - case-1381\nok 1382 - case-1382\nok 1383 - case-1383\nok 1384 - case-1384\nok 1385 - case-1385\nok 1386 - case-1386\nok 1387 - case-1387\nok 1388 - case-1388\nok 1389 - case-1389\nok 1390 - case-1390\nok 1391 - case-1391\nok 1392 - case-1392\nok 1393 - case-1393\nok 1394 - case-1394\nok 1395 - case-1395\nok 1396 - case-1396\nok 1397 - case-1397\nok 1398 - case-1398\nok 1399 - case-1399\nok 1400 - case-1400\nok 1401 - case-1401\nok 1402 - case-1402\nok 1403 - case-1403\nok 1404 - case-1404\nok 1405 - case-1405\nok 1406 - case-1406\nok 1407 - case-1407\nok 1408 - case-1408\nok 1409 - case-1409\nok 1410 - case-1410\nok 1411 - case-1411\nok 1412 - case-1412\nok 1413 - case-1413\nok 1414 - case-1414\nok 1415 - case-1415\nok 1416 - case-1416\nok 1417 - case-1417\nok 1418 - case-1418\nok 1419 - case-1419\nok 1420 - case-1420\nok 1421 - case-1421\nok 1422 - case-1422\nok 1423 - case-1423\nok 1424 - case-1424\nok 1425 - case-1425\nok 1426 - case-1426\nok 1427 - case-1427\nok 1428 - case-1428\nok 1429 - case-1429\nok 1430 - case-1430\nok 1431 - case-1431\nok 1432 - case-1432\nok 1433 - case-1433\nok 1434 - case-1434\nok 1435 - case-1435\nok 1436 - case-1436\nok 1437 - case-1437\nok 1438 - case-1438\nok 1439 - case-1439\nok 1440 - case-1440\nok 1441 - case-1441\nok 1442 - case-1442\nok 1443 - case-1443\nok 1444 - case-1444\nok 1445 - case-1445\nok 1446 - case-1446\nok 1447 - case-1447\nok 1448 - case-1448\nok 1449 - case-1449\nok 1450 - case-1450\nok 1451 - case-1451\nok 1452 - case-1452\nok 1453 - case-1453\nok 1454 - case-1454\nok 1455 - case-1455\nok 1456 - case-1456\nok 1457 - case-1457\nok 1458 - case-1458\nok 1459 - case-1459\nok 1460 - case-1460\nok 1461 - case-1461\nok 1462 - case-1462\nok 1463 - case-1463\nok 1464 - case-1464\nok 1465 - case-1465\nok 1466 - case-1466\nok 1467 - case-1467\nok 1468 - case-1468\nok 1469 - case-1469\nok 1470 - case-1470\nok 1471 - case-1471\nok 1472 - case-1472\nok 1473 - case-1473\nok 1474 - case-1474\nok 1475 - case-1475\nok 1476 - case-1476\nok 1477 - case-1477\nok 1478 - case-1478\nok 1479 - case-1479\nok 1480 - case-1480\nok 1481 - case-1481\nok 1482 - case-1482\nok 1483 - case-1483\nok 1484 - case-1484\nok 1485 - case-1485\nok 1486 - case-1486\nok 1487 - case-1487\nok 1488 - case-1488\nok 1489 - case-1489\nok 1490 - case-1490\nok 1491 - case-1491\nok 1492 - case-1492\nok 1493 - case-1493\nok 1494 - case-1494\nok 1495 - case-1495\nok 1496 - case-1496\nok 1497 - case-1497\nok 1498 - case-1498\nok 1499 - case-1499\nok 1500 - case-1500\n1..1500\n# tests 1500\n# pass 1500\n# fail 0\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:82ea05bab3fc9551830551372723ab484c5893f93b9ee88bbfaf9a1e9cf42abc", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:d99849b21430365b8b3aefd974d26d625092874054c8c09d1eea69e84e9a4e49", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 28981, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 28981, + "class": "EXACT", + "delta": -27135, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 1846, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 1846, + "class": "EXACT", + "delta": 27135, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 28981, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "27135/28981", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 1507, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 1507, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -924,7 +2104,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -952,7 +2132,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -1009,6 +2189,301 @@ "data": "TAP version 13\nok 1 - addressable\n1..1\n# tests 1\n# pass 1\n# fail 0\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:791657819fc5951657ff6cbdaa1fca425944a52aa1613fb2e8cd81603ed58352", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:836ed51a0e11a3552de9a3625db6a0558dd8f5538c2f7ba590679790a1e196fb", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 98, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 98, + "class": "EXACT", + "delta": 1724, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 1822, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 1822, + "class": "EXACT", + "delta": -1724, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 98, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-1724/98", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 8, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 8, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -1070,7 +2545,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -1098,7 +2573,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": false, "retained": { @@ -1154,6 +2629,301 @@ "data": "TAP version 13\nnot ok 1 - incomplete\n message: cut off" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:95e8762ca9ecab63a1e861b6922a93225b3078279824a9d9d0b5ebe5b31adf39", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:1966d17b65518bef4547428e166d6fdea14ae5365bdb8a6221356d3c61744368", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 55, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 55, + "class": "EXACT", + "delta": 2148, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 2203, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 2203, + "class": "EXACT", + "delta": -2148, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 55, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-2148/55", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 3, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 2, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 1, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": true, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -1210,7 +2980,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:0614f60cadb064fb8af6215cf804498049d57bea091b77157a4edde84cb00e2a", + "identity": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", "max_output_bytes": null, "policy_revision": "tap-subset-policy/v1" }, @@ -1238,7 +3008,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": false, "retained": { @@ -1291,6 +3061,301 @@ "data": "this is not TAP\nnot okay maybe FAIL\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:0b83fa88bc0a2593f2fded10cdfc09ad05f3cbbcad382872ab18ed1e8ea7f4a4", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:bf4b58442ea401cf263c39f723953c92168231c0ca89673b96f72ce782ebcddf", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 36, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 36, + "class": "EXACT", + "delta": 2094, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 2130, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 2130, + "class": "EXACT", + "delta": -2094, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 36, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "-2094/36", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 2, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 2, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 2, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [ + "No payload ceiling was configured." + ], + "operator_display": false, + "result": null, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": true, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:d4f3db209483b7a8815d21a107b9e58ee175a2a7dc9d32b9215e3e4131b9b045", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -1336,7 +3401,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:fac3bbe1a598e2699744a561adbc0b6ded1df9604e1d7977920037ea68997423", + "identity": "sha256:1009bca2968d8a48b0c93ad2872015aa03421cbb6eb48e19cf554c29c43b8adb", "max_output_bytes": 3500, "policy_revision": "tap-subset-policy/v1" }, @@ -1364,7 +3429,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": false, "retained": { @@ -1422,6 +3487,299 @@ "data": "TAP version 13\nnot ok 1 - oversized-critical\n message: criticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcriticalcritical\n1..1\n# tests 1\n# pass 0\n# fail 1\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:1009bca2968d8a48b0c93ad2872015aa03421cbb6eb48e19cf554c29c43b8adb", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:5c702b7f86610b695562ce075812bb2415f9d9eba933749d17972fc524ed105a", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:b71cc862f79684b18a6b8996b404e61c602224c64fb1230ca5e97c89f957b4dd", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 32121, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 32121, + "class": "EXACT", + "delta": -30195, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 1926, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 1926, + "class": "EXACT", + "delta": 30195, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 32121, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "30195/32121", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 9, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 9, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [], + "operator_display": false, + "result": 3500, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": true, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:1009bca2968d8a48b0c93ad2872015aa03421cbb6eb48e19cf554c29c43b8adb", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } }, { @@ -1461,7 +3819,7 @@ "protocol_version": "opsle.context-firewall.evidence-packet/v1", "receipt": { "configuration": { - "identity": "sha256:8e3f0537826d358aa26f585f336fdd011fdd8d086787b74f6f8a6e3f83aae534", + "identity": "sha256:54750b51fe1507277a2d8a33b263c398b108e26d132b20ea0668712d46ddfa89", "max_output_bytes": 1846, "policy_revision": "tap-subset-policy/v1" }, @@ -1489,7 +3847,7 @@ "receipt_version": 1, "reducer": { "name": "@opsle/context-firewall/test-output", - "version": "0.2.0" + "version": "0.3.0" }, "reduction_complete": true, "retained": { @@ -1546,6 +3904,299 @@ "data": "TAP version 13\nok 1 - case-0001\nok 2 - case-0002\nok 3 - case-0003\nok 4 - case-0004\nok 5 - case-0005\nok 6 - case-0006\nok 7 - case-0007\nok 8 - case-0008\nok 9 - case-0009\nok 10 - case-0010\nok 11 - case-0011\nok 12 - case-0012\nok 13 - case-0013\nok 14 - case-0014\nok 15 - case-0015\nok 16 - case-0016\nok 17 - case-0017\nok 18 - case-0018\nok 19 - case-0019\nok 20 - case-0020\nok 21 - case-0021\nok 22 - case-0022\nok 23 - case-0023\nok 24 - case-0024\nok 25 - case-0025\nok 26 - case-0026\nok 27 - case-0027\nok 28 - case-0028\nok 29 - case-0029\nok 30 - case-0030\nok 31 - case-0031\nok 32 - case-0032\nok 33 - case-0033\nok 34 - case-0034\nok 35 - case-0035\nok 36 - case-0036\nok 37 - case-0037\nok 38 - case-0038\nok 39 - case-0039\nok 40 - case-0040\nok 41 - case-0041\nok 42 - case-0042\nok 43 - case-0043\nok 44 - case-0044\nok 45 - case-0045\nok 46 - case-0046\nok 47 - case-0047\nok 48 - case-0048\nok 49 - case-0049\nok 50 - case-0050\nok 51 - case-0051\nok 52 - case-0052\nok 53 - case-0053\nok 54 - case-0054\nok 55 - case-0055\nok 56 - case-0056\nok 57 - case-0057\nok 58 - case-0058\nok 59 - case-0059\nok 60 - case-0060\nok 61 - case-0061\nok 62 - case-0062\nok 63 - case-0063\nok 64 - case-0064\nok 65 - case-0065\nok 66 - case-0066\nok 67 - case-0067\nok 68 - case-0068\nok 69 - case-0069\nok 70 - case-0070\nok 71 - case-0071\nok 72 - case-0072\nok 73 - case-0073\nok 74 - case-0074\nok 75 - case-0075\nok 76 - case-0076\nok 77 - case-0077\nok 78 - case-0078\nok 79 - case-0079\nok 80 - case-0080\nok 81 - case-0081\nok 82 - case-0082\nok 83 - case-0083\nok 84 - case-0084\nok 85 - case-0085\nok 86 - case-0086\nok 87 - case-0087\nok 88 - case-0088\nok 89 - case-0089\nok 90 - case-0090\nok 91 - case-0091\nok 92 - case-0092\nok 93 - case-0093\nok 94 - case-0094\nok 95 - case-0095\nok 96 - case-0096\nok 97 - case-0097\nok 98 - case-0098\nok 99 - case-0099\nok 100 - case-0100\nok 101 - case-0101\nok 102 - case-0102\nok 103 - case-0103\nok 104 - case-0104\nok 105 - case-0105\nok 106 - case-0106\nok 107 - case-0107\nok 108 - case-0108\nok 109 - case-0109\nok 110 - case-0110\nok 111 - case-0111\nok 112 - case-0112\nok 113 - case-0113\nok 114 - case-0114\nok 115 - case-0115\nok 116 - case-0116\nok 117 - case-0117\nok 118 - case-0118\nok 119 - case-0119\nok 120 - case-0120\nok 121 - case-0121\nok 122 - case-0122\nok 123 - case-0123\nok 124 - case-0124\nok 125 - case-0125\nok 126 - case-0126\nok 127 - case-0127\nok 128 - case-0128\nok 129 - case-0129\nok 130 - case-0130\nok 131 - case-0131\nok 132 - case-0132\nok 133 - case-0133\nok 134 - case-0134\nok 135 - case-0135\nok 136 - case-0136\nok 137 - case-0137\nok 138 - case-0138\nok 139 - case-0139\nok 140 - case-0140\nok 141 - case-0141\nok 142 - case-0142\nok 143 - case-0143\nok 144 - case-0144\nok 145 - case-0145\nok 146 - case-0146\nok 147 - case-0147\nok 148 - case-0148\nok 149 - case-0149\nok 150 - case-0150\nok 151 - case-0151\nok 152 - case-0152\nok 153 - case-0153\nok 154 - case-0154\nok 155 - case-0155\nok 156 - case-0156\nok 157 - case-0157\nok 158 - case-0158\nok 159 - case-0159\nok 160 - case-0160\nok 161 - case-0161\nok 162 - case-0162\nok 163 - case-0163\nok 164 - case-0164\nok 165 - case-0165\nok 166 - case-0166\nok 167 - case-0167\nok 168 - case-0168\nok 169 - case-0169\nok 170 - case-0170\nok 171 - case-0171\nok 172 - case-0172\nok 173 - case-0173\nok 174 - case-0174\nok 175 - case-0175\nok 176 - case-0176\nok 177 - case-0177\nok 178 - case-0178\nok 179 - case-0179\nok 180 - case-0180\nok 181 - case-0181\nok 182 - case-0182\nok 183 - case-0183\nok 184 - case-0184\nok 185 - case-0185\nok 186 - case-0186\nok 187 - case-0187\nok 188 - case-0188\nok 189 - case-0189\nok 190 - case-0190\nok 191 - case-0191\nok 192 - case-0192\nok 193 - case-0193\nok 194 - case-0194\nok 195 - case-0195\nok 196 - case-0196\nok 197 - case-0197\nok 198 - case-0198\nok 199 - case-0199\nok 200 - case-0200\nok 201 - case-0201\nok 202 - case-0202\nok 203 - case-0203\nok 204 - case-0204\nok 205 - case-0205\nok 206 - case-0206\nok 207 - case-0207\nok 208 - case-0208\nok 209 - case-0209\nok 210 - case-0210\nok 211 - case-0211\nok 212 - case-0212\nok 213 - case-0213\nok 214 - case-0214\nok 215 - case-0215\nok 216 - case-0216\nok 217 - case-0217\nok 218 - case-0218\nok 219 - case-0219\nok 220 - case-0220\nok 221 - case-0221\nok 222 - case-0222\nok 223 - case-0223\nok 224 - case-0224\nok 225 - case-0225\nok 226 - case-0226\nok 227 - case-0227\nok 228 - case-0228\nok 229 - case-0229\nok 230 - case-0230\nok 231 - case-0231\nok 232 - case-0232\nok 233 - case-0233\nok 234 - case-0234\nok 235 - case-0235\nok 236 - case-0236\nok 237 - case-0237\nok 238 - case-0238\nok 239 - case-0239\nok 240 - case-0240\nok 241 - case-0241\nok 242 - case-0242\nok 243 - case-0243\nok 244 - case-0244\nok 245 - case-0245\nok 246 - case-0246\nok 247 - case-0247\nok 248 - case-0248\nok 249 - case-0249\nok 250 - case-0250\nok 251 - case-0251\nok 252 - case-0252\nok 253 - case-0253\nok 254 - case-0254\nok 255 - case-0255\nok 256 - case-0256\nok 257 - case-0257\nok 258 - case-0258\nok 259 - case-0259\nok 260 - case-0260\nok 261 - case-0261\nok 262 - case-0262\nok 263 - case-0263\nok 264 - case-0264\nok 265 - case-0265\nok 266 - case-0266\nok 267 - case-0267\nok 268 - case-0268\nok 269 - case-0269\nok 270 - case-0270\nok 271 - case-0271\nok 272 - case-0272\nok 273 - case-0273\nok 274 - case-0274\nok 275 - case-0275\nok 276 - case-0276\nok 277 - case-0277\nok 278 - case-0278\nok 279 - case-0279\nok 280 - case-0280\nok 281 - case-0281\nok 282 - case-0282\nok 283 - case-0283\nok 284 - case-0284\nok 285 - case-0285\nok 286 - case-0286\nok 287 - case-0287\nok 288 - case-0288\nok 289 - case-0289\nok 290 - case-0290\nok 291 - case-0291\nok 292 - case-0292\nok 293 - case-0293\nok 294 - case-0294\nok 295 - case-0295\nok 296 - case-0296\nok 297 - case-0297\nok 298 - case-0298\nok 299 - case-0299\nok 300 - case-0300\nok 301 - case-0301\nok 302 - case-0302\nok 303 - case-0303\nok 304 - case-0304\nok 305 - case-0305\nok 306 - case-0306\nok 307 - case-0307\nok 308 - case-0308\nok 309 - case-0309\nok 310 - case-0310\nok 311 - case-0311\nok 312 - case-0312\nok 313 - case-0313\nok 314 - case-0314\nok 315 - case-0315\nok 316 - case-0316\nok 317 - case-0317\nok 318 - case-0318\nok 319 - case-0319\nok 320 - case-0320\nok 321 - case-0321\nok 322 - case-0322\nok 323 - case-0323\nok 324 - case-0324\nok 325 - case-0325\nok 326 - case-0326\nok 327 - case-0327\nok 328 - case-0328\nok 329 - case-0329\nok 330 - case-0330\nok 331 - case-0331\nok 332 - case-0332\nok 333 - case-0333\nok 334 - case-0334\nok 335 - case-0335\nok 336 - case-0336\nok 337 - case-0337\nok 338 - case-0338\nok 339 - case-0339\nok 340 - case-0340\nok 341 - case-0341\nok 342 - case-0342\nok 343 - case-0343\nok 344 - case-0344\nok 345 - case-0345\nok 346 - case-0346\nok 347 - case-0347\nok 348 - case-0348\nok 349 - case-0349\nok 350 - case-0350\nok 351 - case-0351\nok 352 - case-0352\nok 353 - case-0353\nok 354 - case-0354\nok 355 - case-0355\nok 356 - case-0356\nok 357 - case-0357\nok 358 - case-0358\nok 359 - case-0359\nok 360 - case-0360\nok 361 - case-0361\nok 362 - case-0362\nok 363 - case-0363\nok 364 - case-0364\nok 365 - case-0365\nok 366 - case-0366\nok 367 - case-0367\nok 368 - case-0368\nok 369 - case-0369\nok 370 - case-0370\nok 371 - case-0371\nok 372 - case-0372\nok 373 - case-0373\nok 374 - case-0374\nok 375 - case-0375\nok 376 - case-0376\nok 377 - case-0377\nok 378 - case-0378\nok 379 - case-0379\nok 380 - case-0380\nok 381 - case-0381\nok 382 - case-0382\nok 383 - case-0383\nok 384 - case-0384\nok 385 - case-0385\nok 386 - case-0386\nok 387 - case-0387\nok 388 - case-0388\nok 389 - case-0389\nok 390 - case-0390\nok 391 - case-0391\nok 392 - case-0392\nok 393 - case-0393\nok 394 - case-0394\nok 395 - case-0395\nok 396 - case-0396\nok 397 - case-0397\nok 398 - case-0398\nok 399 - case-0399\nok 400 - case-0400\nok 401 - case-0401\nok 402 - case-0402\nok 403 - case-0403\nok 404 - case-0404\nok 405 - case-0405\nok 406 - case-0406\nok 407 - case-0407\nok 408 - case-0408\nok 409 - case-0409\nok 410 - case-0410\nok 411 - case-0411\nok 412 - case-0412\nok 413 - case-0413\nok 414 - case-0414\nok 415 - case-0415\nok 416 - case-0416\nok 417 - case-0417\nok 418 - case-0418\nok 419 - case-0419\nok 420 - case-0420\nok 421 - case-0421\nok 422 - case-0422\nok 423 - case-0423\nok 424 - case-0424\nok 425 - case-0425\nok 426 - case-0426\nok 427 - case-0427\nok 428 - case-0428\nok 429 - case-0429\nok 430 - case-0430\nok 431 - case-0431\nok 432 - case-0432\nok 433 - case-0433\nok 434 - case-0434\nok 435 - case-0435\nok 436 - case-0436\nok 437 - case-0437\nok 438 - case-0438\nok 439 - case-0439\nok 440 - case-0440\nok 441 - case-0441\nok 442 - case-0442\nok 443 - case-0443\nok 444 - case-0444\nok 445 - case-0445\nok 446 - case-0446\nok 447 - case-0447\nok 448 - case-0448\nok 449 - case-0449\nok 450 - case-0450\nok 451 - case-0451\nok 452 - case-0452\nok 453 - case-0453\nok 454 - case-0454\nok 455 - case-0455\nok 456 - case-0456\nok 457 - case-0457\nok 458 - case-0458\nok 459 - case-0459\nok 460 - case-0460\nok 461 - case-0461\nok 462 - case-0462\nok 463 - case-0463\nok 464 - case-0464\nok 465 - case-0465\nok 466 - case-0466\nok 467 - case-0467\nok 468 - case-0468\nok 469 - case-0469\nok 470 - case-0470\nok 471 - case-0471\nok 472 - case-0472\nok 473 - case-0473\nok 474 - case-0474\nok 475 - case-0475\nok 476 - case-0476\nok 477 - case-0477\nok 478 - case-0478\nok 479 - case-0479\nok 480 - case-0480\nok 481 - case-0481\nok 482 - case-0482\nok 483 - case-0483\nok 484 - case-0484\nok 485 - case-0485\nok 486 - case-0486\nok 487 - case-0487\nok 488 - case-0488\nok 489 - case-0489\nok 490 - case-0490\nok 491 - case-0491\nok 492 - case-0492\nok 493 - case-0493\nok 494 - case-0494\nok 495 - case-0495\nok 496 - case-0496\nok 497 - case-0497\nok 498 - case-0498\nok 499 - case-0499\nok 500 - case-0500\nok 501 - case-0501\nok 502 - case-0502\nok 503 - case-0503\nok 504 - case-0504\nok 505 - case-0505\nok 506 - case-0506\nok 507 - case-0507\nok 508 - case-0508\nok 509 - case-0509\nok 510 - case-0510\nok 511 - case-0511\nok 512 - case-0512\nok 513 - case-0513\nok 514 - case-0514\nok 515 - case-0515\nok 516 - case-0516\nok 517 - case-0517\nok 518 - case-0518\nok 519 - case-0519\nok 520 - case-0520\nok 521 - case-0521\nok 522 - case-0522\nok 523 - case-0523\nok 524 - case-0524\nok 525 - case-0525\nok 526 - case-0526\nok 527 - case-0527\nok 528 - case-0528\nok 529 - case-0529\nok 530 - case-0530\nok 531 - case-0531\nok 532 - case-0532\nok 533 - case-0533\nok 534 - case-0534\nok 535 - case-0535\nok 536 - case-0536\nok 537 - case-0537\nok 538 - case-0538\nok 539 - case-0539\nok 540 - case-0540\nok 541 - case-0541\nok 542 - case-0542\nok 543 - case-0543\nok 544 - case-0544\nok 545 - case-0545\nok 546 - case-0546\nok 547 - case-0547\nok 548 - case-0548\nok 549 - case-0549\nok 550 - case-0550\nok 551 - case-0551\nok 552 - case-0552\nok 553 - case-0553\nok 554 - case-0554\nok 555 - case-0555\nok 556 - case-0556\nok 557 - case-0557\nok 558 - case-0558\nok 559 - case-0559\nok 560 - case-0560\nok 561 - case-0561\nok 562 - case-0562\nok 563 - case-0563\nok 564 - case-0564\nok 565 - case-0565\nok 566 - case-0566\nok 567 - case-0567\nok 568 - case-0568\nok 569 - case-0569\nok 570 - case-0570\nok 571 - case-0571\nok 572 - case-0572\nok 573 - case-0573\nok 574 - case-0574\nok 575 - case-0575\nok 576 - case-0576\nok 577 - case-0577\nok 578 - case-0578\nok 579 - case-0579\nok 580 - case-0580\nok 581 - case-0581\nok 582 - case-0582\nok 583 - case-0583\nok 584 - case-0584\nok 585 - case-0585\nok 586 - case-0586\nok 587 - case-0587\nok 588 - case-0588\nok 589 - case-0589\nok 590 - case-0590\nok 591 - case-0591\nok 592 - case-0592\nok 593 - case-0593\nok 594 - case-0594\nok 595 - case-0595\nok 596 - case-0596\nok 597 - case-0597\nok 598 - case-0598\nok 599 - case-0599\nok 600 - case-0600\nok 601 - case-0601\nok 602 - case-0602\nok 603 - case-0603\nok 604 - case-0604\nok 605 - case-0605\nok 606 - case-0606\nok 607 - case-0607\nok 608 - case-0608\nok 609 - case-0609\nok 610 - case-0610\nok 611 - case-0611\nok 612 - case-0612\nok 613 - case-0613\nok 614 - case-0614\nok 615 - case-0615\nok 616 - case-0616\nok 617 - case-0617\nok 618 - case-0618\nok 619 - case-0619\nok 620 - case-0620\nok 621 - case-0621\nok 622 - case-0622\nok 623 - case-0623\nok 624 - case-0624\nok 625 - case-0625\nok 626 - case-0626\nok 627 - case-0627\nok 628 - case-0628\nok 629 - case-0629\nok 630 - case-0630\nok 631 - case-0631\nok 632 - case-0632\nok 633 - case-0633\nok 634 - case-0634\nok 635 - case-0635\nok 636 - case-0636\nok 637 - case-0637\nok 638 - case-0638\nok 639 - case-0639\nok 640 - case-0640\nok 641 - case-0641\nok 642 - case-0642\nok 643 - case-0643\nok 644 - case-0644\nok 645 - case-0645\nok 646 - case-0646\nok 647 - case-0647\nok 648 - case-0648\nok 649 - case-0649\nok 650 - case-0650\nok 651 - case-0651\nok 652 - case-0652\nok 653 - case-0653\nok 654 - case-0654\nok 655 - case-0655\nok 656 - case-0656\nok 657 - case-0657\nok 658 - case-0658\nok 659 - case-0659\nok 660 - case-0660\nok 661 - case-0661\nok 662 - case-0662\nok 663 - case-0663\nok 664 - case-0664\nok 665 - case-0665\nok 666 - case-0666\nok 667 - case-0667\nok 668 - case-0668\nok 669 - case-0669\nok 670 - case-0670\nok 671 - case-0671\nok 672 - case-0672\nok 673 - case-0673\nok 674 - case-0674\nok 675 - case-0675\nok 676 - case-0676\nok 677 - case-0677\nok 678 - case-0678\nok 679 - case-0679\nok 680 - case-0680\nok 681 - case-0681\nok 682 - case-0682\nok 683 - case-0683\nok 684 - case-0684\nok 685 - case-0685\nok 686 - case-0686\nok 687 - case-0687\nok 688 - case-0688\nok 689 - case-0689\nok 690 - case-0690\nok 691 - case-0691\nok 692 - case-0692\nok 693 - case-0693\nok 694 - case-0694\nok 695 - case-0695\nok 696 - case-0696\nok 697 - case-0697\nok 698 - case-0698\nok 699 - case-0699\nok 700 - case-0700\nok 701 - case-0701\nok 702 - case-0702\nok 703 - case-0703\nok 704 - case-0704\nok 705 - case-0705\nok 706 - case-0706\nok 707 - case-0707\nok 708 - case-0708\nok 709 - case-0709\nok 710 - case-0710\nok 711 - case-0711\nok 712 - case-0712\nok 713 - case-0713\nok 714 - case-0714\nok 715 - case-0715\nok 716 - case-0716\nok 717 - case-0717\nok 718 - case-0718\nok 719 - case-0719\nok 720 - case-0720\nok 721 - case-0721\nok 722 - case-0722\nok 723 - case-0723\nok 724 - case-0724\nok 725 - case-0725\nok 726 - case-0726\nok 727 - case-0727\nok 728 - case-0728\nok 729 - case-0729\nok 730 - case-0730\nok 731 - case-0731\nok 732 - case-0732\nok 733 - case-0733\nok 734 - case-0734\nok 735 - case-0735\nok 736 - case-0736\nok 737 - case-0737\nok 738 - case-0738\nok 739 - case-0739\nok 740 - case-0740\nok 741 - case-0741\nok 742 - case-0742\nok 743 - case-0743\nok 744 - case-0744\nok 745 - case-0745\nok 746 - case-0746\nok 747 - case-0747\nok 748 - case-0748\nok 749 - case-0749\nok 750 - case-0750\nok 751 - case-0751\nok 752 - case-0752\nok 753 - case-0753\nok 754 - case-0754\nok 755 - case-0755\nok 756 - case-0756\nok 757 - case-0757\nok 758 - case-0758\nok 759 - case-0759\nok 760 - case-0760\nok 761 - case-0761\nok 762 - case-0762\nok 763 - case-0763\nok 764 - case-0764\nok 765 - case-0765\nok 766 - case-0766\nok 767 - case-0767\nok 768 - case-0768\nok 769 - case-0769\nok 770 - case-0770\nok 771 - case-0771\nok 772 - case-0772\nok 773 - case-0773\nok 774 - case-0774\nok 775 - case-0775\nok 776 - case-0776\nok 777 - case-0777\nok 778 - case-0778\nok 779 - case-0779\nok 780 - case-0780\nok 781 - case-0781\nok 782 - case-0782\nok 783 - case-0783\nok 784 - case-0784\nok 785 - case-0785\nok 786 - case-0786\nok 787 - case-0787\nok 788 - case-0788\nok 789 - case-0789\nok 790 - case-0790\nok 791 - case-0791\nok 792 - case-0792\nok 793 - case-0793\nok 794 - case-0794\nok 795 - case-0795\nok 796 - case-0796\nok 797 - case-0797\nok 798 - case-0798\nok 799 - case-0799\nok 800 - case-0800\nok 801 - case-0801\nok 802 - case-0802\nok 803 - case-0803\nok 804 - case-0804\nok 805 - case-0805\nok 806 - case-0806\nok 807 - case-0807\nok 808 - case-0808\nok 809 - case-0809\nok 810 - case-0810\nok 811 - case-0811\nok 812 - case-0812\nok 813 - case-0813\nok 814 - case-0814\nok 815 - case-0815\nok 816 - case-0816\nok 817 - case-0817\nok 818 - case-0818\nok 819 - case-0819\nok 820 - case-0820\nok 821 - case-0821\nok 822 - case-0822\nok 823 - case-0823\nok 824 - case-0824\nok 825 - case-0825\nok 826 - case-0826\nok 827 - case-0827\nok 828 - case-0828\nok 829 - case-0829\nok 830 - case-0830\nok 831 - case-0831\nok 832 - case-0832\nok 833 - case-0833\nok 834 - case-0834\nok 835 - case-0835\nok 836 - case-0836\nok 837 - case-0837\nok 838 - case-0838\nok 839 - case-0839\nok 840 - case-0840\nok 841 - case-0841\nok 842 - case-0842\nok 843 - case-0843\nok 844 - case-0844\nok 845 - case-0845\nok 846 - case-0846\nok 847 - case-0847\nok 848 - case-0848\nok 849 - case-0849\nok 850 - case-0850\nok 851 - case-0851\nok 852 - case-0852\nok 853 - case-0853\nok 854 - case-0854\nok 855 - case-0855\nok 856 - case-0856\nok 857 - case-0857\nok 858 - case-0858\nok 859 - case-0859\nok 860 - case-0860\nok 861 - case-0861\nok 862 - case-0862\nok 863 - case-0863\nok 864 - case-0864\nok 865 - case-0865\nok 866 - case-0866\nok 867 - case-0867\nok 868 - case-0868\nok 869 - case-0869\nok 870 - case-0870\nok 871 - case-0871\nok 872 - case-0872\nok 873 - case-0873\nok 874 - case-0874\nok 875 - case-0875\nok 876 - case-0876\nok 877 - case-0877\nok 878 - case-0878\nok 879 - case-0879\nok 880 - case-0880\nok 881 - case-0881\nok 882 - case-0882\nok 883 - case-0883\nok 884 - case-0884\nok 885 - case-0885\nok 886 - case-0886\nok 887 - case-0887\nok 888 - case-0888\nok 889 - case-0889\nok 890 - case-0890\nok 891 - case-0891\nok 892 - case-0892\nok 893 - case-0893\nok 894 - case-0894\nok 895 - case-0895\nok 896 - case-0896\nok 897 - case-0897\nok 898 - case-0898\nok 899 - case-0899\nok 900 - case-0900\nok 901 - case-0901\nok 902 - case-0902\nok 903 - case-0903\nok 904 - case-0904\nok 905 - case-0905\nok 906 - case-0906\nok 907 - case-0907\nok 908 - case-0908\nok 909 - case-0909\nok 910 - case-0910\nok 911 - case-0911\nok 912 - case-0912\nok 913 - case-0913\nok 914 - case-0914\nok 915 - case-0915\nok 916 - case-0916\nok 917 - case-0917\nok 918 - case-0918\nok 919 - case-0919\nok 920 - case-0920\nok 921 - case-0921\nok 922 - case-0922\nok 923 - case-0923\nok 924 - case-0924\nok 925 - case-0925\nok 926 - case-0926\nok 927 - case-0927\nok 928 - case-0928\nok 929 - case-0929\nok 930 - case-0930\nok 931 - case-0931\nok 932 - case-0932\nok 933 - case-0933\nok 934 - case-0934\nok 935 - case-0935\nok 936 - case-0936\nok 937 - case-0937\nok 938 - case-0938\nok 939 - case-0939\nok 940 - case-0940\nok 941 - case-0941\nok 942 - case-0942\nok 943 - case-0943\nok 944 - case-0944\nok 945 - case-0945\nok 946 - case-0946\nok 947 - case-0947\nok 948 - case-0948\nok 949 - case-0949\nok 950 - case-0950\nok 951 - case-0951\nok 952 - case-0952\nok 953 - case-0953\nok 954 - case-0954\nok 955 - case-0955\nok 956 - case-0956\nok 957 - case-0957\nok 958 - case-0958\nok 959 - case-0959\nok 960 - case-0960\nok 961 - case-0961\nok 962 - case-0962\nok 963 - case-0963\nok 964 - case-0964\nok 965 - case-0965\nok 966 - case-0966\nok 967 - case-0967\nok 968 - case-0968\nok 969 - case-0969\nok 970 - case-0970\nok 971 - case-0971\nok 972 - case-0972\nok 973 - case-0973\nok 974 - case-0974\nok 975 - case-0975\nok 976 - case-0976\nok 977 - case-0977\nok 978 - case-0978\nok 979 - case-0979\nok 980 - case-0980\nok 981 - case-0981\nok 982 - case-0982\nok 983 - case-0983\nok 984 - case-0984\nok 985 - case-0985\nok 986 - case-0986\nok 987 - case-0987\nok 988 - case-0988\nok 989 - case-0989\nok 990 - case-0990\nok 991 - case-0991\nok 992 - case-0992\nok 993 - case-0993\nok 994 - case-0994\nok 995 - case-0995\nok 996 - case-0996\nok 997 - case-0997\nok 998 - case-0998\nok 999 - case-0999\nok 1000 - case-1000\nok 1001 - case-1001\nok 1002 - case-1002\nok 1003 - case-1003\nok 1004 - case-1004\nok 1005 - case-1005\nok 1006 - case-1006\nok 1007 - case-1007\nok 1008 - case-1008\nok 1009 - case-1009\nok 1010 - case-1010\nok 1011 - case-1011\nok 1012 - case-1012\nok 1013 - case-1013\nok 1014 - case-1014\nok 1015 - case-1015\nok 1016 - case-1016\nok 1017 - case-1017\nok 1018 - case-1018\nok 1019 - case-1019\nok 1020 - case-1020\nok 1021 - case-1021\nok 1022 - case-1022\nok 1023 - case-1023\nok 1024 - case-1024\nok 1025 - case-1025\nok 1026 - case-1026\nok 1027 - case-1027\nok 1028 - case-1028\nok 1029 - case-1029\nok 1030 - case-1030\nok 1031 - case-1031\nok 1032 - case-1032\nok 1033 - case-1033\nok 1034 - case-1034\nok 1035 - case-1035\nok 1036 - case-1036\nok 1037 - case-1037\nok 1038 - case-1038\nok 1039 - case-1039\nok 1040 - case-1040\nok 1041 - case-1041\nok 1042 - case-1042\nok 1043 - case-1043\nok 1044 - case-1044\nok 1045 - case-1045\nok 1046 - case-1046\nok 1047 - case-1047\nok 1048 - case-1048\nok 1049 - case-1049\nok 1050 - case-1050\nok 1051 - case-1051\nok 1052 - case-1052\nok 1053 - case-1053\nok 1054 - case-1054\nok 1055 - case-1055\nok 1056 - case-1056\nok 1057 - case-1057\nok 1058 - case-1058\nok 1059 - case-1059\nok 1060 - case-1060\nok 1061 - case-1061\nok 1062 - case-1062\nok 1063 - case-1063\nok 1064 - case-1064\nok 1065 - case-1065\nok 1066 - case-1066\nok 1067 - case-1067\nok 1068 - case-1068\nok 1069 - case-1069\nok 1070 - case-1070\nok 1071 - case-1071\nok 1072 - case-1072\nok 1073 - case-1073\nok 1074 - case-1074\nok 1075 - case-1075\nok 1076 - case-1076\nok 1077 - case-1077\nok 1078 - case-1078\nok 1079 - case-1079\nok 1080 - case-1080\nok 1081 - case-1081\nok 1082 - case-1082\nok 1083 - case-1083\nok 1084 - case-1084\nok 1085 - case-1085\nok 1086 - case-1086\nok 1087 - case-1087\nok 1088 - case-1088\nok 1089 - case-1089\nok 1090 - case-1090\nok 1091 - case-1091\nok 1092 - case-1092\nok 1093 - case-1093\nok 1094 - case-1094\nok 1095 - case-1095\nok 1096 - case-1096\nok 1097 - case-1097\nok 1098 - case-1098\nok 1099 - case-1099\nok 1100 - case-1100\nok 1101 - case-1101\nok 1102 - case-1102\nok 1103 - case-1103\nok 1104 - case-1104\nok 1105 - case-1105\nok 1106 - case-1106\nok 1107 - case-1107\nok 1108 - case-1108\nok 1109 - case-1109\nok 1110 - case-1110\nok 1111 - case-1111\nok 1112 - case-1112\nok 1113 - case-1113\nok 1114 - case-1114\nok 1115 - case-1115\nok 1116 - case-1116\nok 1117 - case-1117\nok 1118 - case-1118\nok 1119 - case-1119\nok 1120 - case-1120\nok 1121 - case-1121\nok 1122 - case-1122\nok 1123 - case-1123\nok 1124 - case-1124\nok 1125 - case-1125\nok 1126 - case-1126\nok 1127 - case-1127\nok 1128 - case-1128\nok 1129 - case-1129\nok 1130 - case-1130\nok 1131 - case-1131\nok 1132 - case-1132\nok 1133 - case-1133\nok 1134 - case-1134\nok 1135 - case-1135\nok 1136 - case-1136\nok 1137 - case-1137\nok 1138 - case-1138\nok 1139 - case-1139\nok 1140 - case-1140\nok 1141 - case-1141\nok 1142 - case-1142\nok 1143 - case-1143\nok 1144 - case-1144\nok 1145 - case-1145\nok 1146 - case-1146\nok 1147 - case-1147\nok 1148 - case-1148\nok 1149 - case-1149\nok 1150 - case-1150\nok 1151 - case-1151\nok 1152 - case-1152\nok 1153 - case-1153\nok 1154 - case-1154\nok 1155 - case-1155\nok 1156 - case-1156\nok 1157 - case-1157\nok 1158 - case-1158\nok 1159 - case-1159\nok 1160 - case-1160\nok 1161 - case-1161\nok 1162 - case-1162\nok 1163 - case-1163\nok 1164 - case-1164\nok 1165 - case-1165\nok 1166 - case-1166\nok 1167 - case-1167\nok 1168 - case-1168\nok 1169 - case-1169\nok 1170 - case-1170\nok 1171 - case-1171\nok 1172 - case-1172\nok 1173 - case-1173\nok 1174 - case-1174\nok 1175 - case-1175\nok 1176 - case-1176\nok 1177 - case-1177\nok 1178 - case-1178\nok 1179 - case-1179\nok 1180 - case-1180\nok 1181 - case-1181\nok 1182 - case-1182\nok 1183 - case-1183\nok 1184 - case-1184\nok 1185 - case-1185\nok 1186 - case-1186\nok 1187 - case-1187\nok 1188 - case-1188\nok 1189 - case-1189\nok 1190 - case-1190\nok 1191 - case-1191\nok 1192 - case-1192\nok 1193 - case-1193\nok 1194 - case-1194\nok 1195 - case-1195\nok 1196 - case-1196\nok 1197 - case-1197\nok 1198 - case-1198\nok 1199 - case-1199\nok 1200 - case-1200\nok 1201 - case-1201\nok 1202 - case-1202\nok 1203 - case-1203\nok 1204 - case-1204\nok 1205 - case-1205\nok 1206 - case-1206\nok 1207 - case-1207\nok 1208 - case-1208\nok 1209 - case-1209\nok 1210 - case-1210\nok 1211 - case-1211\nok 1212 - case-1212\nok 1213 - case-1213\nok 1214 - case-1214\nok 1215 - case-1215\nok 1216 - case-1216\nok 1217 - case-1217\nok 1218 - case-1218\nok 1219 - case-1219\nok 1220 - case-1220\nok 1221 - case-1221\nok 1222 - case-1222\nok 1223 - case-1223\nok 1224 - case-1224\nok 1225 - case-1225\nok 1226 - case-1226\nok 1227 - case-1227\nok 1228 - case-1228\nok 1229 - case-1229\nok 1230 - case-1230\nok 1231 - case-1231\nok 1232 - case-1232\nok 1233 - case-1233\nok 1234 - case-1234\nok 1235 - case-1235\nok 1236 - case-1236\nok 1237 - case-1237\nok 1238 - case-1238\nok 1239 - case-1239\nok 1240 - case-1240\nok 1241 - case-1241\nok 1242 - case-1242\nok 1243 - case-1243\nok 1244 - case-1244\nok 1245 - case-1245\nok 1246 - case-1246\nok 1247 - case-1247\nok 1248 - case-1248\nok 1249 - case-1249\nok 1250 - case-1250\nok 1251 - case-1251\nok 1252 - case-1252\nok 1253 - case-1253\nok 1254 - case-1254\nok 1255 - case-1255\nok 1256 - case-1256\nok 1257 - case-1257\nok 1258 - case-1258\nok 1259 - case-1259\nok 1260 - case-1260\nok 1261 - case-1261\nok 1262 - case-1262\nok 1263 - case-1263\nok 1264 - case-1264\nok 1265 - case-1265\nok 1266 - case-1266\nok 1267 - case-1267\nok 1268 - case-1268\nok 1269 - case-1269\nok 1270 - case-1270\nok 1271 - case-1271\nok 1272 - case-1272\nok 1273 - case-1273\nok 1274 - case-1274\nok 1275 - case-1275\nok 1276 - case-1276\nok 1277 - case-1277\nok 1278 - case-1278\nok 1279 - case-1279\nok 1280 - case-1280\nok 1281 - case-1281\nok 1282 - case-1282\nok 1283 - case-1283\nok 1284 - case-1284\nok 1285 - case-1285\nok 1286 - case-1286\nok 1287 - case-1287\nok 1288 - case-1288\nok 1289 - case-1289\nok 1290 - case-1290\nok 1291 - case-1291\nok 1292 - case-1292\nok 1293 - case-1293\nok 1294 - case-1294\nok 1295 - case-1295\nok 1296 - case-1296\nok 1297 - case-1297\nok 1298 - case-1298\nok 1299 - case-1299\nok 1300 - case-1300\nok 1301 - case-1301\nok 1302 - case-1302\nok 1303 - case-1303\nok 1304 - case-1304\nok 1305 - case-1305\nok 1306 - case-1306\nok 1307 - case-1307\nok 1308 - case-1308\nok 1309 - case-1309\nok 1310 - case-1310\nok 1311 - case-1311\nok 1312 - case-1312\nok 1313 - case-1313\nok 1314 - case-1314\nok 1315 - case-1315\nok 1316 - case-1316\nok 1317 - case-1317\nok 1318 - case-1318\nok 1319 - case-1319\nok 1320 - case-1320\nok 1321 - case-1321\nok 1322 - case-1322\nok 1323 - case-1323\nok 1324 - case-1324\nok 1325 - case-1325\nok 1326 - case-1326\nok 1327 - case-1327\nok 1328 - case-1328\nok 1329 - case-1329\nok 1330 - case-1330\nok 1331 - case-1331\nok 1332 - case-1332\nok 1333 - case-1333\nok 1334 - case-1334\nok 1335 - case-1335\nok 1336 - case-1336\nok 1337 - case-1337\nok 1338 - case-1338\nok 1339 - case-1339\nok 1340 - case-1340\nok 1341 - case-1341\nok 1342 - case-1342\nok 1343 - case-1343\nok 1344 - case-1344\nok 1345 - case-1345\nok 1346 - case-1346\nok 1347 - case-1347\nok 1348 - case-1348\nok 1349 - case-1349\nok 1350 - case-1350\nok 1351 - case-1351\nok 1352 - case-1352\nok 1353 - case-1353\nok 1354 - case-1354\nok 1355 - case-1355\nok 1356 - case-1356\nok 1357 - case-1357\nok 1358 - case-1358\nok 1359 - case-1359\nok 1360 - case-1360\nok 1361 - case-1361\nok 1362 - case-1362\nok 1363 - case-1363\nok 1364 - case-1364\nok 1365 - case-1365\nok 1366 - case-1366\nok 1367 - case-1367\nok 1368 - case-1368\nok 1369 - case-1369\nok 1370 - case-1370\nok 1371 - case-1371\nok 1372 - case-1372\nok 1373 - case-1373\nok 1374 - case-1374\nok 1375 - case-1375\nok 1376 - case-1376\nok 1377 - case-1377\nok 1378 - case-1378\nok 1379 - case-1379\nok 1380 - case-1380\nok 1381 - case-1381\nok 1382 - case-1382\nok 1383 - case-1383\nok 1384 - case-1384\nok 1385 - case-1385\nok 1386 - case-1386\nok 1387 - case-1387\nok 1388 - case-1388\nok 1389 - case-1389\nok 1390 - case-1390\nok 1391 - case-1391\nok 1392 - case-1392\nok 1393 - case-1393\nok 1394 - case-1394\nok 1395 - case-1395\nok 1396 - case-1396\nok 1397 - case-1397\nok 1398 - case-1398\nok 1399 - case-1399\nok 1400 - case-1400\nok 1401 - case-1401\nok 1402 - case-1402\nok 1403 - case-1403\nok 1404 - case-1404\nok 1405 - case-1405\nok 1406 - case-1406\nok 1407 - case-1407\nok 1408 - case-1408\nok 1409 - case-1409\nok 1410 - case-1410\nok 1411 - case-1411\nok 1412 - case-1412\nok 1413 - case-1413\nok 1414 - case-1414\nok 1415 - case-1415\nok 1416 - case-1416\nok 1417 - case-1417\nok 1418 - case-1418\nok 1419 - case-1419\nok 1420 - case-1420\nok 1421 - case-1421\nok 1422 - case-1422\nok 1423 - case-1423\nok 1424 - case-1424\nok 1425 - case-1425\nok 1426 - case-1426\nok 1427 - case-1427\nok 1428 - case-1428\nok 1429 - case-1429\nok 1430 - case-1430\nok 1431 - case-1431\nok 1432 - case-1432\nok 1433 - case-1433\nok 1434 - case-1434\nok 1435 - case-1435\nok 1436 - case-1436\nok 1437 - case-1437\nok 1438 - case-1438\nok 1439 - case-1439\nok 1440 - case-1440\nok 1441 - case-1441\nok 1442 - case-1442\nok 1443 - case-1443\nok 1444 - case-1444\nok 1445 - case-1445\nok 1446 - case-1446\nok 1447 - case-1447\nok 1448 - case-1448\nok 1449 - case-1449\nok 1450 - case-1450\nok 1451 - case-1451\nok 1452 - case-1452\nok 1453 - case-1453\nok 1454 - case-1454\nok 1455 - case-1455\nok 1456 - case-1456\nok 1457 - case-1457\nok 1458 - case-1458\nok 1459 - case-1459\nok 1460 - case-1460\nok 1461 - case-1461\nok 1462 - case-1462\nok 1463 - case-1463\nok 1464 - case-1464\nok 1465 - case-1465\nok 1466 - case-1466\nok 1467 - case-1467\nok 1468 - case-1468\nok 1469 - case-1469\nok 1470 - case-1470\nok 1471 - case-1471\nok 1472 - case-1472\nok 1473 - case-1473\nok 1474 - case-1474\nok 1475 - case-1475\nok 1476 - case-1476\nok 1477 - case-1477\nok 1478 - case-1478\nok 1479 - case-1479\nok 1480 - case-1480\nok 1481 - case-1481\nok 1482 - case-1482\nok 1483 - case-1483\nok 1484 - case-1484\nok 1485 - case-1485\nok 1486 - case-1486\nok 1487 - case-1487\nok 1488 - case-1488\nok 1489 - case-1489\nok 1490 - case-1490\nok 1491 - case-1491\nok 1492 - case-1492\nok 1493 - case-1493\nok 1494 - case-1494\nok 1495 - case-1495\nok 1496 - case-1496\nok 1497 - case-1497\nok 1498 - case-1498\nok 1499 - case-1499\nok 1500 - case-1500\n1..1500\n# tests 1500\n# pass 1500\n# fail 0\n# skipped 0\n# duration_ms 12.5\n" } ] + }, + "value_receipt": { + "evidence": [ + { + "id": "canonical_packet", + "kind": "JSON_POINTER", + "locator": "/", + "trust": "VERIFIED" + }, + { + "id": "configuration", + "kind": "CONTENT_HASH", + "locator": "sha256:54750b51fe1507277a2d8a33b263c398b108e26d132b20ea0668712d46ddfa89", + "trust": "VERIFIED" + }, + { + "id": "input_bytes", + "kind": "CONTENT_HASH", + "locator": "sha256:82ea05bab3fc9551830551372723ab484c5893f93b9ee88bbfaf9a1e9cf42abc", + "trust": "VERIFIED" + }, + { + "id": "semantic_payload", + "kind": "CONTENT_HASH", + "locator": "sha256:d99849b21430365b8b3aefd974d26d625092874054c8c09d1eea69e84e9a4e49", + "trust": "VERIFIED" + }, + { + "id": "raw_locator", + "kind": "RUN_ARTIFACT", + "locator": "artifact://synthetic/run-001.tap", + "trust": "CALLER_SUPPLIED" + } + ], + "limitations": [ + "No token, cost, latency, correctness, or causal savings claim is made.", + "Evidence-event counts cover source transcript events, not derived packet fields.", + "Mechanism source revision was not supplied and is recorded as null.", + "The raw evidence locator is caller supplied; external existence, immutability, and contents are not verified." + ], + "measurements": [ + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "input_bytes" + ], + "id": "raw_bytes", + "limitations": [], + "operator_display": false, + "result": 28981, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 28981, + "class": "EXACT", + "delta": -27135, + "derivation": null, + "direction": "LOWER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_model_visible_bytes", + "limitations": [ + "Result is the canonical evidence packet written to model-visible stdout." + ], + "operator_display": true, + "result": 1846, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": 1846, + "class": "EXACT", + "delta": 27135, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "bytes_initially_avoided", + "limitations": [ + "Signed delta is raw bytes minus initially model-visible bytes; a negative delta indicates expansion." + ], + "operator_display": true, + "result": 28981, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "HIGHER_IS_VALUE", + "evidence_refs": [ + "canonical_packet", + "input_bytes" + ], + "id": "initial_reduction_ratio", + "limitations": [ + "Computed as (raw bytes - initially model-visible bytes) / raw bytes.", + "Negative values indicate canonical packet expansion.", + "Ratios are not directly summable; cumulative ratios must be recomputed from byte totals." + ], + "operator_display": true, + "result": "27135/28981", + "source_verification": "VERIFIED", + "unit": "ratio" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "original_evidence_events", + "limitations": [], + "operator_display": false, + "result": 1507, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "retained_evidence_events", + "limitations": [], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NEUTRAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "suppressed_evidence_events", + "limitations": [], + "operator_display": false, + "result": 1507, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": "SUM", + "safe": true + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "semantic_payload" + ], + "id": "ambiguous_evidence_events", + "limitations": [ + "Counts unclassified source events, including synthetic markers for malformed UTF-8." + ], + "operator_display": false, + "result": 0, + "source_verification": "VERIFIED", + "unit": "event" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "EXACT", + "delta": null, + "derivation": null, + "direction": "NOT_APPLICABLE", + "evidence_refs": [ + "configuration" + ], + "id": "payload_ceiling_bytes", + "limitations": [], + "operator_display": false, + "result": 1846, + "source_verification": "VERIFIED", + "unit": "byte" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "canonical_packet" + ], + "id": "escalation_required", + "limitations": [], + "operator_display": true, + "result": false, + "source_verification": "OBSERVED", + "unit": "boolean" + }, + { + "aggregation": { + "method": null, + "safe": false + }, + "baseline": null, + "class": "OBSERVED", + "delta": null, + "derivation": null, + "direction": "PROTECTION_SIGNAL", + "evidence_refs": [ + "raw_locator" + ], + "id": "raw_locator_available", + "limitations": [ + "Availability means a caller supplied a locator; the external artifact is not verified by the reducer." + ], + "operator_display": false, + "result": true, + "source_verification": "CALLER_SUPPLIED", + "unit": "boolean" + } + ], + "mechanism": { + "id": "opsle.context-firewall", + "name": "Context Firewall", + "revision": "953c48f1cfd154d6b7ed10b51b87fe54e4df45f2", + "version": "0.3.0" + }, + "operation": { + "configuration_id": "sha256:54750b51fe1507277a2d8a33b263c398b108e26d132b20ea0668712d46ddfa89", + "id": "op-synthetic-001", + "name": "test-output-reduction", + "policy_id": "tap-subset-policy/v1" + }, + "run": { + "id": "run-001" + }, + "schema": "opsle.value-receipt.v1" } } ] diff --git a/package.json b/package.json index b531be7..bc4e15f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@opsle/decision-evidence-protocol", - "version": "0.2.0", + "version": "0.3.0", "private": true, "type": "module", "bin": { @@ -8,12 +8,17 @@ }, "exports": { ".": "./src/index.js", - "./context-firewall-v1": "./src/context-firewall-v1.js" + "./context-firewall-v1": "./src/context-firewall-v1.js", + "./context-firewall-value": "./src/context-firewall-value.js", + "./value-receipt-v1": "./src/value-receipt-v1.js" }, "scripts": { "test": "node --test", "conformance": "node ./bin/decision-evidence.js conformance", - "lint": "node --check src/*.js && node --check bin/*.js && node --check tools/*.js" + "determinism": "node --test --test-name-pattern='deterministic|canonical|separate|stdout'", + "interop": "node ./tools/verify-context-firewall-interop.js ../context-firewall", + "lint": "node --check src/*.js && node --check bin/*.js && node --check tools/*.js", + "verify": "npm run lint && npm test && npm run conformance && npm run determinism" }, "engines": { "node": ">=20" diff --git a/src/conformance.js b/src/conformance.js index 2d6bfe4..8676d5f 100644 --- a/src/conformance.js +++ b/src/conformance.js @@ -5,6 +5,7 @@ import { canonicalJson, validateContextFirewallPacket, } from './context-firewall-v1.js'; +import { validateContextFirewallValueReceipt } from './context-firewall-value.js'; function clone(value) { return structuredClone(value); @@ -98,10 +99,16 @@ export async function runContextFirewallConformance(options = {}) { sourceInput: vector.source_input, }); const evaluation = evaluateExpectation(result, vector.expected); + const valueReceipt = validateContextFirewallValueReceipt( + vector.value_receipt, + vector.packet, + ); results.push({ ...evaluation, id: vector.id, kind: 'valid', + pass: evaluation.pass && valueReceipt.valid, + value_receipt_valid: valueReceipt.valid, }); } diff --git a/src/context-firewall-v1.js b/src/context-firewall-v1.js index 9704890..0cdc472 100644 --- a/src/context-firewall-v1.js +++ b/src/context-firewall-v1.js @@ -7,7 +7,7 @@ export const CONTEXT_FIREWALL_INPUT_PROTOCOL = 'opsle.context-firewall.test-run-input/v1'; export const CONTEXT_FIREWALL_REDUCER = '@opsle/context-firewall/test-output'; -export const CONTEXT_FIREWALL_REDUCER_VERSION = '0.2.0'; +export const CONTEXT_FIREWALL_REDUCER_VERSION = '0.3.0'; export const CONTEXT_FIREWALL_POLICY_REVISION = 'tap-subset-policy/v1'; diff --git a/src/context-firewall-value.js b/src/context-firewall-value.js new file mode 100644 index 0000000..c0e2e58 --- /dev/null +++ b/src/context-firewall-value.js @@ -0,0 +1,228 @@ +import { + CONTEXT_FIREWALL_POLICY_REVISION, + CONTEXT_FIREWALL_REDUCER_VERSION, +} from './context-firewall-v1.js'; +import { validateValueReceipt } from './value-receipt-v1.js'; + +export const DECISION_EVIDENCE_MECHANISM_ID = 'opsle.decision-evidence-protocol'; +export const DECISION_EVIDENCE_MECHANISM_NAME = 'Decision Evidence'; +export const DECISION_EVIDENCE_VERSION = '0.3.0'; +export const CONTEXT_FIREWALL_VALUE_PROFILE = + 'opsle.decision-evidence.context-firewall-value/v1'; + +const profile = Object.freeze([ + ['raw_bytes', 'byte', 'EXACT'], + ['initial_model_visible_bytes', 'byte', 'EXACT'], + ['bytes_initially_avoided', 'byte', 'EXACT'], + ['initial_reduction_ratio', 'ratio', 'EXACT'], + ['original_evidence_events', 'event', 'EXACT'], + ['retained_evidence_events', 'event', 'EXACT'], + ['suppressed_evidence_events', 'event', 'EXACT'], + ['ambiguous_evidence_events', 'event', 'EXACT'], + ['payload_ceiling_bytes', 'byte', 'EXACT'], + ['escalation_required', 'boolean', 'OBSERVED'], + ['raw_locator_available', 'boolean', 'OBSERVED'], +]); + +function valueById(receipt) { + return new Map(receipt.measurements.map((item) => [item.id, item])); +} + +function add(violations, code, path, message) { + violations.push({ code, message, path }); +} + +function same(actual, expected) { + return Object.is(actual, expected); +} + +export function validateContextFirewallValueReceipt(receipt, packet) { + const generic = validateValueReceipt(receipt); + const violations = [...generic.violations]; + if (!generic.valid || packet === null || typeof packet !== 'object') { + if (packet === null || typeof packet !== 'object') { + add(violations, 'PACKET_REQUIRED', '/packet', 'Context Firewall packet-v1 required'); + } + return { profile: CONTEXT_FIREWALL_VALUE_PROFILE, valid: false, violations }; + } + if (receipt.mechanism.id !== 'opsle.context-firewall') { + add(violations, 'MECHANISM_MISMATCH', '/mechanism/id', 'Context Firewall mechanism required'); + } + if (receipt.mechanism.version !== CONTEXT_FIREWALL_REDUCER_VERSION) { + add(violations, 'MECHANISM_VERSION_MISMATCH', '/mechanism/version', 'receipt and supported reducer versions differ'); + } + if (receipt.run.id !== packet.receipt?.source?.run_id) { + add(violations, 'RUN_ID_MISMATCH', '/run/id', 'receipt and packet run identities differ'); + } + if (receipt.operation.id !== packet.operation_id) { + add(violations, 'OPERATION_ID_MISMATCH', '/operation/id', 'receipt and packet operation identities differ'); + } + if (receipt.operation.configuration_id !== packet.receipt?.configuration?.identity) { + add(violations, 'CONFIGURATION_ID_MISMATCH', '/operation/configuration_id', 'receipt and packet configurations differ'); + } + if (receipt.operation.policy_id !== CONTEXT_FIREWALL_POLICY_REVISION) { + add(violations, 'POLICY_ID_MISMATCH', '/operation/policy_id', 'supported Context Firewall policy required'); + } + + const values = valueById(receipt); + if (values.size !== profile.length) { + add(violations, 'MEASUREMENT_PROFILE_MISMATCH', '/measurements', 'exact Context Firewall value profile required'); + } + for (const [id, unit, measurementClass] of profile) { + const item = values.get(id); + if (!item) add(violations, 'MEASUREMENT_REQUIRED', '/measurements', `missing ${id}`); + else if (item.unit !== unit || item.class !== measurementClass) { + add(violations, 'MEASUREMENT_SEMANTICS_MISMATCH', `/measurements/${id}`, `${unit}/${measurementClass} required`); + } + } + const measured = packet.receipt?.measurements ?? {}; + const original = measured.original_bytes; + const visible = measured.reduced_bytes; + const expected = new Map([ + ['raw_bytes', original], + ['initial_model_visible_bytes', visible], + ['bytes_initially_avoided', original], + ['initial_reduction_ratio', original === 0 ? null : `${original - visible}/${original}`], + ['original_evidence_events', measured.original_event_count], + ['retained_evidence_events', measured.retained_evidence_count], + ['suppressed_evidence_events', measured.suppressed_evidence_count], + ['ambiguous_evidence_events', packet.decision_evidence?.unclassified_evidence?.length], + ['payload_ceiling_bytes', packet.receipt?.configuration?.max_output_bytes], + ['escalation_required', packet.receipt?.raw_evidence?.escalation_required], + ['raw_locator_available', packet.receipt?.raw_evidence?.reference !== null], + ]); + for (const [id, result] of expected) { + if (values.has(id) && !same(values.get(id).result, result)) { + add(violations, 'MEASUREMENT_VALUE_MISMATCH', `/measurements/${id}/result`, 'receipt value contradicts packet'); + } + } + if (values.has('initial_model_visible_bytes')) { + const item = values.get('initial_model_visible_bytes'); + if (!same(item.baseline, original) || !same(item.delta, visible - original)) { + add(violations, 'MEASUREMENT_VALUE_MISMATCH', '/measurements/initial_model_visible_bytes', 'visible-byte arithmetic contradicts packet'); + } + } + if (values.has('bytes_initially_avoided')) { + const item = values.get('bytes_initially_avoided'); + if (!same(item.baseline, visible) || !same(item.delta, original - visible)) { + add(violations, 'MEASUREMENT_VALUE_MISMATCH', '/measurements/bytes_initially_avoided', 'avoided-byte arithmetic contradicts packet'); + } + } + violations.sort((left, right) => left.path.localeCompare(right.path) || left.code.localeCompare(right.code)); + return { + profile: CONTEXT_FIREWALL_VALUE_PROFILE, + valid: violations.length === 0, + violations, + }; +} + +function measurement({ + id, result, unit, measurementClass, direction, operatorDisplay, + safeToAggregate = false, +}) { + return { + aggregation: { method: safeToAggregate ? 'SUM' : null, safe: safeToAggregate }, + baseline: null, + class: measurementClass, + delta: null, + derivation: null, + direction, + evidence_refs: ['validation_result'], + id, + limitations: [], + operator_display: operatorDisplay, + result, + source_verification: measurementClass === 'EXACT' ? 'VERIFIED' : 'OBSERVED', + unit, + }; +} + +export function verificationClaimCount(result) { + return Object.values(result.verification ?? {}).filter( + (state) => !['NOT_EVALUATED', 'NOT_SUPPLIED'].includes(state), + ).length; +} + +export function createValidationValueReceipt(packet, result, { + mechanismRevision = null, +} = {}) { + if (mechanismRevision !== null + && (typeof mechanismRevision !== 'string' || mechanismRevision.length === 0)) { + throw new TypeError('mechanismRevision must be a nonempty string or null'); + } + const claims = verificationClaimCount(result); + const sourceBacked = result.valid + && result.verification?.input_hash === 'VERIFIED' + && result.verification?.source_accounting === 'VERIFIED'; + const hashPerformed = Object.entries(result.verification ?? {}).some( + ([name, state]) => name !== 'source_accounting' + && !['NOT_EVALUATED', 'NOT_SUPPLIED'].includes(state), + ); + const receipt = { + evidence: [{ + id: 'validation_result', + kind: 'JSON_POINTER', + locator: '/', + trust: 'VERIFIED', + }], + limitations: [ + 'Validation reports checks, trust, sufficiency, and rejection; it does not claim a failure was prevented.', + 'Validation of a packet is not evidence that reduced context preserves model correctness.', + sourceBacked + ? 'Caller-supplied source material was independently matched to the packet.' + : 'Source-backed verification was not completed successfully.', + ], + measurements: [ + measurement({ id: 'validation_performed', result: true, unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: false }), + measurement({ id: 'validation_classification', result: result.classification, unit: 'state', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + measurement({ id: 'verification_claims_evaluated', result: claims, unit: 'count', measurementClass: 'EXACT', direction: 'NEUTRAL', operatorDisplay: true, safeToAggregate: true }), + measurement({ id: 'source_backed_verification', result: sourceBacked, unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + measurement({ id: 'hash_verification_performed', result: hashPerformed, unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: false }), + measurement({ id: 'evidence_sufficiency', result: result.sufficiency, unit: 'state', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + measurement({ id: 'evidence_sufficient', result: result.evidence_sufficient, unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: false }), + measurement({ id: 'tamper_detected', result: result.classification === 'CRYPTOGRAPHIC_MISMATCH', unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + measurement({ id: 'inconsistency_detected', result: result.classification === 'INTERNALLY_INCONSISTENT', unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + measurement({ id: 'raw_escalation_required', result: result.raw_evidence_required, unit: 'boolean', measurementClass: 'OBSERVED', direction: 'PROTECTION_SIGNAL', operatorDisplay: true }), + ], + mechanism: { + id: DECISION_EVIDENCE_MECHANISM_ID, + name: DECISION_EVIDENCE_MECHANISM_NAME, + revision: mechanismRevision, + version: DECISION_EVIDENCE_VERSION, + }, + operation: { + configuration_id: packet?.receipt?.configuration?.identity ?? null, + id: packet?.operation_id ?? null, + name: 'context-firewall-validation', + policy_id: CONTEXT_FIREWALL_VALUE_PROFILE, + }, + run: { id: packet?.receipt?.source?.run_id ?? null }, + schema: 'opsle.value-receipt.v1', + }; + const checked = validateValueReceipt(receipt); + if (!checked.valid) throw new TypeError(`internal value receipt invalid: ${checked.violations.map((item) => item.code).join(', ')}`); + return receipt; +} + +function groupedInteger(value) { + return String(value).replace(/\B(?=(\d{3})+(?!\d))/g, ','); +} + +export function formatDecisionEvidenceIndicator(result) { + const claims = groupedInteger(verificationClaimCount(result)); + if (result.classification === 'STRUCTURALLY_INVALID') { + return '[Decision Evidence] malformed packet rejected | STRUCTURALLY_INVALID'; + } + if (result.classification === 'CRYPTOGRAPHIC_MISMATCH') { + return '[Decision Evidence] tampered packet rejected | CRYPTOGRAPHIC_MISMATCH'; + } + if (result.classification === 'INTERNALLY_INCONSISTENT') { + return '[Decision Evidence] inconsistent packet rejected | INTERNALLY_INCONSISTENT'; + } + const sourceBacked = result.verification?.input_hash === 'VERIFIED' + && result.verification?.source_accounting === 'VERIFIED'; + if (sourceBacked) { + return `[Decision Evidence] source-backed packet verified | ${result.sufficiency} | ${claims} claims checked`; + } + return `[Decision Evidence] packet validated | source unverified | ${result.sufficiency} | ${claims} claims checked`; +} diff --git a/src/index.js b/src/index.js index a1abb3d..33b5723 100644 --- a/src/index.js +++ b/src/index.js @@ -8,3 +8,18 @@ export { canonicalJson, validateContextFirewallPacket, } from './context-firewall-v1.js'; +export { + CONTEXT_FIREWALL_VALUE_PROFILE, + DECISION_EVIDENCE_MECHANISM_ID, + DECISION_EVIDENCE_MECHANISM_NAME, + DECISION_EVIDENCE_VERSION, + createValidationValueReceipt, + formatDecisionEvidenceIndicator, + validateContextFirewallValueReceipt, + verificationClaimCount, +} from './context-firewall-value.js'; +export { + MEASUREMENT_CLASSES, + VALUE_RECEIPT_SCHEMA, + validateValueReceipt, +} from './value-receipt-v1.js'; diff --git a/src/value-receipt-v1.js b/src/value-receipt-v1.js new file mode 100644 index 0000000..7d53079 --- /dev/null +++ b/src/value-receipt-v1.js @@ -0,0 +1,245 @@ +export const VALUE_RECEIPT_SCHEMA = 'opsle.value-receipt.v1'; +export const MEASUREMENT_CLASSES = Object.freeze([ + 'EXACT', 'OBSERVED', 'ESTIMATED', 'MODELED', 'EXPERIMENTAL', +]); + +const units = new Set([ + 'byte', 'event', 'count', 'ratio', 'percent', 'boolean', + 'millisecond', 'token', 'usd', 'state', +]); +const classes = new Set(MEASUREMENT_CLASSES); +const directions = new Set([ + 'HIGHER_IS_VALUE', 'LOWER_IS_VALUE', 'NEUTRAL', + 'PROTECTION_SIGNAL', 'NOT_APPLICABLE', +]); +const verificationStates = new Set([ + 'VERIFIED', 'OBSERVED', 'CALLER_SUPPLIED', 'UNVERIFIED', + 'NOT_APPLICABLE', +]); +const evidenceKinds = new Set([ + 'CONTENT_HASH', 'JSON_POINTER', 'RUN_ARTIFACT', 'PROVIDER_RECORD', + 'URI', 'CALLER_ASSERTION', +]); +const nonsummableUnits = new Set(['ratio', 'percent', 'boolean', 'state']); +const integerUnits = new Set(['byte', 'event', 'count', 'millisecond', 'token']); +const hashPattern = /^sha256:[0-9a-f]{64}$/; +const measurementIdPattern = /^[a-z][a-z0-9_]*$/; + +function object(value) { + return value !== null && typeof value === 'object' && !Array.isArray(value); +} + +function nonempty(value) { + return typeof value === 'string' && value.length > 0; +} + +function finite(value) { + return typeof value === 'number' && Number.isFinite(value); +} + +function add(violations, code, path, message) { + violations.push({ code, message, path }); +} + +function required(value, fields, path, violations) { + for (const field of fields) { + if (!Object.hasOwn(value, field)) { + add(violations, 'REQUIRED_FIELD_MISSING', `${path}/${field}`, 'required field missing'); + } + } +} + +function strings(value, path, violations) { + if (!Array.isArray(value)) { + add(violations, 'ARRAY_REQUIRED', path, 'array required'); + return; + } + value.forEach((item, index) => { + if (!nonempty(item)) add(violations, 'STRING_REQUIRED', `${path}/${index}`, 'nonempty string required'); + }); +} + +function nullableIdentity(value, path, violations) { + if (value !== null && !nonempty(value)) { + add(violations, 'INVALID_IDENTITY', path, 'nonempty string or null required'); + } +} + +function validateEvidence(value, index, state, violations) { + const path = `/evidence/${index}`; + if (!object(value)) { + add(violations, 'OBJECT_REQUIRED', path, 'evidence object required'); + return; + } + required(value, ['id', 'kind', 'locator', 'trust'], path, violations); + if (!nonempty(value.id)) add(violations, 'INVALID_EVIDENCE_ID', `${path}/id`, 'nonempty evidence identity required'); + else if (state.evidenceIds.has(value.id)) add(violations, 'DUPLICATE_EVIDENCE_ID', `${path}/id`, 'duplicate evidence identity'); + else state.evidenceIds.add(value.id); + if (!evidenceKinds.has(value.kind)) add(violations, 'INVALID_EVIDENCE_KIND', `${path}/kind`, 'unsupported evidence kind'); + if (!nonempty(value.locator)) add(violations, 'INVALID_EVIDENCE_LOCATOR', `${path}/locator`, 'nonempty locator required'); + else if (value.kind === 'CONTENT_HASH' && !hashPattern.test(value.locator)) { + add(violations, 'MALFORMED_CONTENT_HASH', `${path}/locator`, 'lowercase sha256:<64 hex> required'); + } + if (!verificationStates.has(value.trust)) add(violations, 'INVALID_TRUST_STATE', `${path}/trust`, 'unsupported trust state'); +} + +function validateDerivation(value, path, violations) { + if (value === null) return; + if (!object(value)) { + add(violations, 'INVALID_DERIVATION', path, 'object or null required'); + return; + } + required(value, ['method', 'assumptions', 'input_measurement_ids', 'experiment_id', 'comparability'], path, violations); + nullableIdentity(value.method, `${path}/method`, violations); + strings(value.assumptions, `${path}/assumptions`, violations); + strings(value.input_measurement_ids, `${path}/input_measurement_ids`, violations); + nullableIdentity(value.experiment_id, `${path}/experiment_id`, violations); + if (!['NOT_APPLICABLE', 'NOT_COMPARABLE', 'CONTROLLED'].includes(value.comparability)) { + add(violations, 'INVALID_COMPARABILITY', `${path}/comparability`, 'unsupported comparability state'); + } +} + +function validateMeasurement(value, index, state, violations) { + const path = `/measurements/${index}`; + if (!object(value)) { + add(violations, 'OBJECT_REQUIRED', path, 'measurement object required'); + return; + } + required(value, [ + 'id', 'baseline', 'result', 'delta', 'unit', 'direction', 'class', + 'evidence_refs', 'source_verification', 'operator_display', 'aggregation', + 'derivation', 'limitations', + ], path, violations); + if (!nonempty(value.id) || !measurementIdPattern.test(value.id)) { + add(violations, 'INVALID_MEASUREMENT_ID', `${path}/id`, 'lowercase measurement identity required'); + } else if (state.measurementIds.has(value.id)) { + add(violations, 'DUPLICATE_MEASUREMENT_ID', `${path}/id`, 'duplicate measurement identity'); + } else { + state.measurementIds.add(value.id); + state.measurementById.set(value.id, value); + } + if (!units.has(value.unit)) add(violations, 'INVALID_UNIT', `${path}/unit`, 'unsupported unit'); + if (!classes.has(value.class)) add(violations, 'INVALID_MEASUREMENT_CLASS', `${path}/class`, 'unsupported measurement class'); + if (!directions.has(value.direction)) add(violations, 'INVALID_DIRECTION', `${path}/direction`, 'unsupported value direction'); + if (!verificationStates.has(value.source_verification)) add(violations, 'INVALID_SOURCE_VERIFICATION', `${path}/source_verification`, 'unsupported verification state'); + if (typeof value.operator_display !== 'boolean') add(violations, 'BOOLEAN_REQUIRED', `${path}/operator_display`, 'boolean required'); + + for (const field of ['baseline', 'result', 'delta']) { + const item = value[field]; + if (item !== null && !finite(item) && typeof item !== 'string' && typeof item !== 'boolean') { + add(violations, 'INVALID_VALUE', `${path}/${field}`, 'finite number, string, boolean, or null required'); + } + } + if (finite(value.baseline) && finite(value.result)) { + if (!finite(value.delta) || Math.abs(value.delta - (value.result - value.baseline)) > 1e-12) { + add(violations, 'DELTA_MISMATCH', `${path}/delta`, 'must equal result minus baseline'); + } + } else if (value.delta !== null) { + add(violations, 'DELTA_WITHOUT_NUMERIC_STATE', `${path}/delta`, 'must be null without numeric baseline and result'); + } + if (integerUnits.has(value.unit)) { + for (const field of ['baseline', 'result']) { + const item = value[field]; + if (item !== null && (!Number.isSafeInteger(item) || item < 0)) { + add(violations, 'INVALID_NONNEGATIVE_INTEGER', `${path}/${field}`, `nonnegative safe integer required for ${value.unit}`); + } + } + } + if (value.unit === 'boolean' && [value.baseline, value.result].some((item) => item !== null && typeof item !== 'boolean')) { + add(violations, 'INVALID_BOOLEAN_MEASUREMENT', path, 'boolean unit requires boolean values'); + } + if (value.unit === 'state' && [value.baseline, value.result].some((item) => item !== null && typeof item !== 'string')) { + add(violations, 'INVALID_STATE_MEASUREMENT', path, 'state unit requires string values'); + } + + if (!Array.isArray(value.evidence_refs) || value.evidence_refs.length === 0) { + add(violations, 'EVIDENCE_REFS_REQUIRED', `${path}/evidence_refs`, 'nonempty array required'); + } else { + for (const reference of value.evidence_refs) { + if (!state.evidenceIds.has(reference)) add(violations, 'UNRESOLVED_EVIDENCE_REF', `${path}/evidence_refs`, `unresolved evidence reference ${JSON.stringify(reference)}`); + } + } + strings(value.limitations, `${path}/limitations`, violations); + validateDerivation(value.derivation, `${path}/derivation`, violations); + if (['ESTIMATED', 'MODELED'].includes(value.class) && ( + !object(value.derivation) || !nonempty(value.derivation.method) + || !Array.isArray(value.derivation.assumptions) || value.derivation.assumptions.length === 0 + )) add(violations, 'DERIVATION_REQUIRED', `${path}/derivation`, `${value.class} requires method and assumptions`); + if (value.class === 'EXPERIMENTAL' && ( + !object(value.derivation) || !nonempty(value.derivation.experiment_id) + || value.derivation.comparability !== 'CONTROLLED' + )) add(violations, 'CONTROLLED_EXPERIMENT_REQUIRED', `${path}/derivation`, 'EXPERIMENTAL requires controlled experiment identity'); + if (['EXACT', 'OBSERVED'].includes(value.class) + && object(value.derivation) + && Array.isArray(value.derivation.assumptions) + && value.derivation.assumptions.length > 0) { + add(violations, 'ASSUMPTIONS_EXCEED_CLASS', `${path}/derivation`, `${value.class} cannot depend on assumptions`); + } + if (value.class === 'EXACT' && value.source_verification !== 'VERIFIED') { + add(violations, 'EXACT_REQUIRES_VERIFIED_SOURCE', `${path}/source_verification`, 'EXACT requires VERIFIED evidence'); + } + + if (!object(value.aggregation) + || typeof value.aggregation.safe !== 'boolean' + || ![null, 'SUM'].includes(value.aggregation.method)) { + add(violations, 'INVALID_AGGREGATION', `${path}/aggregation`, 'safe boolean and SUM or null method required'); + } else { + if (value.aggregation.safe && ( + !['EXACT', 'OBSERVED'].includes(value.class) + || value.aggregation.method !== 'SUM' + || nonsummableUnits.has(value.unit) + || !finite(value.result) + )) add(violations, 'UNSAFE_AGGREGATION', `${path}/aggregation`, 'measurement is not safely summable'); + if (!value.aggregation.safe && value.aggregation.method !== null) { + add(violations, 'UNSAFE_AGGREGATION_METHOD', `${path}/aggregation`, 'unsafe measurement must use null method'); + } + } + if ((value.id?.includes('failure_prevented') || value.id?.includes('failures_prevented')) + && ['EXACT', 'OBSERVED'].includes(value.class)) { + add(violations, 'COUNTERFACTUAL_CLASS_MISUSE', `${path}/class`, 'prevented-failure claims require MODELED or EXPERIMENTAL evidence'); + } +} + +export function validateValueReceipt(receipt) { + const violations = []; + if (!object(receipt)) return { valid: false, violations: [{ code: 'OBJECT_REQUIRED', message: 'receipt object required', path: '/' }] }; + required(receipt, ['schema', 'mechanism', 'run', 'operation', 'measurements', 'evidence', 'limitations'], '', violations); + if (receipt.schema !== VALUE_RECEIPT_SCHEMA) add(violations, 'UNSUPPORTED_SCHEMA', '/schema', `only ${VALUE_RECEIPT_SCHEMA} is supported`); + if (!object(receipt.mechanism)) add(violations, 'OBJECT_REQUIRED', '/mechanism', 'mechanism object required'); + else { + required(receipt.mechanism, ['id', 'name', 'version', 'revision'], '/mechanism', violations); + for (const field of ['id', 'name', 'version']) if (!nonempty(receipt.mechanism[field])) add(violations, 'INVALID_MECHANISM', `/mechanism/${field}`, 'nonempty string required'); + nullableIdentity(receipt.mechanism.revision, '/mechanism/revision', violations); + } + if (!object(receipt.run)) add(violations, 'OBJECT_REQUIRED', '/run', 'run object required'); + else { + required(receipt.run, ['id'], '/run', violations); + nullableIdentity(receipt.run.id, '/run/id', violations); + } + if (!object(receipt.operation)) add(violations, 'OBJECT_REQUIRED', '/operation', 'operation object required'); + else { + required(receipt.operation, ['id', 'name', 'configuration_id', 'policy_id'], '/operation', violations); + nullableIdentity(receipt.operation.id, '/operation/id', violations); + if (!nonempty(receipt.operation.name)) add(violations, 'INVALID_OPERATION', '/operation/name', 'nonempty string required'); + nullableIdentity(receipt.operation.configuration_id, '/operation/configuration_id', violations); + nullableIdentity(receipt.operation.policy_id, '/operation/policy_id', violations); + } + + const state = { evidenceIds: new Set(), measurementIds: new Set(), measurementById: new Map() }; + if (!Array.isArray(receipt.evidence) || receipt.evidence.length === 0) add(violations, 'EVIDENCE_REQUIRED', '/evidence', 'nonempty array required'); + else receipt.evidence.forEach((value, index) => validateEvidence(value, index, state, violations)); + if (!Array.isArray(receipt.measurements) || receipt.measurements.length === 0) add(violations, 'MEASUREMENTS_REQUIRED', '/measurements', 'nonempty array required'); + else receipt.measurements.forEach((value, index) => validateMeasurement(value, index, state, violations)); + strings(receipt.limitations, '/limitations', violations); + + for (const [index, item] of (Array.isArray(receipt.measurements) ? receipt.measurements : []).entries()) { + if (!object(item) || item.unit !== 'usd' || !['ESTIMATED', 'MODELED'].includes(item.class)) continue; + const inputs = object(item.derivation) && Array.isArray(item.derivation.input_measurement_ids) + ? item.derivation.input_measurement_ids : []; + if (!inputs.some((identity) => state.measurementById.get(identity)?.unit === 'token')) { + add(violations, 'MONETARY_ESTIMATE_WITHOUT_TOKENS', `/measurements/${index}/derivation`, 'monetary estimate requires a token measurement input'); + } + } + violations.sort((left, right) => left.path.localeCompare(right.path) || left.code.localeCompare(right.code)); + return { valid: violations.length === 0, violations }; +} diff --git a/tests/context-firewall-v1.test.js b/tests/context-firewall-v1.test.js index d96e267..c2bdcbb 100644 --- a/tests/context-firewall-v1.test.js +++ b/tests/context-firewall-v1.test.js @@ -296,6 +296,10 @@ test('CLI emits machine-readable receipt-only validation', () => { const output = JSON.parse(result.stdout); assert.equal(output.classification, 'VALID_WITH_UNVERIFIED_SOURCE'); assert.equal(output.sufficiency, 'SUFFICIENT'); + assert.equal( + result.stderr, + '[Decision Evidence] packet validated | source unverified | SUFFICIENT | 5 claims checked\n', + ); }); test('CLI rejects malformed JSON with machine-readable control output', () => { diff --git a/tests/value-receipt-v1.test.js b/tests/value-receipt-v1.test.js new file mode 100644 index 0000000..6eff0e7 --- /dev/null +++ b/tests/value-receipt-v1.test.js @@ -0,0 +1,248 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { readFileSync, writeFileSync, mkdtempSync, rmSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import test from 'node:test'; +import { fileURLToPath } from 'node:url'; + +import { + canonicalJson, + validateContextFirewallPacket, +} from '../src/context-firewall-v1.js'; +import { loadContextFirewallVectors } from '../src/conformance.js'; +import { + createValidationValueReceipt, + formatDecisionEvidenceIndicator, + validateContextFirewallValueReceipt, +} from '../src/context-firewall-value.js'; +import { validateValueReceipt } from '../src/value-receipt-v1.js'; + +const cliPath = fileURLToPath(new URL('../bin/decision-evidence.js', import.meta.url)); +const vectors = await loadContextFirewallVectors(); + +function vector(id = 'successful-reduced-run') { + const item = vectors.valid_vectors.find((candidate) => candidate.id === id); + assert.ok(item); + return structuredClone(item); +} + +function packetBytes(packet) { + return Buffer.from(`${canonicalJson(packet)}\n`, 'utf8'); +} + +function measurement(receipt, id) { + const item = receipt.measurements.find((candidate) => candidate.id === id); + assert.ok(item); + return item; +} + +test('accepts a valid Context Firewall value receipt', () => { + const item = vector(); + assert.deepEqual(validateValueReceipt(item.value_receipt), { valid: true, violations: [] }); + assert.deepEqual(validateContextFirewallValueReceipt(item.value_receipt, item.packet), { + profile: 'opsle.decision-evidence.context-firewall-value/v1', + valid: true, + violations: [], + }); +}); + +test('rejects missing fields and unsupported schema versions', () => { + const missing = vector().value_receipt; + delete missing.operation; + assert.ok(validateValueReceipt(missing).violations.some((item) => item.code === 'REQUIRED_FIELD_MISSING')); + const unsupported = vector().value_receipt; + unsupported.schema = 'opsle.value-receipt.v2'; + assert.ok(validateValueReceipt(unsupported).violations.some((item) => item.code === 'UNSUPPORTED_SCHEMA')); +}); + +test('rejects invalid units, classes, and impossible numeric values', () => { + const receipt = vector().value_receipt; + const raw = measurement(receipt, 'raw_bytes'); + raw.unit = 'vibes'; + raw.class = 'MARKETING'; + const codes = validateValueReceipt(receipt).violations.map((item) => item.code); + assert.ok(codes.includes('INVALID_UNIT')); + assert.ok(codes.includes('INVALID_MEASUREMENT_CLASS')); + const impossible = vector().value_receipt; + measurement(impossible, 'raw_bytes').result = -1; + assert.ok(validateValueReceipt(impossible).violations.some( + (item) => item.code === 'INVALID_NONNEGATIVE_INTEGER', + )); +}); + +test('rejects malformed and unresolved evidence references', () => { + const receipt = vector().value_receipt; + receipt.evidence[0].locator = 'sha256:not-valid'; + receipt.evidence[0].kind = 'CONTENT_HASH'; + measurement(receipt, 'raw_bytes').evidence_refs = ['missing']; + const codes = validateValueReceipt(receipt).violations.map((item) => item.code); + assert.ok(codes.includes('MALFORMED_CONTENT_HASH')); + assert.ok(codes.includes('UNRESOLVED_EVIDENCE_REF')); +}); + +test('requires assumptions for estimates and models', () => { + for (const measurementClass of ['ESTIMATED', 'MODELED']) { + const receipt = vector().value_receipt; + const raw = measurement(receipt, 'raw_bytes'); + raw.class = measurementClass; + raw.aggregation = { method: null, safe: false }; + assert.ok(validateValueReceipt(receipt).violations.some((item) => item.code === 'DERIVATION_REQUIRED')); + } +}); + +test('refuses unsafe modeled aggregation and uncontrolled experiments', () => { + const modeled = vector().value_receipt; + const raw = measurement(modeled, 'raw_bytes'); + raw.class = 'MODELED'; + raw.derivation = { + assumptions: ['policy remains stable'], + comparability: 'NOT_COMPARABLE', + experiment_id: null, + input_measurement_ids: [], + method: 'counterfactual model', + }; + assert.ok(validateValueReceipt(modeled).violations.some((item) => item.code === 'UNSAFE_AGGREGATION')); + const experimental = vector().value_receipt; + const rawExperimental = measurement(experimental, 'raw_bytes'); + rawExperimental.class = 'EXPERIMENTAL'; + rawExperimental.aggregation = { method: null, safe: false }; + assert.ok(validateValueReceipt(experimental).violations.some((item) => item.code === 'CONTROLLED_EXPERIMENT_REQUIRED')); +}); + +test('byte-only evidence cannot become a monetary estimate', () => { + const receipt = vector().value_receipt; + const cost = structuredClone(measurement(receipt, 'raw_bytes')); + cost.id = 'estimated_cost_usd'; + cost.unit = 'usd'; + cost.class = 'ESTIMATED'; + cost.baseline = 0; + cost.result = 0.42; + cost.delta = 0.42; + cost.aggregation = { method: null, safe: false }; + cost.derivation = { + assumptions: ['published price applies'], + comparability: 'NOT_APPLICABLE', + experiment_id: null, + input_measurement_ids: ['raw_bytes'], + method: 'bytes times price', + }; + receipt.measurements.push(cost); + assert.ok(validateValueReceipt(receipt).violations.some((item) => item.code === 'MONETARY_ESTIMATE_WITHOUT_TOKENS')); +}); + +test('failure prevented cannot be exact or observed', () => { + for (const measurementClass of ['EXACT', 'OBSERVED']) { + const receipt = vector().value_receipt; + const raw = measurement(receipt, 'raw_bytes'); + raw.id = 'failure_prevented_count'; + raw.class = measurementClass; + if (measurementClass === 'OBSERVED') raw.source_verification = 'OBSERVED'; + assert.ok(validateValueReceipt(receipt).violations.some((item) => item.code === 'COUNTERFACTUAL_CLASS_MISUSE')); + } +}); + +test('strict profile catches a tampered Context Firewall measurement', () => { + const item = vector(); + measurement(item.value_receipt, 'raw_bytes').result += 1; + const result = validateContextFirewallValueReceipt(item.value_receipt, item.packet); + assert.equal(result.valid, false); + assert.ok(result.violations.some((violation) => violation.code === 'MEASUREMENT_VALUE_MISMATCH')); +}); + +test('creates source-unverified and source-backed validation receipts', () => { + const item = vector(); + const unverifiedResult = validateContextFirewallPacket(item.packet, { + packetBytes: packetBytes(item.packet), + }); + const unverified = createValidationValueReceipt(item.packet, unverifiedResult); + assert.equal(validateValueReceipt(unverified).valid, true); + assert.equal(measurement(unverified, 'source_backed_verification').result, false); + const backedResult = validateContextFirewallPacket(item.packet, { + packetBytes: packetBytes(item.packet), + sourceInput: item.source_input, + }); + const backed = createValidationValueReceipt(item.packet, backedResult, { + mechanismRevision: 'a'.repeat(40), + }); + assert.equal(validateValueReceipt(backed).valid, true); + assert.equal(backed.mechanism.revision, 'a'.repeat(40)); + assert.equal(measurement(backed, 'source_backed_verification').result, true); + assert.equal(measurement(backed, 'verification_claims_evaluated').result, 7); +}); + +test('tamper and inconsistency receipts report observed detection, not prevention', () => { + const item = vector(); + item.packet.receipt.input_hash = `sha256:${'0'.repeat(64)}`; + const tamperedResult = validateContextFirewallPacket(item.packet, { + packetBytes: packetBytes(item.packet), + sourceInput: item.source_input, + }); + const tampered = createValidationValueReceipt(item.packet, tamperedResult); + assert.equal(measurement(tampered, 'tamper_detected').result, true); + assert.equal(tampered.measurements.some((candidate) => candidate.id.includes('prevented')), false); + + const inconsistentItem = vector(); + inconsistentItem.packet.receipt.measurements.original_bytes += 1; + const inconsistentResult = validateContextFirewallPacket(inconsistentItem.packet, { + packetBytes: packetBytes(inconsistentItem.packet), + }); + const inconsistent = createValidationValueReceipt(inconsistentItem.packet, inconsistentResult); + assert.equal(measurement(inconsistent, 'inconsistency_detected').result, true); +}); + +test('operator formats name Decision Evidence and preserves canonical output', () => { + const item = vector(); + const result = validateContextFirewallPacket(item.packet, { + packetBytes: packetBytes(item.packet), + sourceInput: item.source_input, + }); + assert.equal( + formatDecisionEvidenceIndicator(result), + '[Decision Evidence] source-backed packet verified | SUFFICIENT | 7 claims checked', + ); +}); + +test('CLI emits validation receipt sidecar without changing canonical stdout', () => { + const item = vector(); + const directory = mkdtempSync(join(tmpdir(), 'decision-evidence-value-')); + const packetPath = join(directory, 'packet.json'); + const sourcePath = join(directory, 'source.json'); + const receiptPath = join(directory, 'receipt.json'); + try { + writeFileSync(packetPath, packetBytes(item.packet)); + writeFileSync(sourcePath, `${canonicalJson(item.source_input)}\n`); + const base = spawnSync(process.execPath, [cliPath, 'validate-context-firewall', '--packet', packetPath, '--source-input', sourcePath], { encoding: 'utf8' }); + const withReceipt = spawnSync(process.execPath, [ + cliPath, 'validate-context-firewall', '--packet', packetPath, '--source-input', sourcePath, + '--mechanism-revision', 'b'.repeat(40), '--value-receipt', receiptPath, + ], { encoding: 'utf8' }); + assert.equal(withReceipt.status, 0, withReceipt.stderr); + assert.equal(withReceipt.stdout, base.stdout); + assert.equal(withReceipt.stderr, '[Decision Evidence] source-backed packet verified | SUFFICIENT | 7 claims checked\n'); + const receipt = JSON.parse(readFileSync(receiptPath, 'utf8')); + assert.equal(validateValueReceipt(receipt).valid, true); + assert.equal(receipt.mechanism.revision, 'b'.repeat(40)); + } finally { + rmSync(directory, { recursive: true }); + } +}); + +test('CLI strictly validates the producer value receipt separately', () => { + const item = vector(); + const directory = mkdtempSync(join(tmpdir(), 'decision-evidence-profile-')); + const packetPath = join(directory, 'packet.json'); + const receiptPath = join(directory, 'receipt.json'); + try { + writeFileSync(packetPath, packetBytes(item.packet)); + writeFileSync(receiptPath, `${canonicalJson(item.value_receipt)}\n`); + const result = spawnSync(process.execPath, [ + cliPath, 'validate-context-firewall-value', '--packet', packetPath, '--receipt', receiptPath, + ], { encoding: 'utf8' }); + assert.equal(result.status, 0, result.stderr); + assert.equal(JSON.parse(result.stdout).valid, true); + assert.equal(result.stderr, '[Decision Evidence] Context Firewall value receipt verified | 11 measurements checked\n'); + } finally { + rmSync(directory, { recursive: true }); + } +}); diff --git a/tools/generate-context-firewall-vectors.js b/tools/generate-context-firewall-vectors.js index 38e08e0..43885d2 100755 --- a/tools/generate-context-firewall-vectors.js +++ b/tools/generate-context-firewall-vectors.js @@ -5,7 +5,7 @@ import { resolve } from 'node:path'; import process from 'node:process'; import { pathToFileURL } from 'node:url'; -const EXPECTED_CONTEXT_FIREWALL_SHA = 'dd34bd9f681314761f1ca87f339648bf611811f3'; +const EXPECTED_CONTEXT_FIREWALL_SHA = '953c48f1cfd154d6b7ed10b51b87fe54e4df45f2'; function parseArgs(args) { const options = { @@ -63,6 +63,8 @@ async function main() { throw new Error(`producer fixture ${fixtureName} did not yield a valid packet`); } const packet = execution.packet; + const valueReceipt = execution.valueReceipt; + valueReceipt.mechanism.revision = head; const sufficiency = packet.decision_evidence.disposition; return { expected: expected( @@ -74,6 +76,7 @@ async function main() { packet, producer_fixture: fixtureName, source_input: fixture.input, + value_receipt: valueReceipt, }; }); diff --git a/tools/verify-context-firewall-interop.js b/tools/verify-context-firewall-interop.js index fb3776e..99db124 100755 --- a/tools/verify-context-firewall-interop.js +++ b/tools/verify-context-firewall-interop.js @@ -8,8 +8,9 @@ import { canonicalJson, validateContextFirewallPacket, } from '../src/context-firewall-v1.js'; +import { validateContextFirewallValueReceipt } from '../src/context-firewall-value.js'; -const EXPECTED_CONTEXT_FIREWALL_SHA = 'dd34bd9f681314761f1ca87f339648bf611811f3'; +const EXPECTED_CONTEXT_FIREWALL_SHA = '953c48f1cfd154d6b7ed10b51b87fe54e4df45f2'; function gitHead(path) { const result = spawnSync('git', ['-C', path, 'rev-parse', 'HEAD'], { encoding: 'utf8' }); @@ -32,18 +33,23 @@ async function main() { ['needs-raw-evidence', 'process/interrupted-truncated', 'NEEDS_RAW_EVIDENCE'], ].map(([id, fixtureName, expectedSufficiency]) => { const fixture = fixtures.corpus.find((item) => item.name === fixtureName); - const packet = reducer.reduceTestRun(fixture.input, fixture.options); + const { packet, valueReceipt } = reducer.reduceWithValueReceipt(fixture.input, { + ...(fixture.options ?? {}), + mechanismRevision: contextHead, + }); const packetBytes = reducer.serializePacket(packet); const result = validateContextFirewallPacket(packet, { packetBytes, sourceInput: fixture.input, }); + const valueResult = validateContextFirewallValueReceipt(valueReceipt, packet); return { classification: result.classification, id, - pass: result.valid && result.sufficiency === expectedSufficiency, + pass: result.valid && result.sufficiency === expectedSufficiency && valueResult.valid, producer_fixture: fixtureName, sufficiency: result.sufficiency, + value_receipt_valid: valueResult.valid, }; }); const tamperFixture = fixtures.corpus.find((item) => item.name === 'normal/small-all-pass');