phase: 23_llm_rate_responsiveness
Phase 23 final verification complete — all green.
```
VERIFIED (criteria)
1 /api/llm/snapshot windows ≈2 s live (1.98–2.00), /api/system window_seconds ≈10 s (9.996–10.005);
/api/config llm.rate_window_seconds=2=LLM_INTERVAL_SECONDS; browser re-check ALL CHECKS PASSED
(data/logs/23-window-{llm,system}.png — /llm prints Δ2.0s, /system footnote Δ10.0s)
2 Phase-13 pins unchanged: floor, 2×span ceiling, 8× jump gate + independent anchor — all pass
(only import/span-line diffs in tests/; git diff confirms no assertion rewritten)
3 Live proof re-derived from artifacts: 780 rows, 0 unlabelled, windows 0.61–3.38 s, 5 starts +
5 ends settled by poll 2 (0 unsettled), 1 m rollups max 42.3 vs raw 201.6, 0 over 300 tok/s;
counterfactual 10 s window: median settle poll 3, |ln| 0.924 vs 0.037
4 uv run pytest: 1494 passed / 15 skipped · coverage 98.94% (floor 94) · ruff clean · pyright 0
errors · node --check clean · bash .agents/validate.sh exit 0 · live 11 passed · store_perf 4 passed
Dev server up, all nine sources ok. No git add/commit run; everything left in the working tree.
DOCS PASS — 4 inconsistencies fixed in AGENTS.md (last two runs above include them)
- UI conventions hero example still said the `.sub` footnote reads `Δ10.0s`; the only hero that
prints a Δ is /llm's → now `Δ2.0s` on /llm, "at the current load" on /ups
- gap 9: "found 10 busy-edges" contradicted its own artifact (17 edges, 10 judged, 7 reported-not-
judged) → 17; and the poll-2 ratios were a 3-of-5 cherry-pick → full five values both windows
- gap 12: the responsive-table fix is now scheduled — names 27_mobile_tables_and_audit
README, config table, .env.example, rates/prom docstrings, app/api bullets and the testing-policy
pins all re-checked against code and found consistent (store pragmas, budgets, throttle, fleet).
NOTES
- Advisory only, not phase 23: fastapi 0.153.0 → 0.156.8 available; dependencies untouched here,
so rule 8's "update on purpose" is left to the operator.
- NOTES.md is empty in the working tree (its items became phases 24–27); left as-is, untracked-file
rules forbid me removing it.
- Next phase: 24_dev_mtls_rollout (25–27 follow).
```
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"""The two Δ windows of phase 23, in one place so the pins cannot drift.
|
||||
|
||||
`app.build_hub` hands out **one `RateEstimator` per measuring cadence**:
|
||||
|
||||
| source | span | knob | cadence |
|
||||
| ------ | ------------- | ----------------------- | ------- |
|
||||
| host | `HOST_WINDOW` | `RATE_WINDOW_SECONDS` | 10 s |
|
||||
| llm | `LLM_WINDOW` | `LLM_INTERVAL_SECONDS` | 2 s |
|
||||
|
||||
Two numbers living in the same payload shape: every measured rate cell carries the `window` the
|
||||
estimator actually used, and `provenance()` in `page-llm.js` / `windowLabel()` in
|
||||
`page-system.js` print it as `Δ<window.toFixed(1)>s`. A pin that names only **one** of the two
|
||||
windows is how a later change could quietly give both sources the same span, so every pin reads
|
||||
them through the constants and helpers here:
|
||||
|
||||
* `tests/test_api.py` — the wiring: which estimator object each source's jobs receive, and the
|
||||
`/api/config` window the LLM page is allowed to echo;
|
||||
* `tests/test_llm_source.py` — the LLM payload: both throughput cells of both engines at the
|
||||
2 s shape, and the phase-13 floor still refusing the poll loop's catch-up gap at that span;
|
||||
* `tests/test_host_source.py` — the host payload: `window_seconds` at the 10 s shape, and the
|
||||
same 10 s cadence starved to `n/a` by the LLM's 2 s span (why one estimator cannot serve both);
|
||||
* `tests/test_rates.py` — the estimator's own gates at both spans, because they are properties of
|
||||
the estimator and not of the window size.
|
||||
|
||||
`config.py`'s defaults are the source of truth for the numbers themselves and
|
||||
`tests/test_config.py` pins them; this module exists so the pins cite one spelling of them
|
||||
instead of five literals that can each drift on their own day.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dashboards.rates import MAX_WINDOW_RATIO, MIN_WINDOW_SECONDS
|
||||
|
||||
#: `RATE_WINDOW_SECONDS` — the Δ window the `host` jobs are measured over.
|
||||
HOST_WINDOW = 10.0
|
||||
|
||||
#: `LLM_INTERVAL_SECONDS` — the Δ window the `llm` jobs are measured over. It *is* their poll
|
||||
#: interval (phase 23): the smallest window a 2 s cadence can honestly fill, which is what stops
|
||||
#: a slot start ramping the hero over five polls.
|
||||
LLM_WINDOW = 2.0
|
||||
|
||||
|
||||
def delta_label(window: float | None) -> str:
|
||||
"""The provenance tag a page prints for a window — `provenance()`'s `toFixed(1)` idiom.
|
||||
|
||||
The pages build `Δ<window>s` out of the payload's own `window` field; this is the same
|
||||
rounding in Python, so a pin can assert *the label the operator reads* (`Δ2.0s`) instead of a
|
||||
bare float whose meaning nobody checked.
|
||||
"""
|
||||
return "" if window is None else f"Δ{window:.1f}s"
|
||||
|
||||
|
||||
def assert_window(window: float | None, span: float, *, where: str) -> None:
|
||||
"""Assert a measured number carries its own source's window, inside the estimator's bounds.
|
||||
|
||||
`window` is a rate cell's `window` field (both engines) or a host payload's `window_seconds`
|
||||
(`/system`'s footnote), and `where` names it in the failure message.
|
||||
|
||||
The bound is a **range**, never a literal, and its ceiling is the estimator's own
|
||||
`2 x span` rather than the span. A span equal to the cadence means only the current sample is
|
||||
ever strictly *inside* the window, so the base comes from the window-empty fallback — the
|
||||
previous sample, one poll back — and a published window is the real poll gap: the dev server
|
||||
reads 2.009-2.026 s on `/llm` and 9.978-10.002 s on `/system`. Anything past `2 x span` is a
|
||||
stall and answers `n/a`, which is the half of this the phase-13 pins hold. Because the window
|
||||
tracks a cadence knob, an operator who raises `LLM_INTERVAL_SECONDS` moves the window and this
|
||||
assertion together, while a pin hard-coded to `2.0` would rot.
|
||||
|
||||
The tight half is the label: `delta_label(window) == delta_label(span)` is what the browser
|
||||
prints, so `Δ2.0s` on `/llm` and `Δ10.0s` on `/system` are one assertion made at two different
|
||||
spans, and a window that had drifted a whole interval would print a different label.
|
||||
"""
|
||||
assert window is not None, f"{where} carries no window at all"
|
||||
assert MIN_WINDOW_SECONDS <= window <= MAX_WINDOW_RATIO * span, (
|
||||
f"{where} window {window} is outside its source's own bounds "
|
||||
f"(floor {MIN_WINDOW_SECONDS}, ceiling {MAX_WINDOW_RATIO} x span {span})"
|
||||
)
|
||||
assert delta_label(window) == delta_label(span), (
|
||||
f"{where} would print {delta_label(window)!r} beside a value measured over {span}s"
|
||||
)
|
||||
Reference in New Issue
Block a user