> ## Documentation Index
> Fetch the complete documentation index at: https://docs.algovoi.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Operator Control Panel

> The operator console for a self hosted AlgoVoi Payment Rails deployment: merchants, payments, refunds, invoices, API keys, compliance and an audit log.

The control panel is the single operator console for a self-hosted AlgoVoi Payment
Rails deployment. It runs over TLS on port **9443**, separate from the customer
payment rails (443) and the raw operator API (8443). One login fronts every
surface below; there is nothing else to install.

***

## 1. Signing in

1. Browse to `https://<your-host>:9443/`.
2. Enter the **admin token** (`PANEL_TOKEN`, generated by the installer and printed
   once at the end of `enterprise-setup.sh`; it also lives in `/etc/algovoi/rails.env`).
3. On first sign-in you are shown a **QR code**. Scan it with Google Authenticator,
   Authy, 1Password, or any TOTP app, then enter the 6-digit code to enrol.
4. On every later sign-in you enter the token **and** the current 6-digit code.

Session lasts 24h. **Sign out** and **Reset 2FA** (re-enrol a new device) are at the
bottom of the left rail. All actions that change data are CSRF-protected and every
page is served `no-store` so an upgrade never shows you a stale screen.

***

## 2. The operator lifecycle: how the pages connect

The tabs are ordered to follow the life of a merchant, left to right:

```
  SET UP THE PLATFORM            ONBOARD & CONFIGURE A MERCHANT             RUN & OVERSEE
  ─────────────────────          ──────────────────────────────            ─────────────────────
  Services  → Chains       →     Merchants → API keys → Networks → Integrations   →   Compliance → Audit log
  (is it up?)(chain RPCs)        (who) (their keys)  (payout/fees)  (order feeds)      (risk/AML)  (evidence)

  Supporting: Trust mesh · Keystone · Agent Passport · Applications · Entry Points  (governance + trust + what's installed)
```

Read it as a sentence: **confirm the platform is healthy (Services) and the chains
you accept are wired (Chains); onboard/inspect a merchant (Merchants), give them API
keys (API keys), set how they get paid (Networks), and pull their store orders in
(Integrations); then watch risk and sanctions (Compliance) and prove every action
after the fact (Audit log).** Keystone/Trust mesh/Applications/Entry Points describe
what the deployment contains and how it governs trust.

***

## 3. Page reference

### 3.1 Services  *(platform health: start here)*

**Purpose.** Live health of the eight rails services (control-plane, gateway,
substrate-2, federation-validator, zkp-receipt, facilitator, control-panel, caddy)
plus the Keystone bridge registration.

**How to use.** Open the tab; each row shows the service, its port, and a green/red
health dot. If anything is red, that subsystem is down: fix it before onboarding.

**Ties to.** Everything. If control-plane or gateway is red, the Merchants /
Compliance / Audit tabs will show errors because they proxy to it.

**By design (host-side).** Starting, stopping and log-reading of services is done on
the host with `systemctl` and `journalctl`, not from the web panel. Exposing service
restart over the web would be a privileged remote-execution surface, so it is
deliberately kept to the host shell where the operator already has root.

***

### 3.2 Chains  *(which blockchains you accept)*

**Purpose.** One RPC URL per network (Algorand, VOI, Hedera, Stellar, Base, Solana,
Tempo, ARC), and a quick per-merchant payout-address setter.

**How to use.** For each network, paste the RPC URL and click **save**; **test**
does a live reachability check. Configured networks show a green "yes". The lower
card sets a payout wallet for a chosen merchant + network.

**Ties to.** These RPCs are what the gateway uses to verify settlements, so they
must be set before a merchant can take live payments. Per-network **payout, sponsor,
stablecoin and HMAC** are managed in depth on the **Networks** tab.

**Not in this version / notes.** The payout card here is a convenience shortcut; the
Networks tab is the fuller per-network editor. No "test all chains" button.

***

### 3.3 Merchants  *(the merchant cockpit)*

**Purpose.** The list of all merchants (tenants) and, for a selected one, a full
money view: settlement balance, payments/fee ledger, payment links, refunds,
disputes, and statements.

