What we cannot prove
Read this before you buy.
An accountability product whose marketing outruns its own evidence is the worst outcome
available to it. This page is the standing list of the things Ujex does not prove, written
in the same weight as the things it does. Every limit below is drawn from the repository's own
security record — THREAT_MODEL.md §5 "Residual risk", the
OWASP agentic mapping's "do not claim" list, and the launch-claims gate that refuses to publish
certain sentences — not from a marketing review.
Nothing here is a roadmap promise. Where a limit has a stated route out of it, the route is named. Where it does not, it does not.
The chain is tamper-evident, not tamper-proof against us
Evidence is hash-chained and append-only. Every block links to the one before it, so an edit anywhere breaks verification everywhere after it. Roots are published hourly at a public endpoint so a third party can pin them.
We do not yet retain those roots outside our own infrastructure. The anchors and the chain they anchor live in the same Firebase project, so the administrative service account can rewrite both. Until an off-operator retainer holds a root, treat the chain as tamper-evident to anyone reading it, not as tamper-proof against us.
We therefore do not say immutable. We say hash-chained, append-only, and tamper-evident, and the difference is the whole point of this section.
There is also a deliberate erasure path. An administrator can redact a payload for a right-to-erasure request; the chain still verifies afterwards, because links are computed over the payload hash rather than the payload. That is the correct design and it is literally an administrator changing what a sealed record contains. You should know it exists.
Sealing is not fail-closed
Every action is recorded as it happens. If sealing is unavailable, work queues rather than disappearing — we will tell you what queued and when it sealed.
What we do not claim is the stronger version: that nothing can execute unless it has already been sealed. On the outbound path the record is written alongside the send, not strictly before it, so an infrastructure fault during sealing can be followed by the work still leaving. Inverting that ordering on every mutating path is a control-plane change, and until it lands, "no action executes without a seal" is not a sentence we are entitled to.
Verification runs in your browser — but we are the key authority
Verification runs in your browser. Pack bytes never leave the page — the page cannot send them. The signing key travels inside the pack, and we publish our key and our chain roots so you can pin them yourself.
We do not say we are not in the loop and cannot be. The key that signs a pack's checkpoint and its attestation is ours, and the pack's own instructions send you to a Ujex endpoint to cross-check it. A determined operator with that key can re-sign a rewritten pack and it will verify. Independent trust requires you to pin the key and the roots from somewhere other than us, and today that somewhere does not exist.
We do not collect verification results
Every pack carries its own proof — we do not collect verification results.
That is a design choice, not an omission, and it forecloses a number some products publish. If verification is genuinely local, there is no instrument anywhere that could tell us a third party's verification failed. We will therefore never publish a count of failed external verifications, in either direction. A zero we could not detect a one against would be decoration.
What a pack covers
A pack covers everything the agent did through Ujex — mail, tools, approvals and memory changes. It cannot attest to actions the agent took outside Ujex.
Evidence Pack v1.2 prints a pack-level custody declaration and commits it through the pack's content identity. That prevents unnoticed editing of a fixed export, but the hashes are unkeyed: a party can change the declaration and recompute a new, internally consistent pack. The local verifier therefore displays the declaration while explicitly declining to authenticate who emitted it. Treat signer-bound custody provenance as a separate, future trust layer rather than a property of this format.
Credentials, and what a signature is bound to
Evidence Pack block integrity is unkeyed SHA-256. The exported field is named
integrityDigest, and a successful local check proves only that the pack's hashes are
internally consistent. It does not prove that the named agent, human, runtime or organisation
created the pack. Agent Passport and AAT manifest signatures are separate artefacts with
separate trust assumptions; their keys must never be presented as block signers.
Every agent gets its own credential, scoped and revocable. Revoking it takes effect on the agent's next request, not when its session happens to expire — the security rules re-check the credential on every read, so revocation does not wait for a token to lapse. That is an unusual property and we are happy to be held to it.
What we do not claim: agent credentials are bearer tokens, not keypairs. They are not generated in an enclave, and a credential copied into a second process works there. Human countersignature is authenticated by a session, not by a hardware key, so a signature is bound to an account rather than to a device.
Device credentials also do not expire on their own. Delegations carry an expiry and are enforced against it; a plain device credential is valid until it is revoked or rotated. If you need an expiry, set one by rotating.
Memory
The agent's memory has a change history. Diff it, review it, roll it back. Writes made during a session marked untrusted are quarantined from search by default, so a poisoned session cannot launder a fact into the trusted set.
Memory is not versioned in git — it is stored as markdown documents with a document-level diff history, and there is no repository to clone. Diffs are per document, not per line, so we cannot show you which block produced a given line.
Export, and leaving
Export is free at every tier, in an open format, with the verification steps printed inside the file. We do not charge to leave. Billing state never suspends access to evidence.
We do not claim the export is complete in the sense of "everything we hold about you". It covers the audit-chain window; reconciling it against the full data model is unfinished work. We do not publish a retention period as indefinite while a retention policy and an erasure path both exist. And post-cancellation retrieval is not yet demonstrated end to end, so treat the export as something to take before you cancel, not after.
Spend, and budgets
Usage is counted from the chain. Provider costs are estimated, not invoice-reconciled.
The cost table is a static estimate per action. Guardrails act on that estimate, which means they are useful for catching runaway behaviour and are not a contractual spend cap. No figure produced by the budget surface reconciles to a provider invoice, and we do not describe it as billing enforcement.
Prompt injection
Prompt-injection scoring is a risk signal and a policy gate, not a guarantee. The classifier is heuristic and model-scored, and it is not trained on your traffic. A high score poisons the session so the exfiltration gate fires and approvals surface the poisoned provenance to the human deciding — that is defence in depth, not prevention.
We do not claim to block all prompt injection. Nobody can.
Explicitly not claimed
The repository maintains its own refusal list, and it is the most honest brand document we have. Verbatim, we do not claim:
- SOC 2
- blockchain or external-ledger immutability
- invoice-exact billing caps
- perfect prompt-injection prevention
Mapped-evidence language is what we use instead: an ISO 42001 mapping, an ISO 42005 evidence pack, an EU AI Act Article 12-oriented record. A mapping is not a certification and we do not let the two share a sentence.
Not yet done
- No external penetration test. The scope is written and the handoff packet exists; the test has not been run.
- Sandboxed tool dispatch is not on by default, and the tool publisher-key allowlist is documented rather than enforced.
- App Check is enforced on human and admin browser calls only. Agent-token and webhook surfaces are unenforced by design.
- OAuth 2.1 token exchange is roadmap. Delegated tokens already carry on-behalf-of actor and subject claims, which is not the same thing.
How to hold us to this
If you find a sentence anywhere on our surfaces that contradicts this page, this page is the one that is correct, and the sentence is a defect — tell us and we will cut it. A claim with no exhibit does not ship, and a claim that outlives its exhibit is cut rather than softened.
2026-08-05 · reconciled against docs/security/THREAT_MODEL.md §5 and the launch-claims gate.