CC Safety Net
코딩 에이전트 CLI 안전층으로 실행 전 파괴적 git·파일시스템 명령과 비밀 파일 접근을 차단
가상화폐·현금·전자자금 이체에 대한 설명 가능한 AML 모니터링, 합성 데이터만 사용, FINTRAC 신고 시스템이 아닙니다
Explainable AML monitoring for virtual currency, cash and electronic funds transfers. Synthetic data only. Not a FINTRAC filing system.
보안HTML · PythonGitHub @siddhartha18pahari온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗The investigator workspace is live at fintrac-aml.vercel.app. No sign-in, no environment variables. The book is synthetic.
Explainable AML monitoring and regulatory reporting for virtual-currency transactions.
Detect → Investigate → Explain → Report
All data in this project is synthetic. Reports are submitted to a local mock receiver. This system is not connected to FINTRAC and must not be used to file anything. See PRIVACY.md.
8KSS/FINTRAC-LVCTR is a single HTML
page that builds a JSON-LD Large Virtual Currency Transaction Report. It is a
genuinely useful artefact — it is where the field names, nesting and code lists
in this project were reconciled from — but it starts at the end of the
compliance process:
Human already knows the transaction is reportable → fill in the form
The hard problems are all upstream of that:
Thousands of transactions
↓ which ones matter?
↓ which ones aggregate, and on what relationship?
↓ who controls the related wallets?
↓ what indicators are present, and how strong?
↓ does a compliance officer need to investigate?
↓ what did the human decide, and why?
↓ which report(s), and does the payload actually validate?
Sentinel implements that pipeline and keeps the report builder at the end of it, where it belongs. docs/LEGACY_REPO_ANALYSIS.md documents exactly what was carried over and what was deliberately left behind.
No database server, no Node toolchain, no network access required.
pip install -r requirements.txt
python run.py
That seeds a synthetic ledger on first run, then serves the console at
http://127.0.0.1:8099/ with API docs at /docs.
Sign in as l.chen / sentinel1234 (compliance officer). Other demo accounts
exercise different halves of the RBAC matrix:
| Account | Role | Can |
|---|---|---|
j.okafor | Analyst | triage alerts, add notes, escalate |
s.rahman | Senior analyst | + record filing decisions, override scores |
l.chen | Compliance officer | + run the pipeline, build reports |
d.vasquez | Approver | + approve a case and submit reports |
a.petrov | Auditor | read-only, including the audit trail |
Password for all of them: sentinel1234. It is set by DEMO_PASSWORD — change
it for any deployment with a public URL, since this file documents the default.
To regenerate the dataset:
python -m scripts.seed --customers 40 --days 45
Run the tests:
pip install -r requirements-dev.txt
python -m pytest
The Next.js app in web/ is a view of one detection run: alerts, customer
risk, the ledger, a network graph, STR drafts, triage, case notes, a rule
simulator and draft filings. Case assignment and notes stay in the browser.
It does not need Postgres.
python -m scripts.export_snapshot
cd web
npm install
npm run dev
The dev server is at http://127.0.0.1:3000/. npm run build is the production
build (next build).
The graph page embeds a self-contained HTML file built with PyVis and NetworkX
from the bundled snapshot. Node colour and size follow residual risk, nodes are
grouped by entity type, and each node has an HTML tooltip. Physics defaults to
vis.js forceAtlas2Based. Pass --solver barnesHut for the Barnes–Hut model.
python -m scripts.build_pyvis_graph
That writes web/public/graph/entity-graph.html and inlines vis-network, so the
page does not call a CDN. The file is committed. Regenerate it after
python -m scripts.export_snapshot when the book changes. The same page can
switch to the in-app graph, which clusters by type, focuses a search hit,
dims non-neighbours, filters by risk and type, and highlights a path to a
sanctions-screening entity.
The geography page uses a Natural Earth world atlas committed at
web/public/geo/countries-50m.json (world-atlas 2). It does not need an API key.
The workspace now also has:
/api/v2/* in the Next.js app is typed with zod and reads the bundled snapshot, so npm run build in web/ needs no environment variables. If OPENAI_API_KEY or AI_GATEWAY_API_KEY is absent, the copilot still routes the same tools and cites the notes.
The FastAPI service mirrors that surface at /api/studio/* (OpenAPI at /docs): alerts, cases, entities, graph, stats, simulation, and chat. The Python chat uses LangChain when langchain-core is installed (see requirements-dev.txt) and the same deterministic router when no model key is set. Statistics and the book simulator live in app/services/statistics.py and app/services/book_simulator.py.
Two Vercel projects, documented in docs/DEPLOY_VERCEL.md.
| Setting | Value |
|---|---|
| Root directory | web |
| Framework | Next.js |
| Build command | next build |
| Environment variables | none |
Import the repository, set the root directory to web, and deploy. Pages and
/api/* read web/src/data/snapshot.json.
The FastAPI app runs as a single Python serverless function serving both the
API and the vanilla console. Root directory is the repository root, not web.
Three things are worth knowing before you start, because each one produces a demo that looks like it works and quietly does not:
DATABASE_URL). The app
refuses to start on a serverless host with non-durable storage rather than
pretending, unless you opt in with ALLOW_EPHEMERAL_STORAGE=1.scikit-learn from requirements.txt; the anomaly layer abstains cleanly,
labels itself 1.0-unavailable, and every rule-based control keeps working.GET /api/health reports which mode is live:
{ "storage": { "durable": true }, "capabilities": { "anomaly_detection": true } }
Provision a database without demo data:
DATABASE_URL="postgresql+psycopg://..." python -m scripts.provision
For anything operational rather than demonstrative, prefer a container with a scheduler (Cloud Run, Fly.io, Render) over serverless: the detection pipeline is a batch job, and it belongs on a cron rather than an HTTP request. No code changes are needed — only where you run it.
Sign in and open the case for Maple Digital Imports Ltd.
The company declared CAD 20,000 of monthly crypto activity at onboarding. Over one day it receives CAD 21,600 from six distinct wallets, moves CAD 10,100 straight back out to a wallet tagged as a high-risk exchange, and shares a beneficiary with an unrelated customer.
Every layer has something to say about it:
| Layer | Finding |
|---|---|
| 24-hour rule | receipts aggregate to CAD 24,999.99 on a shared beneficiary → LVCTR obligation, due in 5 working days |
| Rules | fan-in, near-threshold accumulation, baseline deviation, rapid pass-through, high-risk counterparty, shared beneficiary, chain hopping |
| ML | behavioural anomaly in the top percentile of the population, with feature attributions |
| Graph | the network, the high-risk counterparty and the shared beneficiary, plotted |
| Copilot | a cited STR narrative that passes the unsupported-claim verifier |
| Report | an LVCTR payload that validates clean at all four local levels |
| Controls | the case cannot be closed unfiled, the owner cannot self-approve, and the submitted report cannot be rebuilt |
Full script: docs/DEMO_SCENARIOS.md.
ingestion ──► CAD valuation ──► 24-hour aggregation ──► rules engine
(snapshotted) (deduplicated) (versioned)
│
audit ◄── mock receiver ◄── validation ◄── LVCTR builder │
▲ ▲ ▼
└──────── case management ◄── human review ◄──── risk score
(+ graph, + anomaly)
DATABASE_URL)web/, reading a bundled snapshot. Zod studio routes, a LangChain.js copilot with a no-key fallback, and WebGL force graphs/api/studio over the same snapshot, with a Python LangChain copilot that degrades to deterministic tool routingMore detail: docs/ARCHITECTURE.md.
These are deliberate, and each one is enforced or documented rather than assumed:
submission_endpoint is hard-guarded to mock; anything else raises.fintrac-sentinel/
├── app/
│ ├── config.py regulatory parameters and deployment settings
│ ├── models.py ORM: customers, wallets, transactions, cases, reports, audit
│ ├── security.py password hashing, tokens, the RBAC matrix
│ ├── audit.py append-only hash-chained trail
│ ├── rules/ aml_rules.yaml — the rule catalogue
│ ├── schemas_json/ lvctr.schema.json
│ ├── services/ one module per pipeline stage (see services/__init__.py)
│ ├── routers/ the HTTP API
│ └── static/ the investigator console (no build step)
├── scripts/
│ ├── generate_synthetic.py scenario-driven dataset generator
│ ├── seed.py seed + full detection run
│ └── export_snapshot.py detection run → web/src/data/snapshot.json
├── web/ Next.js investigator workspace (Vercel root: web)
├── tests/ compliance regressions first, including cash and wires
└── docs/
| Document | Contents |
|---|---|
| ARCHITECTURE.md | pipeline stages, boundaries, scaling notes |
| DATA_MODEL.md | tables, invariants, decimal and time conventions |
| AML_RULES.md | every rule, its parameters, and its tuning history |
| FINTRAC_MAPPING.md | canonical model → LVCTR JSON-LD, field by field |
| LEGACY_REPO_ANALYSIS.md | what was reused from the reference repo, and what was not |
| MODEL_CARD.md | the anomaly model: intended use, limitations, governance |
| SECURITY.md | RBAC matrix, controls, what a real deployment must add |
| PRIVACY.md | synthetic-data policy and PII handling |
| DEMO_SCENARIOS.md | every planted scenario and what should fire |
| DEPLOY_VERCEL.md |
Always verify current requirements before implementing regulatory logic. The logic here was written against:
The payload format follows the 2021 JSON-LD structure encoded in the reference repository. A reporting entity must reconcile every field against FINTRAC's current technical documentation before filing anything.
This project is released under the MIT License — see LICENSE.
8KSS/FINTRAC-LVCTRThe reference repository 8KSS/FINTRAC-LVCTR
is licensed GPL v2, so it is worth being precise about what was and was not
taken from it.
Not taken: any source code. That project is a single self-contained HTML page with inline JavaScript; this one is a Python/FastAPI application with a separate front end. No file, function or block was copied or translated.
Taken: the shape of FINTRAC's report format — field names, object
nesting, $id/$ref conventions, code-list values and the field length and
type constraints. These originate in FINTRAC's own technical specification for
the LVCTR upload format; the reference repository is where they were
conveniently transcribed, and it is credited for that throughout
docs/LEGACY_REPO_ANALYSIS.md and
docs/FINTRAC_MAPPING.md. Everything derived from it
is confined to app/services/fintrac_mapper.py and
app/schemas_json/lvctr.schema.json.
A data-interchange format is an interface specification, not an expressive work, and reimplementing one independently is not generally held to create a derivative work. That is the basis for licensing this project under MIT rather than GPL v2. It is a considered position, not legal advice — anyone redistributing this, or building on it commercially, should form their own view.
The reference repository deserves the credit either way: it is the artefact that made the 2021 LVCTR format legible to people outside the reporting entities that already had it working.
| Next.js workspace and the FastAPI console |