Implement public metrics service (WP-0006-T05)
src/target_revenue/metrics.py: compute_metrics(manifest, entries, as_of)
is pure/deterministic like fold.py, reusing fold.py/conversion.py
unchanged. Returns facts/calculations/forecasts as three explicitly
separated blocks (TrustServicePRD TS-FR-5), covering the mandatory Q9
set plus the recommended velocity/forecast tier - forecasts are always
null rather than populated once a Phase has converted or velocity is
non-positive, so nothing disguises a projection as a fact.
Adds GET /phases/{id}/metrics (unauthenticated per FR-9/FR-10).
tests/test_metrics.py (6 tests) needs no Docker/Postgres and runs
under plain system Python. One new Docker-gated test in
test_ledger_hosting.py proves the hosted /metrics response exactly
matches compute_metrics() run offline against the same export.
This commit is contained in:
parent
b7be3d3512
commit
dfc1d90c28
6 changed files with 287 additions and 3 deletions
|
|
@ -192,7 +192,7 @@ with plain system Python; no stray Docker containers left running.
|
|||
|
||||
```task
|
||||
id: TREV-WP-0006-T05
|
||||
status: todo
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "6bab5e64-0091-4a25-906d-758310cbe723"
|
||||
```
|
||||
|
|
@ -202,6 +202,29 @@ Q9 (Initial Target, cumulative credits, Outstanding Target, conversion
|
|||
status, last checkpoint, Longstop timestamp as mandatory; velocity/forecast
|
||||
as recommended, clearly labeled as forecasts per concept §14.6).
|
||||
|
||||
**Result:** `src/target_revenue/metrics.py`'s `compute_metrics(manifest,
|
||||
entries, as_of)` — pure and deterministic like `fold.py` (the only input
|
||||
that varies with wall-clock time, `as_of`, is an explicit parameter, never
|
||||
read internally), reusing `fold.py`/`conversion.py` unchanged. Returns
|
||||
three explicitly separated blocks per TrustServicePRD TS-FR-5: `facts`
|
||||
(Q9's mandatory set — Initial Target, cumulative Development/Remission
|
||||
Credit, Outstanding Target, conversion status, last ledger entry id,
|
||||
Longstop timestamp), `calculations` (target satisfaction percentage,
|
||||
Development/Remission Credit velocity per day, days since last material
|
||||
progress), and `forecasts` (projected conversion date, `null` whenever
|
||||
already converted or velocity is zero/negative — never populated as a
|
||||
disguised fact). Added `GET /phases/{id}/metrics` to `service/app.py`,
|
||||
unauthenticated per FR-9/FR-10. `tests/test_metrics.py` (6 tests, no
|
||||
Docker/Postgres required, runs under plain system Python — no new hard
|
||||
dependency) covers the mandatory-facts set, fact/calculation/forecast
|
||||
separation, percentage correctness, the zero-material-entries case, and
|
||||
`as_of` timezone-awareness. Added one Docker-gated test to
|
||||
`tests/test_ledger_hosting.py` proving the hosted `/metrics` response
|
||||
(fetched with no Authorization header) exactly equals
|
||||
`compute_metrics()` run offline against the same exported Manifest +
|
||||
Ledger. Full suite (offline 36 + metrics 6 + Docker-gated 22) verified
|
||||
passing; no stray containers left running.
|
||||
|
||||
## Conversion Attestation publication
|
||||
|
||||
```task
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue