Refs #4677 and #5038. These two independent workflows collect baselines; they have no schedule or timing merge gate. Run Performance frontend or Performance protocol from Actions after the workflow exists on the default branch, selecting the desired ref. Download the performance-*-<sha> artifact and read the JSON alongside the job summary. Compare explicit commits with identical fixtures and environment; a shared-runner result alone is not a regression verdict.
Both lanes use the existing free ubuntu-24.04 GitHub-hosted x64 runner, one measurement process at a time, Node 24.18.1 and npm ci. Electron is pinned by the repository (43.4.1 at introduction); Playwright/Chromium comes from the lockfile and browser install. JSON records actual OS, CPU, memory, Node and image version; browser results record the browser version. Runner hardware is not dedicated and its image can change. Reject comparisons across different environments and repeat suspicious results.
From a clean checkout, run npm ci. For protocol, build core, storage, mcp, runtime and runtime-host in that order, then node scripts/perf/protocol.mjs. For frontend, run npm --workspace @maka/desktop run build:workspace-deps, npm --workspace @maka/desktop run build, npm --workspace @maka/desktop run build-storybook and npx playwright install --with-deps chromium. From apps/desktop, run MAKA_PERF_OUTPUT="$PWD/../../perf-results" xvfb-run -a npx playwright test --config ../../scripts/perf/playwright.config.ts. From the repository root run xvfb-run -a node scripts/perf/storybook.mjs. Use CI for standard measurements; local runs are for harness debugging.
Reports retain every raw sample. Median averages the two middle observations for even counts; p95 is nearest rank ceil(0.95*n), so ten samples yield the maximum. Counts and one-off diagnostics have n=1 and are not latency distributions. Protocol timings use one discarded warmup and ten measured repetitions; encoding instrumentation is a separate pass and restores JSON.stringify in finally. It counts actual UTF-8 JSON output, including normalization/revision/decoder work, rather than estimated object size. The negative control calls the same production page builder an extra time and must increase measured encoding work. UTF-8 byte caps, decoded values and concatenated page completeness are asserted. This first lane covers Runtime Resource projection through final wire encoding; it does not measure SQLite, transport send, Memory/Plan/Artifact/catalog coordinators, Shell persistence, or Usage. Their implementations are unchanged.
Protocol warm-projection-codec-ms retains production wire decoding but excludes the byte-cap, equality and ordering assertions already run in the untimed baseline and negative-control passes. The cursor progress guard stays in the loop to fail on non-progress instead of hanging. This metric replaces warm-ms (includes validation); do not compare their timings as a product speedup. Existing published reports retain their original metric and values.
The frontend lane measures the current production layout. geometry-navigation.spec.ts reloads three renderer documents in one Desktop
node scripts/perf/geometry-ablation.mjs runs the three fixed-range stories (mixed 24 turns, 45 tools, 1200-line code), with three repetitions each. Its mount CPU/layout counters are recorded before the first upward sweep, so deferred work cannot disappear from the comparison. Scroll metrics cover only that cold upward sweep. Older reports included two return sweeps and are not equivalent timing workloads. Unasserted per-step anchors, LoAF and heap diagnostics are no longer collected by this driver. The script emits the shared report format and full per-frame geometry JSON. Both probes run sequentially in the existing frontend job and upload through its existing artifact step. No additional workflow or production switch exists.
Reports are frontend-geometry-navigation.{json,md} and frontend-geometry-ablation.{json,md}, plus geometry-ablation.json. Compare production reports from the baseline and candidate commits, including every raw sample; three samples do not establish a robust p95. CI success means the scenarios and measurements worked, not that a timing budget or product geometry contract passed. The separate --assert-stable flag remains an explicit geometry assertion, not a hidden performance threshold.
GitHub cannot dispatch a new workflow absent from the default branch. For this PR only, temporarily add push: { branches: [<this PR branch>] } to these workflows, push and inspect both jobs/artifacts. Remove that trigger after verification. Do not merge to obtain a run, add pull_request_target, or leave a permanent automatic trigger. Record both the measured SHA and final SHA in the PR when the sole subsequent change removes the validation trigger.