Accept WP-0008-T05 for trsl:phase:info-tech-canon-service-surface (history/260805-T05-GoLive-info-tech-canon.md). Finish WP-0013 remission automation and WP-0014 extension/breach/attestation Control Plane UI. Update SCOPE, README, and pilot-candidate notes for pilot Stage 1.
5.2 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | state_hub_workstream_id |
|---|---|---|---|---|---|---|---|---|---|---|
| TREV-WP-0013 | workplan | Remission Credit automation (degeneration policy execution) | infotech | target-revenue | finished | claude | infotech | 2026-07-30 | 2026-08-05 | 4a423219-2a3e-413c-b0dc-f8542c2afba1 |
Remission Credit automation (degeneration policy execution)
Spun out of workplans/TREV-WP-0012-phase-provenance-and-policy-modeling.md
(use case 4). Every Phase declares a degeneration_policy
(trsl:policy:linear-longstop-v0 is the accepted v1 norm,
specs/OpenQuestions-WorkingDefaults.md Q7), which is supposed to
generate remission-credit Target Ledger entries over time when
Development Credit progress is insufficient (FR-6,
specs/ProductRequirementsDocument.md). Nothing in this codebase
previously computed or wrote these entries. fold.py can consume them
if they exist; this workplan produces them. This gap predated the Control
Plane UI work — it was never in scope for WP-0006 (Trust Service) or
WP-0009 (Control Plane), and surfaced when reviewing the UI's
Phase-registration flow prompted a fuller look at what a Phase's lifecycle
actually requires end to end.
Blocked on workplans/TREV-WP-0012-phase-provenance-and-policy-modeling.md
T03's decision (how a policy id maps to its spec file) — unblocked
when WP-0012 finished and WP-0015 landed specs/policies/linear-longstop-v0.md.
id: TREV-WP-0013-T01
status: done
priority: high
state_hub_task_id: "d6ab7448-c009-4398-b616-560e8085cf1a"
Design the remission calculation and scheduling model. R(t) = T0 × clamp((t - t0)/(tL - t0), 0, 1) (Q7) needs: a chosen recognition cadence
(daily/monthly UTC per Q7's own text), an idempotent
"has this period's remission already been recorded" check (ledger entries
are append-only — a re-run must not double-remit), and a decision on
where t0 (Phase activation) comes from if it isn't already a manifest
field (registration time? an explicit activated_at?). Cross-check
against whatever trsl:policy:linear-longstop-v0's spec file (once
WP-0012-T03 lands) says, rather than re-deriving the formula from Q7
prose alone.
Result (2026-08-05): Design recorded in
src/target_revenue/remission.py module docstring and
specs/policies/linear-longstop-v0.md Status section:
- t0 = Trust Service
phase_manifests.registered_at. No new manifestactivated_atfield for Stage 0 — a Phase is not active until registered. Pure callers passt0explicitly. - Cadence / idempotency: cumulative delta model, not period-keyed
rows. Each run remits
max(0, R(as_of) − Σ policy remission-credit). Re-run at the sameas_ofis a no-op; missed schedules catch up without double-counting. Dust floorMIN_REMISSION_AMOUNT = 0.01. Scheduled convention: monthly UTC (1st 00:00) or longstop if sooner. - Actor: dedicated Licensor credential labeled
system:policy-engine(rights operator), auto-issued on first use. Never a nullsubmitted_by_token; never a human credential for policy-driven rows. Control Plane audit still records which human triggered an on-demand run. - Formula checked against
specs/policies/linear-longstop-v0.md, not re-derived from Q7 prose alone.
id: TREV-WP-0013-T02
status: done
priority: high
state_hub_task_id: "078da2e7-594b-4bd3-85b6-881a808f1ca2"
Implement and test the calculation as a pure function (mirroring
fold.py's determinism discipline) plus whatever writes the resulting
remission-credit entries into the hosted Target Ledger — a scheduled
job, an on-demand Control Plane action, or both. Decide which actor
"submits" these entries for attribution purposes (no human credential
naturally owns a policy-driven entry) and record that decision explicitly
rather than leaving submitted_by_token implicitly null.
Result: src/target_revenue/remission.py — pure
cumulative_remission / plan_remission / build_remission_entry_input
plus hosted apply_remission_for_phase /
apply_remission_for_all_phases. Trust Service routes:
POST /phases/{id}/remission (on-demand, Operator+),
POST /remission/run (batch for cron). Control Plane:
control_plane.apply_policy_remission + form on phase detail.
Tests: tests/test_remission.py (pure), tests/test_remission_hosting.py
(Docker Postgres — append, idempotency, system:policy-engine
attribution, metrics forecasts).
id: TREV-WP-0013-T03
status: done
priority: medium
state_hub_task_id: "fe12ee80-2868-4857-83ca-04bd7223e270"
Surface it in the Control Plane UI: phase_detail.html's Ledger
table already renders remission-credit rows generically once they
exist; verify that holds, and add a metrics-level explanation (e.g. next
scheduled remission date/amount) if metrics.py doesn't already forecast
one.
Result: metrics.compute_metrics gains optional activated_at and
forecasts remission_if_applied_now, next_scheduled_remission_at,
next_scheduled_remission_amount (labeled forecast, never facts).
Hosted metrics and Control Plane phase detail pass
registered_at as t0. phase_detail.html shows the forecast table,
activation/longstop facts, and an Operator+ "Apply policy remission now"
button. Existing ledger table continues to render remission-credit
rows generically.