View Markdown · Documentation index (llms.txt)
Acceptance Demo — FDC3 Post-Trade Cash-Leg Payment Transfer (TraderX ↔ BankerX)
State 016 · TraderX PR #470 · written 2026-09-30 (maintainer-review follow-up: the agreed acceptance-demo script and the clean-checkout proof).
Per spec.md §0 (terminology, fixed after the maintainer review): the example demonstrates a currency cash-leg payment transfer — the cash leg of an already-executed trade, keyed by a RFC 4122 UUIDv4 UETR. It is not securities delivery-versus-payment (no security leg is delivered) and not payment-versus-payment (no simultaneous second-currency leg).
The one script (what a reviewer follows)
- From a clean checkout of the repository (no other setup):
Openpython3 -m http.server 8090 --directory specs/016-post-trade-settlement-bankerx
http://localhost:8090/generation/traderx-blotter-web/index.html?launcher=1&directory=http%3A%2F%2Flocalhost%3A8090%2Facceptance%2Fappd.json. - Click
LAUNCH BANKERX→ the FDC3 desktop agent opens the clearing receiver in a second window through the App Directory record and the FINOS Web Connection Protocol handshake completes (receiver console:WCP agent connected via getAgent(); blotter log: instance id). - Create/locate a trade row, click
SETTLE (BANKERX)→ the standard intentfdc3.raiseIntent("StartPayment", fdc3.payment)is raised with a machine-built context (amount, pair, rate, debtor/creditor, UETR). - The receiver validates the context and returns its verdict; the
synaptic.settlementStatusoutcome (UETR-keyed) reaches the blotter by the same workspace plumbing and the row flipsSETTLING… → SETTLED; the receipt modal opens. - Re-click
SETTLE (BANKERX)on the same row → suppressed with an explanatory message (FR-01607). - Send an invalid payment (malformed UETR / non-canonical pair, in-page
receiver path documented in
acceptance/README.md) → the receiver returnsRjctwith the exact validation reason; nothing is settled.
Full details, gate list, and the real-vs-simulated boundary:
acceptance/README.md.
Automated proof: the same flow was driven headless twice from a clean
checkout on identical committed bytes with the committed E2E harness
(acceptance/harness/) — all 10 gates
(realFdc3, deskOpen, wcpConnected, tradeBooked, intentReceived,
acsc, receiptModal, dupSuppressed, receiverDupReplay, rejectHonest)
passed in both runs, exit 0.
Clean-checkout proof (the second agreed deliverable)
Performed 2026-09-30 from a pristine clone (HEAD = the state's tip commit):
git clone <traderX>→pipeline/generate-state.sh 014-fdc3-intent-interoperability→ exit 0; the full generated runtime tree renders (generated/code/target-generated/fdc3-intent-interoperability/with the Sail sidecar tree, bootstrap scripts, app directory and runtime caches).scripts/start-state-014-fdc3-intent-interoperability-generated.sh --provider kind --with-sail --dry-run→ the documented--dry-runcontract completes end to end (generation artifacts validated, 012 baseline validated, Sail compose action printed) without a cluster.scripts/start-state-016-post-trade-settlement-bankerx-generated.sh --provider kind --dry-run→ the same contract for this state (pack artifacts validated, Sail receiver overlay merge action printed, 012 baseline delegated).- The offline acceptance flow itself (the
python3 -m http.serverscript above) runs with zero additional installs from the clean checkout.
Known environment limit (disclosed, not a gap in the assets): a full cluster
boot needs kind (or minikube) which was not part of the proof host — every
script honours the documented --dry-run contract, and the offline acceptance
flow requires no cluster at all.
Integration with the existing TraderX application
Per the maintainer review, the standalone web blotter is supporting
material; the integration with the existing TraderX application is the
demonstration that matters. The equivalent flow in the actual TraderX
Angular application (upstream sample app) is delivered through the upstream
service layer: fdc3-interop.service.ts resolves the desktop agent
(getAgent/WCP), gates StartPayment availability on directory resolution,
and raises StartPayment with the fdc3.payment context from the blotter
row — the same intent, context and correlation semantics this offline pack
demonstrates. The estate deployment of the source-built Angular application
is the reference for that tier (see the estate conformance/E2E receipts).
Receiver variants (provider-neutral tiers, FR-01608)
| Tier | Receiver | Where | Role |
|---|---|---|---|
| 2a (default) | Mock receiver | generation/mock-receiver/ (this pack) | Offline acceptance + tests; proves the FDC3 loop, not the rail |
| 2b (opt-in) | BankerX terminal | App Directory URL swap → synaptic-fx-terminal | Settlement rail reference adapter; live estate receipts are its evidence |
No TraderX code change is needed to switch receivers — it is an App Directory
record swap (acceptance/appd.json vs the terminal's appd endpoint).