Status and roadmap
Ce contenu n’est pas encore disponible dans votre langue.
SpeculaPro is built but pre-release: every planned phase is complete, and no release has been published or run by a live institution yet. This page says honestly what is built, what is a first stage, and what is not built, so you know exactly what the rest of these docs describe.
What exists today
Section titled “What exists today”| Area | State |
|---|---|
| Database schema | Built: workspaces, users, roles, entities, transactions, rules and versions, hits, suppressions, alerts, cases, escalation policies, reports, audit log |
| Tenant isolation | Built: Postgres row-level security on every workspace table; the installation’s own tables and every monthly partition are closed to the app database role. Sign-in, SSO and SCIM rate limits hold per process when Redis is down |
| Rule versioning guarantees | Built into the database: frozen approved versions, 4-eyes approval, append-only case timeline |
| Sign-in | Built: password sign-in, required two-factor codes (TOTP), ten single-use recovery codes for a lost phone, passkeys (sign-in with the device’s fingerprint, face or PIN, with no password or code), forced password change at first sign-in, temporary passwords that expire after 72 hours, rate limits and lockout, sessions, API keys. See Sign-in and MFA |
| Encryption of personal data | Built and applied: national IDs, phone numbers, emails and account identifiers are encrypted per workspace (AES-256-GCM) with blind indexes as they arrive; production refuses to start without keys. See Data protection |
| Ingest API | Built: transactions, customers, accounts, FX rates and account events (sign-ins, failed one-time codes and PINs, SIM swaps, profile changes) over REST with API keys; idempotency, versioned updates, multi-currency conversion. See Sending data |
| File import | Built: administrators load customers and transactions from CSV or JSON (up to 50,000 rows a file) under Settings → Data import, with the same checks and idempotency as the ingest API and per-line results. See Importing a file |
| Ingestion adapters | Built: the connector role reads institution Kafka topics (dead-letter topic, offsets committed only after acceptance, a pause when monitoring falls behind) and collects SFTP / S3 file drops (CSV, JSON Lines, ISO 20022 camt.053 and pain.001, gzip), each file once, with a results file written back. Set up under Settings → Data sources. CSV covers transactions and customers only. See File drops and Kafka topics |
| Change data capture | Built: the connector role follows a core-banking database’s changes through Debezium topics (JSON, or Avro with a schema registry) or Postgres logical replication read directly, with versioned table mappings that can need a second person’s approval. Mappings are edited in a form (tables, fields, and options such as date formats and value translation) or as JSON; fields computed from several values or conditions are edited in the JSON view. Not yet tested against a real Oracle or Debezium deployment, or a production replica. See Change data capture |
| Persister | Built: Kafka to Postgres in batches, safe to replay, dead-letter topic. See Persister |
| Maintenance worker | Built: future partitions, clean-up of old idempotency keys, and sending notifications. See Worker |
| Load generator | Built: realistic mobile money traffic for testing. See Load testing |
| Decision-speed benchmark | Built: a fixed benchmark of the real-time decision path in the build pipeline that fails the build when the 99th-percentile or median decision time, or the Redis/Valkey commands per decision, get worse than a committed baseline beyond a tolerance. The baseline was measured on a laptop and the job has not yet run in CI. It guards against regressions; it is not a capacity figure. See Scaling and performance |
| Real-time decisions | Built: POST /api/v1/decisions answers allow, step up, review or block before a payment goes ahead, within the workspace’s time budget, with the reasons. If the checks can’t finish in time, the workspace’s fail-open or fail-closed policy answers. Retries are safe, and a decided payment is also monitored like any other transaction. A blocked payment is stored as blocked, every answer given by the failure policy raises a fraud alert, and label changes are audited. Outcomes are reported back as fraud or legitimate, the Decisions screen shows the log and statistics, and each real-time rule’s page shows its precision. See Real-time decisions and the API |
| Webhooks | Built: under Settings → Webhooks, administrators send signed notifications of blocked and held payments, new alerts and cases, and closed cases to their own systems, with retries, a delivery log and secret rotation. See Webhooks |
| Metrics and tracing | Built: Prometheus metrics on their own port, and OpenTelemetry tracing (off unless you configure a collector). Four ready-made Grafana dashboards ship with the Helm chart (overview, real-time decisions, monitoring and background work, hosted service). See Monitoring |
| Command line | Built: run, migrate, topics, tenant create, tenant reset-password (an operator’s way back in when no administrator can sign in), keys generate, version |
| Container image | Built: a Dockerfile for a distroless, non-root image with the web app built in. Every change is checked automatically (formatting, generated queries, vet, race tests, a vulnerability scan, the frontend checks and an image build). No published image yet. See Building |
| Web app | Built for the Command center, transactions, real-time decisions, alerts, cases, rules (including a visual rule builder), customers, people and API keys, workspace settings, webhooks, data import and notification settings (below). Every Command center panel shows live data. |
| Transactions screen | Built: search the last 1 to 90 days by transaction reference, customer reference or name, filter by direction, channel and flagged, and see which rules hit each transaction. See Transactions and the API |
| Feature store | Built: running totals per account, customer and counterparty in Redis/Valkey, windows from 1 minute to 180 days, plus per-customer device, payee, country and location history for real-time signals (new device, new payee, new country, impossible travel, shared device). See Feature store |
| Rule engine | Built: CEL rules with declared features, parameters and explanations; packs core 1.4.1 (24 rules), fraud 1.4.0 (11), gh-psp 1.2.0 (14), gh-bank 1.1.0 (10), global-fatf 1.2.0 (8), ng-psp 1.2.0 (9), ng-bank 1.2.0 (8), uemoa-emi 1.1.0 (8), uemoa-bank 1.0.0 (8), and sl-psp (8), sl-bank (8), lr-psp (9), lr-bank (8), gm-psp (8), gm-bank (8), gn-emi (8), gn-bank (8), ke-psp (12) and ke-bank (9), all 1.0.0: nineteen packs, 167 different rules; real-time, post-event and scheduled rules; pack upgrades that draft updated rules for approval with your tuning carried over; signed pack files for updates between releases; versions with 4-eyes approval; active and shadow deployment; a visual builder for custom rules that can be tested on sample data, in the Rules screens and through the API. See Managing rules |
| Stream evaluator | Built: evaluates every enabled rule on every transaction, records hits, applies approved suppressions, merges hits into one open alert per subject, and adds new alerts to the subject’s active case. See Stream evaluator |
| Alerts and cases | Built, in the app and through the API: the risk-ordered alert queue, dismissal with dispositions, cases opened from alerts (SP-<year>-<number>), comments, assignment, escalation (levels 1–3) by hand or by escalation policy, team queues, SLA deadlines by priority or by policy level, missed deadlines recorded and notified by the worker, four-eyes closing for high and critical cases (or every case a policy says), reopening, and summary counts. A more severe alert joining a case raises its priority. Names are shown only to roles allowed to see customers; others see a pseudonym. AML and fraud alerts, and their cases, are kept separate by kind. Every action is on the case timeline and in the audit log. See Alerts and cases and the API |
| Alert queue and case screens | Built: the Alerts queue and alert detail, the Cases list (with search, a priority filter and Load more) and case workspace, and the Command center, whose every panel uses live data: today’s monitored and flagged value, the 24-hour money flow, the four-week alert heatmap, rule performance, the latest transactions, the compliance pulse, the priority queue and closures awaiting approval. See also the Dashboard API |
| Production packaging | Built: a Helm chart (one Deployment per role, hardened pods, network policies, monitoring alerts) and a production Docker Compose setup with a one-command first run. The Compose setup is validated but not yet tested end to end. Readiness checks are per role, so web and decision pods stay in service during Kafka or Redis outages. See Kubernetes with Helm and Docker Compose in production |
| Licensing | Built: signed licence files checked offline, with no phone-home. A lapsed licence only pauses new workspaces, new rule versions and pack installs, never monitoring, decisions, alerts or cases. See Licensing |
| Signed rule-pack updates and release signing | Built: rule-pack updates signed by SpeculaPro and checked before they are read; keyless cosign signatures, an SBOM and offline bundles for releases. No release has been published yet. See Rule-pack updates and Verifying releases |
| Regulatory reporting | Built: STRs drafted from cases (subject, alert transactions, narrative and indicators pre-filled), CTR drafts each day for cash at or over the workspace’s threshold (off by default), four-eyes approval enforced in the database, goAML 4.0 XML export kept byte for byte with its SHA-256 (or a CENTIF declaration archive for the UEMOA states and Guinea, layout unconfirmed), a list of attachment titles on each report, and a permanent register with the FIU’s reference and answer. The Reports pages and Settings name the workspace’s own FIU and report format. Upload to goAML Web is manual. The defaults (codes, indicators, the GHS 50,000 CTR threshold) must be confirmed with the FIC. Reports approved or drafted by mistake can be voided with a reason (kept in the register), the settings used at approval are frozen with the report, and an operator can offboard a workspace with speculapro tenant offboard, which exports its reports first. See Regulatory reporting |
| Jurisdictions | Built: a workspace follows a jurisdiction (Ghana, Nigeria, the eight UEMOA states, Sierra Leone, Liberia, The Gambia, Guinea, Kenya, or an FATF baseline for any other country) that sets its reporting format and codes, CTR thresholds, identifier checks and recommended rule packs, with the values still to confirm with each regulator; signed, audited jurisdiction updates without an upgrade. Each jurisdiction says whether cash equal to the CTR threshold is reported (Nigeria: above only); one with no threshold (the FATF baseline) drafts no CTRs until you set one. New packs: global-fatf (8 rules, written in US dollars with defaults for GHS, NGN, XOF and EUR), ng-psp (9), ng-bank (8), uemoa-emi (8), uemoa-bank (8), with French names and descriptions. Reports for the UEMOA states and Guinea export as a CENTIF declaration (DOS, DTE): a French form to print, sign and file, plus XML; its layout and schema are SpeculaPro’s own and unconfirmed with every CENTIF. See Filing with a CENTIF. A workspace that never picked a jurisdiction follows its country’s definition only when its base currency matches. A workspace that was drafting CTRs on its country’s figures in another currency keeps them on upgrade, to be corrected. For Sierra Leone, Liberia, The Gambia, Guinea and Kenya, every threshold, deadline and FIU detail is unverified research, marked to verify with counsel; core, fraud and global-fatf install rough default amounts in their currencies (scaled from US dollars, to review before enabling). See Jurisdictions and The five newest jurisdictions |
| Sanctions and PEP screening | Built: official lists fetched and versioned (UN, OFAC SDN and consolidated, EU, UK; South Africa, Canada, Australia and Kenya on request), an import format and signed bundles for lists with no feed (Nigeria, Ghana, UEMOA, loaded by the operator) and for air-gapped sites, each workspace’s own watch lists that no other workspace sees, default lists that follow the workspace’s jurisdiction, explainable name matching that ignores generic payment words such as Wallet or Agent, automatic screening of customers and counterparties and re-screening when a list changes, providers for PEP data (OpenSanctions, ComplyAdvantage, LSEG World-Check One) with retries when one can’t be reached, and screening records under their own retention category. A Screening page to review potential matches: the customer and the list entry side by side, assigning, comments, a timeline, clearing a false positive (remembered so the pair isn’t raised again) and confirming a true match (a designation and a case), with a second person’s approval for true matches and sanctions clearances once two people can approve; until then only someone with screening.approve decides a sanctions match. Real-time decisions block a confirmed sanctions match and review an open one by default, including when a decision can’t finish in time (confirmed matches are held in memory for that). A counterparty with no stored screening result (the first payment to them) has its name screened against the lists inside the decision itself, and the person a match is assigned to is notified by email, text message or WhatsApp. Importing your own watch list and connecting a provider are done under Settings → Screening or through the API. Not yet: a notification when a new match arrives unassigned; Dow Jones, Bridger and Moody’s Grid connections. By design, not planned: screening a customer’s name during the decision itself (a decision request carries no customer name; customers are screened when their record arrives and the decision reads the stored result), and calling an external provider inside the decision’s time budget. See Sanctions and PEP screening |
| Analytics store and Analytics page | Built: an Analytics page with volume by channel and type, typologies, rule performance, alert outcomes and decision outcomes by month (3 months from Postgres). Optional: a ClickHouse analytics store, filled by the analytics role, extends the page to 24 months and serves long backtests and two long scheduled rules (I2, I3); it can be rebuilt from Postgres or Kafka. Readers use the store only when a workspace’s copy is complete and up to date, and offboarding a workspace deletes its copy. The data protection purge and erasure reach the copy too. Not yet: short run times for long backtests at very large volumes haven’t been demonstrated. See Analytics and Analytics store |
| AI assistant | Built, off until a workspace switches it on: a language model (Claude by default; with a workspace’s own key also OpenAI, Google Gemini, Mistral or any API that speaks the OpenAI chat format, such as a model the institution hosts) reads an open alert and advises whether it looks like a false positive or needs investigating, with its confidence, reasons and what to check next. It never closes, dismisses or escalates anything; a person decides. What is sent is built from structured fields and masked first (names and each part of a customer’s name become placeholders; emails, long numbers and document numbers are replaced, in rule names and thresholds too). Sanctions alerts, critical alerts and alerts about PEPs or sanctioned subjects are never returned as likely false positives. Every review is kept with its exact request and answer, encrypted, and audited; switching it on, or changing its key or model, needs a second person’s approval by default, while switching it off applies at once; a person whose role doesn’t show customers sees the recommendation without the reasoning; optional automatic review of new alerts; usage counted per workspace. On a case, a person can ask for a summary (what it is about, the facts that matter, what is still open) with a suggestion of what to do next (looks like a false positive, a report may be warranted, needs more investigation, not enough to tell): advice only, it changes nothing, never reads notes, closing reasons or files, and is never false positive for sanctions cases, critical cases or cases about PEP or sanctioned subjects; the case list shows the latest suggestion as a marker. A person can ask about the whole queue at once (up to 200 open alerts without advice, or cases never summarised, most urgent first; the worker reads four at a time and each answer is counted and audited like a single one), filter the alert queue by the assistant’s advice, and close up to 100 open alerts together with one outcome and a required reason, which is the person’s own action and is refused for sanctions alerts, critical alerts and alerts about PEP or sanctioned subjects. On a draft STR or SAR made from a case, the person writing it can ask for a draft of the narrative: the case is sent masked, the names are put back on SpeculaPro’s side after the answer, and the draft sits beside the report until the person uses it and saves; the draft is deleted when the report leaves draft, and the report’s checks and approval are unchanged. No call is made for someone whose role doesn’t show customers. On a rule, a rule author can ask how it is doing: the assistant reads the rule’s live version and 90 days of counts (hits, what became of the alerts, and how what the rule measured was spread in each outcome; no customer, transaction or alert text) and answers with an assessment and up to four changes worth testing, each with its reason and what it could miss. Nothing changes on the rule: a suggestion is tried in a backtest and becomes a new version only through the usual approval. It needs ten decided alerts in the 90 days. Limits: tested only against local stand-ins for the Claude API and for an OpenAI-compatible API, not against any real provider, and structured-output support differs between models; a change of provider or address on a workspace’s own key needs the new key in the same save (one path, through the subscription’s key and back, is not checked); the masking is pattern-based, so it is pseudonymisation, not anonymisation, and names under three characters are not masked inside text; the model can be wrong; tuning suggestions rest on how analysts closed past alerts, a workspace-written rule’s name and description are not sent but a bare number in its condition and a single short lowercase word in a parameter are, and rules about sanctioned and politically exposed parties are left out by their category (Designations) alone; the check on a case’s suggestion runs only when the summary is written, so a summary written before the subject was designated keeps its text on the case page until someone asks again (the marker in the case list is dropped); bulk closing refuses held alerts (sanctions, critical, or about a PEP, a PEP’s relative or associate, a sanctioned subject or an account one of them owns) but can’t tell whether the others were read; a batch stops when the person who started it may no longer ask, and after three provider failures in a row; nothing in code checks a summary or a narrative draft for a conclusion or an invented fact; on the hosted service a workspace’s plan can set its monthly calls on the provider’s key (enforced) or leave that key out, and the provider keeps a count of calls and tokens that outlives the workspace; administrators are warned at four fifths of the month’s calls and when they run out, can ask the provider for more from their settings, and the provider can add calls for the month in its console (they do not carry over); monitoring never depends on the allowance; nothing computes prices or invoices, and an installation without a provider console has only SP_AI_MONTHLY_CALLS. See AI assistant, what is sent and kept and its settings |
| Risk models | Built (first stage): each workspace can train an anomaly model on its own transactions (an isolation forest; no labels needed) that gives every transaction a score from 0 to 1 with its reasons. Rules read it as model.score, model.percentile and model.reasons; the model never blocks, holds or alerts by itself. A Models page with a registry, draft → shadow → live → retired, a second person’s approval to go live (enforced in the database), a model card for each version, drift monitoring, and a weekly notification to the people who train and approve models while a shadow or live version’s drift is significant. An optional retraining schedule, weekly or monthly, trains a new draft; it never promotes one. The score and its reasons show on alerts and decisions. Not yet: models that learn from your fraud labels; automatic promotion of a retrained model; choosing the day or hour of a scheduled training; choosing features; scores in scheduled rules (scores aren’t stored for each transaction). See Risk models |
| Multi-region hosting | Built, for a hosted service: each region is a complete, independent installation (a cell) and a workspace is pinned to one; a cell refuses a workspace pinned elsewhere on sign-in, sessions, API keys, webhooks and notifications. A small global directory holds workspace slugs and regions only, for the global sign-in page. API keys carry their region and a key sent to the wrong region gets 421 with the address to use. An operator’s tool moves a workspace between regions with a verified copy in an encrypted bundle, a read-only then unavailable window during which background jobs and data sources leave the workspace alone, and deletion of the old copy. Not yet: run against real regions (the move and failover are exercised in tests only, and the failover drill is written but not yet performed); metrics for cells and the directory; carrying the analytics copy, counters and sanctions list contents in a move. No automatic failover between regions, by design. A self-hosted installation is a single installation and is unchanged. See Data residency and regions |
| Data protection | Built: under Privacy, a data protection officer role sets retention per kind of data (never below the AML minimum of the laws that apply; the strictest wins), with a dry run before a purge can be switched on and legal holds that keep data whatever its age. It handles data subject requests with each law’s deadline, the AML erasure exemption and a tipping-off safeguard (flagged requests go to the MLRO, and exports never contain monitoring data); keeps the record of processing, lawful bases and transfers; and runs a breach register with each law’s notification deadlines and an export for the regulator. Laws built in: Ghana, Nigeria, Kenya, Côte d’Ivoire, Sénégal, South Africa, the EU and the UK, with the FATF baseline elsewhere. Not legal advice; open points are listed. See Data protection |
| Approvals and custom roles | Built: maker-checker for sensitive administrative changes (role grants, re-enabling, credential resets, custom roles, single sign-on, API keys, webhooks, data sources, deny and allow lists, rule packs, the decision policy, four-eyes, case SLAs, escalation policies, reporting settings and the approval policy itself). A change becomes a request that a different person approves, with the reason, the before and after, a stale check and a 7-day expiry. Defaults start once two people can approve. Custom roles from a plain-language permission catalogue, a new L2 investigator role, read-only access to every Settings tab for auditors, and the audit log on screen and through the API. Switching off the two-factor requirement, single sign-on email domains and signed rule-pack imports are covered too, and granting access to personal data, the audit log or reports counts as a privileged grant. See Approvals and Custom roles |
| Single sign-on | Built: one OpenID Connect or SAML 2.0 connection per workspace under Settings → Single sign-on: claimed email domains (DNS-verified), just-in-time accounts and group-to-role mapping, trusting the identity provider’s multi-factor, a connection test, and optional enforcement with break-glass administrators. SCIM 2.0 provisioning: your identity provider creates, updates and deactivates accounts and pushes the groups that give roles, with per-workspace tokens; deactivation ends the person’s sessions at once and nobody is deleted. SCIM gives or removes a privileged role (Administrator, MLRO and the like) only if the workspace allows it. SAML single logout in both directions, by redirect or HTTP-POST. When someone is deactivated, the API keys they created are marked rotation due (or revoked at once, if the workspace chooses), and a key can be rotated in one step. Not included: a sign-out at an OIDC identity provider ending SpeculaPro sessions; per-person API keys. See Single sign-on and Single sign-on security |
| Provider console (hosted service only) | Built: a separate console for the provider’s staff, on its own listener and off by default. Five fixed staff roles with a mandatory second factor; workspaces listed and created; plans and agreed limits recorded (monitoring is never blocked; only adding one more person than agreed is refused); usage and health in numbers; suspension, reactivation and scheduled deletion under dual control; service notices; time-limited, read-only support access that the workspace approves, with a filter so nothing shown says a report exists, and every read in both audit logs; an append-only audit log. Scheduled deletion runs only if the operator opts in. One console per region. Limits: staff roles are fixed, staff have no single sign-on, there are no totals across regions, and a full-read support session shows customer names (identifiers and contact details are masked). See The provider console and Support access |
| Scheduled rules | Built: 9 rules (D3, D4, F5, G1, I1–I4 and GB1) run hourly, daily or weekly in the worker role over stored history, using vetted queries whose parameters you tune but whose logic you can’t change, with leased runs, catch-up after downtime (up to 31 days) and a table of runs on each rule. See Scheduled rules |
| Backtesting | Built: replay a rule version, other parameter values or an unsaved rule from the builder over up to 180 days of history, compared with the live version (hits, alerts, entities, amount, overlap, a daily chart, real-time outcomes and a sample of hits), run in the background by the worker. A scheduled rule is backtested by simulating every run of its schedule, each reading only what had happened by its run time, compared with what the rule actually raised; the backtest can simulate another schedule than the rule’s own, from the panel or the API. See Backtesting |
| Rules screens | Built: the rule library with packs and running switches, and each rule’s page for tuning, approving, shadow testing and making a version live. See Managing rules |
| People and API keys | Built: in Settings, administrators add people, change roles, disable accounts, reset two-factor and passwords, and create and revoke API keys. Invitations and reset passwords expire after 72 hours |
| Workspace settings | Built: under Settings → Workspace and through the API, administrators set the workspace name, time zone, language, the two-factor requirement, four-eyes approval for every closure, the case deadlines and the real-time decision policy (time budget, fail-open or fail-closed). See Workspace settings |
| Customers, designations, suppressions and lists | Built, in the app and through the API: the Customers search and profile (protected fields only with entities.view_pii, every view audited), PEP and other designations (Flag, Remove) with supporting evidence, suppressions proposed from the customer’s page (for one rule, everything, or only with one counterparty) and approved or rejected with a reason on the Rules page, and lists on the Rules page with renaming, deleting and values that expire. See Customers and lists, and the APIs: Customers, Designations, Suppressions and Lists |
| French | Built: the whole web app in English or French, with French terms following UEMOA/BCEAO usage (LBC/FT, déclaration de soupçon, CENTIF, PPE). Each person chooses their language, saved to their profile, or follows the workspace’s default language; numbers, dates and notification messages follow it. The jurisdiction packs carry French names and descriptions. Still in English: the core, fraud and Ghana packs, hit explanations in every pack, the permission catalogue, server error messages and technical values (codes, keys, settings). See Languages |
| Notifications | Built: email (your SMTP server or the Spalce Notification Service), SMS (Spalce) and WhatsApp (through your own GOWA server, after each person confirms their number with a code) for case assignments, closures to approve and their outcome, escalations, rule changes and suppressions to approve, critical alerts, cases due within the hour, missed deadlines and automatic escalations. Each person chooses their channels under Settings → Notifications; choices are per channel, not per type of notification. Messages carry no customer data. Emails use one designed layout in English and French, with a details block and a plain-text part. See Notifications |
| Escalation policies, team queues and automatic escalation | Built, in the app and through the API: Settings → Escalation holds teams (people who share a case queue) and escalation policies. A new case follows the first policy in use that fits it: the level it opens at, the team and the time each level has, whether a missed deadline escalates it by itself, and whether closing it needs a second person. The worker records each missed deadline once (timeline, audit log, notification and the case.sla_breached webhook). Policy changes need a second person’s approval by default. Not built: reassigning open cases when a policy changes (they keep their place). See Escalation policies, Teams and the API |
| Evidence files and the filing package | Built, in the app and through the API: a case takes the documents an investigation collects (pdf, png, jpg, webp, txt, csv, eml, msg, docx, xlsx; 10 MB each, 50 a case). The content must be what the file’s name says; files are encrypted with the workspace’s key, their SHA-256 is recorded and checked on every read, every download is audited, and a removed file keeps its record. A report draft names which of the case’s files go with it, frozen once the report leaves draft, and after export the Filing package is one ZIP of the export, those files and a manifest of their SHA-256. Not built: malware scanning of uploaded files, and viewing a file inside the app (files are always downloaded). See Evidence files and Regulatory reporting |
The binary can run the api, decision, ingest, connector, persist, stream and worker
roles (all starts all seven; the optional analytics role also runs where the analytics store is set up). In practice: you can ask for a decision before a payment goes ahead,
send data in, have it stored, checked against the rules you enable and turned into alerts, which
people dismiss or work as cases in the Alerts and Cases screens, and have your own systems
notified by webhook.
The phases
Section titled “The phases”The order is driven by what the first Ghana PSP or bank needs to go live, and by what is expensive to change later.
Phase 0 — Foundations
Section titled “Phase 0 — Foundations”Repository layout, the single binary with roles, configuration, logging and tracing; the Postgres schema with tenant isolation and partitioned transactions; Kafka topics and a local development stack; sign-in with two-factor codes, the role skeleton and the audit log; the canonical data model and money model; a load-test harness. Complete.
Phase 1 — Post-event AML
Section titled “Phase 1 — Post-event AML”- Ingest through the REST event API (done) and CSV/JSON file upload in Settings → Data import (done), both idempotent
- Persister (done) and feature store (done)
- The CEL rule engine with versions, parameters, 4-eyes approval, and shadow and active slots (done, in the app and the API; see Managing rules)
- Rule library:
coreand part ofgh-psp(done in Phase 1; the rest ofgh-pspand thefraudpack followed in Phase 2; see Pack contents) - Manual risk designations and allow/deny lists (done, in the app and the API)
- Alerts (done: hits merge into alerts) → suppression (done, with second-person approval, in the app and the API) → cases → assignment → escalation (L1 → L2 → MLRO) → disposition (done, in the app and the API, with escalation policies, team queues and automatic escalation added after Phase 1)
- Notifications by email and SMS (done)
- Web app: alert queue and case workspace (done), rule list and parameter editor (done), people and API keys (done), customers and designations (done), dashboard on live data (done), transaction search (done), workspace settings (done)
- English interface, with translation wiring in place
Exit criterion: a pilot PSP can send transactions, get alerts, and work cases end to end. Phase 1 is complete. Escalation policies (automatic routing by score, designation or deadline) and case attachments (evidence files) were both built later.
Phase 2 — Real-time fraud
Section titled “Phase 2 — Real-time fraud”- The decision API, with a time budget and a fail-open or fail-closed policy per workspace, safe retries, and outcome feedback (done; see Real-time decisions)
- Account events and real-time signals: new device, new payee, new country, impossible travel, shared device (done)
- The
fraudpack (10 rules) andgh-psp1.1.0 with the SIM-swap payout and real-time KYC-tier rules, with pack upgrades that keep your tuning (done) - A visual rule builder that writes the CEL for you and tests a rule on sample data; making it live still needs a second person’s approval (done)
- Signed webhooks for decisions, alerts and cases (done)
- Prometheus metrics and OpenTelemetry tracing (done)
- Published performance figures: not yet. Internal measurements so far were taken on a laptop, and will be repeated on production-like hardware before any figure is published. Until then, the numbers in Scaling and performance are targets
Phase 3 — Bank readiness and reporting
Section titled “Phase 3 — Bank readiness and reporting”- goAML STR and CTR reports for Ghana’s FIC (done; uploading to goAML Web is manual, and the codes and thresholds must be confirmed with the FIC. See Regulatory reporting)
- Scheduled rules, the remaining library rules and the
gh-bankpack, with pack upgrades that draft changed rules for approval (done. See Scheduled rules) - Backtesting of draft rules, and of scheduled rules by simulating their schedule (done; deleting or expiring old runs is still to come. See Backtesting)
- Single sign-on with OIDC or SAML, SCIM provisioning and SAML single logout (done. See Single sign-on and SCIM provisioning)
- Self-host packaging: a Helm chart and production Docker Compose, licence keys, signed rule-pack updates and signed releases (done; no release has been published yet. See Self-hosting)
- Kafka topics and SFTP or S3 file drops, including ISO 20022 bank files (done. See Sending data)
- WhatsApp notifications through GOWA (done)
- Four-eyes approval on more actions, custom roles and the audit log screen (done)
- French for the web app and notifications (done; the
core,fraudand Ghana packs, rule explanations and the permission catalogue are still in English)
Phase 4 — Scale and expansion
Section titled “Phase 4 — Scale and expansion”Phase 4 is built. It added an analytics store, sanctions and PEP screening, change data capture, packs for more countries, data protection tools, risk-model scores and multi-region hosting. Several parts are a first stage, and the list says what each still lacks.
- Sanctions and PEP screening: lists, matching, providers, the review workflow and sanctions matches in real-time decisions (done. See Sanctions and PEP screening); a counterparty with no stored result is screened inside the decision itself. By design, a customer’s name is not screened during the decision (a decision request carries no customer name; customers are screened when their record arrives, and the decision reads the stored result), and no external provider is called inside the decision’s time budget; neither is planned. The Dow Jones, Bridger and Moody’s Grid connections are still to come
- Packs for more countries: Nigeria, the UEMOA states, Sierra Leone, Liberia, The Gambia, Guinea and Kenya (done; the last five are unverified, to verify with counsel. See Jurisdictions); others to come
- CENTIF declarations (DOS, DTE) for the UEMOA states and Guinea (done; the layout is SpeculaPro’s own and unconfirmed with every CENTIF. See Filing with a CENTIF)
- CDC ingestion: Debezium topics and Postgres logical replication (done. See Change data capture); a visual mapping builder is still to come
- ClickHouse analytics store and the Analytics page (done, optional. See Analytics store); the data protection purge and erasure reach it
- Data protection: retention and legal holds, data subject requests, registers and the breach register (done. See Data protection)
- Risk models, first stage: per-workspace anomaly scores that rules can read, with shadow, four-eyes promotion, model cards and drift (done. See Risk models); models trained on labelled outcomes are not built: they need labelled data from a pilot. A weekly or monthly retraining schedule that trains drafts is built
- Multi-region hosting with data-residency pinning: regional cells, a global directory and a workspace move tool that waits for the workspace to drain and rebuilds its counters and analytics copy in the target (done; not yet run against real regions. See Data residency and regions)
The documentation in French is also planned; the docs are in English only today.
Built but not yet run for real
Section titled “Built but not yet run for real”- Capacity on real hardware. The performance targets have only been approached on a laptop; no benchmark has run on production-like servers.
- The production Docker Compose setup and the release pipeline. Both are validated, but the Compose setup has not been run end to end and no release has been published.
- Multi-region hosting. Not yet run against real regions; the workspace move and failover are exercised in tests only.
- The decision-speed benchmark in CI. Its baseline is a laptop measurement.
Still to confirm
Section titled “Still to confirm”- The FIC’s reporting format, thresholds and record-retention period, and the same for every other jurisdiction: each one’s page lists the values to confirm.
- Bank of Ghana and Data Protection Commission requirements for where SaaS data may be hosted, and which regions the hosted service will offer.
- The self-host licensing model.
- The performance targets, against the first pilot’s real volumes.