**How to use.** Filter/scan the merchant table; click a row to load its cockpit
below. Cards then show: **Settlement balance** (gross/fees/VAT/refunds/net per
asset), **Payments · fee ledger**, **Payment links** (with a Cancel action on active
links), **Refunds** (set a status), **Disputes** (move open → under\_review →
resolved), and **Statements**.

**Ties to.** A merchant selected here is the subject of the **API keys**,
**Networks**, and **Integrations** tabs. Its risk and sanctions posture appears on
**Compliance**; every action you take is written to **Audit log**.

**Refunds.** A **Payments (refundable ledger)** card lists the merchant's payments;
click **Refund** on a payment to originate a refund (amount in microunits + reason),
which creates it as `pending`. Once you have sent the compensating payment to the
payer, use the refund's status control to mark it `completed` and supply the on-chain
`refund_tx_id` so it is verifiably closed (or `rejected` with a note).

**Invoices.** Each payment on the Payments card has an **Invoice** button that
assigns an invoice number; once assigned it shows as a pill.

**New merchant + agent-to-agent settlement.** A **New merchant** button creates a merchant
inline (name, settlement network, payout address, and its first API key). An
**Agent-to-agent settlement** card allocates that merchant post-quantum agent-to-agent
settlement bound to its own agent DID, with no per-agent fee, and returns the allocation
key plus a one-line offline install. The federation is provisioned automatically at install and
is name-constrained, so you allocate only within your own DID namespace; the member
then settles agent-to-agent with the quickstarts shipped under `examples/mesh_a2a/`.

**Not in this version.** No CSV export of the merchant ledger.

***

### 3.4 API keys  *(credentials)*

