Metadata-Version: 2.4
Name: metaspace-membrane
Version: 0.3.4
Summary: A deterministic safety membrane for machine-generated software (MetaSpace.Bio Engine Project).
Author-email: Szőke László-Ferenc <admin@metaspace.bio>
License: BUSL-1.1
Project-URL: Homepage, https://metaspace.bio
Project-URL: Repository, https://github.com/LemonScripter/metaspace-membrane
Project-URL: Issues, https://github.com/LemonScripter/metaspace-membrane/issues
Project-URL: Landing, https://ai-membrane.metaspace.bio
Keywords: security,sandbox,webassembly,capability,ai-safety,guardrail,claude-code,agent-safety
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: License :: Other/Proprietary License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: pro
Requires-Dist: cryptography>=41; extra == "pro"
Provides-Extra: proofs
Requires-Dist: wasmtime>=13; extra == "proofs"
Requires-Dist: cryptography>=41; extra == "proofs"
Dynamic: license-file

﻿# MetaSpace Membrane

**A deterministic safety membrane for machine-generated software.**

![proofs: reproducible](https://img.shields.io/badge/proofs-reproducible-brightgreen)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.21426513.svg)](https://doi.org/10.5281/zenodo.21426513)
![License: BUSL-1.1](https://img.shields.io/badge/license-BUSL--1.1-blue)

MetaSpace Membrane turns an *undecidable* question — *"is this AI doing the right thing?"* —
into a *decidable* one — *"is this effect inside the declared boundary?"* — and enforces the
answer **deny-by-default**. One `.bio` constitution, three membranes, two products.<!-- claim: C-01 --><!-- claim: C-21 -->

> Part of the **MetaSpace.Bio Engine Project** — Szőke László-Ferenc (admin@metaspace.bio).
> **Patent pending.**

---

## Watch the 60-second explainer

[![MetaSpace Membrane — 60-second explainer](assets/explainer-poster.png)](assets/explainer.mp4)

*Containment, not correctness — the idea in one minute.* ▶ click to play

---

## Screenshots

**The Warden control panel** (`metaspace ui`) — a localhost web UI to configure the membrane
per working directory. No config files to hand-edit; every project shows its mode
(observe / dry-run / **enforcing**) at a glance.

![MetaSpace Warden control panel](assets/panel.png)

**The one-line pitch** — the agent can be *completely* deceived; the harmful effect still
cannot occur.<!-- claim: C-03 --><!-- claim: C-05 -->

![MetaSpace Warden — deny-by-default containment layer](assets/landing.png)

---

## Why

You cannot prove that a generated program does the right thing (Rice's theorem — undecidable).
So we stop verifying intent and **contain effects** instead.<!-- claim: C-21 --> A membrane sits
at a chokepoint, reads the constitution, and blocks anything not explicitly granted. A bug becomes
*a deviation from the constitution* — machine-measurable and enforceable.

The guarantee is only as hard as the chokepoint is unbypassable — each tier's exact strength and
condition is recorded in [`docs/CLAIMS.md`](docs/CLAIMS.md):<!-- claim: C-01 --><!-- claim: C-02 --><!-- claim: C-15 -->

```
heuristic    ->  language guard  ->  harness hook  ->  WebAssembly
(advisory)       (bypassable)        (hard on agent)   (unbypassable)
```

> **Case study — "Friendly Fire" (AI Now Institute, 2026):** a prompt-injected coding agent is
> steered by a malicious repo into running a payload → RCE. We assume the model is *fully*
> deceived and still make the effect unreachable. A real functional payload fires without the
> membrane and never with it. See **[`docs/THREAT_FRIENDLY_FIRE.md`](docs/THREAT_FRIENDLY_FIRE.md)**
> · reproduce with `python evidence/run_friendly_fire_proof.py`.<!-- claim: C-03 -->

## Install & try (60 seconds)

```bash
pip install metaspace-membrane
metaspace install     # user-level, starts in dry-run (observe, no blocking)
metaspace demo        # live self-test: watch it block the attack, then `metaspace enforce`
```

![`metaspace demo` — the "Friendly Fire" attack blocked live](assets/demo.gif)

*`metaspace demo` running the real hook: the agent is assumed fully deceived, yet every attack effect is blocked while normal work still runs.*<!-- claim: C-36 -->

Requires **Python 3.10+** (the hook has zero third-party dependencies — nothing else to install).<!-- claim: C-31 -->
The membrane installs **outside any project's write scope**, so a prompt-injected agent cannot
disable it.<!-- claim: C-33 --> Full guide + honest scope: **[`docs/INSTALL.md`](docs/INSTALL.md)**.

---

## Two products, one engine

| | **Product A — App membrane** | **Product B — Agent membrane** |
|---|---|---|
| Contains | any application ⊂ its `.bio` | the coding assistant ⊂ its limits |
| Chokepoint | WebAssembly capability import | Claude Code PreToolUse hook |
| Guarantee | **unbypassable** (hard, WebAssembly only)<!-- claim: C-01 --> | hard on the agent (sits outside it)<!-- claim: C-02 --> |
| Status | WebAssembly/WASI **or** OS-sandbox (Landlock): real native programs, kernel-contained<!-- claim: C-04 --> | **Warden MVP** — install → enforce → report loop, proven end-to-end<!-- claim: C-32 --> |

Both are built on the same `core/` decision engine (`guard.py`) and the same `.bio` file.

---

## Status & maturity

This is a **research prototype / reference implementation** (TRL ~3–4). The mechanisms are real,
falsifiable, and enforced by real substrates — run `python evidence/run_falsification.py` to make
the repo try (and fail) to prove itself hollow, and `python evidence/run_fuzz.py` for 5000
adversarial cases. They are demonstrated on **real programs** and fuzzed inputs, but at lab scale,
by a single author, **without a third-party security audit or production users**. "Patent pending"
refers to the underlying method; the two "products" are working **proofs-of-concept**, not shipped
software.<!-- claim: C-08 --> See [`SECURITY.md`](SECURITY.md) for the threat model and how to
try to break it. Every claim above is tracked with its proof in
[`docs/CLAIMS.md`](docs/CLAIMS.md).<!-- claim: C-45 -->

---

## The `metaspace` CLI

```bash
pip install .                             # installs the `metaspace` command
metaspace init .                          # synthesize a draft constitution from your code
metaspace ratify metaspace.bio            # review + justify + stamp RATIFIED
metaspace gate metaspace.bio              # exit 0 only if RATIFIED (use in CI)
metaspace report path/to/audit.jsonl      # human-readable session safety report
```

One entry point over the engine: `synthesize`, `ratify`, `gate`, `report`, `init`. Cross-platform
by construction, and **verified on Linux**: `run_proofs.py` is green on Debian (kernel 6.1,
Python 3.11) and on Windows — the full suite passes on both, with the Landlock proof skipped on
Windows (it runs only where the OS provides it).<!-- claim: C-04 --> The runs also surfaced and
fixed real bugs (a path-portability bug, a shared-parser bug). macOS is not yet verified (no host
available) — see [`SECURITY.md`](SECURITY.md).<!-- claim: C-43 -->

> Exact per-release counts live in [`CHANGELOG.md`](CHANGELOG.md); the ledger of every claim and
> the proof backing it is [`docs/CLAIMS.md`](docs/CLAIMS.md).

---

## Run the proofs (the evidence is a reproducible run)

```bash
pip install wasmtime
python run_proofs.py        # runs every proof; exit 0 if all pass
```

Or run them individually:

```bash
python products/app_membrane/run_wasm_demo.py         # every capability kind mediated (FS/NET/ENV/SUBPROCESS): 4 ALLOW / 5 DENY
python products/app_membrane/bypass_proof.py          # ungranted gate -> unknown import (blocked)
python products/app_membrane/wasi/run_wasi_demo.py    # real Rust program contained by WASI capabilities
python evidence/run_landlock_demo.py                  # real native program OS-confined by .bio (Linux/Landlock, M3)
python evidence/demos/run_synth_demo.py               # code -> constitution -> enforcement (closed loop)
python evidence/demos/run_ratify_demo.py              # ratification is content-bound (tamper detected)
python evidence/demos/run_gate_demo.py                # production gate: only RATIFIED runs
python evidence/demos/run_knowledge_demo.py           # 2 ALLOW / 5 DENY (hallucination blocked)
python evidence/demos/run_entailment_demo.py          # soft tier flags faithfulness (never blocks)
python products/ai_membrane/test_hook.py              # 17/17
python evidence/run_product_e2e.py                    # Warden loop: real hook -> audit -> report (M1)
python evidence/run_mcp_e2e.py                        # one core, second harness: MCP broker parity (M2)
python evidence/run_team_gate_e2e.py                  # team/CI gate: only a ratified, unbroadened .bio passes (M4)
python evidence/run_falsification.py                  # self-falsification: proofs are real, not slop
```

The last one is a **self-falsification audit**: it mutates a constitution (the decision flips),
sabotages `guard.check()` (a proof then fails), and has WebAssembly itself refuse an ungranted
syscall — so the evidence is measuring real behaviour, not printing `PASS`.

No hosted CI required — the proof is a command anyone can run.

---

## MetaSpace Warden — the agent membrane (Product B)

**Warden** is the shipping product: a deny-by-default membrane for a Claude Code session. You
install it, it enforces a hardened default constitution from *outside* the agent, and it leaves
a session safety report. The whole loop is a reproducible proof
(`python evidence/run_product_e2e.py`), driving the *real* hook over a realistic session:<!-- claim: C-02 --><!-- claim: C-32 -->

```
install the membrane  ->  the agent acts (writes, shell, fetches)
                      ->  the hook enforces the shipped constitution (deny-by-default)
                      ->  it logs a project-local audit (.metaspace/session_audit.jsonl)
                      ->  `metaspace report` summarizes what was blocked, by capability
```

In the proof, of a realistic 11-step session the membrane allows 6 legitimate actions and blocks
5 (a write outside the project, `git push`, `rm -rf /`, a `curl … | bash`, and a beacon to an
unlisted host) — then `metaspace report` shows the block breakdown (FILESYSTEM / SHELL / NETWORK).

**As a Claude Code plugin (one command):**

```
/plugin marketplace add LemonScripter/metaspace-membrane
/plugin install metaspace-membrane@metaspace
```

Restart the session and run `/hooks` to confirm the PreToolUse membrane is active. The plugin
ships a hardened default constitution (project-only writes, host allowlist, dangerous-command
block); `${CLAUDE_PROJECT_DIR}` is used as the project boundary automatically.

**Or as a portable installer** (writes `.claude/settings.json` directly, with an editable
constitution in `.claude/metaspace/`):

```bash
python products/ai_membrane/install.py /path/to/your/project
```

Restart the Claude Code session, then run `/hooks` to confirm it is active. Removing the hook
block reverts either method.

The session constitution is deny-by-default: writes are limited to the project directory,
outbound network to an allowlist, and dangerous shell patterns are blocked. The membrane logs
every decision to `.metaspace/session_audit.jsonl` in the project; after a session, see what it
blocked with:<!-- claim: C-02 -->

```bash
metaspace report          # reads ./.metaspace/session_audit.jsonl by default
```

### Other harnesses: the generic MCP broker

The membrane's decision lives in one harness-independent core (`core/agent_adapter.py`); the
Claude Code hook is just one thin adapter over it. A second adapter — a generic **MCP
capability-broker** (`products/mcp_membrane/server.py`, a minimal JSON-RPC stdio server) —
exposes *mediated effect tools* (`fs_write`, `fs_read`, `net_fetch`) to any MCP-capable agent,
each gated by the same core, deny-by-default. `python evidence/run_mcp_e2e.py` drives both the
hook and the broker over their real interfaces and shows they reach identical verdicts.<!-- claim: C-02 -->

**Honest condition (the hard-vs-advisory line):** an MCP tool the agent may *voluntarily* call
is only advisory — back to self-discipline, which does not contain a misaligned agent. The
broker is *hard* only when the agent is deployed with its ambient authority removed, so the
broker's tools are its **only** path to the filesystem/network. Under that condition the
guarantee equals the hook's; the broker cannot constrain effects reached through some other
unmediated tool.<!-- claim: C-02 -->

### Team / CI: gate the constitution at merge time

Commit a **ratified** `metaspace.bio` to your repo, and make "the effect boundary here is
human-ratified and hasn't been silently broadened" a build-breaking check — the same
content-bound ratification as the runtime gate, now enforced in CI and pre-commit:

```yaml
# .github/workflows/metaspace-gate.yml  (ships in this repo as a template)
- run: pip install "metaspace-membrane @ git+https://github.com/LemonScripter/metaspace-membrane"
- run: metaspace gate metaspace.bio      # exit 0 only if RATIFIED and unbroadened
```

```yaml
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/LemonScripter/metaspace-membrane
    rev: main
    hooks: [{ id: metaspace-gate }]
```

An unratified constitution, or one widened after ratifying (→ TAMPERED), fails the build.<!-- claim: C-47 -->
`python evidence/run_team_gate_e2e.py` proves the whole flow with the real CLI. (Honest note:
there is no hosted-CI badge — GitHub Actions is disabled on this repo — so the gate logic is
proven locally and cross-OS instead, on Windows and real Linux.)

---

## The `.bio` constitution

One file, three lenses:

```bio
CAPABILITIES {
  FILESYSTEM write "out/**"
  NETWORK    out   "api.allowed.com"
}

KNOWLEDGE {
  ENTITY order FROM "kb/orders.json"
  FIELD  order.status IN pending, shipped, delivered, refunded
  ACTUATE refund PROVENANCE verified_db
  CITATION REQUIRED
  SOURCE verified_db
}
```

- **Capability** — mediates effects on the world (deny-by-default).<!-- claim: C-01 -->
- **Value invariant** — guards safety bounds.
- **Knowledge** — grounded facts only: no invented entities, no ungrounded actuation.<!-- claim: C-48 -->

---

## Synthesize a constitution from code

Point the synthesizer at a file or directory; it detects the code's real effects
(filesystem, network, env, subprocess, hardware, import-path) and drafts a `.bio` — marked
`SYNTHESIZED`, since a human ratifies before it is trusted:

```bash
python synthesize.py path/to/app --out app.constitution.bio
```

`evidence/demos/run_synth_demo.py` runs the loop end-to-end: it synthesizes a constitution
from a sample app, feeds it straight into the membrane, and shows the app can then only do
what it declared — an effect it never had (a subprocess) is denied by default.<!-- claim: C-50 -->
This is a static heuristic; the runtime membrane, not the synthesis, is the
guarantee.<!-- claim: C-51 -->

Ratify a reviewed constitution (SYNTHESIZED 🟡 → RATIFIED 🟢):

```bash
python ratify.py app.constitution.bio --yes
```

Ratification is **content-bound**: the stamp carries a fingerprint of the enforced policy, so
a later edit that widens a scope or adds a capability is detected as TAMPERED 🔴 — you cannot
ratify a policy and then quietly broaden it.<!-- claim: C-46 -->

In production, gate the membrane on ratification — `Guard(..., require_ratified=True)` (or
`core.gate`) runs **only** a RATIFIED constitution; a SYNTHESIZED or TAMPERED one is refused,
fail-closed. A policy is enforceable only after human ratification.

Capabilities the dry-run learned are marked **provisional**: ratification is refused until each
carries a written `JUSTIFY` reason — a per-item, read-gated justification that defeats
rubber-stamping (`--yes` cannot bypass it). The code enforces the justification's *presence*,
not its *truth*, so the human's judgement on the reason still matters.<!-- claim: C-46 -->

---

## Layout

```
core/          shared decision engine (guard, knowledge, analyzer, agent_adapter)
products/      app_membrane (WebAssembly + Landlock) · ai_membrane (hook + installer) · mcp_membrane (broker)
evidence/      runnable proofs + decisions
docs/          ARCHITECTURE.md
```

See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the full technical background, or the
technical whitepaper [`docs/MetaSpace_Membrane_Whitepaper_EN.pdf`](docs/MetaSpace_Membrane_Whitepaper_EN.pdf)
(LaTeX source alongside; every claim is a reproducible run or true by construction).

---

## Honest limits

- Product A's hard guarantee requires a real substrate: the WebAssembly capability model, or an
  OS sandbox (**Landlock**, `products/app_membrane/sandbox_enforcer.py`) that confines a stock
  native program's filesystem writes to its `.bio` from the kernel. A language-level guard is
  bypassable and is not shipped as a product. The Landlock MVP confines *writes* (read/execute
  unrestricted so any binary runs); it is Linux-only and fail-closed if
  unavailable.<!-- claim: C-01 --><!-- claim: C-04 --><!-- claim: C-15 -->
- The code→constitution synthesis is a static heuristic; a **dry-run learning mode**
  (`core/dryrun.py`) observes concrete runtime effects and augments the constitution *before*
  ratification, so it does not false-positive-block legitimate dynamic behaviour.
- The agent membrane affects tool effects, not the model's prose; its shell check is a
  **structural allowlist** (`core/shell_policy.py`) — obfuscation-resistant and
  fail-closed.<!-- claim: C-02 --><!-- claim: C-05 -->
- **The shell allowlist is defence-in-depth, not the boundary.** Shell interpreters are hardened
  (`bash -c CMD` is re-checked recursively, piped stdin refused), but an allowlisted *language*
  runtime is not an allowlist-shaped question: `python -c "…"` and `node -e "…"` execute code no
  entry describes. Measured, not theorised — an agent refused `whoami` read the username through
  `python -c`. A development agent needs those runtimes, so on shell-mediated hosts the guarantee
  rests on the FILESYSTEM write-scope and the NETWORK out-scope, which mediate what such code can
  actually *do*.<!-- claim: C-63 --><!-- claim: C-02 -->
- A constitution's allowlist is parsed by one quote-aware parser, so a comment can never silently
  empty it; an allowlist that is declared but unreadable **denies** rather than degrading to a
  porous denylist.<!-- claim: C-62 -->
- The epistemic tier has two parts, named honestly: a **hard tier** that is a real
  deterministic *membrane* (it contains/blocks)<!-- claim: C-48 -->, and a **soft tier** that is
  *not* a membrane but an **advisory flag** (it qualifies/flags, never blocks).<!-- claim: C-49 -->
  The reproducible threat-model matrix
  (`evidence/demos/run_threat_matrix_demo.py`, rendered in `docs/ARCHITECTURE.md`) shows exactly
  what each layer catches — including where a schema-valid but fabricated statement passes the
  hard layers and is only flagged.

---

© Szőke László-Ferenc — MetaSpace.Bio Engine Project. Patent pending. Licensed under the
**Business Source License 1.1** — see [LICENSE](LICENSE). Source-available: free to use, copy,
modify and redistribute for **any non-competing purpose** (internal use, research, education, and
products that merely depend on it); each version converts to **Apache-2.0** four years after its
release. The only reserved use is offering a competing commercial safety-membrane product/service.
For commercial or competing-use licensing: admin@metaspace.bio.

<sub>Designed and authored by Szőke László-Ferenc, with AI pair-programming assistance (Claude).</sub>

