fix(08-05): route-cpu gate law re-anchored to the post-ALT measured truth (escalation record — no retirement)
Task 3, re-scoped per the plan's honest-FAIL branch: the CPU verdict FAILED (the ladder ran to its documented stop), so the c3 class is NOT retired — the record instead carries the executed-and-measured ALT truth. - budget-gates.mjs: the verdict law documents the Phase-8 outcome (ALT EXECUTED, optimality green, CPU verdict FAIL 152.788/185.692 ms quoted with date; L=32 probe measured worse) — the stale 'next-milestone item' wording is gone; ROUTE_CPU_DRIFT_GUARD_MS re-anchored 200 → 400 (the post-ALT documented band outgrew the old guard; ≈2x the worst shipped- config run 185.692 ms); the guard stays a regression trip-wire, the 8 ms budget stays and its FAIL still prints every run - budget-audit.test.mjs: CPU3 pins the new law (evidence must name the EXECUTED-in-Phase-8 verdict and must NEVER say 'next-milestone'); 19/19 vectors ok (the count holds — no vector dropped) - docs/BUDGETS.md: route-cpu row carries the Phase-8 measured numbers + date; the c3 section is the honest post-ALT record (what changed, the quoted gate lines, the one-directional-Lipschitz wall, the open escalation) — staged as selective hunks; the tree's pre-existing doc-sync edits in other sections remain uncommitted, untouched grep law: zero 'next-milestone' hits in budget-gates.mjs + BUDGETS.md; ROUTE_CPU_DRIFT_GUARD_MS still exported and used.
This commit is contained in:
+82
-43
@@ -55,16 +55,16 @@ rounded away, never hidden in a footnote.
|
|||||||
|
|
||||||
| Measurement | Current | Budget | Headroom | Evidence |
|
| Measurement | Current | Budget | Headroom | Evidence |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| A* CPU p95 (local ladder, full 25-pair sample) | 83.989 ms (runs today: 67.5–84.0 ms; documented band 38–93 ms) | 8 ms ladder budget (10 ms free ceiling) | **−76.0 ms** — the accepted c3 class (see below) | `route-cpu` |
|
| A* CPU p95 (local ladder, full 25-pair sample) | **152.788 ms** — measured 2026-10-25 on the Phase-8 ARG2 build (L=24, toTable-only ALT steering); n=23 routed (2 unreachable probes reported separately). The D-04 extended 100-pair verdict measured **185.692 ms** the same day (n=53). Not statically pinnable — re-run `npm run budget-audit` to refresh (shared host, run-to-run variance ≈ 2x). Pre-ALT historical band 38–93 ms; the L=32 ladder probe measured **182.725 ms** (25-route) / **204.499 ms** (extended) | 8 ms ladder budget (10 ms free ceiling) | **−144.8 ms** — the c3 class REMAINS (see below) | `route-cpu` (Phase-8 campaign) |
|
||||||
| Route payload (BA9 gz sum: fixtures + routing/route/guidance sources) | 79,815 gz bytes | 204,800 gz bytes (200 KiB) | +124,985 | `bundle-budget` |
|
| Route payload (BA9 gz sum: fixtures + routing/route/guidance sources) | 79,815 gz bytes — **recorded measurement, re-derived at `f018ab1`** as `route-fixtures.json` + every `*.ts` under `routing/src`, `web/src/route`, `web/src/guidance` (22 inputs, `zlib.gzipSync`); `route-fixtures.json` alone is 16,576 gz bytes. Re-run to refresh | 204,800 gz bytes (200 KiB) | +124,985 | `bundle-budget` |
|
||||||
| Whole-app bundle (`web/dist/assets/*.js`, gz-summed) | 479,178 gz bytes (3 hashed assets) | 500,000 gz bytes | +20,822 | `bundle-budget` |
|
| Whole-app bundle (`web/dist/assets/*.js`, gz-summed) | 479,179 gz bytes (3 hashed assets; `zlib.gzipSync` — the gate's method; **recorded measurement, re-run to refresh**. A shell `gzip -c` sum of the same files measured 476,389 B in this session — a different tool, not the gate figure) | 500,000 gz bytes | +20,821 | `bundle-budget` |
|
||||||
| Worker bundle (uncompressed) | not measured — `bot/dist` absent (wrangler builds in memory on deploy) | 64 MiB | n/a | `bundle-budget` |
|
| Worker bundle (uncompressed) | not measured — `bot/dist` absent (wrangler builds in memory on deploy) | 64 MiB | n/a | `bundle-budget` |
|
||||||
| KV writes — session mint (POST /api/session) | 2 writes (`session:<token>` + `chat:<chat_id>`), TTL 900 s | 1,000/day | see the daily estimate | `kv-writes` |
|
| KV writes — session mint (POST /api/session) | 2 writes (`session:<token>` + `chat:<chat_id>`), TTL 900 s | 1,000/day | see the daily estimate | `kv-writes` |
|
||||||
| KV writes — location pin (chat flow) | 1 write (`loc:<chat_id>`), TTL 300 s | 1,000/day | see the daily estimate | `kv-writes` |
|
| KV writes — location pin (chat flow) | 1 write (`loc:<chat_id>`), TTL 300 s | 1,000/day | see the daily estimate | `kv-writes` |
|
||||||
| KV writes — guidance envelope (POST /api/guidance) | 1 write (`guidance:<id>`), TTL 7,200 s | 1,000/day | see the daily estimate | `kv-writes` |
|
| KV writes — guidance envelope (POST /api/guidance) | 1 write (`guidance:<id>`), TTL 7,200 s | 1,000/day | see the daily estimate | `kv-writes` |
|
||||||
| KV writes — **cron guidance tick** | **0 writes** (source-proven) | 1,000/day | full | `kv-writes` |
|
| KV writes — **cron guidance tick** | **0 writes** (source-proven) | 1,000/day | full | `kv-writes` |
|
||||||
| KV writes — daily estimate (derived) | ≈ 4 writes per guided chat-session (2 mint + 1 envelope + 1 pin share; deletes excluded) — 1,000/day ≈ **250 guided chat-sessions/day**; private beta (≈ 5–10 drivers) is ≪ the ceiling | 1,000/day | large | derived (formula stated) |
|
| KV writes — daily estimate (derived) | ≈ 4 writes per guided chat-session (2 mint + 1 envelope + 1 pin share; deletes excluded) — 1,000/day ≈ **250 guided chat-sessions/day**; private beta (≈ 5–10 drivers) is ≪ the ceiling | 1,000/day | large | derived (formula stated) |
|
||||||
| KV list requests | **1,440/day derived** (60 s cron × 1 `list` per tick) | 1,000/day | **−440/day — OVER** (discovered finding; see below) | source derivation |
|
| KV list requests | **720/day derived** (2-minute cron `*/2 * * * *` × 1 `list` per tick — the post-retune current state; see RESOLUTION) | 1,000/day | **+280/day — under** (the pre-retune `*/1` state was 1,440/day, −440/day over) | source derivation (`bot/wrangler.jsonc` + `bot/src/guidance/cron.ts`) |
|
||||||
| Static asset cache headers (live) | not measured in this run — the deployed origin serves a bundle older than `web/dist` (the probe reads HTTP status first and reports deployment drift); the HTML entry observed revalidating: `cache-control: public, max-age=0, must-revalidate` | the `_headers` policy | — | `cache-headers` (--live) |
|
| Static asset cache headers (live) | not measured in this run — the deployed origin serves a bundle older than `web/dist` (the probe reads HTTP status first and reports deployment drift); the HTML entry observed revalidating: `cache-control: public, max-age=0, must-revalidate` | the `_headers` policy | — | `cache-headers` (--live) |
|
||||||
| Subrequests per request class | see the dedicated table below | 50/request | ≥ +48 per class | `subrequests` |
|
| Subrequests per request class | see the dedicated table below | 50/request | ≥ +48 per class | `subrequests` |
|
||||||
| Golden route corpus (`routing:corpus`) | exit 0 — corpus gate PASS, gz 16,576 B / 102,400 B budget | green (SC4.a) | — | `golden-corpus` |
|
| Golden route corpus (`routing:corpus`) | exit 0 — corpus gate PASS, gz 16,576 B / 102,400 B budget | green (SC4.a) | — | `golden-corpus` |
|
||||||
@@ -121,52 +121,91 @@ enforcement point for SC4.a / SC4.b):
|
|||||||
A failing corpus FAILS the gate carrying that child's own failure output verbatim — the
|
A failing corpus FAILS the gate carrying that child's own failure output verbatim — the
|
||||||
record then cannot claim the corpora are green, because the gate just re-proved them.
|
record then cannot claim the corpora are green, because the gate just re-proved them.
|
||||||
|
|
||||||
## The KV list budget — a DISCOVERED over-ceiling finding (07-04)
|
## The KV list budget — the 07-04 over-ceiling finding, RESOLVED by the launch-gate retune
|
||||||
|
|
||||||
The audit's source derivation found one over-ceiling number that the launch gate must see:
|
The audit's source derivation found one over-ceiling number. It is **no longer the current
|
||||||
|
state**: the launch gate resolved it by retuning the cron and the card cadence (the
|
||||||
|
RESOLUTION section at the end of this record is authoritative). What follows keeps the
|
||||||
|
finding auditable and states the post-retune arithmetic.
|
||||||
|
|
||||||
- **Current:** the cron trigger is `*/1 * * * *` (60 s scan, D-11's window) and every tick
|
- **Historical (pre-retune):** the cron trigger was `*/1 * * * *` (60 s scan, D-11's
|
||||||
makes exactly one `env.chat_sessions.list(...)` call ⇒ **1,440 list requests/day derived**.
|
lower window edge) and every tick made exactly one `env.chat_sessions.list(...)` call ⇒
|
||||||
|
**1,440 list requests/day derived**.
|
||||||
|
- **Current (post-retune):** the trigger is `*/2 * * * *` (120 s ticks) in
|
||||||
|
`bot/wrangler.jsonc` and every tick still makes exactly one `list` call ⇒ **720 list
|
||||||
|
requests/day derived** — **+280/day headroom under the ceiling**. `CARD_CADENCE_S` in
|
||||||
|
`bot/src/guidance/cron.ts` is `240` (a card window every 4 minutes; `SCAN_TICK_S` stays
|
||||||
|
`60` as the window-width comparison, and `240 % 120 = 0` keeps the windows aligned to
|
||||||
|
ticks).
|
||||||
- **Ceiling:** the free plan allows **1,000 KV list requests/day**; beyond it, list
|
- **Ceiling:** the free plan allows **1,000 KV list requests/day**; beyond it, list
|
||||||
operations fail with errors until the 00:00 UTC reset.
|
operations fail with errors until the 00:00 UTC reset.
|
||||||
- **Consequence:** every UTC day after ~16 h 40 m, the cron's KV list fails — the tick
|
- **Consequence that no longer applies:** at 1,440/day every UTC day after ~16 h 40 m the
|
||||||
degrades (the list error surfaces as a waitUntil rejection; no cards fire until UTC
|
cron's KV list would fail — the tick would degrade (the list error surfaces as a
|
||||||
midnight). Benign for a morning driver, not benign for an evening one.
|
waitUntil rejection; no cards fire until UTC midnight), benign for a morning driver, not
|
||||||
- **Why this plan does not auto-fix it:** the tick spacing is coupled into the due-card
|
for an evening one. At 720/day the ceiling is never approached; this paragraph is kept
|
||||||
math — `projectTurnCards`' due rule is `nowSec % CARD_CADENCE_S < SCAN_TICK_S` with
|
as the record of why the retune mattered.
|
||||||
`CARD_CADENCE_S = 180` and `SCAN_TICK_S = 60`. Moving the trigger to 120 s (D-11's
|
- **Why it was a decision, not a config edit:** the tick spacing is coupled into the
|
||||||
window upper edge, 720 lists/day) breaks the divisibility (`180 % 120 ≠ 0`) and retimes
|
due-card math — `projectTurnCards`' due rule is `nowSec % CARD_CADENCE_S < SCAN_TICK_S`.
|
||||||
the designed 3-minute card cadence — a product-timing decision, not a config-only
|
At `CARD_CADENCE_S = 180`, moving the trigger to 120 s broke the divisibility
|
||||||
change.
|
(`180 % 120 ≠ 0`) and retimed the designed 3-minute card cadence, so the pair had to be
|
||||||
- **The maintainer's options:** (i) retune the pair (e.g. `CARD_CADENCE_S = 240` with a
|
retuned together — a product-timing decision.
|
||||||
120 s tick ⇒ 720 lists/day, cards every 4 min) — a deliberate product decision with
|
- **The decision taken:** option (i) — `CARD_CADENCE_S = 240` with a 120 s tick ⇒ 720
|
||||||
test updates in `bot/test/guidance-cron.test.mjs`; (ii) accept the documented
|
lists/day, cards every 4 min — with the test updates in
|
||||||
degradation; (iii) Workers Paid — breaks the $0 law, requires sign-off. This is
|
`bot/test/guidance-cron.test.mjs` (see RESOLUTION). Options (ii) accept the documented
|
||||||
recorded as an open decision for the 07-06 launch gate.
|
degradation and (iii) Workers Paid (breaks the $0 law) were not taken.
|
||||||
|
- **Tooling caveat (as of this correction):** `scripts/budget-audit.mjs`'s printed
|
||||||
|
comparison table still hard-codes the pre-retune `derived 1,440/day … OVER` row — the
|
||||||
|
gate re-measures the write classes but does not re-derive lists/day from
|
||||||
|
`bot/wrangler.jsonc`. The source derivation above (720/day) is authoritative for the
|
||||||
|
budget; the printed row is a known stale line, not a second finding.
|
||||||
|
|
||||||
## Cross-metro CPU degradation (the c3 class)
|
## Cross-metro CPU degradation (the c3 class — post-ALT state)
|
||||||
|
|
||||||
The honest escalation from Phase 6 (plan 06-04), restated as the record's CPU row:
|
The record as of the Phase-8 campaign (2026-10-25). The class was NOT retired:
|
||||||
|
the ALT lever was executed and honestly measured, and the verdict kept it.
|
||||||
|
|
||||||
- Short product routes (2–8 km) measure **2–8 ms** on a quiet isolate — inside the 8 ms
|
- **What changed (Phase 8):** the ARG2 graph carries build-time landmark
|
||||||
ladder budget. The full 25-pair sample (the corpus demo-script pairs plus 10
|
tables (L=24 by the D-02 rule, quantum 0.1 s, coverage 0.980), the search
|
||||||
quadrant-sampled cross-city worst cases) measures **p95 38–93 ms** across runs — over
|
steers with the toTable triangle bounds, and the D-03 optimality gate is
|
||||||
budget, and this box's shared-load variance is ≈ 2x.
|
GREEN — all 53 routed record pairs reproduce the frozen pre-ALT seconds
|
||||||
- The mitigation ladder was exhausted WITHIN the $0 law: (a) tighten `DRIVABLE_CLASSES` +
|
within ±0.1% (max |Δ| 0.005%), verdict classes preserved.
|
||||||
rebuild — **rejected on correctness** (12/25 pairs unreachable; the dropped classes are
|
- **What the verdict measured (the quoted gate lines, 2026-10-25):**
|
||||||
the fine mesh tying landmarks to the arterials), reverted; (b) bidirectional A* —
|
`GATE FAIL: p95 152.788 ms exceeds the 8 ms budget (A1)` (25-route CI
|
||||||
**kept** (provably optimal, no worse on the p95 class, better on short product routes);
|
sample, n=23) and `GATE FAIL: p95 185.692 ms exceeds the 8 ms budget —
|
||||||
(c) Workers Paid — **rejected** ($5/mo breaks the $0 law; needs maintainer sign-off).
|
D-04 extended verdict` (100 coordinate-pinned cross-metro pairs, n=53).
|
||||||
- The DECIDED posture (c3, now): cross-metro CPU exhaust → the Worker's 1102 path → the
|
The pre-committed ladder ran to its documented stop: a `--landmarks 32`
|
||||||
client's fail-honest null → the **router-pending state** — designed degradation, never
|
rebuild measured WORSE (`p95 182.725 ms` / `p95 204.499 ms`) — more
|
||||||
a fabricated route. The committed upgrade lever is the **ALT landmark preprocessing**
|
anchors buy no pruning under the sound steering and cost per-node work.
|
||||||
(build-time, still $0 at runtime) — a NEXT-MILESTONE item, not this phase.
|
- **Why the fast configuration is gone (the honest wall):** the original
|
||||||
- Evidence: `routing/scripts/measure-route-cpu.mjs`'s LADDER HISTORY (in-file) and the
|
four-family potential (toTable + fromTable bounds maxed together) returned
|
||||||
06-04 plan summary (`.planning/phases/06-turn-by-turn-guidance-live-driving/06-04-SUMMARY.md`).
|
SUBOPTIMAL routes on the real graph — the D-03 gate caught x038 at
|
||||||
- The `route-cpu` gate therefore compares the re-run p95 against a 200 ms DRIFT GUARD
|
1234.6 s vs the 1214.8 s Dijkstra optimum (x045: 1475.5 vs 1460.6). The
|
||||||
(≈ 2x the worst documented run): inside the band = the documented accepted state (the
|
fromTable bound d̂(ℓ,t) − d̂(ℓ,v) is one-directional Lipschitz: its u-side
|
||||||
8 ms comparison is still printed, headroom negative); beyond it = uncharted regression
|
term needs the reverse edge, which a oneway does not provide (the anchor
|
||||||
and the gate FAILS.
|
reached one node 126.8 s faster than its own 1.49 s upstream neighbour).
|
||||||
|
The shared Ikeda average p = (h_f − h_b)/2 serves BOTH search directions,
|
||||||
|
so every family inside it must be two-sided; only the toTable pair (plus
|
||||||
|
the haversine) is. Fixtures are bidirectional, which is why the suite
|
||||||
|
never caught it — the D-03 gate did, and its A11/A12 pins now forbid the
|
||||||
|
regression structurally.
|
||||||
|
- **The DECIDED posture (unchanged in substance):** cross-metro CPU exhaust →
|
||||||
|
the Worker's 1102 path → the client's fail-honest null → the
|
||||||
|
**router-pending state** — designed degradation, never a fabricated route.
|
||||||
|
- **The honest escalation (open, maintainer decisions):** direction-split
|
||||||
|
potentials with a re-proven bidirectional meet rule (search-skeleton work —
|
||||||
|
explicitly out of Phase 8's untouchable lines), Contraction Hierarchies
|
||||||
|
(the Phase-6 deferral), or Workers Paid (rejected on the $0 law; reversing
|
||||||
|
it needs maintainer sign-off). Nothing here promises routes in budget —
|
||||||
|
only that the measurement is printed and the gate decides.
|
||||||
|
- Evidence: `routing/scripts/measure-optimality-gate.mjs` (the D-03 record),
|
||||||
|
`routing/scripts/measure-route-cpu.mjs`'s LADDER HISTORY (in-file), and
|
||||||
|
the 08-05 plan summary
|
||||||
|
(`.planning/phases/08-alt-landmark-preprocessing-routing-backend-v2/08-05-SUMMARY.md`).
|
||||||
|
- The `route-cpu` gate compares the re-run p95 against a 400 ms DRIFT GUARD
|
||||||
|
(≈ 2x the worst documented accepted run — re-anchored 2026-10-25 from 200,
|
||||||
|
which the post-ALT measurements had outgrown): inside the band = the
|
||||||
|
documented accepted state (the 8 ms comparison is still printed, headroom
|
||||||
|
negative); beyond it = uncharted regression and the gate FAILS.
|
||||||
|
|
||||||
## Static assets
|
## Static assets
|
||||||
|
|
||||||
|
|||||||
@@ -21,20 +21,31 @@
|
|||||||
* runCacheHeaderGate() id: cache-headers — the LIVE header probe (re-used from cloudflare-probes.mjs)
|
* runCacheHeaderGate() id: cache-headers — the LIVE header probe (re-used from cloudflare-probes.mjs)
|
||||||
* runGoldenCorpusGate() id: golden-corpus — RE-RUNS `routing:corpus` + `search:corpus` as child processes
|
* runGoldenCorpusGate() id: golden-corpus — RE-RUNS `routing:corpus` + `search:corpus` as child processes
|
||||||
*
|
*
|
||||||
* The route-cpu verdict law (the c3 class, decided in Phase 6 / 06-04): the
|
* The route-cpu verdict law (the c3 class, decided in Phase 6 / 06-04,
|
||||||
* full-sample ladder p95 (25 pairs incl. the 10 adversarial quadrant worst
|
* re-measured in Phase 8 / 08-05): the full-sample ladder p95 (25 pairs incl.
|
||||||
* cases) MEASURED 38–93 ms across runs — over the 8 ms product budget, and
|
* the 10 adversarial quadrant worst cases) MEASURED 38–93 ms pre-ALT across
|
||||||
* the mitigation ladder was exhausted WITHIN the $0 law ((a) rejected on
|
* runs — over the 8 ms product budget, and the mitigation ladder was
|
||||||
* correctness — 12/25 pairs unreachable, (b) bidirectional A* shipped,
|
* exhausted WITHIN the $0 law ((a) rejected on correctness — 12/25 pairs
|
||||||
* (c) Workers Paid rejected on the $0 mandate). The DECIDED posture is the
|
* unreachable, (b) bidirectional A* shipped, (c) Workers Paid rejected on
|
||||||
* honest degradation: cross-metro CPU exhaust → Error 1102 → fail-honest
|
* the $0 mandate). The DECIDED posture is the honest degradation: cross-metro
|
||||||
* null → the client's router-pending state; the committed upgrade lever is
|
* CPU exhaust → Error 1102 → fail-honest null → the client's router-pending
|
||||||
* ALT landmark preprocessing (next milestone). This gate therefore checks
|
* state. The ALT landmark lever was EXECUTED in Phase 8 (ARG2 binary +
|
||||||
* the measured p95 against the DOCUMENTED accepted band (a 200 ms drift
|
* landmark steering) and MEASURED on 2026-10-25: the optimality gate is green
|
||||||
* guard ≈ 2x the worst documented run): a p95 inside the band is the
|
* (route seconds equal the frozen pre-ALT record within ±0.1%), but the CPU
|
||||||
* documented state (the record still prints it against the 8 ms budget with
|
* verdict FAILED honestly — 25-route p95 152.788 ms, extended 100-pair p95
|
||||||
* negative headroom — nothing is hidden); a p95 beyond it is UNCHARTED
|
* 185.692 ms (both far over the 8 ms budget; the L=32 probe measured worse:
|
||||||
* regression and FAILS.
|
* 182.725 / 204.499 ms). The sound-but-slower toTable-only steering is
|
||||||
|
* mandatory: the fromTable families are one-directional Lipschitz (their
|
||||||
|
* u-side term needs the reverse edge, which a oneway does not provide) and
|
||||||
|
* the shared Ikeda average p = (h_f − h_b)/2 is consistent only with
|
||||||
|
* two-sided families — the c3 class therefore REMAINS the accepted designed
|
||||||
|
* degradation, and the honest escalation (direction-split potentials with a
|
||||||
|
* re-proven meet rule, Contraction Hierarchies, or Workers Paid) stays open
|
||||||
|
* for the maintainer. This gate checks the measured p95 against the
|
||||||
|
* DOCUMENTED accepted band (a drift guard ≈ 2x the worst documented
|
||||||
|
* accepted run): a p95 inside the band is the documented state (the record
|
||||||
|
* still prints it against the 8 ms budget with negative headroom — nothing
|
||||||
|
* is hidden); a p95 beyond it is UNCHARTED regression and FAILS.
|
||||||
*
|
*
|
||||||
* Test injectability (the privacy-audit suite precedent): every gate accepts
|
* Test injectability (the privacy-audit suite precedent): every gate accepts
|
||||||
* opts-only path overrides; production callers pass nothing.
|
* opts-only path overrides; production callers pass nothing.
|
||||||
@@ -55,10 +66,13 @@ export const P95_BUDGET_MS = 8;
|
|||||||
export const ROUTE_PAYLOAD_BUDGET_BYTES = 204800;
|
export const ROUTE_PAYLOAD_BUDGET_BYTES = 204800;
|
||||||
/** The whole-app bundle ceiling (D-06's record row): 500 KB gz for ALL of web/dist/assets/*.js. */
|
/** The whole-app bundle ceiling (D-06's record row): 500 KB gz for ALL of web/dist/assets/*.js. */
|
||||||
export const APP_BUNDLE_BUDGET_BYTES = 500000;
|
export const APP_BUNDLE_BUDGET_BYTES = 500000;
|
||||||
/** The drift guard for the accepted c3 band: the documented accepted p95 tops
|
/** The drift guard for the accepted c3 band: the documented accepted runs top
|
||||||
* at 93.6 ms (06-04's worst shared-box run); beyond 200 ms nothing the
|
* at 185.692 ms (the shipped L=24 ARG2 config's extended-100 verdict,
|
||||||
* escalation examined applies — uncharted regression. */
|
* 2026-10-25); the pre-ALT band topped at 93.6 ms (06-04's worst shared-box
|
||||||
export const ROUTE_CPU_DRIFT_GUARD_MS = 200;
|
* run) and the L=32 probe measured 204.499 ms. The guard sits at ≈ 2x the
|
||||||
|
* worst documented shipped-config run — beyond it nothing the escalation
|
||||||
|
* examined applies: uncharted regression. */
|
||||||
|
export const ROUTE_CPU_DRIFT_GUARD_MS = 400;
|
||||||
|
|
||||||
/** A missing environment is the exit-2 class: pass:false + notRun:true. */
|
/** A missing environment is the exit-2 class: pass:false + notRun:true. */
|
||||||
function notRun(id, reason) {
|
function notRun(id, reason) {
|
||||||
@@ -122,9 +136,9 @@ export function runCpuLadderGate(opts = {}) {
|
|||||||
// state (see the header's verdict law); beyond the drift guard = FAIL.
|
// state (see the header's verdict law); beyond the drift guard = FAIL.
|
||||||
const pass = !uncharted;
|
const pass = !uncharted;
|
||||||
const verdict = uncharted
|
const verdict = uncharted
|
||||||
? `UNCHARTED REGRESSION — p95 beyond the ${ROUTE_CPU_DRIFT_GUARD_MS} ms drift guard (the documented accepted c3 band tops at ~93 ms)`
|
? `UNCHARTED REGRESSION — p95 beyond the ${ROUTE_CPU_DRIFT_GUARD_MS} ms drift guard (the documented accepted c3 band tops at 185.7 ms measured, 2026-10-25)`
|
||||||
: overBudget
|
: overBudget
|
||||||
? `over the ${P95_BUDGET_MS} ms product budget — the DOCUMENTED, ACCEPTED c3 class (cross-metro honest degradation: 1102 → fail-honest null → router-pending; mitigation ladder exhausted within the $0 law; the ALT landmark lever is a next-milestone item)`
|
? `over the ${P95_BUDGET_MS} ms product budget — the DOCUMENTED, ACCEPTED c3 class (cross-metro honest degradation: 1102 → fail-honest null → router-pending; the ALT landmark lever was EXECUTED in Phase 8 and measured over budget on 2026-10-25 — optimality green, CPU verdict FAIL — so the class remains; the escalation stays open)`
|
||||||
: `within the ${P95_BUDGET_MS} ms product budget`;
|
: `within the ${P95_BUDGET_MS} ms product budget`;
|
||||||
const evidence =
|
const evidence =
|
||||||
`p95 ${p95.toFixed(3)} ms <= 8 ms budget (10 ms free-plan ceiling) — NOT satisfied as stated: ` +
|
`p95 ${p95.toFixed(3)} ms <= 8 ms budget (10 ms free-plan ceiling) — NOT satisfied as stated: ` +
|
||||||
|
|||||||
@@ -111,6 +111,10 @@ await test("CPU3 on the current tree the ladder runs, the measured p95 is printe
|
|||||||
assert.match(r.evidence, /10 ms free-plan ceiling/, "the free-plan ceiling must be printed");
|
assert.match(r.evidence, /10 ms free-plan ceiling/, "the free-plan ceiling must be printed");
|
||||||
assert.match(r.evidence, /GATE FAIL/, "the child's own GATE FAIL line (cross-metro class) is part of the evidence");
|
assert.match(r.evidence, /GATE FAIL/, "the child's own GATE FAIL line (cross-metro class) is part of the evidence");
|
||||||
assert.match(r.evidence, /c3/, "the accepted c3 escalation class must be named");
|
assert.match(r.evidence, /c3/, "the accepted c3 escalation class must be named");
|
||||||
|
// 08-05 pin: the record carries the POST-ALT truth — the ALT lever was
|
||||||
|
// executed and measured over budget (never "a next-milestone item" again).
|
||||||
|
assert.match(r.evidence, /EXECUTED in Phase 8/, "the executed-and-measured ALT verdict must be named");
|
||||||
|
assert.doesNotMatch(r.evidence, /next-milestone/, "the stale next-milestone wording must never return");
|
||||||
});
|
});
|
||||||
|
|
||||||
await test("CPU4 a missing graph binary is notRun — NEVER a pass (T-07-22)", async () => {
|
await test("CPU4 a missing graph binary is notRun — NEVER a pass (T-07-22)", async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user