target-revenue/specs/TargetRevenueControlPlaneConcept.md
tegwick 7c2e33bc31 Split TREV-WP-0009 into Control Plane (WP-0009) and Effort Calculator (WP-0010)
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.
2026-07-30 11:02:45 +02:00

7.2 KiB

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.