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
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI

on:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm run lint
- run: npm test
- run: npm run conformance
11 changes: 11 additions & 0 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@
generic input → Decision Evidence Protocol → generic output
```

```text
packet-v1 ────────────────┐
├→ independent validator → structured result
optional source bytes ───┘
```

## Ports

- Input adapter: translates a host’s observable state into the generic contract.
Expand All @@ -14,3 +20,8 @@ generic input → Decision Evidence Protocol → generic output
## Independence

Host-specific adapters are optional and removable. Disabling the project should return the host to its prior behavior. No core module may import Taslos Tasks internals.

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.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## 0.2.0 - 2026-08-25

- Added an independent Context Firewall packet-v1 validator and stable API.
- Added machine-readable receipt-only and source-backed CLI validation.
- Added 24 public-safe conformance vectors with tamper, accounting, escalation,
version, hash, provenance, and numeric boundary failures.
- Added exact-revision cross-repository interoperability verification without a
runtime dependency.
- Documented structural versus cryptographic verification, source suppression,
raw-evidence limitations, and the EXP-001 boundary.

## 0.1.0 - 2026-08-25

- Published initial theory, falsifiable specification, benchmark plan, architecture, and provenance.
Expand Down
121 changes: 116 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@ A small structured envelope can improve interoperability and reduce context whil

## Mechanism

Emit status, exit state, changed entities, warnings/errors, test counts, repository revisions, duration, verification, uncertainty, provenance, artifacts, and an explicit raw-output escalation reason only when applicable.
Emit status, exit state, changed entities, warnings/errors, test counts,
repository revisions, duration, verification, uncertainty, provenance,
artifacts, and an explicit raw-output escalation reason only when applicable.

The reference implementation also independently validates Context Firewall
`opsle.context-firewall.evidence-packet/v1` packets. It does not import or call
Context Firewall. With source bytes, it recomputes hashes, reclassifies the
documented TAP subset, verifies retained line locators, and derives suppression
accounting independently.

## Why it matters

Expand All @@ -22,17 +30,109 @@ The Opsle thesis asks: **What if we stopped using intelligence for work that doe

A universal event schema, embedding raw logs by default, or expanding fields without demonstrated decision value.

## Public API

```js
import {
validateContextFirewallPacket,
} from '@opsle/decision-evidence-protocol';

