Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ jobs:
- run: npm run lint
- run: npm test
- run: npm run conformance
- run: npm run determinism
18 changes: 18 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
43 changes: 43 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
22 changes: 21 additions & 1 deletion SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
46 changes: 44 additions & 2 deletions bin/decision-evidence.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import { readFile, writeFile } from 'node:fs/promises';
import process from 'node:process';

import {
canonicalJson,
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');
Expand All @@ -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) {
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions docs/context-firewall-packet-v1.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down
21 changes: 21 additions & 0 deletions docs/value-receipt-v1.md
Original file line number Diff line number Diff line change
@@ -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.
Loading
Loading