**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,