Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 33 additions & 24 deletions HANDOFF.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Payment Intelligence Modules — handoff

_Last updated: 2026-05-07 17:07 +08_
_Last updated: 2026-05-07 20:40 +08_

This is the next-session entry point for `Raafet57/payment-intelligence-modules`.
Read this file first, then check live `git` / GitHub state before acting.
Expand All @@ -9,61 +9,68 @@ Read this file first, then check live `git` / GitHub state before acting.

- Repository: `https://github.com/Raafet57/payment-intelligence-modules`
- Local path on Hermes: `/Users/Shared/AgentWork/repos/payment-intelligence-modules`
- Product baseline before the current branch: `c31575c` — merge commit for PR #11, which folded SSI Control Tower into `apps/ssi-control-tower/`.
- Active feature branch for unified SSI UI integration: `feat/ssi-unified-ui-integration`
- Product baseline before the current branch: `3e71236` — merge commit for PR #12, which added the static root `/ssi` suite entry point.
- Active feature branch: `feat/ssi-public-evidence-control-tower`
- Deployment/release/tag/public announcement: **not done**

## Current branch scope

This branch adds the first unified-suite UI slice for SSI Control Tower while preserving the root static/browser-only privacy boundary.
This branch improves the folded SSI Control Tower backend module under `apps/ssi-control-tower/` using public bank SSI / wire / settlement-instruction evidence while preserving the synthetic-only privacy boundary.

Implemented shape:

- New root-suite route: `/ssi`.
- New static page: `src/pages/SsiPage.tsx`.
- SSI appears in the suite header nav and Home module grid with `Backend` status.
- The `/ssi` page documents the folded FastAPI/Jinja app posture and local run path without coupling to the backend runtime.
- No root-suite API call, iframe, storage, telemetry, external request, or clickable localhost link was added.
- README and ROADMAP route lists/docs include `/ssi` and clarify root-browser-runtime boundaries.
- Sanitized public evidence sidecar: `apps/ssi-control-tower/docs/public_ssi_field_evidence_sources.json`.
- Evidence note: `apps/ssi-control-tower/docs/public_ssi_field_evidence.md`.
- At least 10 official bank public pages were verified; the repo keeps only bank name, URL, page title, and abstract field categories.
- New `/public-evidence` Jinja page for the source/category model.
- New `/api/v1/dashboard/operator-summary` aggregate API.
- Dashboard now has five command-centre panels: today's risk, T+1 blockers, pending approvals, aging exceptions, and export readiness.
- Rule chips drill into `/exceptions?rule_id=...`; the exceptions queue honors the filter.
- New `/exceptions/{exception_id}` detail page with root cause, impacted market/currency/asset, owner, recommended action, evidence required, SLA/age/breach, approval/export context, and recent audit trail.
- New read-only `/demo` and `/demo/step/{n}` walkthrough, fully synthetic and database-write-free.
- Claude Code was used for implementation and frontend review; the final Claude frontend review returned `APPROVE` after fixing blockers.

## Modules currently in the browser suite

| Module | Route | Current posture |
| ----------------------- | -------------: | ------------------------------------------------------------------------------------------------ |
| Scrubber | `/scrubber` | Browser-only ISO 20022 XML scrubber/anonymiser. |
| Module | Route | Current posture |
| ----------------------- | -------------- | ------------------------------------------------------------------------------------------------ |
| Scrubber | `/scrubber` | Browser-only ISO 20022 XML scrubber/anonymiser. |
| Storyteller | `/storyteller` | Operator narrative and structured field projection for supported `pacs.*` / `camt.*` files. |
| IBAN Workbench | `/iban` | Validate, Build, Catalogue, and Provenance panels from bundled SWIFT IBAN Registry-derived data. |
| BIC Validator | `/bic` | Demo/snapshot-bound only; not current-production BIC Directory validation. |
| CBPR+ Readiness Checker | `/cbpr` | Local readiness/structure checks only; not certified/full XSD/MyStandards validation. |
| Payment Insights Lite | `/insights` | Local lifecycle insight over files the user provides; not live payment tracking. |
| SSI Control Tower | `/ssi` | Static entry page for the folded backend module under `apps/ssi-control-tower/`. |
| IBAN Workbench | `/iban` | Validate, Build, Catalogue, and Provenance panels from bundled SWIFT IBAN Registry-derived data. |
| BIC Validator | `/bic` | Demo/snapshot-bound only; not current-production BIC Directory validation. |
| CBPR+ Readiness Checker | `/cbpr` | Local readiness/structure checks only; not certified/full XSD/MyStandards validation. |
| Payment Insights Lite | `/insights` | Local lifecycle insight over files the user provides; not live payment tracking. |
| SSI Control Tower | `/ssi` | Static root entry page for the folded backend module under `apps/ssi-control-tower/`. |

## Verification evidence for this branch

Local gates run before handoff:

```bash
cd apps/ssi-control-tower && make test
python3 -m ruff check apps/ssi-control-tower
pnpm verify
pnpm test:e2e
git diff --check
cd apps/ssi-control-tower && make test
```

Results:

- `cd apps/ssi-control-tower && make test` passed: **106 passed**.
- `python3 -m ruff check apps/ssi-control-tower` passed: all checks passed.
- `pnpm verify` passed: lint, format check, typecheck, Vitest, privacy audit, deterministic IBAN/BIC/CBPR data checks, and build.
- `pnpm test:e2e` passed, including the new `/ssi` Playwright smoke and the privacy-boundary route loop.
- Root Vitest inside `pnpm verify`: 30 files passed / 230 tests passed.
- `pnpm test:e2e` passed: 21 Playwright tests passed.
- `git diff --check` passed.
- `cd apps/ssi-control-tower && make test` passed as a sanity check that the folded backend module was not broken.
- Static secret scan over changed/untracked files: 11 files scanned, 0 findings.
- Independent read-only Codex diff review: `APPROVE`.
- Claude Code frontend/design review: final verdict `APPROVE`.

## Boundaries to preserve

Design source:

- `DESIGN.md` remains the app-level design contract.
- Use the light fintech/practitioner visual system: spacious white cards, subtle borders/shadows, blue/cyan accents, and strong privacy-first messaging.
- Claude Code is currently the preferred frontend/design implementation agent for this app; use it for UI polish, then verify independently.

Root suite privacy/product boundaries:

Expand All @@ -74,8 +81,10 @@ Root suite privacy/product boundaries:
SSI backend module boundaries:

- `apps/ssi-control-tower/` is a separate FastAPI/Jinja backend module with its own Python environment, tests, SQLite dev data, and synthetic fixtures.
- Public SSI data must remain synthetic and masked.
- Public-source SSI evidence is category-only. Do not commit raw account numbers, IBANs, BICs, ABA/clearing codes, correspondent chains, page excerpts, retrieval hashes, or reversible redaction maps.
- Public SSI data in the app must remain synthetic and masked. Account-bearing fields must contain literal `****` when represented in fixtures.
- Real SSI data, raw account numbers, proprietary workflows, credentials, and reversible redaction maps must never be committed.
- Demo routes must remain read-only and database-write-free.

Payment/product claim boundaries:

Expand Down
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ The root suite remains static and browser-only. Backend/product-control modules

## Modules

