CivicPay Open Framework
A clean-room, open-source reference implementation of financial-data-governance methodology — payment reconciliation, data-quality monitoring, exception workflow, and a tamper-evident audit-evidence layer — for U.S. community banks, credit unions, and small fintechs.
Status: Pre-alpha (v0.1). Research/teaching reference, not production software.
Why this exists
Financial-sector data-integrity failures — unreconciled payments, data-quality defects, missing audit trails — can cause real consumer harm and have been the subject of significant regulatory enforcement actions across the U.S. financial sector. The institutions most exposed to these failure modes (community banks, credit unions, small fintechs) are often the least able to afford enterprise tooling. CivicPay Open Framework makes a practitioner-informed reconciliation / data-quality / audit-evidence methodology freely adoptable on synthetic data, using only open-source components.
What it is (and is not)
CivicPay Open Framework is a governance toolset, not a payment processor or core banking system. It runs entirely on synthetic data. See DISCLAIMER.md and SECURITY.md.
- Not a payment processor, money transmitter, or core banking system.
- Not Reg E / BSA / AML compliance advice.
- Not production-ready; not for real PII without an institution-specific security and compliance review.
Architecture
┌─────────────────────────────────────────────────────────────────────┐
│ 0. Enrollment & Validation (point of capture, v0.2) │
│ form / CLI → validate → dual-source gate → accept or mismatch │
└──────────────────────────────────┬────────────────────────────────────┘
│ mismatch routes below
▼
┌─────────────────────────────────────────────────────────────────────┐
│ Streamlit Dashboard │
│ (recon summary · DQ scores · exceptions · audit log · enrollment) │
├──────────────┬────────────────┬──────────────────┬───────────────────┤
│ 1. Recon │ 2. Data- │ 3. Exception │ 4. Audit- │
│ matching │ quality │ workflow │ evidence │
│ + outcome │ checks + │ priority + SLA │ hash-chained │
│ counts │ quality score │ aging + resolve │ log + export │
├──────────────┴────────────────┴──────────────────┴───────────────────┤
│ DuckDB (embedded, synthetic data) │
└─────────────────────────────────────────────────────────────────────┘
determinism (seed=) tamper-evidence (SHA-256 chain)
Layer 0 is upstream of the original four: it prevents dirty data from ever reaching the ledger, complementing layers 1–4's post-hoc detection.
- Payment Reconciliation — match inbound payment files against ledger entries; classify matched / unmatched / exception.
- Data-Quality Monitoring — completeness, accuracy, consistency, timeliness, anomaly checks; per-dataset quality score.
- Exception Workflow — priority-ranked queue, SLA aging, resolution with root-cause capture.
- Audit-Evidence Layer — append-only, hash-chained (tamper-evident) event log; exportable evidence packages.
- Enrollment & Validation (v0.2) — a point-of-capture complement to the four layers above: a constrained-input Streamlit form and CLI batch path validate candidate records, then a dual-source agreement gate (one pure-Python path, one independent SQL path) accepts a record only when both agree — otherwise it's routed into the same exception workflow for human review.
Tech stack
Python 3.11+ · DuckDB (embedded, no infrastructure) · dbt (v0.2) · Streamlit · Faker · Typer · RapidFuzz · pytest · ruff.
Install
pip install -e ".[dev]"
# Optional: dbt analytical marts (see docs/dbt.md) — not needed for core CLI usage
pip install -e ".[dbt]"
Quickstart
One command runs the full pipeline end-to-end (seed → reconcile → DQ → exceptions → audit verify):
civicpay run-all
Or step by step:
# 1. Generate deterministic synthetic data and load into DuckDB
civicpay seed --seed 42
# (Or write raw CSV/Parquet only, without loading)
civicpay seed --seed 42 --files-only
# 2. Run payment reconciliation against the ledger
civicpay recon run --batch-id BATCH-001
# 3. Run data-quality checks across all datasets
civicpay dq check --batch-id DQ-001
# (single dataset) civicpay dq check --dataset transactions
# 4. View the exception queue (sorted by computed priority, with SLA aging)
civicpay exception list --status open
# Resolve one, capturing root cause (emits an audit event)
civicpay exception resolve --id EXC-DQ-001-000001 --root-cause "stale upstream feed"
# 5. Verify the audit hash chain is intact (detects tampering)
civicpay audit verify --batch BATCH-001
# Export a tamper-evident evidence package as JSON
civicpay audit export --batch BATCH-001 --out evidence.json
# Launch the dashboard
civicpay dashboard
dbt analytical marts (v0.2)
pip install -e ".[dbt]" # dbt-core + dbt-duckdb, not installed by default
civicpay dbt run # build mart_recon_summary, mart_dq_summary, mart_exception_aging
civicpay dbt test # run the dbt schema/data tests
Runs directly against the same DuckDB file the pipelines write to — no warehouse. See docs/dbt.md for what each mart mirrors and why.
Enrollment & validation (v0.2)
# Launch the constrained-input Streamlit enrollment form
civicpay enroll
# Or validate a batch: the seeded pending_enrollments pool by default,
# or an external CSV via --file
civicpay enroll validate
civicpay enroll validate --file records.csv
Rules (program caps, term ranges, regions, dual-source tolerance) live in
config/enrollment_rules.yml. Accepted records
land in accepted_enrollments; dual-source disagreements route to the same
exception queue as recon/DQ (civicpay exception list/resolve, or the
dashboard's Enrollment & Validation section, which can also resolve a
mismatch by accepting either computed value or rejecting it for re-entry).
Data quality configuration
DQ checks are configured in config/dq_checks.yml — per-dataset check definitions (type, rule, params), type weights, and the exception-routing cap. See docs/data-quality.md for the full check catalogue.
Determinism & re-runs
Data generation and all pipelines are deterministic given a fixed --seed. Each run should use a fresh --batch-id (the audit log and exception queue are append-only; re-running the same batch id on the same DB collides on primary keys).
See docs/reconciliation.md for the reconciliation module's full technical documentation (algorithm, data model, configuration, API, test results, and operational behavior). See docs/data-quality.md for the DQ module, docs/exceptions.md for the exception workflow (priority, SLA aging, the demo backlog cohort), docs/audit.md for the audit-evidence layer (hash chaining, evidence export, and two real bugs found and fixed in it), docs/architecture.md for the module status table, and docs/methodology.md for the overall design.
Clean-room provenance
This project is developed clean-room: from public regulatory requirements, published technical standards, and original design — never from any employer's proprietary systems, code, or data. See PROVENANCE.md.
License
Apache-2.0. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file civicpay-0.1.0.tar.gz.
File metadata
- Download URL: civicpay-0.1.0.tar.gz
- Upload date:
- Size: 176.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
843f85644269541a1ce0b3b6cc6a2f81e49883285b18ebfea4d0a01f29e0dcb6
|
|
| MD5 |
1263fc3f1fc8024fec8739772442cbf0
|
|
| BLAKE2b-256 |
3f8db3871475f5d937977f65d089c12b111e069d97e15aec96191133d7609c28
|
Provenance
The following attestation bundles were made for civicpay-0.1.0.tar.gz:
Publisher:
install.yml on ChiaoAnChang/civic_pay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
civicpay-0.1.0.tar.gz -
Subject digest:
843f85644269541a1ce0b3b6cc6a2f81e49883285b18ebfea4d0a01f29e0dcb6 - Sigstore transparency entry: 2704718439
- Sigstore integration time:
-
Permalink:
ChiaoAnChang/civic_pay@8f22791a6927bd698ff9d40ffa18e54fa7b80cf4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ChiaoAnChang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
install.yml@8f22791a6927bd698ff9d40ffa18e54fa7b80cf4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file civicpay-0.1.0-py3-none-any.whl.
File metadata
- Download URL: civicpay-0.1.0-py3-none-any.whl
- Upload date:
- Size: 83.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
21165baedfad82f065be4755b993926eb677aca82eb498377c9eccea062bfe94
|
|
| MD5 |
866027b865adad82148ee83c1b78568a
|
|
| BLAKE2b-256 |
520da3d40aeeb5ea6f1b9cd98d16aacb0e81259c681267e48a3c6859ed8b1c9b
|
Provenance
The following attestation bundles were made for civicpay-0.1.0-py3-none-any.whl:
Publisher:
install.yml on ChiaoAnChang/civic_pay
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
civicpay-0.1.0-py3-none-any.whl -
Subject digest:
21165baedfad82f065be4755b993926eb677aca82eb498377c9eccea062bfe94 - Sigstore transparency entry: 2704718503
- Sigstore integration time:
-
Permalink:
ChiaoAnChang/civic_pay@8f22791a6927bd698ff9d40ffa18e54fa7b80cf4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/ChiaoAnChang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
install.yml@8f22791a6927bd698ff9d40ffa18e54fa7b80cf4 -
Trigger Event:
push
-
Statement type: