FSMA 204 food traceability: supplier data in, verifiable evidence out.
RegEngine is an API-first traceability evidence platform for food supply chains. It ingests supplier and ERP records, normalizes Critical Tracking Events (CTEs) and Key Data Elements (KDEs), evaluates versioned rules, and produces tenant-scoped records, tamper-evident audit evidence, and FDA-oriented exports.
Inflow Workbench prepares data with preflight checks, readiness scores, a fix queue, and a commit gate. Optional Jev assistance suggests CSV column mappings and missing event types; deterministic validation and authenticated tenant boundaries remain authoritative.
Website · Verify a bundle · Product description · Python SDK
This is a pre-production application with deployed public proof surfaces. The capability inventory below describes checked-in implementation and release policy, not proof of customer adoption or live configuration.
Public proof surface
You don't have to take our word for any of this — try it yourself:
- regengine.co/verify — drop an audit bundle exported from your own workspace into the verifier and confirm file-hash and Merkle-root integrity.
This README describes behavior that is visible in checked-in code, configuration, tests, and runbooks.
Current Status
- Stage: pre-production.
- Backend deploy target in checked-in Railway config: one consolidated FastAPI app in server/main.py, built by the repo-root Dockerfile.
- Frontend: Next.js App Router app in frontend/.
- Database migrations: Alembic at alembic/versions/.
- Tenant isolation posture: tenant authority is derived from authenticated principal state; caller-supplied tenant IDs are assertions only.
- Primary domain: FSMA 204 food traceability. Other regulatory, document, NLP, and graph modules exist, but FSMA ingestion and compliance are the best-evidenced product path in this repository.
What The Product Does
Implemented capabilities in the current tree. Route availability is controlled by server/router_policy.py; a module or UI page existing does not mean its API is enabled in production.
| Capability | Evidence |
|---|---|
| API key protected webhook CTE ingest | services/ingestion/app/webhook_router_v2/routes.py |
| Canonical tenant context for API-key, JWT, and ingestion RBAC callers | services/shared/tenant_context.py |
| Legacy ingestion route tenant-context migration inventory | docs/security/tenant-route-inventory.md |
| Paid endpoint subscription gate | services/ingestion/app/subscription_gate.py |
CSV template download and CSV or Excel .xlsx CTE ingest (workbook converted to CSV text on the same route) |
services/ingestion/app/csv_templates.py, services/ingestion/app/shared/xlsx_rows.py, docs/engineering/TRACEABILITY_FILE_INTAKE.md |
EPCIS 2.0 JSON and XML ingest, including the /ingest dashboard upload tab |
services/ingestion/app/epcis/router.py, frontend/src/lib/epcis-upload.ts |
| GS1 identifier check-digit validation (GLN/GTIN/SSCC) used by webhook and EPCIS ingest | services/shared/fsma_validation.py |
| Optional Jev CSV column mapping and file-CTE suggestions, confidence-based review, upload UI prompts, and operator preview/evaluation tools; automatic application defaults off | services/shared/jev/, docs/engineering/JEV_HEADER_MAPPING.md |
| Optional LlamaIndex Extract v2.5 document extraction: a fail-open second pass on bulk-upload supplier PDFs the table parser cannot read, with per-field citations, confidence and evidence; rows still go through classify, validate and human commit; operator command-line tool | services/shared/document_extract/, docs/engineering/DOCUMENT_EXTRACT.md |
| Inflow Workbench preflight, readiness, fix queue, scenario library, and commit gate | services/ingestion/app/inflow_workbench.py |
| Supplier portal preflight before persistence | services/ingestion/app/supplier_portal.py |
| Supplier CSV manifest remediation (implemented; excluded from the production router allowlist): byte-exact manifest intake, per-row validation and staging with provenance, exception/remediation cases, case-scoped single-use supplier correction links, revalidation with granular release, deterministic evidence bundles, scheduler-drained correction-link email delivery | services/ingestion/app/remediation/ |
| Buyer remediation dashboard (requires the remediation API to be enabled; manifest list, per-record case status, release and correction-link actions) | frontend/src/app/remediation/page.tsx |
| CTE persistence, hash-chain storage, and verification (legacy and canonical stores; dual-write retirement mid-cutover) | services/shared/cte_persistence/core.py, services/shared/canonical_persistence/writer.py, docs/persistence/dual-write-cutover.md |
| Compliance score reads from stored FSMA CTE data | services/ingestion/app/compliance_score.py |
| FDA-oriented CSV and evidence-bundle export routes | services/ingestion/app/fda_export/router.py |
| Request-response cases, scoped evidence package assembly, and auditor workflows | services/ingestion/app/request_workflow_router.py, services/ingestion/app/auditor_router.py |
| Recall readiness assessments, gap checklists, and recall reports | services/ingestion/app/readiness_router.py, services/ingestion/app/recall_report.py |
| EPCIS JSON-LD export and broader recall simulations (experimental routers; excluded from the production allowlist) | services/ingestion/app/epcis_export.py, services/ingestion/app/recall_simulations.py |
| Subscription-gated access and persisted usage metering; Stripe usage reporting requires an operator call | services/ingestion/app/subscription_gate.py, DESIGN_metering-billing.md |
| Tenant/admin/user/API-key management, including a sysadmin rename of an organization and the tenant row that shares its id | services/admin/app/, docs/engineering/ADMIN_ORGANIZATIONS.md |
| Persisted admin tenant provisioning | services/admin/app/routes.py |
| Tamper-evident admin audit log hashing | services/admin/app/audit.py |
| Audit-chain verification for admin audit exports | services/admin/app/audit_integrity.py |
| Passwordless email-OTP and passkey login | services/admin/app/auth/challenges_router.py, frontend/src/lib/passwordless-auth.ts |
| Public email-verification gate for free compliance tools (no-auth lead capture with rate limits, GDPR lead-erasure endpoints) | services/admin/app/tool_verification_routes.py |
| Scheduler jobs (deadline monitor, data archival, outbox drains, scheduled recall drills with persisted mock-audit drill records) and scheduler metrics surface | services/scheduler/ |
Frontend dashboard, auth, sandbox, docs, and product pages. /contact and /signup both post to POST /api/contact |
frontend/src/app/, docs/operations/LAUNCH_TRUST_PROVISIONING.md |
| Inbound email ingestion: Postmark inbound-parse webhook, Basic-Auth + per-tenant sender allowlist, CSV attachments routed through the existing CSV ingest path, claim-then-act idempotent audit trail. Built and unit-tested; not enabled in production and has no admin/self-service provisioning UI — see docs/engineering/EMAIL_INGESTION.md | services/ingestion/app/email_ingest/ |
Production Spine
ingest source record
-> preflight in Inflow Workbench
-> normalize to CTE/KDE shape
-> score readiness and route fix queue items
-> pass commit gate
-> persist tenant-scoped event data
-> evaluate rules
-> expose compliance/audit/export views
The diagram describes the Workbench workflow. Direct webhook, CSV, and EPCIS intake has route-specific validation and persistence; it does not universally pass through Workbench. Event persistence is mid-migration from a legacy CTE store to a canonical hash-chain store: some write paths still write both stores, newer paths write canonical-only, and read paths have consumer-specific cutover flags. Chain verification defaults to canonical reads; FDA CSV export v1 retains a legacy code default. Historical rollout observations are recorded in the cutover runbook; current deployment flags must be read back separately (see docs/persistence/dual-write-cutover.md). Graph, NLP, generic regulatory-intelligence, and document-ingestion modules are present, but they should not be treated as the core product contract without checking the relevant tests and deploy wiring.
Architecture
Runtime Shape
The repo still contains six service directories:
| Directory | Purpose |
|---|---|
| services/admin | tenants, users, roles, MFA, API keys, audit logs, admin routes |
| services/ingestion | webhook, CSV, EPCIS, sandbox, export, CTE persistence integration |
| services/compliance | compliance validation routes and FSMA rules JSON |
| services/graph | graph and supply-chain query modules |
| services/nlp | regulatory/document extraction modules |
| services/scheduler | scheduled jobs, job metrics, operational checks |
The repo-root Dockerfile copies all service directories and starts server/main.py with Gunicorn/Uvicorn. server/main.py mounts routers from the service directories into one FastAPI process.
The old independent service entrypoints still exist, for example services/ingestion/main.py, but the repo-root railway.toml points at the root Dockerfile.
Infrastructure
Verified from checked-in config and code:
- PostgreSQL is required. Production connection is supplied through
DATABASE_URL. - Local development stack in docker-compose.dev.yml starts PostgreSQL and Redis (Redis backs the subscription gate, rate limiting, and idempotency caching — without it authenticated ingest fails closed with 503).
- Redis is used by rate limiting, queues, session/subscription checks, and other runtime paths when configured.
- Neo4j code and health checks exist, but the default local development stack does not start Neo4j. The deploy-gating
/readinessprobe contacts Neo4j only when the graph subsystem is enabled; withNEO4J_URIset but graph routers disabled (the production default) Neo4j is reportednot_probedand never contacted. Only PostgreSQL failure returns 503 from/readiness; Redis/Neo4j errors degrade the payload but still return 200 (server/main.py). - The frontend is a separate Next.js application with its own package lock and CI workflow.
Data And Schema
- Alembic is the active schema migration system.
- Root migration config: alembic.ini.
- Migration files: alembic/versions/.
- Deploy migration runner: scripts/run-migrations.sh.
- Runtime DDL is fully owned by Alembic as of v098/v099: application boot performs no schema DDL, the boot-time RLS function definitions were dropped in favor of migration-pinned
set_tenant_context/set_admin_context, and the app role can run withoutCREATEprivilege (a startupadmin_database_init_skippedwarning is expected under least privilege). One-transaction revoke runbooks: runbooks/prod-revoke-create-after-v098.sql, runbooks/prod-least-privilege-db-role.sql. - Legacy Flyway-style SQL migrations under service directories have been removed (meta-issue #2004); scripts/check_orphan_migrations.py is a CI guard that keeps orphan migrations at zero, rejects any reintroduced top-level Flyway tree, and enforces the
alembic/sqlreference contract in both directions: analembic/sqlfile referenced by no Alembic revision fails CI (archive it under docs/archive/migrations/ instead), and a revision referencing a missing SQL file fails CI. Superseded companion SQL already archived: see docs/archive/migrations/README.md. - Per-label metered billing (v121, alembic/versions/20260912_ceb552c6d36d_v121_billing_usage_counters.py) adds a new
billingschema — the first Postgres-durable billing state in the repo; Stripe subscription/customer state otherwise lives entirely in Redis (services/ingestion/app/stripe_billing/state.py). Design, deviations, and known follow-ups: DESIGN_metering-billing.md.
Schema-related CI guards include:
- scripts/check_alembic_revisions.py
- scripts/check_tenant_id_uuid_only.py
- scripts/check_orphan_migrations.py
- ORM drift gate:
alembic checkruns in backend CI against an Alembic-head database. alembic/env.py registers all four declarative Bases (admin, agent-operator, api-key store, scheduler state) so every ORM model is compared for structural drift; raw-SQL-managed tables with no ORM model are exempt by design. - Schema parity contract: scripts/schema_parity_audit.py compares the migrated schema against the checked-in contract docs/schema/expected_schema.json — every table, including raw-SQL FSMA tables the ORM gate cannot see. A migration that changes the schema must regenerate the snapshot in the same PR or CI fails. The checked-in snapshot includes
billing.tenant_usage_countersandbilling.tenant_usage_event_ledger; schema parity is distinct from the RLS test coverage described below. - RLS regression gate scope: tests/migrations/test_rls_coverage.py only sweeps the
fsmaschema plus a curatedpublicallowlist. Tables in other schemas — including the newbilling.tenant_usage_event_ledger/billing.tenant_usage_counters
