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/Withdrawalsapproval directly into automaticSigningRequestcreation — this tutorial's own code (release-order.ts,withdraw.ts) is what plays that role today, callingexecuteSettlement/requestand 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.