specs/PhaseLifecycleUseCases.md enumerates all nine use cases from the workplan systematically, grounded in the actual schema, code, and the three real pilot-candidate manifests rather than abstractly. Two findings surfaced beyond the original scope: first-Phase and successive-Phase provenance turn out to be one shared modeling question (both feed T02), and breach-record publication already has a decided Operator+ rights tier per the Control Plane concept doc while extension registration/canonicalization does not — recorded as an explicit open question for WP-0014-T01 instead of an assumption. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
11 KiB
Phase Lifecycle Use Cases
workplans/TREV-WP-0012-phase-provenance-and-policy-modeling.md T01.
Written after using the Control Plane UI (WP-0009-T04) for the first time
surfaced that the Phase Manifest schema and the UI built on top of it
don't yet cover several use cases the framework's own normative documents
already commit to. This document enumerates those use cases systematically
— as a map of what exists, what's missing, and what's out of scope by
design — before T02–T05 turn any of the gaps into schema or UI
decisions.
This is a documentation-only artifact. It does not itself change any schema, code, or UI.
1. First Phase ever declared for a repo
The common case today: a repo has never had a Phase before, and one is declared for its first governed Milestone Release.
Real examples (examples/pilot-candidates/*/manifest.json,
specs/PilotPhaseCandidateSurvey.md): net-kingdom-local-identity,
railiance-vergabe-teilnahme, info-tech-canon-service-surface. All
three currently use a trsl:phase:draft-... id — none has actually been
registered against the hosted Trust Service. That's intentional: no real
Phase go-live is authorized yet
(workplans/TREV-WP-0008-governance-and-pilot-rollout.md T05).
What the manifest captures today: milestone_release.name (a free-text
label, e.g. "vergabe-teilnahme-v1 (RAILIANCE-WP-0002/RAILIANCE-WP-0014)")
and milestone_release.source_revision (a bare short SHA, e.g.
"398b0fe"). What it does not capture: which repo, or which Forgejo
instance, that revision belongs to. The workplan references embedded in
the name string are the only thing tying a Phase back to its source
today, and they're prose, not structured data — a human convention, not
something the schema or the UI can rely on.
Gap → WP-0012-T02 (repo identification fields).
2. A successive Phase on a repo that already had an earlier Phase
FR-11 (specs/ProductRequirementsDocument.md) requires the framework to
"support multiple independently governed, sequential Phases over a
software's lifetime, each identifying its base release, included change
set, Milestone Release, Initial Target, Future License, degeneration
policy, and ledger." Rule 7 (specs/TargetRevenueFrameworkCore.md §4)
then requires that rights already granted by an earlier converted
Milestone Release can never be withdrawn or restricted by a later Phase.
None of this is modeled in the schema today. There is no field
anywhere in phase_manifest.schema.json for "the Phase this one
succeeds" or "the base release this Phase's change set is measured
against." A second Phase for the same repo today would look, structurally,
identical to a completely unrelated repo's first Phase — the only
difference would be human-readable text in milestone_release.name.
This matters concretely: railiance-vergabe-teilnahme's candidate manifest
already names two workplans (RAILIANCE-WP-0002/RAILIANCE-WP-0014)
inside a single Milestone Release's name — a preview of exactly this
use case arriving before the schema was ready for it.
Open question this use case raises, not yet answered: what does a first-ever Phase put in a "base Phase" field that a successive Phase would use? A null/absent value works structurally, but the Trust Service's fold and validation logic downstream should treat "no prior Phase" and "prior Phase exists" as two branches it explicitly recognizes, not an accidentally-empty string.
Gap → WP-0012-T02 (repo identification fields, same task — the two questions are tightly coupled: "which repo" and "which prior Phase for that repo" are really one provenance model, not two).
3. Operator registers a Phase; Contributor proposes; Operator/Admin reviews
Already built (workplans/TREV-WP-0009-target-revenue-control-plane.md,
all four tasks done). Included here for completeness and cross-reference,
not to redesign it:
- Rights model: Viewer / Contributor / Operator / Admin, ordinal via
registry.RIGHTS_TIERS/has_right()(specs/TargetRevenueControlPlaneConcept.md§2's table). - Operator+ registers a Phase (
control_plane.register_phase) and appends Development Credit directly (control_plane.append_development_credit). - Contributor submits a proposed entry instead
(
control_plane.propose_ledger_entry); Operator+ approves (appending under the reviewer's own credential,control_plane.approve_proposed_entry) or rejects (control_plane.reject_proposed_entry). - Every action is recorded in the Control Plane's own audit log
(
control_plane.record_audit_event/get_audit_log), independent of the Trust Service's own signed records, which only ever attest "thebinkytenant acted," never which individual human. - UI:
service/control_plane_app.py+service/control_plane_templates/(WP-0009-T04).
No gap here, no follow-up workplan.
4. Remission Credit accrual over time under the active degeneration policy
trsl:policy:linear-longstop-v0 (the accepted v1 norm,
specs/OpenQuestions-WorkingDefaults.md Q7) defines
R(t) = T0 × clamp((t − t0)/(tL − t0), 0, 1), with discrete
remission-credit ledger entries computed on a published schedule. FR-6
(specs/ProductRequirementsDocument.md) requires this to actually happen.
Nothing in this codebase computes or writes these entries.
fold.py can consume a remission-credit entry if one exists in the
ledger; nothing produces one. This is not a Control Plane UI gap — it
predates the UI entirely, and was never in scope for WP-0006 (Trust
Service) either. It surfaced now only because working through this
use-case list prompted a fuller look at what a Phase's lifecycle actually
requires end to end, not because anything about the recent UI work
introduced it.
Gap → workplans/TREV-WP-0013-remission-credit-automation.md
(its own workplan, not folded into this modeling pass, since it's a
missing implementation, not a missing decision).
5. Conversion Event fires; Attestation published
FR-7 defines the Conversion Event as the objective moment Outstanding
Target reaches zero, computable from the Manifest + Ledger alone, with no
Trust Service declaration required (attestation.py's module docstring:
"a Conversion Event is true the instant the ledger fold first reaches
Outstanding Target = 0, independent of whether anything ever publishes an
attestation about it"). attestation.publish_attestation is implemented,
tested, and exposed at GET /phases/{id}/attestation — idempotent,
publish-on-first-observation, never regenerated.
What's missing is purely presentational: the Control Plane UI has no view of a Phase's Attestation once one exists. A caller has to know to hit the Trust Service endpoint directly.
Gap → workplans/TREV-WP-0014-control-plane-extensions-breach-attestation-ui.md
T03.
6. Monetization Extension registration and canonical-status review
FR-4 defines the six-field extension contract; registry.register_extension
and registry.promote_extension_canonical are implemented and tested.
Canonicalization is a governance action (set_extension_status,
SECURITY DEFINER, never a plain UPDATE) — the same pattern already used
for credential revocation and proposed-entry review elsewhere in this
project.
Two things are missing, one of them a real open question, not just UI:
- No Control Plane UI to register an extension or review/promote one.
- Unresolved:
specs/TargetRevenueControlPlaneConcept.md§2's rights table (cited in use case 3 above) does not mention extension registration or canonicalization at all — unlike breach records (use case 7), which the table explicitly assigns to Operator+. Whether registering a new extension should require any rights tier at all (the Trust Service's ownregistry.register_extensiondoesn't gate it today — any authenticated tenant can call it directly), and who should be able to canonicalize one, needs an explicit answer before UI work starts, not an assumption made while building the form.
Gap → workplans/TREV-WP-0014-control-plane-extensions-breach-attestation-ui.md
T01.
7. Breach/Compliance Record publication
FR-10 and License V1C1 §7.4: a Licensor's own breach/termination
determination, anonymized (Phase + category only) by default, named only
with an explicit Commercial Use Agreement opt-in.
breach_record.publish_breach_event/get_breach_records are implemented
and tested. Unlike extension registration, this one's rights tier is
already decided: specs/TargetRevenueControlPlaneConcept.md §2 assigns
"publish breach/compliance records" to Operator+ explicitly, alongside
Phase registration and direct ledger append. No open rights question here
— purely a missing UI.
Gap → workplans/TREV-WP-0014-control-plane-extensions-breach-attestation-ui.md
T02.
8. A second Licensor tenant besides binky onboards
Today, binky is the only Licensor identity in every environment (test
fixtures, the local dev instance, presumably any eventual deployment).
registry.create_licensor_identity/issue_sub_credential support a
second tenant structurally and are exercised in tests, but never in any
real onboarding flow — there is no "onboard a new Licensor" use case
documented anywhere, only "issue another credential for the Licensor that
already exists."
Judged not to need its own workplan (per the decision recorded in
workplans/TREV-WP-0012-phase-provenance-and-policy-modeling.md's
closing section) — this is squarely a governance matter and belongs under
workplans/TREV-WP-0008-governance-and-pilot-rollout.md if and when a
second real tenant is actually on the table. Revisit that call if it
turns out to need real design work once that happens, rather than
speculatively designing it now.
9. An external auditor verifies a Phase's evidence package offline
FR-8/FR-9: a complete Phase evidence package (manifest, ledger,
extensions, attestation) can be exported in an open format and
independently verified — recomputing the fold, checking the Ed25519
signature chain — without trusting, or even being able to reach, the
Trust Service or the Control Plane at all (NFR-1 determinism/
reproducibility; attestation.py's own docstring makes the same point
about conversion status specifically).
This use case has, by design, no Control Plane UI surface. Recording
it here explicitly so it doesn't get silently miscounted as "not yet
built" alongside cases 4–7 above, which are real gaps. fold.py and
hashing.py are the offline-verifiable surface this use case depends on;
both are already implemented, tested, and covered by the hosted
conformance suite (tests/test_hosted_conformance.py).
Summary table
| # | Use case | Status |
|---|---|---|
| 1 | First Phase for a repo | Partially modeled — no repo/provenance fields (→ T02) |
| 2 | Successive Phase, same repo | Not modeled at all (→ T02) |
| 3 | Register / propose / review (rights model) | Done (WP-0009) |
| 4 | Remission Credit accrual | Not implemented (→ WP-0013) |
| 5 | Conversion Attestation view | Backend done, no UI (→ WP-0014-T03) |
| 6 | Extension registration/canonicalization | Backend done, no UI, rights tier undecided (→ WP-0014-T01) |
| 7 | Breach/Compliance Record | Backend done, no UI, rights tier already decided (→ WP-0014-T02) |
| 8 | Second Licensor tenant onboarding | Structurally supported, no onboarding flow — deferred to WP-0008 |
| 9 | Offline evidence verification | Done by design, no UI needed |