Sign in

Authenticated, role-based access — auditors are read-only.

Omissia — Loophole Detection

Loading plaza…  |  reconciling ANPR ↔ transactions ↔ e-tag SQLite · live API
Prepared by  for 
plaza:
Ready. Click run to scan the shift.
⏱ auto-recon: —
ANPR camera reads
independent ground truth — what actually passed
Recorded transactions
what cashiers / lanes logged
E-tag / RFID passes
electronic account debits
Bank settlement lines
money that actually reached the bank

Reconciliation summary — every camera read matched against payment (SQL join across 3 feeds)

Run the reconciliation to see the match breakdown
properly accounted for underpaid / discount fraud no payment recorded (revenue gap)
Vehicles passed (ANPR)
Flagged events
Est. leakage (this shift)
Projected annual leakage

Live camera monitor every ANPR read as it arrives ·

Batch CSV import means the operator finds a ghost pass hours later. A live RTSP/ONVIF feed pushes each read within seconds — with camera ID, OCR confidence, and a per-read anomaly scan (no-payment window, low OCR confidence, unauthorised exemption). This is the ambient monitor for the control room.
Reads (last 50)
Alarms in view
Low-confidence
Poll
off

Cameras

Camera IDPlazaLaneReadsMean confidenceLow-confidenceLast seen
Loading cameras…

Live stream

WhenPlaza · LaneCameraPlateConfAlarm
Start the poll to see reads stream in.

Fleet overview every plaza in the deployment ·

The reconciliation engine runs per plaza. In production a deployment covers 17–31 gates; opening a tab per gate is not a strategy. This view rolls the latest run for every plaza into one snapshot — status, flags, and revenue leak — so operations can spot the outlier gate at a glance and drill in.
Gates
Lanes
Critical flags
Revenue leak (latest run)
StatusGateProvinceLanes CriticalHighMedium Leak (USD)Last runLatest alert
Loading fleet…

Flagged events — ranked by value filter:

TimeLane / CashierLoophole click row → fix & preventEvidenceValue
Run the reconciliation to populate flags.

Leakage by loophole type

Leakage across the shift (by hour)

Cashier outliers — peer comparison (this shift) gov-exempt booking rate vs. lane peers

CashierLaneTransactionsExempt-booking %Peer avgFlag
Run the reconciliation to profile cashiers.

Statistical drift — 30-day baseline (cashiers & plates) z-scores vs own history & peer pool

Sits alongside the deterministic detectors and surfaces patterns the rules weren’t written for. Score ≥ 3.0 = HIGH, ≥ 2.0 = MED. Cashiers are scored against their own 30-day exempt-rate history (SELF) and the day’s peer pool (PEER); plates are scored against the population on (uses · distinct cashiers · exempt share).

Cashier anomalies — top 5

CashierTodayz(self)z(peer)Severity
Run the reconciliation.

Plates of interest — top 5

PlateUsesScoreWhy
Run the reconciliation.

Raw feed inspector — the rows behind the flags

The proof a technical reviewer asks for: for each flagged vehicle, the three feeds side by side. The gap between what ANPR saw and what was recorded is the leak.
TimeLaneANPR sawTransaction loggedE-tag debitVerdict
Run the reconciliation, then click “Show raw rows”.

Bank-settlement reconciliation — does the collected money reach the bank? 4-way match: road → lane → account → bank

The road-side checks prove a vehicle was charged. This proves the money actually arrived in the operator's bank account — the gap between collected and banked is settlement leakage / cash skim.
Run the reconciliation to trace the money to the bank
reached the bank collected but never banked
ChannelCollected / chargedReached bankGap
Run the reconciliation to trace settlement.

Mobile money reconciliation EcoCash · OneMoney · Telecash ·

Zimbabwe's dominant retail rails are USSD-initiated. The driver dials *151# at the booth, the lane records "paid" — but the settlement into the operator's bank account can lag hours or fail silently. The Gweru $9.8M audit finding was exactly this gap. This checks every lane-side mobile-money transaction against the provider's settlement feed and surfaces uncleared, failed, and amount-mismatch cases.
Cleared
Not cleared
Amount mismatch
USSD leak (USD)
WhenProviderUSSD refPlateTypeSeverityAmountEvidence
Run the reconciliation to see mobile-money gaps.

Tamper-evident ledger cryptographic audit trail · SHA-256 hash chain

Every recorded transaction is hash-chained and sealed, and each trusted checkpoint is also written to an append-only, hash-chained anchor log outside the database. So even an admin who tampers with a row and re-seals can't launder it: verification still flags that the live head no longer matches the trusted anchor. (In production the anchor lives in an append-only / off-box store.)

Admin action trail hash-chained · append-only · auditor-readable

Every privileged action lands here — threshold and rule edits, violation decisions and escalation sign-offs, user disable/reset, data-subject erasures, imports, re-seals and re-anchors. The chain is verified on every load: a deleted, reordered or edited entry breaks it visibly.
WhenActorActionTargetDetail
Loading…

Velocity / cloned-tag detection network-wide · impossible travel between plazas

Compares each e-tag's consecutive passes across plazas. A tag appearing at two plazas too far apart to drive between in the elapsed time is a cloned or shared tag — the same method used to catch cloned phones.
TagFromToDistanceElapsedImplied speed
Run the reconciliation to scan the network.

Active alerts evaluated on every reconciliation run

Threshold rules below are checked each run; breaches raise alerts here and (if a webhook is configured) POST to your ops channel.
Run the reconciliation to evaluate alerts.

Alert thresholds

Tune what raises an alert. Numeric rules use the threshold field; presence rules fire whenever the condition occurs.
OnRuleThresholdSeverity
Loading rules…

Recent alert history

WhenSeverityAlert
No alerts recorded yet.

Data-subject rights (POPIA) access · erasure · legal-hold report

Respond to a POPIA data-subject request from a client's information officer. Access returns a JSON aggregate of everything Omissia holds; erasure anonymises where possible and reports what is retained under a legitimate-interest / legal-obligation exception (financial records, enforcement notices, hash-chained audit trail). Erasure is dry-run by default — you must explicitly execute to mutate. Every executed erasure is recorded to the admin action chain. See docs/compliance/popia.md.

User accounts disable a compromised account or reset a forgotten password

Actions here are audit-logged (see the admin action chain). Disabling an account terminates any live session on the next request; resetting a password does the same and forces a change on next login. You cannot disable your own account or the last enabled admin — the deployment must always have at least one usable admin.
UsernameRoleMFAMust change pwStatusCreated
Loading…

SMS / WhatsApp recipients provider:

Webhook → Slack/Teams is useless for a Zimbabwe field supervisor. Recipients configured here receive an SMS or WhatsApp message on every alert whose severity is in their list and whose plaza matches (or "all"). The provider is set via TOLL_SMS_PROVIDERstub (default) persists to the audit log without hitting a gateway; twilio or africastalking deliver over the real rails when credentials are set.
NamePhoneChannelSeveritiesPlazaActive
Loading…

Recent messages

SentToChannelProviderAlertSeverityStatusBody
No messages yet.

Exempt Plate Registry the single source of truth for authorised exemptions

Only plates listed here may receive an exempt-code booking without raising an "Unauthorized exemption" flag. Adding or revoking a plate is logged to the admin-action audit trail.
PlateCategoryDescriptionStatus
Loading registry…

Header badge "Prepared by … for …" line at the top of every page

Set once during client provisioning (or here). Stored in the deployment-settings table — same value for every user on this VPS. Edits are logged to the admin-action audit trail.

Violation queue human-in-the-loop reviewer workflow

Penalty-worthy flags are promoted into a queue on every reconciliation run. Confirm or dismiss each one, then issue a printable penalty notice.
WhenLanePlate TypeTierSeverityWhy flagged Staff FeePenalty StatusNotice IDAction
Run reconciliation to populate the queue.

Incident management

A detected flag either becomes an auto-issued violation notice or nothing. Real incidents — internal investigations, ZACC escalations, supplier disputes — need somewhere to live with a full audit trail. Open one here; every status change, note, and evidence attachment is appended to the case log.
Open
Investigating
Escalated
Resolved
IDTitleCategorySeverity StatusAssigneePlazaOpenedEvents
Loading incidents…

Messages 1:1 conversations with the deployment operator

