Skip to content

DPI production hardening: grants service, TAP runtime, BITE store (FATFD C0-C7, v1.0.0)#5

Merged
sumerjohal merged 4 commits into
mainfrom
feat/dpi-production-hardening
Jul 8, 2026
Merged

DPI production hardening: grants service, TAP runtime, BITE store (FATFD C0-C7, v1.0.0)#5
sumerjohal merged 4 commits into
mainfrom
feat/dpi-production-hardening

Conversation

@sumerjohal

Copy link
Copy Markdown
Collaborator

Summary

Takes Pancake from POC to a tested DPI service, executed as seven FATFD quality cycles (see .audit/reports/cycle_report_20260707.md):

  • FATFD harness (.audit/): integrity validator (checks A-E), guardrails with architecture invariants + credential-security checklist, findings knowledge base, pre-commit hook.
  • Normative specs (services/specs/): CREDENTIAL_PROFILE.md (SD-JWT VC field-access grant with ODRL policy + StatusList2021 revocation) and MERKLE_LISTID.md (FieldList ListID construction with verified test vectors).
  • Grants service (services/pancake_services/grants/): hub-delegated RS256/JWKS auth (hub is the trust anchor; no local passwords, no OTP), FieldLists idempotent by Merkle construction, SD-JWT VC grant issuance / DPI-account retrieval / revocation (recorded before success; hub report when HUB_URL set), public status list, relying-party verify endpoint.
  • Signed MEAL audit ledger: Ed25519-signed, SHA-256 hash-chained lifecycle events with an OpenScience audit API (/audit/{geoid}, compliance report, chain verification). Fixes the legacy implementation/meal.py linkage and hash-order bugs with regression tests.
  • TAP runtime (services/pancake_services/tap/): per-vendor scheduler, exponential-backoff retry owned by the runtime, ${VAR} env-interpolated vendor config (missing var = hard error), frozen ingest contract sink(bite) -> None for vendor-adapter workstreams.
  • BITE store (services/pancake_services/store/): content-hash dedupe, envelope validation, GeoID/type/vendor/time queries, authenticated GET /bites.
  • Packaging + docs: Dockerfile, docker-compose (Postgres 16), .env.example, rewritten CI, services/README.md deployment guide, openapi.json export (15 paths), SPRINT_4_DATA_WALLETS.md rewritten from Indy/Aries to the shipped SD-JWT design.

Findings ledger: 5 findings discovered, 4 fixed, 1 learned (issuer key custody: env var for the sprint, vault/KMS before production).

Test plan

  • 99 tests passing (services/tests 95 + legacy regression 4), 1 intentional skip
  • ruff check services clean
  • python .audit/validate_fatfd.py passes (0 open findings)
  • End-to-end demo green: issue -> retrieve via DPI account -> verify -> revoke -> audit chain (services/demo/end_to_end_demo.py)
  • Test-issuer kit mints the 5 relying-party credentials (valid/expired/revoked/tampered/wrong-geoid)
  • CI run on this PR (same suite, Python 3.12)
  • docker compose up smoke on a Docker-equipped machine (no Docker on the dev laptop)

Made with Cursor

sumerjohal and others added 4 commits July 7, 2026 16:13
…tusList + test-issuer kit

- .audit/ harness: validator (checks A-E), guardrails, knowledge base, pre-commit hook
- services/specs: CREDENTIAL_PROFILE.md (SD-JWT VC field-access grant, ODRL, StatusList2021) and MERKLE_LISTID.md (ListID construction + verified test vectors)
- pancake_services.grants: merkle.py, sdjwt.py, statuslist.py, issuer.py
- testkit mints 5 verifier-development credentials; dev keys generated at runtime (gitignored)
- 43 tests passing, ruff clean; legacy intake tests skip cleanly when no app package

Co-authored-by: Cursor <cursoragent@cursor.com>
…rants, revocation) + signed MEAL audit ledger

- C2: FastAPI app factory, SQLAlchemy models, JWKS-cached RS256 hub-token auth, create-on-first-seen user mirroring
- C3: /fieldlists (Merkle ListIDs, idempotent, owner-scoped), /grants issue/received/revoke/status-list/verify; DPI-account credential delivery (no OTP); revocation recorded before success, hub report when HUB_URL set
- C4: MealStore with Ed25519-signed, hash-chained packets + OpenScience audit API; closes PC-2026-0001
- Legacy implementation/meal.py: fixed previous_packet_id linkage and hash-order bugs (PC-2026-0004) with regression tests
- 83 tests passing (79 services + 4 legacy regression), ruff clean

Co-authored-by: Cursor <cursoragent@cursor.com>
…erface) + BITE store with query API

- TAP: canonical adapter base, per-vendor interval scheduler, exponential-backoff retry in the runtime (adapters stay dumb), YAML config with ${VAR} env interpolation (missing var = hard error)
- Frozen ingest contract for vendor-adapter workstreams: sink(bite) -> None; production sink is BiteStore.save
- BITE store: content-hash dedupe, envelope validation, GeoID/type/vendor/time queries with pagination, authenticated GET /bites
- End-to-end test: runtime -> store -> query by GeoID
- 99 tests passing, ruff clean

Co-authored-by: Cursor <cursoragent@cursor.com>
…1.0.0

- Dockerfile + docker-compose (postgres 16) + .env.example; deployment guide in services/README.md
- CI rewritten: ruff + FATFD validator + both test suites + e2e demo + testkit smoke (Python 3.12)
- sprints/SPRINT_4_DATA_WALLETS.md rewritten from Indy/Aries to the shipped SD-JWT VC design (closes PC-2026-0003)
- export_openapi.py (15 paths) for the grant API-catalog deliverable
- demo/end_to_end_demo.py: issue -> retrieve -> verify -> revoke -> audit, all assertions green
- Final state: 99 tests, 0 open findings, cycle report in .audit/reports/

Co-authored-by: Cursor <cursoragent@cursor.com>
@sumerjohal sumerjohal merged commit 471825d into main Jul 8, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant