Build contract — workflow management
1 · This console observes and retries; it never moves money. Three workflows on this list
(
escrow-wire-release,
eat-transfer-out,
subescrow-disbursement-handoff)
touch the release of client funds, and they carry the
APPROVAL marker for that reason. Nothing on this
surface — not
Force Retry, not a DLQ replay — may cause a disbursement to execute. A retry re-enters
the workflow at its approval gate; the four-eyes check (approver ≠ proposer) runs in Vectr and is never
satisfiable from an operator console. If an operator could replay a fund movement to completion from here, the
qualified-escrow separation the platform depends on would be gone. The console draws that rule:
Force Retry renders disabled on all three, and ONE allowlist —
APPROVAL_WORKFLOWS —
drives the badge, the retry gate and the issue 1350 founder-gate, so a workflow joining the list is gated
everywhere at once (the live console's gate matches only
wire-release and
eat-transfer-out today; the built
subescrow-disbursement-handoff row must join that
set). The hand-off itself is idempotent: every transmission carries an idempotency key
(
disbursement_instruction_id), so a permitted upstream retry re-presents the same instruction to
the rails and can never produce a duplicate wire.
1a · The sub-escrow family is one contract, two adapters. The eight
subescrow-* workflows (issue 2146 dual-mode decision, issue 2706 catalog) are mode-independent:
each tenant binds either the
sub-escrow platform (incumbent) adapter — sub-accounts managed on the
bank's existing platform, the bank keeps master + wire execution — or the
built-in ledger adapter
against the bank core's real-time API. The adapter chips on each row are the per-tenant split, and the drawer
lists the binding per tenant; the election itself lives in that tenant's QI Hub escrow settings. Balance
snapshots written by
subescrow-balance-sync are the source for the exchanger-facing balance
display; any snapshot that disagrees with the ledger files an exception into the QI Ops work queue
(
subescrow-exception-router) rather than surfacing a wrong number. The bank core remains system
of record for the master deposit; the ledger is the authoritative record of allocation across sub-accounts.
subescrow-kyc-aml-export is the family's only NPI-egress workflow and carries the issue 2816
contract: the KYC provider is a pluggable per-tenant seam, never a hardcoded vendor (Persona is today's bound
implementation; a bank-mandated vendor binds in its place per partnership); the export is exchanger-level —
identity payload, inquiry references, OFAC screening results and W-9-adjacent data, per sub-account — because
the bank validates independently and one QI manages many entities; and NPI in transit is handled under
GLBA / Reg P, fields minimized, an audit entry per export.
2 · Status colour is a scale and is never the only signal.
running is
--admin (in flight, not a verdict),
ok/warning/failed are the
good/warn/bad triad, and
dead-letter is the SAME red as
failed but filled rather than
tinted — worse than one failure, told apart by weight, icon and label as well as hue. Every pill carries its
word; no state is legible by colour alone.
3 · The rail is chrome, not a surface. It is painted from
--console-rail-* and
stays dark in both themes, so its foregrounds are measured against the rail fill. The rail's own red and teal
(
--console-rail-bad,
--console-rail-teal) exist because the content-scale status hues
are measured against
--surface and are not readable on it.
4 · Category hue is wayfinding, never health. The five dots say WHICH family a workflow belongs
to (automation / AI / infra / security / sub-escrow). A category dot must never change because a run failed.
The adapter chips are wayfinding too: built-in carries the family blue, the incumbent stays neutral, and
neither ever encodes a run verdict.
5 · "Live data" must be true or must say otherwise. The pill claims a live connection to the
run store; when that connection degrades, the banner states the staleness and the timestamp rather than letting
stale counts read as current. A KPI with no fresh source behind it is removed, not dimmed.
6 · Deadline workflows are the ones that cannot silently fail.
forty-five-day-id-watcher and
one-eighty-day-deadline-guard are the statutory clocks;
a failure on either is a P0 and must page, never merely land in the DLQ. Nothing in this console may edit a
statutory date — a 45- or 180-day date changes only through an approved four-eyes override carrying a legal
basis, recorded on the exchange.
7 · Every action here is an audited state change. Force Retry, Pause and DLQ replay each write
an audit-log entry with the actor, the workflow, the run id and the reason, and forward it to the Vectr audit
log like every other state change.
8 · Provenance. This surface reads Vectr run state; it is a mockup and the run figures are
synthetic. It previously depended on
../_system.css and the Tailwind CDN, both dark-only, which is
why it had no light theme; the classes it actually used are now reproduced against the token contract and both
themes are designed.
--console-rail-*,
--hub-disbursement and
--scrim are
[PROPOSED]: add them to
packages/web-app/src/index.css in
:root and
.dark before writing a call site. (An earlier revision of this file wrote
var(--hub-disburse), a token no sheet defines — the security category dot rendered transparent;
it now uses the real
--hub-disbursement.)