Limen Admin Panel
Motus Limen · gateway policy console
Overview
Active policy, reachable destinations and the simulated session's live traffic.
Live traffic
Every simulated request runs through the same rule engine as the console, consistent with the current models and policy. The content of a request is never shown here.
No request yet in this column.
No request yet in this column.
No request yet in this column.
No request yet in this column.
Configure.
The administrator declares two logical models and creates the engineering and finance teams, then one virtual key for each. Limen never reads the prompt at this step or any other: the application declares the data class itself, in a header, a key or metadata.
model_name: local-default → ollama/qwen2.5:0.5b model_name: external-default → ollama/qwen2.5:0.5b team: engineering · team: finance · one virtual key each Admin UI: http://127.0.0.1:4000/ui
Policy.
The administrator reads the policy table aloud. Engineering stays on the local model for every declared data class; finance may reach the external model only with public data, and personal data is held for review. A request that matches no row — finance asking in plain text, with no class declared as public or personal — is denied by default: the gateway fails closed rather than guessing.
| Group | Data class | Model | Route |
|---|---|---|---|
| engineering | text · documents · public · personal | local-default | allow |
| finance | public | external-default | allow |
| finance | personal | — (held) | review |
policy table fingerprint sha256:75bfd0e51dbfcd4606509c021a3c5e8b7ccc323b24bfe154be111ce52c659bca
Users chat.
The trial first warms the local model once through the gateway with the engineering key and discards the reply — narrated, not one of the declared prompts. It then sends three declared strings, each with a 180-second limit: one from engineering, two from finance. The outcomes below are the real capture, not a script's guess at them.
allowed · HTTP 200 · engineering / text reply (first 200 chars): "Oh, I see you've set the variable `violet-orbit-allowed` to be allowed. That's interesting! How can I assist you with it? If you have any questions or need help with anything related to this setting, " held for review · HTTP 451 · finance / personal {"error":{"message":"requires human review","code":"451", "provider_specific_fields":{"clause":"finance_personal_review"}}} denied · HTTP 403 · finance / text {"error":{"message":"denied","code":"403", "provider_specific_fields":{"clause":"no_matching_policy"}}}
Watch.
The administrator inspects the metadata-only spend log, the two local webhook alerts the trial raised, and the review queue. Everything carries a tenant, a clause and a prompt hash. Nothing carries the prompt itself — including the review listing that a human would open to act on the held request.
alert-01.json — route: review, clause: finance_personal_review policy_table_fingerprint: sha256:75bfd0e51dbfcd4606509c021a3c5e8b7ccc323b24bfe154be111ce52c659bca prompt_hash: fb3709da10af60804e88cc1807faf044d3d19460156b04bee0ccdbeef7b889f3 alert-02.json — route: deny, clause: no_matching_policy run_ref: sha256:aec03485ef4560554e86662bc6f18ec8b729bb032aa537901b04c28861957142 prompt_hash: 31844601553c657d7bc71587baed02d40d0bb8e87b53eec664fc1c614b396506
Prove.
The administrator submits the trial's own checkpoints, copies the refreshed evidence, and validates it offline — with the published validator, not one of ours. For the anchors, verification runs through OpenTimestamps' own ots tool against three calendars nobody here operates. Then, once, a policy clause in a copied trace is changed on purpose, so the reader sees the check refuse a forged record before trusting it to accept a genuine one.
trial/gateway-trial checkpoint-000000 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000001 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000002 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000003 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000004 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000005 anchored bitcoin-block:965509 2026-09-04T18:48:44Z
trial/gateway-trial checkpoint-000006 pending - -
… 17 more checkpoints pending, as of this capture
Calendar https://finney.calendar.eternitywall.com: Pending confirmation in Bitcoin blockchain
Calendar https://bob.btc.calendar.opentimestamps.org: Pending confirmation in Bitcoin blockchain
Calendar https://alice.btc.calendar.opentimestamps.org: Pending confirmation in Bitcoin blockchain
T11 $.records[11].integrity.payload_hash: payload_hash does not match the record:
declared sha256:d53c7042f99be4ff93b647f97d25329b2fd0ff2dc90e4bf00193cf24bb7f1009
recomputed sha256:7a80264ac48d3b627e381efb29da48d4e3fb2d79ddc9a770ff2f6a460423916bWhat you did not see.
The prompt itself is never stored — only its hash, in every decision, effect, commitment and alert above. max_tokens bounds every call so a runaway generation cannot run up cost or time. The client's own copy of the allowed reply, under demo/out/requests/, may echo the declared prompt back — that is the application's log, not Limen's evidence, and the two are kept separate on purpose.
Verify it yourself.
Five commands, against the same repository, reproduce every claim on this page.
bash demo/run.sh --dry-run
pytest demo/tests -q
LIMEN_EVIDENCE_DIR=demo/out/evidence python -m limen.evidence.review list --json
find demo/out/evidence/decisions -name '*.jsonl' -exec motus-validate jsonl {} \;
grep -R -n -E 'violet-orbit-allowed|copper-lantern-review|marble-kite-denied' demo/out/evidence || true