Known limitations

What mnd8t does not do, stated plainly. Read this before you rely on it — knowing where the boundary sits is part of using the product correctly.

Status: sandbox developer preview

mnd8t is a developer preview. It cannot move real money today, and it is not yet a production service. Live-money execution is disabled in code and the service refuses to start with it enabled; wallet support is a simulated account plus one EVM testnet adapter; and nothing here has been load-tested. Read every section below on that footing.

What a customer can actually do today:

Available now Not available yet
Author, version, publish and revoke mandates Moving real money — live execution is off in code
Run in shadow mode against real traffic and compare decisions Production SLAs, load-tested throughput, capacity guarantees
Run in enforce mode against a simulated wallet or an EVM testnet Any mainnet or bank-rail adapter
Deterministic APPROVE / REJECT / ESCALATE with full reason sets Enterprise SSO, billing, mobile app, self-service org invites
Human approval links and the approvals dashboard Approval emails by default (configure a provider)
Signed, independently verifiable evidence receipts Compliance screening of any kind (KYC/AML/sanctions)
Single-use authorisation artifacts for your own executor mnd8t executing anything on your behalf, ever — by design
Verify whether a mandate's objective was fulfilled, against evidence you supply Evidence mnd8t fetches or checks itself — no carrier, merchant, bank or ERP integrations

The honest use for it right now is evaluation: wire an agent up in shadow mode, see what the policy would have decided against your real traffic, and run the full execution loop end to end on a testnet. Putting real customer money behind it requires the review in SECURITY.md, which has not been done.

What mnd8t deliberately does not do

These are not gaps waiting to be filled. They define the service.

  • mnd8t does not execute. It decides whether a proposed action is authorised and issues a signed authorisation artifact. Submitting the transaction is yours, or your regulated provider's. There is no execution code path in the service.
  • mnd8t does not hold assets or keys. No custody, no key management, no wallet. Your execution credentials never reach it.
  • mnd8t does not accept, route or price orders. It does not select an asset, counterparty, venue, exchange rate or execution time.
  • mnd8t does not perform compliance screening. No KYC, AML, sanctions or fraud checks. authority_status records your assertion about who you authorise paying; external_checks stores results from your own provider exactly as supplied, and verifies none of them.
  • mnd8t does not validate legal authority. A delegator attestation is a recorded assertion. mnd8t evidences that someone claimed the authority; it cannot certify they held it.
  • mnd8t does not convert currencies. You supply the amount already normalised into the mandate's currency, with provenance. The engine evaluates only that figure.
  • Nothing here is a compliance certification. Evidence receipts prove what was decided and by whose authority. Whether that satisfies a given regulation is a question for your own advisers.

What this makes you responsible for

  • The accuracy of your valuations. mnd8t trusts the policy amount you send. It fetches no exchange rates, so if the conversion is wrong — or if something that can influence it wants the limit not to bind — the decision is made against the wrong number. Mitigate it with asset-denominated limits (per_transaction.by_asset, asset_budgets), which are evaluated against the quantity that actually moves and cannot be affected by a valuation. For a budget that aggregates across assets, set require_asserted_valuation on the mandate: the figure must then come from a credential holding valuations:assert, which an agent key does not carry. That relocates the trust rather than creating it — an asserting backend sharing a host with the agent is no safer — and mnd8t still does not check whether the number is right, only that the agent did not choose it.
  • Reporting execution honestly. Confirmations record who reported the outcome and whether it was independently verified. A CUSTOMER_ASSERTED verification means exactly that — nobody checked it.
  • Keeping your counterparty list current. An agent can only pay who you have said it may pay.

Product limits

  • One active mandate per agent. Decisions resolve against the agent's most recently updated mandate. Several concurrent mandates for one agent are not supported.

  • Approved reservations expire after 24 hours. Confirm or cancel promptly; a decision left hanging releases its budget hold and must be re-authorised. The exception is a decision whose authorisation artifact was claimed: its budget is never released on a timer, because the executor may already have moved the money. It becomes UNRECONCILED and keeps counting against the limit until you report the outcome with /confirm or /fail. Nothing reconciles this automatically — mnd8t does not observe the transaction — so an executor that dies mid-flight leaves budget held until somebody says what happened.

  • Budget periods follow the mandate's schedule timezone (UTC when no schedule is set). Changing that timezone mid-period starts a new period.

  • Live-money execution is disabled. The service refuses to start with it enabled — see SECURITY.md for the review required to change that.

  • Wallet support is limited to a simulated account and one EVM testnet adapter. Additional providers connect through the same adapter interface.

  • No enterprise SSO, billing, or mobile application.

  • Organisation membership is managed by an administrator. There is no self-service invitation flow; a user with several organisations acts on one at a time.

  • Approval emails are not sent by default. Approval links appear in the dashboard and in server logs unless an email provider is configured.

  • Outcome evidence is asserted by you, and nothing checks it. mnd8t does not fetch evidence from a carrier, merchant, bank or ERP, does not reconcile it against anything, and cannot tell a true delivery note from an invented one. GET /v1/mandates/{id}/outcome is only ever as good as what was submitted. There are no carrier, merchant or ERP integrations, no escrow, no refunds and no dispute management — an objective that comes back NOT_FULFILLED tells you so and does nothing about it.

  • An outcome needs an objective, and old mandates have none. Verification requires policy.objective on the mandate's published version. Mandates published before it existed return 409; adding one means publishing a new version, because a published version is immutable by design.

  • Outcome evidence deduplicates only on a reference you supply. Two submissions of the same fact without a reference are two facts, and will be counted twice.

  • API keys created before scoping hold every scope. They were backfilled rather than downgraded, because the migration cannot tell an agent's key from an operator's and silently removing authority would break live integrations. GET /v1/api-keys flags them as scopes_backfilled. Rotate any that an agent carries to the AGENT preset — until you do, those keys can still publish a mandate.

Operational limits

  • PostgreSQL 16 or later. The schema uses a conservative baseline, so it will run on older majors for local development, but anything below 16 is unsupported and end-of-life majors must not be used in production.
  • Rate limiting is per instance. Multi-instance deployments should add a shared store or edge rate limiting to enforce a global budget.
  • One active signing key at a time. Rotation publishes a new key id; receipts signed with a retired key remain verifiable only while that key stays in the published key document.
  • Performance is not load-tested. Decision latency is well inside target in normal use, and the metrics endpoints compute on read — expect to add aggregation before high sustained volume.
6 min read · Need something that isn't here? Browse all documentation