Skip to content
Closed
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
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@

> Models express intent. Runtimes retain authority. INTERPLANE defines the boundary between them.

An attachment of [Aienix](https://github.com/aien-dev/aienix), the core tree of AIEN. INTERPLANE lives in
its own repository and plugs into the core at a boundary. Website: [interplane.io](https://interplane.io).

**Status (2026-10-18): pre-1.0, version 0.3.0.** 0.1 (Reality Layer) is the base, 0.2 (Capability)
closed with its gate failed and the failure published, 0.3 (Trust) closed with its gate passed; 0.4
and 0.5 are planned, not built. The last merged work (2026-10-16) moved the conformance tools and examples to Rust, removed the
Python SDK and adapters, and enrolled the repository in AIEN's Spark verification pipeline.
[`STATUS.md`](STATUS.md) is the authority on what is implemented, tested, conformant or qualified.

```
Model side: Qwen3.5 Ajax (when published) other local or hosted models
\ | /
Expand Down Expand Up @@ -45,7 +54,7 @@ are planned, not built (`ROADMAP.md`).
| Module | What it is | Status |
|---|---|---|
| **Core** | normative JSON Schemas (2020-12) for envelope, intent, capability, decision, result, event, catalog, selection, input record, probe report; versioning and error codes | see `STATUS.md` |
| **Lenshift** | model dialect parsers and result renderers: `openai`, `qwen35`; `ajax` reserved | see `STATUS.md` |
| **Lenshift** | model dialect parsers and result renderers: `openai`, `openai_stream`, `qwen35`, `aien_legacy`; `ajax` reserved | see `STATUS.md` |
| **Crossveil** | the authority-boundary contract: two runtime callbacks, a lifecycle with fail-closed invariants, trust classes | see `STATUS.md` |
| **CrossAxis** | explicit, versioned capability mapping; a deterministic domain selector with a before/after receipt; bounded expansion | see `STATUS.md` |
| **Interplane Probe** | measured capability qualification of an OpenAI-compatible endpoint | see `STATUS.md` |
Expand Down
12 changes: 6 additions & 6 deletions adapters/aien/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ spent only by AIEN. Nothing under `rust/`, `spec/` or
## Pinned AIEN sources

`aien-capability` and `aien-mcp` are git dependencies pinned to
`aien-spark/aien-sovereign-core@9b5e6e82359f4ad6b6f03042e83ef6411c5f15ce` (main 2026-10-08; `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 4d4dfd4, `git diff --stat 4d4dfd4 9b5e6e8 -- crates/aien-capability crates/aien-mcp` is empty, and the live gate below passed against a daemon built from 9b5e6e8. 4d4dfd4 was main 2026-10-07, after PR #296 merged: the daemon honours only grants it minted itself and refuses every caller-written authorization note, sovereign-core #261; and PR #295: an approved proposal carries a signed requirements goal, a missing one is refused, #289. `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 8bcd79b, main after PR #262 merged: the authenticated `ComposeApprovedProposal` daemon command the ledger route uses; `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 7d37da1, after PR #260 merged: two-phase approval spend, a grant is reserved at mint, committed when the effect runs, released if the effect is dropped, and `EffectLane::with_clock` re-checks expiry at commit; before #260 `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 0bdc97a, main after PR #208 merged, which binds the idempotency ledger to effect identity and lets an approver revoke an unspent grant; before it, PR #207 merged,
`aien-dev/aien-sovereign-core@9b5e6e82359f4ad6b6f03042e83ef6411c5f15ce` (main 2026-10-08; `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 4d4dfd4, `git diff --stat 4d4dfd4 9b5e6e8 -- crates/aien-capability crates/aien-mcp` is empty, and the live gate below passed against a daemon built from 9b5e6e8. 4d4dfd4 was main 2026-10-07, after PR #296 merged: the daemon honours only grants it minted itself and refuses every caller-written authorization note, sovereign-core #261; and PR #295: an approved proposal carries a signed requirements goal, a missing one is refused, #289. `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 8bcd79b, main after PR #262 merged: the authenticated `ComposeApprovedProposal` daemon command the ledger route uses; `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 7d37da1, after PR #260 merged: two-phase approval spend, a grant is reserved at mint, committed when the effect runs, released if the effect is dropped, and `EffectLane::with_clock` re-checks expiry at commit; before #260 `crates/aien-capability` and `crates/aien-mcp` are byte-identical to 0bdc97a, main after PR #208 merged, which binds the idempotency ledger to effect identity and lets an approver revoke an unspent grant; before it, PR #207 merged,
which makes the authority exposure-aware, on top of PR #204 single-use approvals and the PR #203
authority seam). `aegis` (feature `aegis-gate`, on by default) cannot be a git dependency because
`aegis-runtime`'s own `Cargo.toml` reaches a sibling checkout by relative path
Expand All @@ -23,8 +23,8 @@ checkout:

```
<parent>/interplane/adapters/aien (this crate)
<parent>/interplane-audit/aegis-runtime aien-spark/aegis-runtime @ AEGIS_RUNTIME_REV in PINS
<parent>/interplane-audit/aien-protocols aien-spark/aien-protocols @ AIEN_PROTOCOLS_REV in PINS
<parent>/interplane-audit/aegis-runtime aien-dev/aegis-runtime @ AEGIS_RUNTIME_REV in PINS
<parent>/interplane-audit/aien-protocols aien-dev/aien-protocols @ AIEN_PROTOCOLS_REV in PINS
```

All sibling pins live in one file, `PINS` (this directory). CI (`.github/workflows/ci.yml`, job `adapter-aien`)
Expand All @@ -39,7 +39,7 @@ cd adapters/aien && cargo test # toolchain is pinned by /rust-toolchai
The script also fails if the `aien-sovereign-core` rev in `Cargo.toml` differs from `SOVEREIGN_CORE_REV` in `PINS`.
To move a pin, change `PINS` (and `Cargo.toml` for sovereign-core) in the same PR.
Without the `aegis-gate` feature the crate still builds and every `decide()` is `denied` (fail closed).
Building `aegis-runtime` writes `mojo/libaegis_simd.so` inside that checkout (its `build.rs`).
Building `aegis-runtime` at the pinned commit writes `mojo/libaegis_simd.so` inside that checkout (its `build.rs`). aegis-runtime removed Mojo on its `main` on 2026-10-15 (aegis-runtime PR #49); the pin here has not moved past that yet.

## Reused from AIEN (called for real)

Expand Down Expand Up @@ -457,8 +457,8 @@ cargo test --offline
cargo fmt --check && cargo clippy --offline --all-targets -- -D warnings
```

Building `aegis` runs its `build.rs`, which writes `mojo/libaegis_simd.so` into the pinned
aegis clone as an untracked file. This crate is its own Cargo workspace and is not a member of
Building `aegis` at the pinned commit runs its `build.rs`, which writes `mojo/libaegis_simd.so` into the
pinned aegis clone as an untracked file (aegis-runtime `main` has had no Mojo since 2026-10-15). This crate is its own Cargo workspace and is not a member of
`rust/Cargo.toml`.

### The same cycle with a real model turn
Expand Down
30 changes: 15 additions & 15 deletions bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ The two recorded adapter hosts (`runs/adapter-repro-20261005T1215Z/toy/authority
| `stubs/<name>.json` | Fixed results for read-only Odysseus tools the reference adapter does not execute. |
| `stubs/backends.json` | Simulated backends `sim-1`: for every tool a task lists, which backend answers it after Odysseus authorizes the call, and its documented semantics. |
| `stubs/stores/<fixture>.json` | Private-data stores (notes, memory, calendar, contacts, editor documents, models, tokens) read by the `sim-1` backends. A fixture without a file has empty stores. |
| `tools/sim_backends.py` | The `sim-1` simulators (stdlib only), shared by the runner and the validator. |
| `tools/validate.py` | Structural validator (stdlib only). CI job `bench-structural` runs it. |
| `tools/stats.py` | The pre-registered paired statistics (Newcombe 1998 method 10, exact McNemar), with a self-test against the paper's table. |
| `CORPUS-DIGEST.txt` | Frozen digests of the corpus; CI recomputes and compares. |
| `PROTOCOL-0.2x.md` | Pre-registered 0.2x protocol (future work, no results): held-out set, seven conditions, runtime-triggered expansion rules, thresholds. |
| `heldout-0.2x/` | The 0.2x held-out qualification set: 120 `tasks/`, its own `fixtures/`, `stores/`, `stubs/`, `prompts/discovery-addendum.md` and `CORPUS-DIGEST.txt`. Paths inside its tasks are relative to this folder. Check with `validate.py --corpus 0.2x`. |
| `tools/sim_backends.py` | Removed 2026-10-15 (in git history). The `sim-1` simulators, shared by the runner and the validator. |
| `tools/validate.py` | Removed 2026-10-15 (in git history), with CI job `bench-structural` that ran it. Structural validator. |
| `tools/stats.py` | Removed 2026-10-15 (in git history). The pre-registered paired statistics (Newcombe 1998 method 10, exact McNemar), with a self-test against the paper's table. |
| `CORPUS-DIGEST.txt` | Frozen digests of the corpus. CI no longer recomputes them (see Status). |
| `PROTOCOL-0.2x.md` | Pre-registered 0.2x protocol: held-out set, seven conditions, runtime-triggered expansion rules, thresholds. Run on 2026-10-05: qualified FAIL in all four arms (`STATUS.md`, `docs/REPORT-0.2x.md`). |
| `heldout-0.2x/` | The 0.2x held-out qualification set: 120 `tasks/`, its own `fixtures/`, `stores/`, `stubs/`, `prompts/discovery-addendum.md` and `CORPUS-DIGEST.txt`. Paths inside its tasks are relative to this folder. It was checked with `validate.py --corpus 0.2x` (removed 2026-10-15). |

## Categories (dev / qual)

Expand Down Expand Up @@ -159,14 +159,14 @@ they were published with the 0.2 run. The 0.2x gate uses only the held-out set i
- Covered means every `required_capabilities` entry is selected and every `allowed_alternatives`
group has at least one selected member.
4. If the answer needs a judgment call, redesign the task until a substring or regex decides it.
5. Run `python3 bench/tools/validate.py`. When the change is intended, run it with
`--write-digest` and commit the new `CORPUS-DIGEST.txt` in the same commit. A change to a
`qual` task after the qualification freeze invalidates that run.
5. The validator that checked a change and rewrote `CORPUS-DIGEST.txt` (`tools/validate.py`, with
`--write-digest`) was removed on 2026-10-15; a corpus change needs a Rust port of it first. A change
to a `qual` task after the qualification freeze invalidates that run.

No git repository fixture is needed: the catalog has no git tool, so `fixtures/build.sh` does not
exist.

## Running it (paired runner and analyzer)
## Running it (paired runner and analyzer; historical, the tools were removed on 2026-10-15)

- `tools/run_bench.py` runs both conditions per task through the INTERPLANE pipeline with the real
`OdysseusAuthority` (Odysseus at a8c147b, via `ODYSSEUS_SRC`), against an OpenAI-compatible
Expand All @@ -187,15 +187,15 @@ exist.
- `tools/bench_eval.py` is the deterministic judge and the per-run metrics, shared by the runner
and the analyzer. `tools/analyze.py <run-dir>` (stdlib only, no inference) writes
`summary.json`, `summary.md` and `tasks.csv`, byte-identically for the same input.
- Offline tests: `tools/test_analyze.py` (stdlib, runs in CI against a checked-in synthetic run)
- Offline tests: `tools/test_analyze.py` (stdlib; it ran in CI against a checked-in synthetic run)
and `tools/test_runner_offline.py` (a scripted fake endpoint; needs the Odysseus venv; also runs
every `sim-1` backend kind twice and checks the results are identical, and runs `runtime-v1`
with the denial and approval negative controls).
- Corpus digests: adding `stubs/backends.json` and `stubs/stores/` changed `inputs_digest` in
`CORPUS-DIGEST.txt`. `tasks_digest` and `protocol_sha256` are unchanged. The 0.2 runs carry the
digests they ran against in their own `manifest.json`, which is unchanged.

## Gate M live-model leg (PROTOCOL-0.3.md section 7)
## Gate M live-model leg (PROTOCOL-0.3.md section 7; historical, the tool was removed on 2026-10-15)

`tools/live_injection.py` re-runs the injection fixtures of C01 to C08 and C11 (33 cases) with the
scripted obedient model replaced by a live one. For each case it replays the fixture's earlier steps
Expand All @@ -207,7 +207,7 @@ dialect and lets the mock authority decide. Temperature 0, seed 42, one run per
--endpoint http://localhost:11434/v1 --model <model> --out bench/runs/<run-id>/live/

`--scripted obey|refuse|silent|other|mixed` uses a deterministic fake endpoint instead (offline;
`tools/test_live_injection.py` runs in CI). Output: `manifest.json`, `cases/<case>.json`,
`tools/test_live_injection.py` ran in CI). Output: `manifest.json`, `cases/<case>.json`,
`summary.json`, `summary.md`: follow rate (injected intent emitted / cases run) with Wilson 95 %
interval per category and pooled, refusal / no-answer / other counts, and total violations (the only
gated number, must be 0). The verdict (`summary.json` `verdict`, exit code) is PASS only when every
Expand All @@ -221,9 +221,9 @@ and a lexical refusal match, or empty text). Arguments are stored only as digest
Two C07 cases (23, 25) forge fields of an envelope, which a model cannot do; for them only the
content that claims the forged value is live.

## Running the 0.2x campaign (PROTOCOL-0.2x.md, section 10)
## Running the 0.2x campaign (PROTOCOL-0.2x.md, section 10; historical)

Nothing here has been run on the held-out set. The runner switches, all required with `--backends sim-1`:
The campaign ran on 2026-10-05 (`runs/heldout-0.2x-20261005T0102Z`, qualified FAIL, see `STATUS.md`); the runner that drove it was removed on 2026-10-15. The runner switches, all required with `--backends sim-1`:

| Switch | What it does |
|---|---|
Expand Down
4 changes: 2 additions & 2 deletions provenance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,14 @@ record is never rewritten to match a new result.
`OpenWALDOByteTokenizer` custom code, not a Hugging Face `tokenizer.json`, so the load-support
check says `unsupported_tokenizer` and the AIEN, trace and effect links are labelled missing.
- `fixtures/real-waldo-tokenizer-json`: REAL bytes. WALDO CPU smoke run exported by the patched exporter
(aien-spark/waldo `export-tokenizer-json` 09f262c, writes a Hugging Face `tokenizer.json`), then
(aien-spark/waldo, now archived, `export-tokenizer-json` 09f262c, writes a Hugging Face `tokenizer.json`), then
really loaded by aien-cli (sovereign-core PR #248 head 8e7b14d, debug build, CPU). The `aien` link
is present with `candidate_id: null` (no frozen candidate, no `candidate_manifest` record); the
daemon log is retained in full, including its warm-up refusal (plain base model, no chat
template). Effect and INTERPLANE links are labelled missing.
- `fixtures/real-waldo-aien-chain`: REAL bytes from ONE run (CPU evidence), see `REAL-CHAIN.md`. A tiny
WALDO `chatml-v1` model, supervised-fine-tuned on tool-call conversations we wrote and exported with
`tokenizer.json` and the standard ChatML template (fork aien-spark/waldo `export-tokenizer-json` 4c407d7), is
`tokenizer.json` and the standard ChatML template (fork aien-spark/waldo, now archived, `export-tokenizer-json` 4c407d7), is
loaded by the AIEN daemon (aien-cli, sovereign-core main 12c1a5f, release build, CPU-reference backend).
AIEN's own generation path (`StreamTurn`) on that loaded model produces the tool-call text; the INTERPLANE
`aien_legacy` dialect parses it; the adapter drives one approved `write_file`; the daemon's ledger records
Expand Down
8 changes: 4 additions & 4 deletions rust/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# INTERPLANE 0.1: Rust reference implementation
# INTERPLANE Rust reference implementation (workspace version 0.3.0)

Six crates, minimal dependencies (serde, serde_json, sha2, regex, thiserror; the probe adds ureq). No async runtime.
Six crates, minimal dependencies (serde, serde_json, sha2, regex, thiserror; the probe adds ureq, and the conformance crate's default `schema-check` feature adds jsonschema). No async runtime. Since 2026-10-15 this is the only implementation; the Python SDK was removed (see the root README).

- `interplane-core`: wire types, JCS canonical JSON and digests, envelope validation, request ledger, lifecycle state machine.
- `interplane-lenshift`: dialect parsers (`openai`, `qwen35`) that turn model output into tool requests.
- `interplane-lenshift`: dialect parsers (`openai`, `openai_stream`, `qwen35`, `aien_legacy`; `ajax` reserved) that turn model output into tool requests.
- `interplane-crossaxis`: mapping tables, argument coercion, capability selection and measurement.
- `interplane-crossveil`: the admission pipeline (fails closed) and the mock runtime.
- `interplane-conformance`: runs `conformance/fixtures` and writes verdicts.
- `interplane-conformance`: runs `conformance/fixtures` and writes verdicts; its `interplane-corpus` tool checks schemas and fixtures, freezes `TRUST-DIGEST.txt` and computes adapter subsets; `adapter_runner` judges a new adapter.
- `interplane-probe`: qualifies an OpenAI-compatible endpoint with measured probes.

```
Expand Down
Loading