Lalabase
티켓·문서·근무시간·고객대화를 한 곳에 모아 KI로 검색, 소프트웨어 기업 고객 프로젝트용, 오픈소스로 자체 서버·독일 클라우드에 배포
수익 전 FSMA 204 기록 관리 소프트웨어, 무료 FTL·CTE·KDE·TLC 검사 제공, FDA 준수일은 2028년 7월 20일
Pre-revenue FSMA 204 recordkeeping software. Free FTL, CTE, KDE, and TLC checkers. The FDA compliance date is July 20, 2028. Not legal advice.
비즈니스Python · TypeScriptGitHub @regengine온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기API-first FSMA 204 food traceability: supplier data ingestion, Inflow preflight, CTE/KDE validation, tamper-evident audit evidence, recall readiness, and FDA-oriented exports. Optional Jev-assisted CSV mapping.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗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.
You don't have to take our word for any of this — try it yourself:
This README describes behavior that is visible in checked-in code, configuration, tests, and runbooks.
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 |
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.
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.
Verified from checked-in config and code:
DATABASE_URL./readiness probe contacts Neo4j only when the graph subsystem is enabled; with NEO4J_URI set but graph routers disabled (the production default) Neo4j is reported not_probed and never contacted. Only PostgreSQL failure returns 503 from /readiness; Redis/Neo4j errors degrade the payload but still return 200 (server/main.py).set_tenant_context / set_admin_context, and the app role can run without CREATE privilege (a startup admin_database_init_skipped warning is expected under least privilege). One-transaction revoke runbooks: runbooks/prod-revoke-create-after-v098.sql, runbooks/prod-least-privilege-db-role.sql.alembic/sql reference contract in both directions: an alembic/sql file 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.Schema-related CI guards include:
alembic check runs 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.billing.tenant_usage_counters and billing.tenant_usage_event_ledger; schema parity is distinct from the RLS test coverage described below.fsma schema plus a curated public allowlist. Tables in other schemas — including the new billing.tenant_usage_event_ledger / billing.tenant_usage_counters (v121) — are not examined by this gate. The v121 migration enables and FORCEs RLS with a real get_tenant_context() predicate on both tables (code-reviewed), but that posture is not CI-locked the way fsma.* tables are, and there is no dedicated tests/migrations/test_v121_*.py migration test (unlike v111/v120).FSMA rule evaluation has both advisory and blocking modes.
RULES_ENGINE_ENFORCE.POST /validate endpoint derives its verdicts from the same versioned rules engine (services/compliance/app/routes.py), not a local field check. Evaluation there is advisory (nothing is persisted), tenant identity comes from the authenticated API key rather than the payload, and engine no-verdict outcomes fail closed: valid=false with a NO_VERDICT error, or 503 when the rules database is unavailable. Golden tests: tests/compliance/test_validate_rules_engine_golden.py.Do not assume every ingestion path rejects all non-compliant records by default. Check the deployed RULES_ENGINE_ENFORCE setting and route-specific tests before treating a tenant path as blocking.
Verified controls in the codebase:
request.state.api_key, and ingestion RBAC stores the accepted principal on request.state.principal.app.tenant_id) is converged on the canonical set_tenant_guc / set_tenant_guc_if_uuid helpers in services/shared/tenant_context.py; the adhoc-tenant-guc-set-config Semgrep rule in .semgrep/tenant-trust.yaml fails CI (.github/workflows/security.yml) on inline set_config('app.tenant_id', ...) call sites. Two deliberate session-scoped exceptions set the GUC through the SQL set_tenant_context() function instead: services/admin/app/models.py and services/ingestion/regengine_ingestion/storage/database.py. The Semgrep rule is defense-in-depth; the fail-hard RLS predicate remains the enforcement layer.DATABASE_URL and roles and aborts when either is SUPERUSER, BYPASSRLS, or has an unknown posture. remains required deployment evidence, not an opt-out switch.Tenant-scoped HTTP handlers must use authenticated principal state as the source of tenant authority. Path, query, header, and JSON body tenant_id values are treated as caller assertions only; conflicts with the authenticated tenant fail closed with 409 E_TENANT_MISMATCH. Missing principal or tenant context fails with 401 E_NO_PRINCIPAL or 401 E_NO_TENANT. The current legacy ingestion route inventory is maintained in docs/security/tenant-route-inventory.md.
Subscription-gated paid routes also fail closed: missing or inactive subscriptions return 402, and Redis/circuit uncertainty returns 503 because the service cannot confirm entitlement state.
Known authentication caveat: two login/session code paths (passwordless cookie sessions and the legacy Supabase-session flow in proxy.ts) coexist in the frontend. Treat auth behavior as code-and-test verified, not marketing-copy verified.
Prerequisites:
pyproject.toml declares >=3.11,<3.13.Backend setup:
python3 -m venv venv
source venv/bin/activate
pip install --require-hashes -r requirements.lock
export POSTGRES_PASSWORD=regengine
docker compose -f docker-compose.dev.yml up -d
export DATABASE_URL="postgresql://regengine:${POSTGRES_PASSWORD}@localhost:5432/regengine"
export ADMIN_DATABASE_URL="postgresql://regengine_sysadmin:${POSTGRES_PASSWORD}@localhost:5432/regengine"
export MIGRATIONS_DATABASE_URL="postgresql://regengine_owner:${POSTGRES_PASSWORD}@localhost:5432/regengine"
export REDIS_URL="redis://localhost:6379/0"
./scripts/run-migrations.sh
Mint a local test API key against this stack (seeds the test tenant and its
trialing billing status too, so subscription-gated routes work):
./venv/bin/python scripts/create_test_api_key.py
The raw key is never printed in full. It is written once to
~/.regengine/test-api-key (mode 0600, override with --key-file); load it
with export REGENGINE_TEST_API_KEY="$(cat ~/.regengine/test-api-key)" and
pass it in the X-RegEngine-API-Key header.
In development the backend validates DB-backed keys only when the server
process runs with ENABLE_DB_API_KEYS=true.
To exercise the full customer experience against this stack — provisioning a
tenant and API key, activating billing, ingesting from a simulated customer
system, and verifying evidence — run the customer-journey harness in the
inflow-lab repo. Provide a
pre-provisioned, tenant-bound REGENGINE_API_KEY; automated demo callers may
not mint live credentials. The harness seeds billing:tenant:{tenant_id} in
Redis so the subscription gate passes.
Run the persisted Inflow-to-RegEngine proof when you need real local evidence instead of DB-free simulation:
DATABASE_URL="postgresql://regengine:${POSTGRES_PASSWORD}@localhost:5432/regengine" \
./venv/bin/python scripts/verify_inflow_to_regengine_e2e.py \
--output-dir /tmp/regengine-inflow-e2e
Run the consolidated backend:
source venv/bin/activate
uvicorn server.main:app --reload --port 8000
Run an individual legacy service entrypoint when needed:
source venv/bin/activate
uvicorn services.ingestion.main:app --reload --port 8002
Frontend setup:
cd frontend
npm install
npm run dev
Backend:
source venv/bin/activate
pytest
Ingestion full suite, matching the xdist step of the CI hard gate (the CI job additionally runs services/ingestion/tests/remediation/ single-process against a dedicated migrated Postgres database):
source venv/bin/activate
pytest services/ingestion/tests --dist=loadfile -n auto -q --no-cov
Frontend:
cd frontend
npm run lint
npm run test:run
Security and tenant-boundary checks:
python3 -m pytest services/shared/tests services/ingestion/tests services/admin/tests services/compliance/tests -q --no-cov
python3 -m pytest --collect-only -q
semgrep --config=.semgrep/tenant-trust.yaml --error .
Notes:
.env is loaded by BaseServiceSettings; developer-specific values can affect config-default tests. CI runs from a clean environment.TestClient and do not skip on connection errors. A live golden-corpus smoke is opt-in via REGENGINE_LIVE_SMOKE=1 and fails, never skips, when the target stack is unreachable.REMEDIATION_TEST_SUPERUSER_DSN/REMEDIATION_TEST_APP_DSN; they skip locally without one. CI sets REGENGINE_REQUIRE_DB=1, which turns an unreachable database into a hard failure instead of a skip.Main workflows live in .github/workflows/.
Backend CI (.github/workflows/backend-ci.yml) includes:
services/sharedalembic check across all registered ORM Bases, against an Alembic-head database)REGENGINE_REQUIRE_DB=1 so an unreachable database fails the gate instead of skippingtests/shared/test_*_live.py file (glob, not an explicit list) runs against an Alembic-migrated scratch Postgres on every PR and nightly, with skips treated as fatal — added after two incidents where live-DB tests silently skipped in CI and regressions reached production (#2658)ci-status gateBackend and frontend CI also run nightly on a cron schedule, plus manual workflow_dispatch. Because the push/pull-request triggers are path-filtered, stretches of merges that miss the filters leave gates unexercised; the nightly run surfaces gate drift on main as a red run within 24 hours. Scheduled runs use their own concurrency group so a nightly cannot cancel an in-flight push-triggered run.
The security workflow (.github/workflows/security.yml) separately runs blocking Semgrep gates (the OWASP top-ten and security-audit registry rulesets plus the repo's tenant-trust rules — zero blocking findings allowed), gitleaks and detect-secrets secrets scanning, and a workflow tool-pinning gate that rejects non-SHA-pinned action refs and unpinned semgrep/pip-audit/Railway-CLI installs across every workflow file in .github/workflows/; these run outside the backend ci-status gate.
Frontend CI is separate in .github/workflows/frontend-ci.yml.
SDK CI (.github/workflows/sdk-ci.yml) is path-filtered to regengine/**, tests/sdk/**, and the workflow file itself. It installs the SDK package into a clean venv (pip install ./regengine, plus pytest, pytest-asyncio, httpx, and requests — no backend dependency tree) and runs tests/sdk/ from outside the repo root with PYTHONPATH cleared, so the installed package is exercised rather than the source tree. The route-contract test in that suite requires FastAPI, skips in the clean venv, and runs in the full backend suite instead.
Verified deployment files:
requirements.lock, runs Alembic migrations through scripts/run-migrations.sh, and starts server.main:app./readiness as the healthcheck.pip install -e ./regengine.RegEngineClient.EXPERIMENTAL_METHODS in regengine/client.py. The client cannot create records and has no per-category FTL lookup.regengine-verify CLI (regengine/verify_records.py) verifies record hashes online or offline. The separate public Merkle bundle verifier served at regengine.co/sdk/verify_chain.py is checked in at frontend/public/sdk/verify_chain.py.These are current repo facts, not speculation:
api_keys auth tables, and the agent-operator
tables (ingestion_runs, ingestion_run_receipts, agent_artifacts,
agent_artifact_reviews) — see server/main.py startup. Extend that
coverage deliberately if more ORM surfaces become part of the production
contract; ORM surfaces outside these three Bases are not boot-checked.CanonicalEventStore defaults to writing both the canonical hash-chain store (fsma.traceability_events) and the legacy store (fsma.cte_events); several newer ingest routes intentionally write canonical-only. Chain verification reads the canonical store by default since #3039 (code default flipped 2026-09-02; CHAIN_VERIFY_READ_CANONICAL=0 is the emergency rollback — the canonical verifier recomputes event digests from row content, which the legacy verifier cannot). The FDA v1 recall export retains a legacy code default, with canonical reads controlled by FDA_EXPORT_V1_READ_CANONICAL. The cutover runbook records earlier production rollout observations; verify the current deployed flag separately before asserting live read behavior. CI enforces dual-write parity and legacy-vs-canonical golden equivalence in tests/invariants/; plan, read-path inventory, and never-do list live in the same doc.docs/PRODUCT_DESCRIPTION.md — canonical positioning and capability availability.
docs/engineering/JEV_HEADER_MAPPING.md — optional CSV suggestions, review policy, privacy defaults, and evaluation tools.
docs/engineering/DOCUMENT_EXTRACT.md — optional document data extraction (LlamaIndex Extract v2.5 on supplier PDFs): request flow, failure modes, data handling, configuration, command line.
docs/engineering/TRACEABILITY_FILE_INTAKE.md — Excel .xlsx on the CSV ingest route, the dashboard EPCIS 2.0 upload, and X12 944/945 warehouse advices: routes, field mapping, and rejection rules.
frontend/README.md — current UI surfaces and consolidated-backend development setup.
2026-09-04 GitHub issue review and rollout — fixes, validation, and outstanding provisioning.
DESIGN_metering-billing.md — per-label metered billing: schema, the persist_event/persist_events_batch usage-counting hook, Stripe Billing Meters reporting, API surface, and documented deviations/follow-ups (see also the Data And Schema and Important Limitations sections above).
docs/engineering/EMAIL_INGESTION.md - inbound email (Postmark) ingestion: how it works, config, rollout status, and known limitations.
ARCHITECTURE.md - current runtime shape, system map, and debt register.
RegEngine is proprietary, source-visible software — all rights reserved by RegEngine LLC (LICENSE). This repository is private. Transparency and audit are served by the public proof surface above, which requires no source access; where source is shared it is shared under licence, not as an open-source project: viewing the source is welcome, but no rights to use, modify, or redistribute are granted. External pull requests are not accepted (CONTRIBUTING.md). Licensing inquiries: [email protected].
Before changing this repository's visibility, work through docs/security/PRE_PUBLIC_CHECKLIST.md. Confidential business material is currently tracked in-tree, and
git rmremoves it fromHEADonly — every prior revision stays readable.
Permissive exceptions — the public verifier tools are Apache 2.0 (declared in LICENSE) so anyone can use, copy, and embed them: the Merkle bundle verifier (frontend/public/sdk/verify_chain.py) and the regengine-verify per-record CLI (regengine/verify_records.py). Inflow Lab, the integration simulator, is Apache 2.0 in its own repository for the same reason.
Before changing schema, ingestion, auth, tenant isolation, or audit logic, start with:
Keep changes scoped. Do not treat old issue text, stale docs, or marketing copy as proof of current behavior; verify against code, tests, and GitHub Actions. If docs and code conflict, fix or call out the conflict in the PR.
| 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/ |
billingADMIN_DATABASE_URLREGENGINE_REQUIRE_RLS_ENFORCEMENT=1TenantContext before route handlers read or write tenant data.POST /v1/admin/tenants persists a TenantModel row with active status before returning the tenant UUID.REGENGINE_E2E_MODE plus REGENGINE_E2E_EMAIL_OUTBOX; hard-blocked in production by services/admin/app/e2e_safety.py), codes are also written to a Playwright outbox file. If RESEND_API_KEY is unset outside E2E mode, codes are not delivered at all — the challenge flow drops the code with only an error log. Logout revokes the opaque browser session server-side, not just client-side cookie clearing.user_emails row with a keyed email fingerprint, an active user, and an organization_memberships row (_load_valid_identity in services/admin/app/auth/challenges_router.py). Ineligible addresses receive the same accepted challenge response but no email (logged as auth_challenge_email_suppressed_ineligible_identity). Identity rows are provisioned at invite acceptance via services/admin/app/auth/identity_helpers.py; users predating that provisioning are backfilled by Alembic v094 (alembic/versions/20260715_feb267263e0a_v094_passwordless_identity_backfill.py), which hard-fails in production if AUTH_OTP_HMAC_SECRET is unset./api/v1/tools (services/admin/app/tool_verification_routes.py): email in, 6-digit code out, verified leads stored in tool_leads, plus public GDPR lead-erasure endpoints. Endpoints are rate limited. Tool-access JWTs are signed with a dedicated TOOL_ACCESS_SECRET that is never shared with session keys; startup raises in production if it is unset. Tool-access JWTs expire after 24 hours and the /api/tools/check-access gate verifies that expiry on every check; the optional TOOL_ACCESS_TOKEN_EXPIRE_HOURS env var can only shorten the lifetime (values above 24 hours fall back to the default) and is never required./api/v1/remediation/supplier (services/ingestion/app/remediation/supplier_router.py): buyer-issued correction links carry the raw token in the URL fragment, which browsers never send to the server; the JSON endpoints receive the token in the request body, so it never appears in a URL path or query string and cannot land in access/proxy logs. Only token hashes are stored (services/ingestion/app/remediation/tokens.py); exchange is single-use and mints one 30-minute session; token and session failures return uniform error bodies, with deny reasons for known tokens recorded in the audit log rather than the response; the JSON endpoints are rate limited (the static /form page is not). Tenant identity is read only from the server-side token row — supplier request bodies define no tenant field./api/client-errors (frontend/src/instrumentation-client.ts, frontend/src/app/api/client-errors/route.ts): 10% of page loads with a per-load report cap, query strings stripped client- and server-side, payloads carry no user identifiers, per-IP rate limited (per server instance), and the route always responds 204/429 with no body. The beacon keeps browser Sentry out of the frontend instrumentation entry point, but @sentry/nextjs is still statically imported by client error-boundary components (for example frontend/src/app/error.tsx), so do not treat the client bundle as third-party-SDK-free.ingest_events() helper that requires a tenant-bearing payload because it has no request context. HTTP and router callers should derive that payload tenant from authenticated tenant context.pending rows are never drained — draining them would revoke links buyers already shared out of band. At send time the drainer re-validates the referenced token and follows the buyer reissue path, so a delivered email never carries a revoked or superseded link./usage* routes in routes.py) counts every accepted TraceabilityEvent toward a tenant's usage unconditionally (CanonicalEventStore.persist_event/persist_events_batch, on by default), but reporting that usage to Stripe is not automatic:
report_tenant_usage_to_stripe. Usage accumulates in billing.tenant_usage_counters until an admin/operator calls POST /api/v1/billing/usage/report for a tenant. A periodic scheduler job is a documented, unbuilt follow-up (DESIGN doc §5.1/§7.3) — it is not wired into services/scheduler/service.py.POST /api/v1/billing/usage/opt-in assumes a Stripe Billing Meter named regengine_label_events already exists in the Stripe Dashboard and that STRIPE_PRICE_METERED_LABEL_EVENTS is set; nothing in this repo creates either, and opt-in returns 500 if the env var is unset.services/ingestion/tests/test_billing_usage_core.py, test_billing_usage_reporting.py, test_billing_usage_routes.py, services/shared/tests/test_canonical_persistence_meter_usage.py) run against a fake SQLAlchemy session and a monkeypatched stripe.billing.MeterEvent.create — no test exercises a live Postgres or a live Stripe API call, and (per the Data And Schema section above) the v121 migration has no dedicated migration test and its new tables sit outside the automated RLS coverage gate.GET /api/v1/billing/usage's billing_period_start/_end are a local UTC-calendar-month approximation, not the tenant's real Stripe invoice anchor (deviation documented in DESIGN doc §3.3/§7.2). This does not change what Stripe actually bills — Stripe's own Meter aggregates usage into the customer's real invoice period regardless of local bucketing — only what the endpoint displays as the "current period".GET /usage, POST /usage/report, POST/DELETE /usage/opt-in).ASYNC_PROCESSES.md - async and background processing notes.
CANONICAL_OWNERSHIP.md - module ownership notes.
SECURITY.md - security posture.
docs/security/tenant-route-inventory.md - tenant-scoped ingestion route inventory.
docs/persistence/dual-write-cutover.md - CTE dual-write retirement plan and read-path cutover inventory.
docs/architecture/agent-org.md - agent organization v1 (pods, dev-only inboxes, scoped keys, suppression gate): what's real today and what isn't. Full design rationale in DESIGN_agent-org.md.
CHANGELOG.md - change history.
CONTRIBUTING.md - contribution workflow.
docs/runbooks/ - operational runbooks.