| Module | Route | Status | What it does |
| --------------------------- | -------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Scrubber** | `/scrubber` | Available | Strip personally identifying fields from `pacs.*` / `camt.*` XML before sharing with peers or vendors. Produces a privacy-safe mapping summary. |
| **Storyteller** | `/storyteller` | Available | Turn a `pacs.002 / 004 / 008 / 009` or `camt.052 / 053 / 054` message into a plain-language narrative plus a structured field projection and quick insights. |
| **IBAN Workbench** | `/iban` | Available | Validate, build, catalogue, and trace provenance for IBANs from bundled SWIFT IBAN Registry-derived data. Builder computes MOD-97 check digits from exact-length BBAN fields; no live BIC, VOP, account existence, or reachability checks. |
| **BIC Validator\*** | `/bic` | Demo | ISO 9362 syntax checks plus a tiny bundled snapshot lookup. **Demonstration only:** bundled BIC data is not accurate/current enough for production, routing, compliance, reachability, or payment decisions. |
| **CBPR+ Readiness Checker** | `/cbpr` | Available | Browser-only AppHdr / Document namespace / CBPR+ schema-profile coverage checks, plus UETR, BIC syntax, and IBAN syntax/checksum hints. Not a certified validator or MyStandards usage-rule engine. |
| **Payment Insights Lite** | `/insights` | Available | Local lifecycle insight over ACK/NACK, `pacs.*`, and `camt.*` files you provide. Groups files by identifiers in memory; not live payment tracking, VOP, reachability, or settlement monitoring. |
| **SSI Control Tower** | `/ssi` | Backend (folded) | Static entry point for the separate FastAPI/Jinja SSI readiness and governance cockpit under `apps/ssi-control-tower/`. Not part of the root browser runtime; run locally when needed. |
| Vault | — | Planned | Planned encrypted local export bundle: user-controlled download/import, no cloud vault, no server storage, and no persistent browser storage by default. Not built yet. |
| Module | Route | Status | What it does |
| --------------------------- | -------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Scrubber** | `/scrubber` | Available | Strip personally identifying fields from `pacs.*` / `camt.*` XML before sharing with peers or vendors. Produces a privacy-safe mapping summary. |
| **Storyteller** | `/storyteller` | Available | Turn a `pacs.002 / 004 / 008 / 009` or `camt.052 / 053 / 054` message into a plain-language narrative plus a structured field projection and quick insights. |
| **IBAN Workbench** | `/iban` | Available | Validate, build, catalogue, and trace provenance for IBANs from bundled SWIFT IBAN Registry-derived data. Builder computes MOD-97 check digits from exact-length BBAN fields; no live BIC, VOP, account existence, or reachability checks. |
| **BIC Validator\*** | `/bic` | Demo | ISO 9362 syntax checks plus a tiny bundled snapshot lookup. **Demonstration only:** bundled BIC data is not accurate/current enough for production, routing, compliance, reachability, or payment decisions. |
| **CBPR+ Readiness Checker** | `/cbpr` | Available | Browser-only AppHdr / Document namespace / CBPR+ schema-profile coverage checks, plus UETR, BIC syntax, and IBAN syntax/checksum hints. Not a certified validator or MyStandards usage-rule engine. |
| **Payment Insights Lite** | `/insights` | Available | Local lifecycle insight over ACK/NACK, `pacs.*`, and `camt.*` files you provide. Groups files by identifiers in memory; not live payment tracking, VOP, reachability, or settlement monitoring. |
| **SSI Control Tower** | `/ssi` | Backend (folded) | Static root entry point for the separate FastAPI/Jinja SSI readiness and governance cockpit under `apps/ssi-control-tower/`. The backend module now includes public-evidence sourcing, command-centre panels, exception detail, and guided demo routes; run locally when needed. |
| Vault | — | Planned | Planned encrypted local export bundle: user-controlled download/import, no cloud vault, no server storage, and no persistent browser storage by default. Not built yet. |

\*The BIC module intentionally does **not** perform live BIC Directory lookup,
current bank-directory enrichment, current SEPA reachability checks, SWIFT FIN
Expand Down Expand Up @@ -62,6 +62,11 @@ banned APIs or absolute-URL `fetch` calls appear under `src/`.
`pacs.*`, and `camt.*` files the user provides in the browser. It is not live
payment tracking, settlement monitoring, VOP, SEPA reachability, or live bank
lookup.
- **SSI Control Tower:** the folded backend module uses synthetic fixtures plus a
sanitized public-evidence sidecar from official bank SSI/wire/settlement pages.
The sidecar stores only bank name, URL, title, and abstract field categories;
no account numbers, IBANs, BICs, routing codes, correspondent chains, excerpts,
hashes, or real SSI values are committed.
- **VOP / Verification of Payee:** out of scope for the offline suite because it
requires live certified EPC access.
- **Current SEPA reachability, bank address enrichment, and live BIC validation:**
Expand Down Expand Up @@ -167,6 +172,7 @@ apps/
ssi-control-tower/ # Separate FastAPI/Jinja backend module; not part of root browser runtime
app/ # Python app, routers, services, web templates
data/ # Synthetic fixtures/reference YAML only; local DBs ignored
docs/ # SSI docs including sanitized public-source evidence methodology
tests/ # pytest suite for the SSI backend module
pyproject.toml # Python dependencies owned by the nested module
Makefile # module-local test/install commands
Expand Down
2 changes: 1 addition & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Merged SSI foundation includes:
- instruction-level validation, instruction exceptions, and a unified control queue API;
- approval, export, and account-privacy hardening for the synthetic public prototype.

