The two deliverables have independent formula/rights decisions and implementation arcs; keeping them in one workplan blurred that they can be reviewed and sequenced separately, even though the Control Plane's Phase-registration flow is expected to consume the Calculator's output once both exist. WP-0009 (Target Revenue Control Plane): keeps the original workstream ID, retitled and re-tasked to 3 focused tasks - rights-model decision (human gate), backend auth/audit layer, interactive UI flows. WP-0010 (Development Effort Calculator, new): 3 tasks - formula decision (human gate), implementation, application to the real candidate repos already identified in WP-0008. No real Phase declaration in either workplan's scope. Updated both concept documents' workplan cross-references and README.md's summary table accordingly.
136 lines
7.2 KiB
Markdown
136 lines
7.2 KiB
Markdown
# Target Revenue Control Plane — Concept
|
|
|
|
Status: Concept v0.1
|
|
Date: 2026-07-30
|
|
Workplan: `workplans/TREV-WP-0009-target-revenue-control-plane.md`
|
|
Primary artifacts: `specs/TrustServiceProductRequirementsDocument.md`, `src/target_revenue/service/app.py`, `specs/TRSL-Governance.md` §1 (Licensor identity), `scripts/trf_onboard.py`
|
|
|
|
**Scope note:** this is a concept, not an implementation. It defines what
|
|
the Control Plane UI is for, who uses it, and what it must and must not
|
|
be able to do — building directly on the hosted Trust Service
|
|
(`workplans/TREV-WP-0006-trust-service-implementation.md`, finished) and
|
|
the onboarding mechanism (`specs/TrustServiceOnboarding.md`) rather than
|
|
replacing either.
|
|
|
|
---
|
|
|
|
## 1. Purpose
|
|
|
|
Everything in `scripts/trf_onboard.py` today is a CLI, operated by
|
|
whoever has shell access and the Licensor's token in an environment
|
|
variable. That is adequate for the dry-run routine already exercised
|
|
(`info-tech-canon`), but not adequate for **an actual "binky tenant" user**
|
|
— someone who should be able to interactively register Phases, review
|
|
Phase status, and — the maintainer's specific requirement — **interactively
|
|
create Development Credit ledger entries**, without needing to construct
|
|
raw JSON payloads or hold the Licensor's raw API token directly in their
|
|
own shell environment.
|
|
|
|
The Control Plane is a web (or equivalent interactive) front end over the
|
|
existing hosted Trust Service API (`service/app.py`), for the `binky`
|
|
tenant specifically, not a replacement for that API or a new Trust
|
|
Service instance.
|
|
|
|
## 2. Users and rights model — the actual new design gap
|
|
|
|
**This is the concept's main open design question**, not something WP-0006
|
|
already solved: WP-0006's auth model is **one token per Licensor**
|
|
(`migrations/0001_registries.sql`'s `licensors` table), sufficient for a
|
|
script or CI pipeline acting *as* the Licensor, but not sufficient for
|
|
**multiple human users**, potentially with **different rights**, acting
|
|
*on behalf of* the same Licensor tenant (`binky`).
|
|
|
|
**Candidate rights tiers** (not yet decided, proposed for workplan T01 to
|
|
resolve):
|
|
|
|
| Right | Can do |
|
|
|---|---|
|
|
| Viewer | Read Phase status, metrics, ledger, attestations, breach records (all already public per FR-9/FR-10 — a Viewer arguably needs no new auth at all, since these are unauthenticated reads today) |
|
|
| Contributor | Everything Viewer can, plus: submit a *proposed* Development Credit entry for review (not directly appended) |
|
|
| Operator | Everything Contributor can, plus: directly append Development Credit/Remission Credit entries, register new Phases, publish breach/compliance records |
|
|
| Admin | Everything Operator can, plus: manage which human users hold which right within the `binky` tenant |
|
|
|
|
**Design tension to resolve, not paper over:** WP-0006's Ledger append API
|
|
(`ledger.append_entry`) currently authenticates a single Licensor token,
|
|
not an individual human user — so "Operator Alice" and "Operator Bob"
|
|
both acting for `binky` are currently indistinguishable at the API layer
|
|
(both just look like "the `binky` token"). Either (a) the Control Plane
|
|
issues per-human-user sub-credentials that map to the same underlying
|
|
Licensor identity (requiring a schema/API change in WP-0006's auth
|
|
layer — a real, scoped follow-on task), or (b) the Control Plane holds
|
|
the one Licensor token server-side and layers its own human-user
|
|
authentication/authorization in front of it, recording *which human*
|
|
took an action in its own audit log distinct from the Trust Service's
|
|
own record (simpler, no WP-0006 changes required, but the Trust
|
|
Service's own signed records still only attest "the `binky` Licensor did
|
|
this," not "Alice, acting for `binky`, did this"). **Recommendation: start
|
|
with (b)** — it requires no changes to the already-finished, tested
|
|
WP-0006 auth model, and the Control Plane's own audit log (§5) can carry
|
|
the finer-grained human-attribution that the Trust Service's own
|
|
cryptographic signature does not need to.
|
|
|
|
## 3. Core interactive flow: creating a Development Credit entry
|
|
|
|
The maintainer's specific requirement. Concretely, for an Operator-tier
|
|
user:
|
|
|
|
1. Select a registered Phase (from a list, via `GET /phases/{id}` reads —
|
|
already public, already implemented).
|
|
2. Fill a form for a new `development-credit` ledger entry: amount,
|
|
currency, recognized date, evidence reference, applicable Monetization
|
|
Extension (selected from `specs/CanonicalMonetizationProfiles.md`'s
|
|
catalog, not free text).
|
|
3. The Control Plane server-side calls `POST /phases/{id}/ledger`
|
|
(`ledger.append_entry`, already implemented, WP-0006-T04) using the
|
|
`binky` Licensor token it holds — the human user never sees or handles
|
|
that token directly.
|
|
4. The Control Plane records, in its own audit log (§5), which human user
|
|
initiated this specific entry, alongside the Trust Service's own
|
|
returned signed record.
|
|
5. Display the updated Phase status (`GET /phases/{id}/metrics`, already
|
|
implemented) immediately after, so the user sees the effect of what
|
|
they just did.
|
|
|
|
**Nothing here requires changing the Ledger append API itself** — the
|
|
Control Plane is a client of it, exactly like `scripts/trf_onboard.py` is
|
|
today, just interactive and multi-user rather than single-shot CLI.
|
|
|
|
## 4. Other interactive capabilities (lower priority than §3)
|
|
|
|
- Registering a new Phase, using the Development Effort Calculator
|
|
(`specs/DevelopmentEffortCalculatorConcept.md`) to help populate
|
|
`target_basis`, rather than requiring the user to hand-author a JSON
|
|
manifest.
|
|
- Viewing the Breach/Compliance Record history for a Phase and initiating
|
|
a new breach/cure/determined event (Operator+ only, per License V1C1
|
|
§7.4's Licensor-determination principle — the Control Plane must not
|
|
let this become the Control Plane's own discretionary judgment about
|
|
whether a breach occurred, consistent with TSD §4.1's forbidden-action
|
|
column).
|
|
- Viewing the Conversion Attestation once a Phase converts (read-only,
|
|
already public).
|
|
|
|
## 5. Audit logging — a Control Plane responsibility, not a Trust Service one
|
|
|
|
Every write action taken through the Control Plane must be logged with:
|
|
which human user, what action, when, and the resulting Trust-Service-
|
|
signed record's id — **in the Control Plane's own storage**, since the
|
|
Trust Service itself has no concept of individual human users under one
|
|
Licensor token (§2). This log is the answer to "who actually clicked the
|
|
button," which matters operationally even though it's not part of the
|
|
Trust Service's own cryptographic guarantees.
|
|
|
|
## 6. Explicit non-goals
|
|
|
|
- Replacing `scripts/trf_onboard.py` — the CLI remains valid for
|
|
scripted/CI use; the Control Plane is for interactive human use.
|
|
- Changing the Trust Service's core guarantees (determinism, append-only,
|
|
no discretionary conversion authority) — the Control Plane is a client,
|
|
bound by the same rules any other client is.
|
|
- Deciding the human-user rights model unilaterally — §2 is a proposal
|
|
for workplan T01 to confirm, not a decided design.
|
|
- Multi-tenant support for Licensors other than `binky` — in scope
|
|
structurally (the Trust Service already supports multiple Licensors,
|
|
TS-FR-8), but this concept is scoped to the one tenant that currently
|
|
exists; extending the UI to other tenants is natural future work, not
|
|
blocking this concept.
|