Implement hosted Phase/Extension Registry (WP-0006-T03)
Adds migrations/0001_registries.sql (licensors, phase_manifests, extensions tables; trf_app role with no UPDATE/DELETE grant on either table, canonicalization only via a SECURITY DEFINER function), and src/target_revenue/registry.py + service/app.py: a thin FastAPI layer wrapping the existing validation.py checks with persistence and per-Licensor token auth, adding no new validation logic per ADR-0002. New optional service/service-dev dependency groups keep the core offline library dependency-free. tests/test_registry_hosting.py (7 tests, Docker-gated, auto-skip otherwise) spins an ephemeral disposable Postgres container and verifies registration, rejection, duplicate/ unknown-token handling, extension canonicalization, and two explicit database-privilege checks that the app role cannot bypass the append-only/governance-gated guarantees.
This commit is contained in:
parent
e8e8629efd
commit
7e0c62a8b5
8 changed files with 580 additions and 2 deletions
|
|
@ -108,7 +108,7 @@ thin HTTP layer. T03–T08 may now build against this decision.
|
|||
|
||||
```task
|
||||
id: TREV-WP-0006-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "fb9f00e5-5755-44e4-ad07-ba0dc73596b8"
|
||||
```
|
||||
|
|
@ -120,6 +120,29 @@ than one golden fixture. Reject non-conformant manifests/extensions at
|
|||
registration, exactly as the Stage 0 validators already do — this task
|
||||
adds multi-tenancy and persistence, not new validation logic.
|
||||
|
||||
**Result:** Implemented per ADR-0002. `migrations/0001_registries.sql`
|
||||
creates `licensors`, `phase_manifests`, `extensions` tables, a
|
||||
`trf_app` role with **no UPDATE/DELETE grant** on `phase_manifests` or
|
||||
`extensions` (database-enforced append-only, not just application
|
||||
convention), and a `set_extension_status()` SECURITY DEFINER function as
|
||||
the only sanctioned path to `canonical`/`deprecated` — canonicalization is
|
||||
therefore a recorded, attributable governance action the application role
|
||||
cannot perform via ordinary UPDATE. `src/target_revenue/registry.py` wraps
|
||||
the existing `validation.py` checks (no new validation logic) with
|
||||
persistence and per-Licensor token authentication. `src/target_revenue/service/app.py`
|
||||
exposes a thin FastAPI surface (`POST/GET /phases`, `POST/GET /extensions`).
|
||||
Added a `service`/`service-dev` optional-dependency group
|
||||
(`pyproject.toml`) so the core offline library keeps zero new hard
|
||||
dependencies. `tests/test_registry_hosting.py` (7 tests, requires Docker,
|
||||
auto-skips otherwise) spins an ephemeral, disposable Postgres container —
|
||||
never the shared state-hub `infra-postgres-1`/`custodian` instance —
|
||||
covering registration, rejection with diff, duplicate-`phase_id` rejection,
|
||||
unknown-token rejection, extension canonicalization via the governance
|
||||
function, and two explicit database-privilege tests proving `trf_app`
|
||||
cannot UPDATE/DELETE `phase_manifests` or UPDATE `extensions` directly.
|
||||
Original 36-test offline suite verified unchanged and passing with plain
|
||||
system Python (no service deps required).
|
||||
|
||||
## Hosted Target Ledger append API
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue