migrations/0003_attestations.sql: one row per Phase, no UPDATE/DELETE
grant for trf_app (a published attestation is permanent).
src/target_revenue/attestation.py: publish_attestation() is idempotent
(existing row returned unchanged, never regenerated) and derives
conversion_timestamp from the ledger itself via _find_conversion_prefix(),
which finds the earliest prefix where the fold reaches Outstanding
Target = 0 rather than trusting entries[-1] or wall-clock publish time -
so a later unrelated entry can never change an already-converged Phase's
recorded conversion moment. Raises NotConvertedError rather than
fabricating a conversion. Reuses conversion.generate_attestation()
unchanged. Guarded the psycopg import behind TYPE_CHECKING so the pure
helper stays testable under plain system Python.
service/app.py adds GET /phases/{id}/attestation (unauthenticated,
publish-on-first-observation).
tests/test_attestation.py (3 tests, no Docker/Postgres) proves the
earliest-crossing behavior. 6 new Docker-gated tests in
test_ledger_hosting.py cover pre-conversion 404, the core
legal-technical property that /metrics facts/calculations/forecasts
are identical whether or not /attestation was ever called, one-time
publication, signature verification, and DB-level UPDATE/DELETE
rejection.
24 lines
1,023 B
PL/PgSQL
24 lines
1,023 B
PL/PgSQL
-- WP-0006-T06: Conversion Attestation publication.
|
|
-- Depends on migrations/0001_registries.sql and 0002_ledger.sql.
|
|
|
|
BEGIN;
|
|
|
|
-- One attestation per Phase, ever. A Phase converts at most once (there is
|
|
-- no "un-converting"), so this table has no update path by design, not
|
|
-- merely by omitted grant: publish_attestation() in
|
|
-- src/target_revenue/attestation.py treats an existing row as the
|
|
-- authoritative, already-published record and never attempts to replace it.
|
|
CREATE TABLE IF NOT EXISTS attestations (
|
|
phase_id text PRIMARY KEY REFERENCES phase_manifests(phase_id),
|
|
attestation jsonb NOT NULL,
|
|
signature text NOT NULL,
|
|
published_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
GRANT SELECT, INSERT ON attestations TO trf_app;
|
|
-- Deliberately no UPDATE, no DELETE for trf_app: a published attestation is
|
|
-- a permanent historical record of an already-true fact, never subject to
|
|
-- revision (ADR-0002 compensating guardrail pattern, same as
|
|
-- phase_manifests and ledger_entries).
|
|
|
|
COMMIT;
|