Follow-up scope remains: deeper product UI polish inside the FastAPI app, deployment/publication decisions, and real-data/private-lab workflows only after explicit approval.
Follow-up scope now includes a public-evidence command-centre slice inside the FastAPI app: sanitized public bank SSI/wire/settlement-instruction source pointers, `/public-evidence`, `/api/v1/dashboard/operator-summary`, five operator dashboard panels, rule-filtered exceptions, exception detail pages, and a read-only guided `/demo`. Deployment/publication decisions and real-data/private-lab workflows remain separate approval gates.

### 1. Deployment target decision

Expand Down
15 changes: 14 additions & 1 deletion apps/ssi-control-tower/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,26 @@ V2 adds a first SSI Plus-shaped source-truth layer while preserving the V1 synth

V2 privacy posture: source rejects, audit payloads, API responses, and dashboard aggregates avoid raw account values, source record keys, BDP keys, EIDs, institution names, and city values. See `docs/v2_ssiplus_source_truth_slice.md`.

## Public SSI evidence and command-centre slice

The Control Tower now includes a public-evidence methodology that uses at least 10 official bank wire/settlement-instruction pages to shape field categories without committing operational SSI values:

- `/public-evidence` renders the sanitized source list and category model.
- `docs/public_ssi_field_evidence.md` documents the evidence rule: store only bank, URL, page title, and field categories.
- `docs/public_ssi_field_evidence_sources.json` is the sanitized sidecar consumed by tests and demo mode.
- `/api/v1/dashboard/operator-summary` emits five operator panels: today's risk, T+1 blockers, pending approvals, aging exceptions, and export readiness.
- `/demo` is a read-only guided scenario from import to exception remediation, approval, and export. It is synthetic and does not write to the database.
- `/exceptions/{exception_id}` provides root cause, impacted market/currency/asset, owner, recommended action, required evidence, and recent audit context.

The public-source methodology is category-only. It does not copy account numbers, IBANs, BICs, routing codes, correspondent chains, page excerpts, or retrieval hashes into the repo.

## Tests

```bash
make test
```

The contract tests cover ingestion mapping, normalization, required-field rules, format rules, duplicate-active detection, stale checks, governance rules, exception workflows, four-eyes approvals, immutable audit triggers, readiness scoring, export filtering, and the full demo flow.
The contract tests cover ingestion mapping, normalization, required-field rules, format rules, duplicate-active detection, stale checks, governance rules, exception workflows, four-eyes approvals, immutable audit triggers, readiness scoring, export filtering, public-evidence sanitization, guided demo privacy, command-centre aggregates, exception detail pages, and the full demo flow.

## Commands

Expand Down
7 changes: 7 additions & 0 deletions apps/ssi-control-tower/app/api/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from app.api import as_dict
from app.deps import get_db
from app.models import ExceptionCase, SourceFile, SourceReject, SsiInstruction
from app.services.operator_dashboard import operator_summary
from app.services.readiness import UNRESOLVED, readiness_score

router = APIRouter(prefix="/api/v1/dashboard", tags=["dashboard"])
Expand All @@ -20,6 +21,12 @@ def get_readiness_score(session: Session = Depends(get_db)):
return readiness_score(session)


@router.get("/operator-summary")
def get_operator_summary(session: Session = Depends(get_db)):
"""Five-panel command-centre summary for the operator dashboard."""
return operator_summary(session)


@router.get("/exceptions-by-severity")
def exceptions_by_severity(session: Session = Depends(get_db)):
cases = session.query(ExceptionCase).filter(ExceptionCase.status.in_(UNRESOLVED)).all()
Expand Down
Loading
Loading