target-revenue/specs/TrustServiceOnboarding.md
tegwick ee4cf14cbc Define and implement multi-repo onboarding mechanism (WP-0006-T07)
specs/TrustServiceOnboarding.md defines the mechanism: a Phase Manifest
file is committed to the declaring repo (durable, independently
foldable forever) and separately registered with the hosted service;
once registered, the Ledger's live authoritative copy is the hosted
service only, not a second competing file. Licensor token bootstrapping
is explicitly out of scope here (a WP-0008-T01 governance action).

scripts/trf_onboard.py: a dependency-light CLI (stdlib urllib +
target_revenue.validation only, no FastAPI/psycopg needed to onboard a
Phase) with validate/register-phase/append-entry/status subcommands.
The Licensor token is read only from a named environment variable,
never accepted as a literal argument.

tests/test_trf_onboard.py (4 tests, no network/Docker) proves
invalid-manifest and missing-token-env cases fail before any HTTP
attempt, by monkeypatching the request function to raise if called.
tests/test_onboarding_hosted.py (1 Docker-gated test) runs an actual
uvicorn server on a real socket and drives the full
register -> append -> status round trip through the CLI as an external
repo would invoke it.
2026-07-29 22:00:34 +02:00

106 lines
7.1 KiB
Markdown

# Trust Service Onboarding: Multi-Repo Registration Mechanism
Status: Draft v0.1
Date: 2026-07-29
Workplan: `workplans/TREV-WP-0006-trust-service-implementation.md` T07
Primary artifacts: `specs/PhaseManifestSpecification.md`, `specs/TargetLedgerSpecification.md`, `specs/TrustServiceProductRequirementsDocument.md`, `docs/adr/ADR-0002-hosted-trust-service-stack.md`, `scripts/trf_onboard.py`
**Scope note:** this document defines the **mechanism** by which any repo
registers a Phase against a running hosted Trust Service instance. It does
**not** select which repos or Phases go first — that is
`workplans/TREV-WP-0008-governance-and-pilot-rollout.md` T02 (repo/Phase
survey) and T03 (draft pilot manifests), which use this mechanism rather
than redefine it. It also does not authorize any real Phase to go live —
that remains gated behind WP-0008-T05 regardless of how well this
mechanism works.
---
## 1. What a repo commits to itself vs. submits to the Trust Service
A recurring confusion this document exists to close: a Phase Manifest is
**not** solely a Trust Service database row. It has two authoritative
copies with different roles, and both are required, not just one:
| Artifact | Lives in | Role |
|---|---|---|
| Phase Manifest file (e.g. `trf/phase-<slug>.json`) | The declaring repo's own version control, committed | The repo's own durable, git-history-backed record of what it declared and when — survives independent of any Trust Service instance's uptime or even existence (TSD §1.2's offline-verifiability property applies here too: this file alone, plus its ledger export, must remain independently foldable forever). |
| The same Phase Manifest, registered | The hosted Trust Service's `phase_manifests` table (`migrations/0001_registries.sql`) | The multi-tenant, queryable, publicly-servable copy other parties (Customers, auditors, Enforcement Partners) read without needing access to the declaring repo at all. |
| Target Ledger entries | The hosted Trust Service's `ledger_entries` table only | Per ADR-0002, the Ledger's authoritative live copy is the hosted service once a Phase is registered there — a repo does **not** also maintain a second, competing ledger file post-registration (that would reintroduce exactly the "which copy is authoritative" ambiguity Stage 0's single-golden-fixture model never had to answer). A repo *may* keep periodic exports for its own archival/offline-verification purposes (§4 below), but those are copies, not a second source of truth. |
| Extension registrations, Conversion Attestation | The hosted Trust Service, per T03/T06 | Same reasoning as the Ledger. |
**Rule of thumb:** anything that must exist and remain meaningful even if
this Trust Service instance is retired, replaced, or briefly down belongs
committed to the repo (the Manifest declaration itself). Anything that
must be a single, live, multi-party-queryable authority belongs
exclusively in the hosted service once registered (the Ledger).
## 2. Licensor bootstrapping (out of band, not part of this mechanism)
Before any repo can register a Phase, its Licensor identity must already
be resolved (`workplans/TREV-WP-0008-governance-and-pilot-rollout.md` T01)
and a row must exist in the `licensors` table with an issued API token
(`migrations/0001_registries.sql`). This document assumes that step has
already happened; it is a governance action, not a mechanical one, and is
explicitly out of this task's scope. The token itself must never be
committed to the repo — it is a deployment secret (CI secret store,
environment variable at declaration time), referenced by name in the
repo's own tooling, never by value.
## 3. Step-by-step mechanism
1. **Author the Phase Manifest locally**, conforming to
`specs/PhaseManifestSpecification.md` and
`schemas/phase_manifest.schema.json`, following the shape already
established by `examples/phase-001/manifest.json`.
2. **Validate offline before doing anything else**
`python -m target_revenue.validation` equivalent via
`scripts/trf_onboard.py validate <manifest-path>` (wraps
`validation.validate_phase_manifest`, the same check the hosted
service itself runs at registration, so a rejection is caught locally
with the identical field-by-field diff rather than discovered only via
a failed network call).
3. **Commit the Manifest file to the repo** before registering it — this
preserves a git-history record of intent to declare, independent of
whether registration succeeds on the first attempt.
4. **Register**: `scripts/trf_onboard.py register-phase --url <trust-service-url> --token-env <ENV_VAR_NAME> --manifest <path>`. Performs the same offline validation as step 2 again (defense in depth — a manifest edited after step 2 but before this step must still be caught), then `POST /phases`.
5. **Append Ledger entries as commercial payments are recognized.** In
practice this step is automated by whatever billing/payment pipeline
the product line already uses, not run manually per payment —
`scripts/trf_onboard.py append-entry --url ... --token-env ... --phase-id ... --entry <path>` is the mechanism that pipeline calls, or a template for it.
6. **Monitor via the public, unauthenticated read endpoints**
`scripts/trf_onboard.py status --url ... --phase-id ...` (wraps
`GET /phases/{id}/metrics`) — no token needed for this step, since
metrics are public per FR-9/FR-10.
7. **Conversion and Attestation require no onboarding action at all.**
Per WP-0006-T06, the moment the ledger fold reaches
`Outstanding Target = 0`, conversion is already true; the Trust Service
publishes the Attestation on first observation. Nothing in this
mechanism gates on, waits for, or triggers that separately.
## 4. Offline verifiability remains intact after hosting
Any party — including the declaring repo itself, independent of the
Trust Service's continued availability — can export a Phase's current
Ledger via `GET /phases/{id}/ledger` (public) and independently recompute
Outstanding Target with `target_revenue.fold.fold_outstanding_target`
against the committed Manifest file. This is the same offline-first
property `docs/adr/ADR-0002-hosted-trust-service-stack.md` and
`specs/TrustServiceProductRequirementsDocument.md` §3 require the hosted
service to preserve, not a new guarantee invented for onboarding — this
section just makes explicit that a repo can exercise it as part of its own
routine (e.g., a periodic CI job that exports and re-verifies), not only a
theoretical possibility.
## 5. Explicit non-goals
- Selecting which of `coulomb-loop`, `net-kingdom`, `helix-forge`, or a
`railiance-*` repo registers first, or which Milestone Release qualifies
`workplans/TREV-WP-0008-governance-and-pilot-rollout.md` T02/T03.
- Resolving Licensor identity — WP-0008-T01.
- Authorizing any registration performed via this mechanism to bind real
money or a real License header change — WP-0008-T05, unaffected by this
mechanism existing or working correctly.
- A CI/CD template for automated payment-pipeline integration — a
reasonable future deliverable once a real pilot Phase's billing
pipeline is known, not invented speculatively here.