Skip to content

I2489 — A screen over its budget fails the build: the UI's latency budgets are benchmark policy, and bench --check holds them

Make the owner's UI latency budget something CI enforces: the benchmark policy declares absolute bounds, bench --check holds them with or without a baseline and on every host, and the ui job runs that check on every change that can slow a screen.

DONE wave 2 · p1 · implementation profile · parallel safe

Part of development-runtime — The runtime has a development surface.

Objective

Make the owner's UI latency budget something CI enforces: the benchmark policy declares absolute bounds, bench --check holds them with or without a baseline and on every host, and the ui job runs that check on every change that can slow a screen.

Why

ADR 0142, part 4. The owner's pack set the budgets (a cached capability under 50 ms at p95, a warm server-rendered page under 100 ms, a live update under 250 ms) and said they are 'measured, never invented'. Today nothing holds them: the bench times the UI's screens since the UI-performance batch, and reports; it refuses nothing. The UI was eight seconds slow on master for a day before a person said so.

Current state

majordomus bench times every screen of the UI (system.http.ui.* over a pinned context, system.http.live.ui.* over the live view) and bench --check compares a run with a baseline of the same host. A target that was always too slow never regresses, and a platform with no baseline compares nothing, so nothing held a screen to a bound. Measured before this change, debug build at load 57: every warm screen at 1-21 ms p95 except /ui/command at 400-660 ms.

Desired state

.ai/repo/benchmarks/rust/policy.yaml gains budgets: each a prefix of target keys, a cache mode, a metric, a bound in milliseconds and a minimum number of samples, every key but the last required and a malformed one a policy error that names it. Check::compare judges every measurement a budget bounds, whether or not a baseline exists and whatever host recorded it, as PASS, OVER or SHORT; bench --check prints the budget lines with the target, its value and its bound, says within or over budget, and exits 10 when anything is over. The policy declares a warm screen of the UI within 100 ms at p95 for both views. The ui job of validate runs bench system.http. --check before the browser audit, as a step of the ui-audit gate. /ui/command no longer walks the registry once per command: it indexes command lines once per screen. Not done here: measuring the first request after the repository moved, which is I2485.

Scope

  • apps/majordomus-cli/src/bench/baseline.rs
  • apps/majordomus-cli/src/ui/command.rs
  • apps/majordomus-cli/tests/bench_units.rs
  • .ai/repo/benchmarks/rust/policy.yaml
  • .ai/repo/ci/gates.yaml
  • .github/workflows/validate.yml
  • .ai/repo/benchmarks/rust/README.md
  • docs/MAJORDOMUS_UI.md
  • test/cases/1099_a_screen_over_its_budget_fails.sh
  • .ai/repo/project/issues/I2489.yaml

Dependencies

What waits on this

Acceptance criteria

  • A warm screen measured over its budget fails bench --check with exit 10 and no baseline to compare, and the report names the screen, its value and its bound
  • A budget bounds only the prefix and the cache mode it names, and a measurement of fewer samples than its minimum is SHORT and does not fail
  • A budget with a required key missing, or a cache mode that is not one, is a policy error that names the key
  • The repository's policy declares the UI's budget for the pinned and the live view, and every screen is within it
  • The ui job runs the check before the browser audit, under a bound smaller than the job's

Validation

  • bin/majordomus plan validate
  • cargo test --test bench_units
  • MJ_TEST_JOBS=2 bash test/run.sh 1099_a_screen_over_its_budget_fails
  • majordomus bench system.http. --transport system --profile ci --no-write --check

Evidence required

  • bench_budget_unit_tests
  • ui_budget_gate_case_1099
  • ui_budget_bench_results

Evidence

coverstypecommandresultat commit
bench_budget_unit_teststestcargo test --manifest-path apps/majordomus-cli/Cargo.toml --test bench_unitstest result: ok. 7 passed; 0 failed, on a tree equal to master 3442ce68c5: a result over its budget fails the check and is named, one within it passes, a result with too few samples is reported and not judged3442ce6
ui_budget_gate_case_1099testbash test/run.sh 1099_a_screen_over_its_budget_failsok 1099_a_screen_over_its_budget_fails, on a tree equal to master 3442ce68c5: a screen over its budget fails the check and is named, one within it passes, the policy declares both views3442ce6
ui_budget_bench_resultscimajordomus bench system.http. --transport system --profile ci --no-write --checkbench --check: within budget, in the ui job of validate run 38379385624 on master e506c041a4 (job 115235815811), a GitHub-hosted Linux runner; every system.http.ui. and system.http.live.ui. result warm, p95, at or under 100 ms with 20 samples. Not repeated on 3442ce68c5: a local run on a Mac at load 125 could not hold its own server (exit 13)3442ce6

Timeline

started
2026-10-13T12:50:07Z
verified
2026-10-13T12:50:24Z
completed
2026-10-13T12:50:44Z

Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.

Canonical record: .ai/repo/project/issues/I2489.yaml. Read it back with majordomus plan show I2489.

Searches the titles and descriptions of every page this site publishes.