src/target_revenue/metrics.py: compute_metrics(manifest, entries, as_of)
is pure/deterministic like fold.py, reusing fold.py/conversion.py
unchanged. Returns facts/calculations/forecasts as three explicitly
separated blocks (TrustServicePRD TS-FR-5), covering the mandatory Q9
set plus the recommended velocity/forecast tier - forecasts are always
null rather than populated once a Phase has converted or velocity is
non-positive, so nothing disguises a projection as a fact.
Adds GET /phases/{id}/metrics (unauthenticated per FR-9/FR-10).
tests/test_metrics.py (6 tests) needs no Docker/Postgres and runs
under plain system Python. One new Docker-gated test in
test_ledger_hosting.py proves the hosted /metrics response exactly
matches compute_metrics() run offline against the same export.
13 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| TREV-WP-0006 | workplan | Trust Service reference implementation (PRD Phase 4b) | infotech | target-revenue | active | claude | infotech | 2026-07-29 | 2026-07-29 | 03f63e7e-c17a-4dcc-aa34-a79824dafcf3 |
Trust Service reference implementation (PRD Phase 4b)
Builds the hosted Trust Service that WP-0002 deliberately deferred: Phase
Registry, Extension Registry, hosted Target Ledger, Metrics, and Conversion
Attestation publication, serving multiple repos rather than the single
offline golden-Phase package. This is the piece explicitly named in
SCOPE.md §3 as out of scope until now.
Unblocked as of 2026-07-29: SCOPE.md §4 rule 2 required (a) WP-0003's
core extract deliverables to exist, and (b) working defaults for Longstop,
currency, recognition, and minimum evidence to be published, before full
Trust Service implementation could start. Both conditions are now met
(WP-0003 finished 2026-07-29; specs/OpenQuestions-WorkingDefaults.md
published since Stage 0). This workplan is the first to actually start
that implementation.
Why now: the midterm goal is to govern and monetize the evolution of
repos across the coulomb Forgejo org's product lines (coulomb-loop,
net-kingdom, helix-forge, the railiance-* family) — that requires a
real, multi-repo-capable Trust Service, not the single-Phase offline
library WP-0002 produced.
Does not include: accepting real payments or tracking a real Phase for
any production repo — see workplans/TREV-WP-0008-governance-and-pilot-rollout.md
for the human-gated go-live step. This workplan builds the infrastructure;
it does not turn it on for anyone's real money.
Trust Service Product Requirements Document
id: TREV-WP-0006-T01
status: done
priority: high
state_hub_task_id: "c98a1871-ae5c-4c91-b59c-88a6e4ccc193"
Produce specs/TrustServiceProductRequirementsDocument.md: scope,
stakeholders, and requirements for the hosted service, building directly
on specs/TechnicalSpecificationDocument.md §4 (component architecture)
and §3's schemas. Must state explicitly which of WP-0002's Stage 0
guarantees (determinism, offline verifiability, no Trust Service discretion
over conversion) the hosted service inherits unchanged versus which
Stage-0-only constraints (single golden Phase, no auth, no multi-tenancy)
it must now lift.
Result: specs/TrustServiceProductRequirementsDocument.md produced.
Nine stakeholders identified (including Enforcement Partner, a category
that did not exist at framework-PRD-drafting time). §3 states five
inherited-unchanged Stage 0 guarantees (determinism, offline verifiability,
no discretionary conversion authority, append-only ledger semantics, closed
core vocabulary); §4 tables ten Stage-0-only constraints that must lift,
mapped to their owning T03–T08 task, plus one flagged gap: no WP-0006 task
currently owns the Breach/Compliance Record hosting component (TSD §4.1's
2026-07-29 addition, post-dates WP-0002) — recommend either a new T09 or
folding it into T06 before implementation starts. Nine functional
requirements (TS-FR-1–9) elaborate framework PRD FR-8/9/10 for a hosted,
multi-tenant, authenticated context without redefining any schema field.
Stack and storage ADR (hosted service — distinct scope from ADR-0001)
id: TREV-WP-0006-T02
status: done
priority: high
human_accept_required: true
human_accepted_by: Bernd
human_accepted_at: "2026-07-29"
state_hub_task_id: "06eabd46-5de5-4d80-9bb7-c70ef6d80df9"
docs/adr/ADR-0001-stage0-library-stack.md explicitly scoped out hosting,
storage, and multi-tenancy decisions (its Revisit trigger names this exact
moment). Record a new ADR for: storage engine for the append-only Target
Ledger at multi-repo scale, authentication/authorization model for Phase
Registry writes, and hosting/deployment target — railiance-infra and
railiance-cluster are the existing platform-infrastructure repos in this
Forgejo org and are the natural first candidates to investigate, not
assumed by default.
Human accept gate: per the same policy as ADR-0001 — agents may draft, must not treat as accepted without explicit maintainer sign-off.
Result: Accepted 2026-07-29 by the maintainer (Bernd), no changes
requested. docs/adr/ADR-0002-hosted-trust-service-stack.md: PostgreSQL
(append-only enforced at the database-grant/trigger level, not just
convention) for storage; per-Licensor API token for write/read-grant access
control, decoupled from the existing Ed25519 per-entry signature;
railiance-cluster's existing k3s/Helm/GitOps baseline (on the
railiance-infra-provisioned HostEurope server) for hosting, rather than
new infrastructure; Python reusing src/target_revenue/ directly behind a
thin HTTP layer. T03–T08 may now build against this decision.
Phase Registry and Extension Registry hosting
id: TREV-WP-0006-T03
status: done
priority: high
state_hub_task_id: "fb9f00e5-5755-44e4-ad07-ba0dc73596b8"
Implement hosted versions of the Phase Registry and Extension Registry
components (specs/TechnicalSpecificationDocument.md §4.1), serving
multiple Phase Manifests and extension registrations across repos rather
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
id: TREV-WP-0006-T04
status: done
priority: high
state_hub_task_id: "591e87d6-3b64-4f1f-b870-edf834edc522"
Implement an authenticated append API for Target Ledger entries per Phase, preserving WP-0002's append-only, hash-chained, deterministically-foldable guarantees exactly. Any party who can compute the fold offline from an export must get the same Outstanding Target as the hosted service — this is the property to test most aggressively, since it's the one a hosted service could most easily and least visibly break.
Result: migrations/0002_ledger.sql adds ledger_entries
(GENERATED ALWAYS AS IDENTITY sequence for exact append order; trf_app
again has no UPDATE/DELETE grant). src/target_revenue/ledger.py's
append_entry(): rejects any caller-supplied previous_entry_hash/
signature outright (server-computed only), enforces phase ownership
(a Licensor may only append to its own registered Phase — TS-FR-8
isolation), serializes concurrent appends per Phase via
pg_advisory_xact_lock, computes the chain tip from the last stored entry
and signs with the Trust Service instance's own Ed25519 key
(service/keys.py, env-configured or ephemeral-with-warning for dev),
reusing validation.py's existing schema/currency checks unchanged.
service/app.py adds POST/GET /phases/{id}/ledger and an unauthenticated
GET /public-key (so an external party can verify signatures without
trusting this API's own access control at all). Fixed an unrelated route
ordering bug found while wiring this in: {phase_id:path} on the plain
GET /phases/{id} route was greedily matching /ledger-suffixed paths
too, since phase IDs contain colons but no slashes and never needed the
:path converter — switched all phase routes to plain {phase_id}.
tests/test_ledger_hosting.py (8 tests, Docker-gated): hash-chain linkage
across appends, forged-hash/signature rejection, cross-Licensor isolation,
currency-mismatch rejection, duplicate-entry-id rejection, DB-level
UPDATE/DELETE privilege checks, signature verification via the public-key
endpoint, and — the task's own highest-priority property — appending a
mixed development-credit/remission-credit/credit-reversal sequence through
the API, exporting it, and confirming fold.fold_outstanding_target over
the export reproduces the exact expected Development Credit, Remission
Credit, and Outstanding Target. Offline 36-test suite re-verified unchanged
with plain system Python; no stray Docker containers left running.
Metrics service
id: TREV-WP-0006-T05
status: done
priority: medium
state_hub_task_id: "6bab5e64-0091-4a25-906d-758310cbe723"
Implement the public metrics set from specs/OpenQuestions-WorkingDefaults.md
Q9 (Initial Target, cumulative credits, Outstanding Target, conversion
status, last checkpoint, Longstop timestamp as mandatory; velocity/forecast
as recommended, clearly labeled as forecasts per concept §14.6).
Result: src/target_revenue/metrics.py's compute_metrics(manifest, entries, as_of) — pure and deterministic like fold.py (the only input
that varies with wall-clock time, as_of, is an explicit parameter, never
read internally), reusing fold.py/conversion.py unchanged. Returns
three explicitly separated blocks per TrustServicePRD TS-FR-5: facts
(Q9's mandatory set — Initial Target, cumulative Development/Remission
Credit, Outstanding Target, conversion status, last ledger entry id,
Longstop timestamp), calculations (target satisfaction percentage,
Development/Remission Credit velocity per day, days since last material
progress), and forecasts (projected conversion date, null whenever
already converted or velocity is zero/negative — never populated as a
disguised fact). Added GET /phases/{id}/metrics to service/app.py,
unauthenticated per FR-9/FR-10. tests/test_metrics.py (6 tests, no
Docker/Postgres required, runs under plain system Python — no new hard
dependency) covers the mandatory-facts set, fact/calculation/forecast
separation, percentage correctness, the zero-material-entries case, and
as_of timezone-awareness. Added one Docker-gated test to
tests/test_ledger_hosting.py proving the hosted /metrics response
(fetched with no Authorization header) exactly equals
compute_metrics() run offline against the same exported Manifest +
Ledger. Full suite (offline 36 + metrics 6 + Docker-gated 22) verified
passing; no stray containers left running.
Conversion Attestation publication
id: TREV-WP-0006-T06
status: todo
priority: high
state_hub_task_id: "f08d3d73-4c75-4049-97d0-c27ae8513336"
Implement Conversion Attestation generation and publication as a hosted
service, preserving the non-discretionary rule from
src/target_revenue/conversion.py: the service publishes evidence of a
conversion already true from the Manifest + Ledger, never a precondition
for it. Any repo's own tooling must be able to recompute conversion status
without querying this service at all.
Multi-repo onboarding flow
id: TREV-WP-0006-T07
status: todo
priority: medium
state_hub_task_id: "44c5846e-1f37-41fe-8ac0-fc7d88628e9f"
Define and implement how a repo (e.g. coulomb-loop, net-kingdom,
helix-forge, a railiance-* repo) registers a Phase against the hosted
Trust Service: what it commits to its own repo (a Phase Manifest file,
per specs/PhaseManifestSpecification.md) versus what it submits to the
Trust Service (the registration call). Coordinate with
workplans/TREV-WP-0008-governance-and-pilot-rollout.md, which selects
the actual first repos — this task defines the mechanism, not the pilot
selection.
Conformance test suite at hosted scale
id: TREV-WP-0006-T08
status: todo
priority: medium
state_hub_task_id: "359c9c5e-a49a-40c1-82ea-2bf80e93e7d6"
Extend WP-0002's conformance suite to run against the hosted service: multiple concurrent Phases across different repos, the golden Phase example replayed through the hosted API rather than only the offline library, and a specific regression test that hosted and offline folds of the same exported ledger always agree.