Skip to main content

Known limitations

Real, confirmed-in-code (or confirmed live) findings — several of which no isolated unit test had caught before this Business Case existed. The full technical version, with file:line citations, lives in examples/marketplace-mercatto/GAPS.md; this page is the reader-friendly index, in the order chapters reference them.

F.1 — Settlement does not gate on Workflow state

executeSettlement() can be called with or without a delivery event ever being ingested — Ishtaran validates financial invariants, never facts about the physical world. This is a deliberate design, not a bug: confirming delivery before settling is the integrator's job. See Confirming delivery.

F.2 — No clawback after a full Settlement

Once a Settlement has fully distributed the Distributable Amount, there's no platform mechanism to reverse what was already credited. Any correction after that point is a new, separate movement — never an edit to the historical Settlement.

F.3 — No public route to read the Pricing Policy in advance

An integrator only learns the real Fee percentage from the result of a Settlement itself — never before calling it. See Settlement and Split.

F.4 — No official Sandbox mechanism to skip Withdrawal cooldowns

Neither the 24h destination-activation cooldown nor the 168h destination-change cooldown can be fast-forwarded. This Business Case never bypasses them — see Withdrawal.

F.9 — Some calls need a Member session, not an API Key

accounts.authorizeApplication, every workflows.* mutation, and events.ingest all reject an Application API Key today. See Architecture.

F.10 — No self-service financial API for AccountHolders

A seller's own login can only manage their own identity — not check their balance or request a withdrawal. Every financial call on their behalf uses the marketplace's own credentials. See Seller balance.

F.15 — Rapid partial Settlements can hit a transient concurrency conflict

Standard, expected optimistic-concurrency behavior (409 CONCURRENT_MODIFICATION) when Settlement calls land close together on the same order — the correct response is a bounded retry, same as any optimistic-concurrency API. See Partial Settlement.

F.16 — Settlement's real execution path is SelfCustody, not "computes Fee and posts Ledger"

Earlier drafts of this tutorial (and its own architecture diagram) described executeSettlement as directly posting Ledger Entries. That was accurate for the platform's ManagedCustody model, but SelfCustody — the only mode this Sandbox actually runs today (DEC-037, docs/architecture/CUSTODY-EXECUTION-MODES.md) — is different: executeSettlement builds a real SigningRequest and returns with the Settlement Executing; nothing is final, and no Ledger Entry exists yet, until every execution leg is signed, broadcast, and confirmed. See Settlement and Split for the full mechanics, and self-custody-settlement.ts for the sign/confirm/wait code every chapter from there on reuses.

F.17 — Settlement now requires a registered NetworkCostPayerAccount

Broadcasting a Settlement's execution legs costs real network resources, charged separately from the Platform Fee — Mercatto has to tell Ishtaran, once per AssetNetwork, which of its own Accounts pays for that. Without it, executeSettlement fails before building any SigningRequest. See Settlement and Split and register-network-cost-payer-account.ts.

F.18 — Open product question: how does a brand-new NetworkCostPayerAccount get its first balance?

Registering a NetworkCostPayerAccount (F.17) isn't enough by itself — the platform also checks that account's real Available balance before letting it pay for anything, and there is no route today to fund an Account independent of a Transaction. For a brand-new marketplace's very first Settlement, this is a genuine chicken-and-egg problem the platform doesn't yet solve: nothing has settled yet to fund the account, but funding requires a settlement. This tutorial's own local verification worked around it with a dev-only tool, never something usable in Sandbox or Production — this is flagged as an open decision for the platform owner, not solved here. See GAPS.md §F.18 for the full detail.

The rest

GAPS.md also documents platform-execution findings outside this tutorial's own scope, from the same audit pass:

  • Nothing yet wires Settlement/Withdrawals approval directly into automatic SigningRequest creation — this tutorial's own code (release-order.ts, withdraw.ts) is what plays that role today, calling executeSettlement/request and then driving the signing protocol explicitly. Real work either way, in Sandbox as much as Production — not a Production-only gap.
  • Real blockchain execution — a signed transaction actually landing on a real network — is Production-only and not available yet; Sandbox's broadcast/confirmation is simulated end to end, deliberately, not a shortcut this tutorial hides.

Two earlier findings from this list — the Network Fee model not distinguishing the transferred asset from the resource that pays for network execution, and no pre-broadcast viability check existing — were resolved by the platform's Network Execution Engine (see Settlement and Split and Withdrawal); GAPS.md §F.13/F.14 keep the original findings on record alongside what actually changed.

None of these are fixed by inventing a workaround — every one is either fixed at the root (see the platform's own Ledger/Settlement audit trail) or documented precisely enough that a future session picks up exactly where this one left off.