const result = validateContextFirewallPacket(
packet,
{
packetBytes,
sourceInput,
},
);
```

`sourceInput` is optional and uses Context Firewall's public input shape. A
caller that has only stream bytes can instead supply `sourceStreams` as
`{ name, bytes }` entries. Supplying neither validates the receipt internally
and returns `VALID_WITH_UNVERIFIED_SOURCE`; it never reports the input hash as
independently verified.

The structured result includes:

- `classification`: `VALID`, `VALID_WITH_UNVERIFIED_SOURCE`,
`STRUCTURALLY_INVALID`, `INTERNALLY_INCONSISTENT`, or
`CRYPTOGRAPHIC_MISMATCH`;
- `sufficiency`: `SUFFICIENT`, `NEEDS_RAW_EVIDENCE`, or `INVALID`;
- `verification`: per-claim states for configuration, source, semantic payload,
retained line hashes, canonical packet bytes, measurements, and accounting;
- `raw_evidence`: suppression, preservation, destruction, and caller-locator
claim state, with locator verification explicitly `CALLER_CLAIM_ONLY`; and
- `violations`: stable path-specific failure objects.

`NEEDS_RAW_EVIDENCE` is valid protocol output but
`evidence_sufficient` is always false.

## CLI

Validate canonical packet bytes from stdin:

```bash
node ./bin/decision-evidence.js \
validate-context-firewall
```

Validate a packet and its source input:

```bash
node ./bin/decision-evidence.js \
validate-context-firewall \
--packet packet.json \
--source-input source.json
```

Output is canonical machine-readable JSON. Exit code 0 means a valid receipt,
including valid-but-insufficient escalation receipts; callers must inspect
`sufficiency`. Exit code 1 means validation failure. Invocation or JSON errors
use exit code 2.

## Verification

```bash
npm run lint
npm test
npm run conformance
```

The self-contained conformance corpus contains 24 public-safe vectors: 9 valid
producer packets and 15 intentional structural, consistency, boundary, and
cryptographic failures. See
[the packet-v1 profile](docs/context-firewall-packet-v1.md).

The separately run cross-repository compatibility proof is:

```bash
node \
tools/verify-context-firewall-interop.js \
../context-firewall
```

It requires the exact documented read-only Context Firewall revision and does
not create a runtime or CI dependency on that repository.

## Current maturity

**PROTOTYPE** under the [Opsle maturity model](https://github.com/opsle/research/blob/main/MATURITY.md).
The authoritative lifecycle stage is recorded by
[Opsle Research](https://github.com/opsle/research). The packet-v1 validator,
automated failure tests, conformance vectors, and exact-revision interoperability
proof establish a narrow verification claim. They do not establish comparative
benefit, benchmark readiness, or model correctness.

## Existing evidence

Structured provider results and operational metrics show feasibility inside one system. Cross-tool adequacy is unverified.
The generic envelope validator remains available. Context Firewall packet-v1
interoperability is now executable and deterministic at the revisions recorded
in the authoritative Opsle registry.

## Evidence still missing

Adapter trials across test, Git, build, lint, typecheck, shell, and deployment tools; versioning and conformance rules.
Other tool classes, independent implementations beyond Context Firewall,
measured decision adequacy, comparative benchmarks, and replication remain
missing.

## Benchmark strategy

Expand Down Expand Up @@ -61,7 +161,18 @@ A small dependency-free reference prototype is included for falsification and in

## Known limitations

Adapter trials across test, Git, build, lint, typecheck, shell, and deployment tools; versioning and conformance rules.
- A syntactically valid source hash is not independently verified without
supplied source bytes.
- `raw_evidence.reference` is caller-owned. Validation proves only whether a
nonempty reference was declared, not whether its target exists, is immutable,
is available, or contains the claimed bytes.
- Packet v1 hashes canonical `decision_evidence`; it has no self-referential
whole-packet hash. The validator instead checks exact canonical packet bytes
when supplied and always checks the fixed-point `reduced_bytes` measurement.
- The strict TAP-subset classifier is not arbitrary TAP or general log support.
- A valid receipt does not prove that a model will make a correct decision from
reduced evidence. That remains the planned EXP-001 question, and no model or
provider experiment is run here.

## License

Expand Down
11 changes: 11 additions & 0 deletions SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

Status: experimental prototype contract.

Versioned Context Firewall profile:
`opsle.decision-evidence.context-firewall-validation/v1`.

## Compatibility boundary

The primitive accepts generic structured input and emits generic structured output. It must not require a Taslos Tasks database, worker, scheduler, package, runtime path, or private service.
Expand Down Expand Up @@ -29,10 +32,18 @@ The primitive accepts generic structured input and emits generic structured outp
- Raw output is referenced, not embedded by default.
- Protocol growth requires measured decision value.

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).

## 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.

## Versioning

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
versions are rejected explicitly; they are not interpreted as compatible.
76 changes: 76 additions & 0 deletions bin/decision-evidence.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env node
import { readFile } from 'node:fs/promises';
import process from 'node:process';

import {
canonicalJson,
validateContextFirewallPacket,
} from '../src/context-firewall-v1.js';
import { runContextFirewallConformance } from '../src/conformance.js';

function usage() {
return [
'usage: decision-evidence validate-context-firewall [--packet PATH|-] [--source-input PATH]',
' decision-evidence conformance',
'',
].join('\n');
}

async function readBytes(path) {
if (path !== '-') return readFile(path);
const chunks = [];
for await (const chunk of process.stdin) chunks.push(chunk);
return Buffer.concat(chunks);
}

function parseValidateArgs(args) {
let packet = '-';
let sourceInput = 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 throw new TypeError(`unknown or incomplete argument: ${args[index]}`);
}
return { packet, sourceInput };
}

async function parseJsonFile(path, label) {
const bytes = await readBytes(path);
try {
return { bytes, value: JSON.parse(bytes.toString('utf8')) };
} catch {
throw new TypeError(`${label} must be valid JSON`);
}
}

async function main() {
const [command, ...args] = process.argv.slice(2);
if (command === 'conformance') {
if (args.length > 0) throw new TypeError('conformance accepts no arguments');
const report = await runContextFirewallConformance();
process.stdout.write(`${canonicalJson(report)}\n`);
process.exitCode = report.conformance === 'PASS' ? 0 : 1;
return;
}
if (command !== 'validate-context-firewall') {
process.stderr.write(usage());
process.exitCode = 2;
return;
}
const options = parseValidateArgs(args);
const packet = await parseJsonFile(options.packet, 'packet');
const sourceInput = options.sourceInput === null
? undefined
: (await parseJsonFile(options.sourceInput, 'source input')).value;
const result = validateContextFirewallPacket(packet.value, {
packetBytes: packet.bytes,
sourceInput,
});
process.stdout.write(`${canonicalJson(result)}\n`);
process.exitCode = result.valid ? 0 : 1;
}

main().catch((error) => {
process.stderr.write(`${canonicalJson({ code: 'INVALID_INVOCATION', message: error.message })}\n`);
process.exitCode = 2;
});
7 changes: 6 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Documentation

This directory is reserved for glossary, threat model, adapter guidance, and experiment interpretation that would obscure the core specification.
This directory holds profile-specific normative guidance and verification
boundaries that would obscure the generic specification.

- [`context-firewall-packet-v1.md`](context-firewall-packet-v1.md) defines the
supported producer contract, enforced invariants, sufficiency semantics, and
known limits.
Loading
Loading