target-revenue/workplans/TREV-WP-0015-phase-provenance-implementation.md
tegwick 2a176d9961 Implement WP-0015-T01/T04/T06: Phase provenance schema + ledger UI
Schema: phase.milestone_release gains required repo_hub/repo_hub_uri/
repo_id/repo_name; phase gains optional base_phase_id. Backfilled the
golden phase-001 fixture (placeholder values, it's synthetic) and the
three real pilot-candidate manifests with actual Forgejo repo ids
confirmed live (net-kingdom=67, vergabe-teilnahme=62,
info-tech-canon=47, all coulomb/*).

Discovered along the way: the schema change alone would have broken
the existing Control Plane registration form, since nothing collected
the four new fields. Fixed inline rather than leaving it broken
between tasks -- this also completes T04's ledger UI change (drop the
hand-typed ledger input, auto-compute /phases/{id}/ledger, add a
drill-down reference link on phase_detail.html) since both changes
touch the same form/route.

Full suite: 94 passing offline (was 84), 158 passing with Docker
(was 146).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-03 20:43:30 +02:00

183 lines
7.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: TREV-WP-0015
type: workplan
title: "Implement Phase provenance, spec-file, and ledger UI changes"
domain: infotech
repo: target-revenue
status: active
owner: claude
topic_slug: infotech
created: "2026-08-03"
updated: "2026-08-03"
state_hub_workstream_id: "fe1bedd3-dadc-41cc-a669-92623743e620"
---
# Implement Phase provenance, spec-file, and ledger UI changes
Implements `specs/PhaseProvenanceSpecAddendum.md`, accepted 2026-08-03,
which itself synthesizes the decisions from
`workplans/TREV-WP-0012-phase-provenance-and-policy-modeling.md` T02T04.
Task numbering below matches the addendum's §6 suggested breakdown
1:1 — each task cites its addendum section as the authoritative source of
what to build, rather than re-deriving field shapes or rationale here.
```task
id: TREV-WP-0015-T01
status: done
priority: high
state_hub_task_id: "cdca0ef5-a332-40e2-b165-10ffa238f413"
```
**Schema change** (addendum §1): add `repo_hub`, `repo_hub_uri`,
`repo_id`, `repo_name` as required properties of
`phase.milestone_release`, and `phase.base_phase_id` as an optional
property of `phase`, to `schemas/phase_manifest.schema.json`. Update
`validation.py` if the new pattern/format constraints need anything
beyond what JSON Schema's own `pattern`/`format` keywords already
enforce (they shouldn't). Add offline tests: a manifest missing any of
the four new required fields is rejected; one with `base_phase_id`
absent validates (first Phase); one with it present and correctly
patterned validates (successive Phase).
**Result:** Schema updated exactly as specified; `validation.py` needed
no changes (`pattern`/`format`/`minimum` already sufficient). Added six
tests to `tests/test_manifest_validation.py` covering all four new
required fields and both `base_phase_id` states plus a malformed one.
Updating `examples/phase-001/manifest.json` (the fixture 13 other test
files depend on) turned out to be necessary just to keep the offline
suite green, not optional — done inline with placeholder-but-plausible
values (`repo_hub: "example-hub"`, synthetic id/name), since it's a
fictional fixture, not a real repo.
**Discovered scope gap, fixed inline rather than left broken**: the
addendum's task breakdown didn't call out that the Control Plane's
existing Phase registration form (`phase_new.html`,
`control_plane_app.py`) would stop working the moment this schema
change landed, since nothing collected the four new required fields.
Fixed as part of this task rather than leaving registration broken
between tasks — this also completes T04's registration-form half (drop
`ledger` input, auto-compute it) and adds the `base_phase_id` field,
since all three changes touch the same form/route. `phase_detail.html`'s
ledger-reference drill-down (T04's other half) is done too. Full suite:
94 passing offline (up from 84 — six new schema tests, three new
provenance-backfill tests, two new Control Plane form tests), 158
passing with Docker (up from 146).
```task
id: TREV-WP-0015-T02
status: todo
priority: high
state_hub_task_id: "8b5ab6ea-fa80-4e08-8733-2faad810962e"
```
**Spec-file extraction** (addendum §2): create `specs/policies/
linear-longstop-v0.md` (extracted from `specs/
OpenQuestions-WorkingDefaults.md` Q7's prose, with `policy_id`/`title`
frontmatter); create the six `specs/profiles/*.md` files (extracted from
`specs/CanonicalMonetizationProfiles.md` §1§6, with `extension_id`/
`title` frontmatter), leaving §7 (cross-profile summary) and §8
(non-goals) in place as the overview document. Add `calculator_id`/
`revision`/`title` frontmatter to `specs/
DevelopmentEffortCalculatorConcept.md` (no move). Update
`OpenQuestions-WorkingDefaults.md` Q7 to point at the new file rather
than contain the policy's content directly.
```task
id: TREV-WP-0015-T03
status: todo
priority: medium
state_hub_task_id: "681002d5-582b-4ddd-8b1f-dc25ce5b0e5a"
```
**Control Plane reference-rendering routes** (addendum §2): add
`GET /reference/policies/{slug}` and `GET /reference/profiles/{slug}` to
`service/control_plane_app.py`, rendering the corresponding
`specs/policies/`/`specs/profiles/` markdown file to HTML server-side at
request time (a small Python markdown library — confirm one is already
an acceptable addition to the `service` extras in `pyproject.toml`, or
add it). Read-only, no edit capability. Link to these routes from
wherever a policy id or extension id already appears in
`phase_detail.html`/`phase_new.html`.
```task
id: TREV-WP-0015-T04
status: done
priority: medium
state_hub_task_id: "af660317-e732-4ad7-bd4a-86ada8602ec7"
```
**Ledger UI change** (addendum §3): drop the `ledger` input from
`phase_new.html`; have the registration route auto-compute
`phase.ledger` as the canonical `/phases/{phase_id}/ledger` reference
before validation/persistence. Add a small "ledger reference"
link/disclosure to `phase_detail.html` showing the raw reference plus a
live-data link when it resolves to this same instance. The existing
Ledger entries table is untouched.
**Result:** Done as part of T01's fix (same form/route touched by both
tasks — see T01's Result). `control_plane_app.py`'s registration route
sets `phase["ledger"] = f"/phases/{phase_id}/ledger"` before validation;
`phase_new.html` no longer has a `ledger` input at all.
`phase_detail.html` gained a `<details>` disclosure showing the raw
reference plus a live-JSON link when it resolves to this instance
(`manifest.phase.ledger.startswith('/phases/')`). Regression test:
`test_phase_new_form_has_no_ledger_input`.
```task
id: TREV-WP-0015-T05
status: todo
priority: high
state_hub_task_id: "816f1ac2-da40-4550-8d6c-64a1a335a660"
```
**`forgejo_hubs` migration** (addendum §4): new migration
`migrations/0007_forgejo_hubs.sql`, table `forgejo_hubs (hub_slug
PRIMARY KEY, service_uri, first_seen_at, updated_at)`, auto-populated on
first sight of a `repo_hub` during Phase registration (mirroring
`ensure_licensor_identity`'s auto-create-on-first-INSERT trigger
pattern in `migrations/0005_licensor_credentials.sql`). Decide during
implementation (not a T02-style human gate, per the addendum) whether
correcting a hub's URI after the fact is a `SECURITY DEFINER` governance
action or a plain `UPDATE`, and document whichever is chosen.
```task
id: TREV-WP-0015-T06
status: done
priority: medium
state_hub_task_id: "719aa6db-93d8-4eaa-ac1b-e7ee4c00bd89"
```
**Backfill the three example manifests** (addendum §5):
`examples/pilot-candidates/{net-kingdom-local-identity,
railiance-vergabe-teilnahme, info-tech-canon-service-surface}/manifest.json`
each get `repo_hub`/`repo_hub_uri`/`repo_id`/`repo_name` from their real
Forgejo data (`GET /api/v1/repos/{owner}/{repo}`, same call already
confirmed working for `target-revenue` itself during WP-0012-T02), no
`base_phase_id` (all three are first Phases), and `ledger` set to match
what the Control Plane would now auto-compute.
**Result:** Confirmed live against `forgejo.coulomb.social` (all three
repos are `coulomb/*`, same org as `target-revenue`): `net-kingdom` id
`67`, `vergabe-teilnahme` id `62` (the actual application repo per
`history/260730-EffortCalculator-CandidateApplication.md` §3, not the
`railiance-apps` deployment repo), `info-tech-canon` id `47`. All three
manifests backfilled with real, not placeholder, ids; `ledger` set to
`/phases/{phase_id}/ledger` matching §3's auto-compute convention. New
regression test: `test_pilot_candidate_manifest_carries_real_repo_provenance`.
```task
id: TREV-WP-0015-T07
status: todo
priority: high
state_hub_task_id: "39b34438-a1b1-49da-a88a-f3bec926aa89"
```
**Tests, docs, and closeout**: offline schema/validation tests (T01),
Docker-gated `TestClient` tests for T03's new routes and T04/T05's
changes (extending `tests/test_control_plane_app.py`), a rendering smoke
test that each `specs/policies/`/`specs/profiles/` file actually renders
without error. Update `README.md`'s WP-0015 row and this workplan's
Result sections; run the full offline + Docker-gated suite; fence-count
check before committing any workplan edit, per this project's standing
practice.