target-revenue/workplans/TREV-WP-0015-phase-provenance-implementation.md
tegwick 1fb7212e2d Implement WP-0015-T02: extract policy/profile spec files
specs/policies/linear-longstop-v0.md extracted from
OpenQuestions-WorkingDefaults.md Q7's prose, with policy_id/title
frontmatter -- Q7 now records only the adoption decision, pointing at
this file for the formula itself.

Six specs/profiles/*.md files extracted from
CanonicalMonetizationProfiles.md's per-profile sections (#1-6), each
with extension_id/title frontmatter matching the ids already used in
real Phase Manifests. CanonicalMonetizationProfiles.md keeps the
cross-profile summary and non-goals sections, now pointing at the
extracted files instead of containing their content.

DevelopmentEffortCalculatorConcept.md gets calculator_id/revision/title
frontmatter for consistency, no move (already conformed as one file per
model). Checked for stale cross-references before editing -- nothing
in the repo links to the removed section anchors.

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

8.8 KiB
Raw Blame History

id type title domain repo status owner topic_slug created updated state_hub_workstream_id
TREV-WP-0015 workplan Implement Phase provenance, spec-file, and ledger UI changes infotech target-revenue active claude infotech 2026-08-03 2026-08-03 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.

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).

id: TREV-WP-0015-T02
status: done
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.

Result: specs/policies/linear-longstop-v0.md and all six specs/profiles/*.md files created exactly as scoped, each with the decided frontmatter shape. CanonicalMonetizationProfiles.md §1§6 replaced with a linked list pointing at the new files; §7 (cross-profile summary) and §8 (non-goals) untouched. OpenQuestions-WorkingDefaults.md Q7 now records only the adoption decision, pointing at the policy file for content. DevelopmentEffortCalculatorConcept.md got its calculator_id/revision/title frontmatter, no move (already conformed). Checked for stale cross-references before editing — nothing in the repo links to the removed CanonicalMonetizationProfiles.md section anchors (grep confirmed), so no other file needed updating. Offline suite unaffected (no code reads these doc files' content) — 94 passing, unchanged.

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.

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.

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.

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.

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.