Direct messages between the deployment admin (Univern operator) and non-admin accounts (ZINARA auditor, partner viewer). Every message is stored inside this deployment — no central service. Client-to-client messaging is disabled by design. Retention: message rows are never auto-pruned (see docs/compliance/data-retention.md).
No conversations yet.
Select a conversation to view the thread.

Vehicle history every event across the network for a single plate

When ZACC arrests a syndicate, they need to trace a plate across months and gates. This view merges every ANPR read, cashier transaction, e-tag pass, weighbridge weighing, and violation for a plate into one time-ordered timeline — with a running tally of what was paid vs. what's still owing.

Staff named individuals behind cashier codes

Add the people working this plaza. Once a staff member is assigned to a booth below, every flag, cashier outlier, and violation for that cashier code resolves to their name (and their supervisor's) instead of just a code.
NameRoleStatus
Loading staff…

Shift assignments cashier code → person, per shift window

Assign a staff member to a booth code (e.g. C-07) for a shift window. Resolution uses minutes-of-day, so flags timestamped within the window attribute correctly even across overlapping or back-to-back shifts.
Cashier codeStaffSupervisorShift windowStatus
Loading shifts…

Streaming ingestion HTTP NDJSON · idempotent · dead-letter logged

Partner systems POST events as they happen — one JSON object per row, newline-delimited. Each row is deduped on its natural key. Bad rows are logged to the dead-letter queue with the reason.
Feed Endpoint Inserted (1h) Duplicates Rejected Rate / min Last seen
No events ingested yet.

Dead-letter queue most recent 20 rejected rows

Rows the validator rejected (missing fields, unknown plaza/lane, bad timestamp). The full payload preview is kept so an operator can fix and re-post.
WhenFeedReasonPayload preview
No rejected rows.

Send a test event

Smoke-test the live endpoint from the dashboard. Pick a feed; an example payload is loaded so you can edit and submit.

API keys Bearer token auth for partner systems — no login session needed

Hand one of these to a partner's integrator (camera vendor, POS system, RFID reader) instead of a user account — it authenticates POST /api/ingest/<feed> only, nothing else. The raw key is shown once, at creation; only its hash is stored after that.
LabelCreatedLast usedStatus
No keys yet.

Operator reports finance & ZINARA-ready

Standard daily reports generated live from the source tables. Pick one, choose plaza + date if applicable, then preview or download CSV (Excel / Google Sheets friendly).
Pick a report and click Run.

Scheduled reports runs automatically on each scheduler cycle

Add a standing order: pick a report, cadence, and plaza. The scheduler runs it automatically and stores the CSV — browse run history and download any past output below. No email required; pipe to Slack/Teams via the alert webhook.
ReportCadencePlazaStatus
Loading schedules…

Bulk CSV import six feeds · preview before commit · upsert-safe

Drop the partner's CSV exports for any of the six toll feeds, set a plaza name, click Preview to see what would land (no rows written), then Confirm to commit. With Upsert ticked, an import re-uses an existing plaza by name rather than duplicating it — the safe choice for monthly re-imports. Feed columns match samples/ (see toll-loophole-data-request.md).
If a partner's CSV doesn't use our column names, each feed below flags it and lets you map their columns to ours — pick a saved preset to auto-fill, or map once and save under a vendor name so the 2nd plaza from the same partner is instant.
ANPR camera reads
columns: timestamp, lane, plate, vehicle_class, axles
Transactions
columns: timestamp, lane, plate, amount, cashier, fee_type, exempt_code
E-tag / RFID passes
columns: timestamp, lane, plate, status, debit
Bank settlement
columns: channel, batch_date, ref_lane, ref_ts, gross, fee, net
Weighbridge
columns: timestamp, lane, plate, axles, gross_kg
OBU / GPS traces
columns: timestamp, plate, lat, lon, speed_kmh

First-run setup shown automatically until dismissed

Six things worth doing before handing this deployment to a client. Nothing here is required to keep using Omissia — dismiss any time and revisit this tab later.

1. DNS

Confirm the domain's A record points at this VPS: dig +short <your-domain>.

2. Admin MFA

Enrol two-factor authentication on this admin account from Account & security (top-right menu). This step ticks itself off once enabled.

3. Partner data import

Bring in the client's real feed exports from the tab.

4. Off-site backups

Generates a fresh backup-encryption key. This is not saved anywhere — copy it immediately into /etc/omissia.env on the server and restart the service.

5. Alert webhook

Generates a signing secret for a Slack / Teams / email-gateway webhook URL. The secret is not saved anywhere — copy it immediately.

6. Auditor account optional

Create a read-only account for the client. They'll be asked to set their own password on first login.

Financial-audit pack platform engine · invoices + vendors

Same reconciliation + anomaly engine, different vertical. Runs three flagship audit-analytics detectors against an AP-style invoice ledger: Benford's-Law digit distribution on amounts, threshold-clustering for "just-under" gaming of approval gates, and split-PO detection across vendor + approver windows.

Upload your own data CSV / Peppol UBL · idempotent re-upload · admin only

Pick a vendor master and / or an invoice ledger, or drop in a Peppol/UBL e-invoice XML directly. The natural-key dedup (invoice_no) means re-uploading the same file doesn't duplicate rows — useful for partner data that's still being curated.
Vendor master
columns: name, address, bank_account, tax_id, registered_at
Invoice ledger
columns: vendor_name, invoice_no, invoice_date, posted_date, amount, currency, status, approver, gl_account, department, po_no
Peppol / UBL e-invoice
one BIS Billing 3.0 / UBL 2.1 Invoice XML document per upload — the format SARS's e-invoicing framework is expected to use from 2028

Findings queue triage · drill-down · decide

Every detector finding lands here. Click a row to see the underlying invoices that drove the score; mark each one Confirmed / Dismissed / False positive. Decisions are preserved across reruns, so re-importing data doesn't reset reviewer work.
SevDetectorSubjectEvidence AmountStatusReviewerActions
Run the audit to populate.

1 · Benford's Law leading-digit distribution test

A clean population of finance numbers follows Benford's expected log distribution. A χ² above 20 at 8 degrees of freedom (the 99% critical value) is a strong manipulation signal. Vendors with their OWN χ² above 25 over ≥40 invoices are flagged individually.

Observed vs expected, leading digit 1–9

Vendors flagged

VendorInvoicesχ²Severity
Run the audit to populate.

2 · Threshold clustering "just under the approval gate"

For each approval threshold, compare invoices in the 90–99.9% just-under band against the 75–89% comparison band. A z-score above 3.0 indicates a deliberate spike. Approvers concentrated in the just-under band are listed below.

Configured approval thresholds — edit these to match your policy

LabelAmount
Loading…

Invoices clustered just under each gate

ThresholdJust-under countExpectedzSeverity
Run the audit.

Approvers concentrated below a gate

ApproverBelow gateInvoicesTotalSeverity

3 · Splitting / serial sub-threshold payments classic split-PO scheme

Same vendor + same approver + multiple invoices in a 14-day window that individually stay under Tier-1 but collectively exceed it. The most common way a director-tier sign-off is circumvented.
VendorApproverCountTotalWindowCrossed thresholdSeverity
Run the audit.

4 · E-invoice vs ledger gap SARS e-invoicing readiness

A Peppol/UBL e-invoice (uploaded on the panel above) that SARS's own network has an independent record of, but that has never once shown up in this client's own CSV/ERP feed — money the tax authority can see that never made it into the books. The inverse (a CSV invoice with no e-invoice yet) isn't flagged: e-invoicing isn't mandatory in South Africa until 2028, phased in by taxpayer size, so most CSV-only invoices today are just business as usual, not a gap.
VendorInvoiceDateAmountSeverity
Run the audit.

5 · E-invoicing readiness exposure, not a guess

There's no legitimate way for this system to know which of your vendors SARS classifies as a large VAT taxpayer — that's confidential SARS-side data. What it can show honestly: which vendors have actually sent at least one confirmed Peppol/UBL e-invoice, weighted by spend rather than headcount, since SARS's own rollout targets the largest taxpayers first (voluntary pilots from 2026 → mandatory for the largest by 2028 → mid-size after → small/micro later, no date yet).
VendorInvoicesSpendE-invoice on file?
Run the audit.