**Purpose.** Two sets of keys: **operator admin keys** (cross-tenant, platform-wide)
and **per-merchant API keys** (what a merchant's integration authenticates with).

**How to use.** *Operator admin keys:* Issue (optionally scoped; blank = full),
Rotate, Suspend/Unsuspend, Revoke. A newly issued/rotated secret is shown **once**,
copy it immediately. Issuing runs a deliberate \~15s key-derivation, so the button
shows "issuing…". *Merchant keys:* pick a merchant, then Issue / Rotate /
Deactivate / Revoke; the new key's plaintext is shown once.

**Ties to.** Merchant keys are what an **Integrations** store or a merchant's own
software uses to call the rails. The panel itself authenticates to the control-plane
with a static admin key, so revoking DB admin keys here never locks you out of the
panel.

Admin keys also have **Scopes** (edit the scope list), **Extend** (push out the
expiry by N days), and **Audit** (view that key's own action history).

**Not in this version.** Complete for its purpose.

***

### 3.5 Networks  *(how a merchant gets paid)*

**Purpose.** Per-merchant, per-network settlement configuration: **sponsor wallet**
(fee-pooled zero-fee transactions on Algorand/VOI), **preferred stablecoin** (asset
id + decimals), and **HMAC signing secret** rotation.

**How to use.** Pick a merchant; each of their network configs lists the payout
address and current stablecoin. Per row: **Set stablecoin** (e.g. USDC asset id +
6 decimals), **Set sponsor** (address + 25-word mnemonic, stored encrypted; blank to
disable), **Rotate HMAC** (new secret shown once, old signatures stop validating).

**Ties to.** Consumes the merchant chosen in **Merchants**; the payout address here
is the same one the **Chains** payout shortcut edits. The stablecoin/sponsor choices
determine what actually settles on-chain for that merchant.

You can also **Set payout** inline per network, **Register network** (pick a network,
optional payout address) and **Deregister** a network from this tab.

**Not in this version.** Complete for its purpose.

***

### 3.6 Integrations  *(store order feeds)*

**Purpose.** Connect a merchant's e-commerce store (WooCommerce, Shopify, Magento,
BigCommerce, PrestaShop, OpenCart, etc.) so store orders auto-generate payment links.

**How to use.** Pick a merchant; connected stores list platform, status, the
**webhook URL** to paste into the store, last event time, and a Disconnect button.
To connect: choose a platform, enter the preferred network, and paste the store's
API credentials as JSON (stored encrypted).

**Ties to.** Uses the merchant from **Merchants**; the payment links it generates
show up in that merchant's **Payment links** card. Screening of incoming order URLs
is governed by **Compliance**.

**View store orders** lists the recent orders that came through a connected store.

**Not in this version.** The Slack/Teams/Discord *notification* channels are merchant
self-service, not operator-managed here.

***

### 3.7 Compliance  *(risk, sanctions, AML)*

**Purpose.** The live compliance surface: screening **posture** toggles, sanctions/
threat **feed health**, a per-tenant **risk dashboard**, and screening **hits**, AML
**holds**, compliance **events**, **SAR** filings and **rules**.

**How to use.** Flip **URL/IP threat screening** and **Tor exit hard-block** on/off
(takes effect immediately). **Refresh sanctions feeds now** pulls OFSI/OFAC/EU lists.
The risk table shows each merchant's mode, risk tier, kill-switch state and daily
volume vs cap, with a **Kill / Unkill** button per row: Kill prompts for a reason and
freezes all of that merchant's payments; Unkill unfreezes. The lower panels list
recent hits/holds/events/SARs and active rules.

**Ties to.** Reads the same merchants as **Merchants** (risk rows are those tenants);
screening decisions here gate the payments those merchants can take, and every
compliance action is written to **Audit log**.

**Not in this version.** No SAR-filing or rule-edit actions in the UI; risk rows do
not yet deep-link into the Merchants cockpit.

***

### 3.8 Audit log  *(tamper-evident evidence)*

**Purpose.** The hash-chained record of every privileged action, with an integrity
check. This is your regulator/auditor evidence surface.

**How to use.** Browse newest-first (paginated), filter by **actor**, **action** or a
**from/to date range**, click **Verify chain integrity** to confirm the tamper-evident
chain is unbroken (reports rows checked, or the exact position if broken), and
**Export CSV** to download the filtered log for an auditor.

**Ties to.** Captures the actions taken on every other tab: issuing keys, changing
posture, cancelling links, resolving disputes, kill-switching a merchant. It is the
proof layer under the whole console.

**Not in this version.** Complete for its purpose.

***

### 3.9 Trust mesh  *(substrate-2 governance)*

**Purpose.** Runtime posture of the substrate-2 governance mesh: issuers, policy,
and bridged services.

**How to use.** The top shows a plain-language posture summary (issuer count, policy
bound yes/no, keystone active, bridged services, all-up), with the raw issuer/policy/
service records below. Empty until you bind issuers and a policy (POST to the
substrate-2 API on :8094).

**Ties to.** The governance layer beneath Keystone; most rails deployments run it
idle unless they federate trust across issuers.

**Not in this version.** Binding issuers/policy is done via the substrate-2 API, not
from the panel (advanced federation, rarely needed for payment rails).

***

### 3.10 Keystone  *(trust-step estate + settings)*

**Purpose.** The installed Keystone steps (passport → delegation → revocation →
journey → cancellation → refund, etc.), each editable, plus any known steps not
installed.

**How to use.** Each installed step shows its ref/posture/package and an editable
JSON settings box: edit and **Save settings**, or **Reset to default**. The lower
card lists available (uninstalled) steps with their pip install command.

**Ties to.** Defines the trust primitives the rails enforce on every payment
lifecycle; the governance of these steps is what Trust mesh oversees.

**Not in this version.** Complete for its purpose.

***

### 3.11 Agent Passport  *(federated issuer: issue, verify, revoke)*

**Purpose.** Run the rails' own federated agent-passport issuer from one tab. A
passport is a Falcon-1024 signed credential that authorises an agent to act,
bounded by scopes, a spend limit, a spend window, and an expiry. The issuer key is
self-provisioned on install (secret held in a `0600` key file, never in the
environment) and its identity `did:key:passport-<kid>` is published to the
federation registry, so verifiers across the mesh check a passport against the
issuer's published key.

**How to use.** *Issue a passport*: pick the tenant, enter the agent DID, scopes
(comma-separated), spend limit, window, and expiry, then issue. The panel returns
the signed credential. *Issued passports* lists every passport with its status and
a **Revoke** control (revocation is scoped to the owning tenant and cannot touch
another tenant's passport). *Verify* checks a pasted credential offline and shows
`verified` / `not verified` with the agent DID. *CRL and verify portal* exposes the
per-issuer revocation list by `kid` and a shareable verify-portal link a
counterparty can open.

**Ties to.** The federation validator (3.9 Trust mesh governs the mesh the issuer
publishes into) and the Keystone passport step (3.10). This is the operator surface
for the passport primitive that used to be a separate product; it now ships in the
rails bundle.

**Not in this version.** Complete for its purpose. Revocation fails closed: if the
revocation list cannot be read, verify returns `unverifiable` rather than a false
`verified`.

***

### 3.12 Applications  *(what's installed)*

**Purpose.** Inventory of the AlgoVoi applications present in this deployment
(name, category, version, summary).

**How to use.** Read-only reference: useful for support and version audits.

**Ties to.** A manifest view; confirms which optional apps (e.g. Command Center)
are bundled.

**Not in this version.** Read-only by design.

***

### 3.13 Entry Points  *(diagnostic)*

**Purpose.** The Python entry points registered by the installed packages (console
scripts, keystone steps), grouped by type.

**How to use.** Read-only diagnostic: confirms the keystone steps and services the
runtime discovered.

**Ties to.** Low-level companion to Keystone/Applications for support.

**Not in this version.** Read-only by design.

***

## 4. Validation summary (this build)

Every tab was checked against the live control-plane responses:

| Tab                                      | Loader vs API shape                                             | Result                     |
| ---------------------------------------- | --------------------------------------------------------------- | -------------------------- |
| Services, Chains(RPC)                    | services\[], endpoints\[]                                       | OK                         |
| Merchants + cockpit                      | items\[], balance, ledger, links, refunds, disputes, statements | OK                         |
| API keys                                 | admin items\[], merchant keys                                   | OK                         |
| Networks                                 | network-configs\[]                                              | OK                         |
| Integrations                             | items\[]                                                        | OK                         |
| Compliance                               | `feeds{}`, risk.tenants\[], items\[], rules\[]                  | OK                         |
| Audit log                                | entries\[], verify chain\_intact                                | OK                         |
| Trust mesh, Keystone, Apps, Entry Points | posture, installed\[], apps\[], `groups{}`                      | OK                         |
| **Chains → payout dropdown**             | read `d.tenants`; API returns `d.items`                         | **FIXED** (empty dropdown) |

All 12 tabs attach handlers and are clickable (JS executed via jsdom, 12/12).

***

## 5. Feature completeness

As of panel **0.1.8** every operator surface is built out. Delivered across the last
builds: Compliance **kill/unkill** toggle; Merchant **refund origination** and
verified completion with `refund_tx_id`; **invoice** assignment; per-network
**register / deregister / payout**; admin-key **scope edit / expiry extend / per-key
audit**; Audit **CSV export + date-range filter**; Integration **store-order feed**;
Trust-mesh **plain-language posture**.

The one deliberate exclusion is **service start/stop/restart and log tailing**, which
stays on the host (`systemctl` / `journalctl`): exposing privileged service control
over the web is a remote-execution surface we do not want in the panel. Everything
else an operator needs day to day is in the console.

***

## 6. Zero to running in five minutes (validated path)

Every step below was executed end to end against a fresh install of the shipping
bundle; the "Proven" column is the actual result observed.

| Time         | Action                                                                                                                                                                                             | Where                   | Guide        | Proven result                          |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | ------------ | -------------------------------------- |
| 0:00 to 2:30 | Run `bash enterprise-setup.sh --license @licence.key`. Brings up all 8 services, primes the sanctions feeds, initialises the DB, prints your `PANEL_TOKEN`, `ADMIN_API_KEY` and substrate-2 token. | host shell              | Install (§1) | rc=0, "v1.8: LIVE", feeds 7/7          |
| 2:30 to 3:00 | Sign in: browse `https://host:9443`, enter `PANEL_TOKEN`, scan the QR, enter the 6-digit code.                                                                                                     | :9443                   | §1           | panel loads, 12 tabs                   |
| 3:00 to 3:15 | Confirm health: **Services** tab, all eight green.                                                                                                                                                 | Services                | §3.1         | 8/8 active                             |
| 3:15 to 3:45 | Wire your chains: **Chains** tab, paste an RPC URL for each network you accept, **Save**, **Test**.                                                                                                | Chains                  | §3.2         | save 200, configured=yes               |
| 3:45 to 4:15 | A merchant self-onboards: they hit your customer rails at `:443/signup` with a wallet + network; a tenant is created with its network config and payout address auto-set.                          | :443 (merchant)         | §3.3         | appears in **Merchants**, total +1     |
| 4:15 to 4:30 | Issue their key: **API keys** tab, pick the merchant, **Issue merchant key**, hand the one-time secret to them.                                                                                    | API keys                | §3.4         | key issued, plaintext shown once       |
| 4:30 to 4:45 | As needed: set stablecoin/sponsor (**Networks**) or connect their store (**Integrations**).                                                                                                        | Networks / Integrations | §3.5, §3.6   | 200                                    |
| 4:45 to 5:00 | Confirm oversight is live: **Compliance** shows screening Enforcing + feeds fresh; **Audit log** > Verify chain = intact.                                                                          | Compliance / Audit      | §3.7, §3.8   | posture 2/2, feeds fresh, chain intact |

**Result:** the merchant can transact, and every action above is already written to
the tamper-evident audit chain.

**What "running" needs at minimum:** a healthy platform (Services green), one wired
chain (Chains), and one merchant with a payout and a key. Signup auto-creates the
merchant with its network and payout, so the operator's own five minutes are really
*install, sign in, wire chains, confirm compliance and audit are live*; merchants
then self-serve.

**Validation note.** Two setup blockers were found while validating this exact path,
and both are fixed: (1) saving a chain RPC failed with a 500 because the RPC config
wrote to a read-only `/opt/algovoi` path, now pointed at the writable data dir in the
installer; (2) the Chains payout dropdown was empty because it read the wrong list
key, fixed in the panel. Both ship in the next build; the running review instance is
already patched.

***

## Appendix A. Action reference: every control and what should happen

Each control below was cross-referenced against the actual system behaviour. The
"What should happen" column is the intended, validated outcome; "Then" is the state
you should see or the next step it enables.

### Services

| Control    | Input | What should happen                                             | Then                                                                     |
| ---------- | ----- | -------------------------------------------------------------- | ------------------------------------------------------------------------ |
| (open tab) | none  | Eight services render, each with a port and a green health dot | If any is red, that subsystem is down; fix on the host before onboarding |

### Chains

| Control                      | Input                        | What should happen                                                                                            | Then                                                           |
| ---------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| **Save** (per network)       | an RPC URL                   | The URL is stored; the row's Configured flips to a green "yes"                                                | The gateway can now verify settlements on that chain           |
| **Test** (per network)       | none                         | A live reachability probe runs; you get "OK" with a detail such as `chainId=84532`, or "FAIL" with the reason | Confirms the URL actually reaches a node before you rely on it |
| **Save payout** (lower card) | merchant + network + address | The payout address is stored for that merchant and network                                                    | Same address the Networks tab shows; where settlements pay out |

### Merchants

| Control                                 | Input                                    | What should happen                                                                                                      | Then                                                                                     |
| --------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| **Filter** box                          | text                                     | The merchant table filters live by name or short id                                                                     | none                                                                                     |
| **Click a row**                         | none                                     | The cockpit loads the merchant's cards (balance, refundable payments, fee ledger, links, refunds, disputes, statements) | That merchant becomes the subject of API keys, Networks and Integrations                 |
| Payment links **Cancel**                | none (active link only)                  | The link is cancelled; the cockpit reloads                                                                              | The link can no longer be paid                                                           |
| Payments **Refund**                     | amount (microunits) + reason             | A refund is created against that payment as `pending`                                                                   | It appears in the Refunds card awaiting completion                                       |
| Payments **Invoice**                    | none                                     | An invoice number is assigned to that payment                                                                           | Shows as an `inv` pill on the row                                                        |
| Refunds **status** = completed          | on-chain `refund_tx_id` (52 to 64 chars) | The refund is marked `completed` and bound to the tx                                                                    | The facilitator can verify receiver, amount and network; the refund is verifiably closed |
| Refunds **status** = pending / rejected | rejected takes an optional note          | The refund status is updated                                                                                            | `rejected` records the note                                                              |
| Disputes **status** select              | open / under\_review / resolved          | The dispute moves along its lifecycle                                                                                   | Resolution is recorded and audited                                                       |

> **Refund flow (complete in 0.1.7).** Originate from the Payments card **Refund**
> button (creates `pending`), send the compensating payment to the payer off the
> panel, then set the refund to `completed` and supply the `refund_tx_id` so it is
> verified end to end. `rejected` closes it with a note. This closes the earlier
> caveat where the panel could set status but not complete a verified refund.

### API keys

| Control                                           | Input                                 | What should happen                                                            | Then                                                                      |
| ------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| **Issue admin key**                               | label, optional scopes (blank = full) | \~15s key derivation runs ("issuing…"), then the new secret is shown **once** | Copy it immediately; it is never shown again                              |
| **Rotate / Suspend / Unsuspend / Revoke** (admin) | none                                  | The key state changes; a rotated secret is shown once                         | Revoking a DB admin key never locks you out (the panel uses a static key) |
| **Scopes** (admin)                                | comma-separated scopes (blank = full) | The key's scope list is replaced                                              | Narrows or widens what that key can do                                    |
| **Extend** (admin)                                | number of days                        | The key's expiry is pushed out                                                | Keeps a key valid without rotating it                                     |
| **Audit** (admin)                                 | none                                  | That key's own action history loads below the table                           | Trace what a specific key has done                                        |
| Pick a **merchant**                               | none                                  | That merchant's API keys load                                                 | none                                                                      |
| **Issue merchant key**                            | label                                 | The new key's plaintext is shown **once**                                     | Hand it to the merchant's integration                                     |
| **Rotate / Deactivate / Revoke** (merchant)       | none                                  | The key state changes                                                         | The merchant's software must use the new key                              |

### Networks

| Control              | Input                                                         | What should happen                                         | Then                                                                 |
| -------------------- | ------------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------- |
| Pick a **merchant**  | none                                                          | Their per-network configs list (payout, stablecoin)        | none                                                                 |
| **Set stablecoin**   | asset id ("0" = native, e.g. 31566704 = USDC) + decimals      | The preferred settlement asset is updated for that network | Payments settle in that asset                                        |
| **Set sponsor**      | address + 25-word mnemonic (both to enable; blank to disable) | The sponsor wallet is stored encrypted                     | Enables fee-pooled zero-fee transactions on Algorand/VOI             |
| **Rotate HMAC**      | none                                                          | A new signing secret is generated and shown **once**       | Old signatures stop validating; update the merchant's webhook secret |
| **Set payout**       | a chain address                                               | The network's payout address is updated                    | Where that network settles                                           |
| **Register network** | pick a network + optional payout                              | A new network config is added for the merchant             | The merchant can now accept that chain                               |
| **Deregister**       | none                                                          | The network config is removed                              | The merchant stops accepting that chain                              |

### Integrations

| Control               | Input                                           | What should happen                                                           | Then                                                                 |
| --------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| Pick a **merchant**   | none                                            | Their connected stores list with a webhook URL each                          | none                                                                 |
| **Connect store**     | platform + preferred network + credentials JSON | The store is connected; credentials stored encrypted; a webhook URL is shown | Paste that URL into the store; orders then auto-create payment links |
| **Disconnect**        | none                                            | The integration is removed                                                   | Orders stop flowing                                                  |
| **View store orders** | none                                            | The recent orders from that store load below                                 | See what the store has sent                                          |

### Compliance

| Control                                    | Input       | What should happen                                                         | Then                                                     |
| ------------------------------------------ | ----------- | -------------------------------------------------------------------------- | -------------------------------------------------------- |
| **URL/IP threat screening** toggle         | on/off      | Screening of payments and webhook URLs is enforced or disabled immediately | Reflected in the row label (Enforcing / Off)             |
| **Tor exit hard-block** toggle             | on/off      | Tor-exit payments are rejected (block) or flagged (escalate)               | Reflected in the row label                               |
| **Refresh sanctions feeds now**            | none        | OFSI/OFAC/EU lists download and upsert                                     | The feeds table shows fresh timestamps and sizes         |
| Risk row **Kill**                          | a reason    | The merchant's kill switch activates; all their payments freeze            | The risk row shows kill switch ON; the action is audited |
| Risk row **Unkill**                        | none        | The kill switch deactivates                                                | The merchant can transact again                          |
| Risk / hits / holds / events / SAR / rules | none (read) | Each panel lists the latest records with a count                           | Risk rows are the same merchants as the Merchants tab    |

### Audit log

| Control                    | Input           | What should happen                                                                                 | Then                                          |
| -------------------------- | --------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| **Filter** actor/action    | text            | The log filters to matching entries                                                                | none                                          |
| **Prev / Next**            | none            | Page through the log (50 per page)                                                                 | none                                          |
| **From / to date**         | dates           | The log filters to that date range (combines with actor/action)                                    | Narrow to an incident window                  |
| **Verify chain integrity** | none            | The hash chain is recomputed; you get "chain intact (N rows checked)" or the exact broken position | Your tamper-evidence proof for auditors       |
| **Export CSV**             | current filters | The filtered log downloads as a CSV file                                                           | Hand to an auditor or load into a spreadsheet |

### Keystone

| Control                                | Input      | What should happen                       | Then                                                    |
| -------------------------------------- | ---------- | ---------------------------------------- | ------------------------------------------------------- |
| Edit a step's JSON + **Save settings** | valid JSON | The step's active settings are persisted | The rails enforce the new policy on that lifecycle step |
| **Reset to default**                   | none       | The step returns to its shipped defaults | none                                                    |

### Trust mesh / Applications / Entry Points

Read-only. Trust mesh shows substrate-2 posture (empty until issuers and a policy are
bound on :8094); Applications lists installed apps; Entry Points lists registered
console scripts and keystone steps. No actions to perform.

***

## Appendix B. End-to-end interaction chains (what should happen across pages)

**Chain 1: platform to first live payment.**
Services all green (§3.1) then Chains: Save + Test the RPC for your network (§3.2)
then a merchant self-signs-up on :443 and appears in Merchants with its network and
payout already set (§3.3) then API keys: issue their merchant key (§3.4) then the
merchant transacts and the payment appears in their Merchants ledger, with the
settlement verified against the RPC you wired.

**Chain 2: store to auto-invoicing.**
Integrations: Connect store with credentials (§3.6) then paste the shown webhook URL
into the store then a store order fires the webhook then a payment link auto-appears
in that merchant's Payment links card (§3.3) then the buyer pays and it settles.

**Chain 3: oversight and evidence.**
Compliance: screening Enforcing + feeds fresh (§3.7) screens every payment then any
hit or hold surfaces in Compliance then if a merchant looks bad you **Kill** them from
the risk row to freeze all their payments (Unkill to release) then every operator
action (key issued, link cancelled, dispute resolved, kill switched) writes to Audit
log then Verify chain integrity proves the record is unbroken for an auditor.

**Chain 4: refund a payment.**
Merchants: open the merchant, click **Refund** on the payment (§3.3) which creates a
`pending` refund then send the compensating payment to the payer off the panel then
set the refund to `completed` with the on-chain `refund_tx_id` then the facilitator
verifies receiver, amount and network and the refund is closed and audited.

**Chain 5: key rotation.**
API keys: Rotate a merchant key (§3.4) then the new secret is shown once then update
the merchant's integration then the old key stops working then the rotation is on the
Audit log.
