Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,8 @@ windows/bench/windows-first-paint*.json text eol=lf
# Raw IPC timing corpora are evidence payloads, not reviewable line-oriented source.
# Keep exact bytes in Git but suppress text diffs; producers emit compact JSON.
*/bench/results/ipc-rtt/*.raw.json -diff text eol=lf

# KEL-270 handover quit deadline evidence. The captured logs, TSVs and JSON are
# CRLF as the Windows runner wrote them and SHA256SUMS is over those exact
# bytes; -text stops core.autocrlf from rewriting them on any checkout.
windows/keld/handover-quit-deadline-2026-10-14/** -text
30 changes: 30 additions & 0 deletions MEASUREMENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1735,3 +1735,33 @@ Fresh-process and warm-cache are separate campaigns. Their central values must
not be subtracted to claim that cache warming caused a percentage speedup or
slowdown. What this campaign establishes is that the registered warm-cache
treatment is reproducible under a thermally verified v3 block-corpus session.

## Keld handover quit deadline D — windows (2026-10-14, diagnostic)

KEL-270 T4d S6c2a (gyldlab/keld#722, merge commit `1b4365ac`) sets the deadline D
a profile handover gives the reference application to request `Quit` after the host's
`LastWindowClosed` write. The rule is D = max(10 s, 4 x the measured maximum). The raw
evidence is at
[`windows/keld/handover-quit-deadline-2026-10-14/`](./windows/keld/handover-quit-deadline-2026-10-14/)
(verify with `sha256sum -c SHA256SUMS` there).

One sample is the host-monotonic interval from the return of the `LastWindowClosed`
write to the lifecycle-Quit handler's entry for the `Quit` that claims the session. 30
idle runs and 30 runs under full-core load (16 busy-loop burners on 16 logical cores)
all passed. The host was a debug build with the `kel135-profile-test-root` feature built
from Keld `045b4a45` (the pull request's measured path is unchanged by its later
commits), on Windows 11 10.0.26300, AMD Ryzen 7 5800H, WebView2 155.0.4283.45, Bun 1.4.2.

| subset | n | min | median | p90 | max |
|---|---:|---:|---:|---:|---:|
| idle | 30 | 0.485 ms | 0.624 ms | 1.060 ms | 1.148 ms |
| full-core load | 30 | 0.739 ms | 1.035 ms | 68.985 ms | 218.510 ms |

The maximum over both subsets is 218.510 ms; four times it is 0.874 s, below the 10 s
floor, so D = 10 s. p90 uses `sorted[int(0.9 * n)]`, not nearest-rank (stated in the
bundle's README).

This is a single-machine, single-session, debug-host diagnostic. It is not a
`result.v*` document, not a release-build measurement, and says nothing about other
machines, a loaded WebView2 content process, or the barrier wait before `LastWindowClosed`
(`ui_end_us`, up to 29.1 s under load, which is not part of D).
117 changes: 117 additions & 0 deletions windows/keld/handover-quit-deadline-2026-10-14/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# KEL-270 T4d S6c2a: the quit deadline D measurement (keld-benches artifact)

Quantity: D, the time the reference application has after the host's `LastWindowClosed`
write at a profile handover to request `Quit` (KEL-53 §4 *Margin and deadlines*).
Rule: D = max(10 s, 4 x the measured maximum).

## What one sample is

One run of the §7 h11 cell (`profiles::handover::kel270_s6c2a_h11_reference_app_quits_within_d_after_handover`
in `crates/keld-host/tests/no_flag_windows.rs`). The host (`keld-host.exe`, debug, built
with `--features kel135-profile-test-root`, installed by the KEL-254 per-user fixture and
operator-signed with the KEL-135 acceptance publisher P1) runs under the debug seam
`KELD_TEST_WINDOWS_HANDOVER=1`: right after the first session's `Ready` it requests a
profile handover, ends its UI loop through `AppWindowCommand::Quit`, writes
`LastWindowClosed` once the loop has returned and waits for the reference application's
`Quit`. The sample is the interval on the host's monotonic clock from the return of that
`LastWindowClosed` write (`signal_last_window_closed`) to the lifecycle-Quit handler's
entry for the frame (`lifecycle_quit`), recorded only for the `Quit` that claims the
session, printed by the host as
`KELD_TEST_WINDOWS_HANDOVER {"cause":"lifecycle-quit","ui_end_us":..,"quit_wait_us":..,"forced_after_us":null,"deadline_us":10000000}`.
`quit_wait_us` is the sample; `ui_end_us` (request to loop return, the barrier wait) is
recorded beside it. The reference application is the t1b fixture
(`crates/keld-host/tests/fixtures/t1b_harness.ts`, bundled with `@keld/api`), which on
`LastWindowClosed` reports `LAST_WINDOW_CLOSED` on its control socket and then invokes
the lifecycle `Quit` call, the same path the `@keld/electron` `window-all-closed` default
takes.

## Subsets

- `idle`: 30 runs, nothing else running on the machine but the harness.
- `load`: 30 runs under full-core load: 16 busy-loop PowerShell processes
(`while ($true) { $x = 1 }`), one per logical core, started by `burners.ps1 start`
before the runs and stopped after them (the KEL-270 F55 method).

## Files

- `samples.json`: every run (subset, run, outcome, cause, `quit_wait_us`, `ui_end_us`,
`deadline_us`), the per-subset min/median/p90/max and the computed D.
- `idle-samples.tsv`, `load-samples.tsv`: the raw evidence lines per run as the runner
captured them (`run-cell.ps1`), one row per run.
- `idle-runs/`, `load-runs/`: the per-run logs (`run-NN.log`), each with the host's
stdout (the evidence line, `KELD_PROFILE_TEST_*`, the `KELD_KEL270_H11` record) and
the test's assertions.
- `burners.log`: the burner start/status/stop receipts of the load subset.
- `environment.json`: machine, OS build, toolchain, WebView2 runtime, host build and
the commit hash the host and test binary were built from.
- `host-record.json`: the signed host's embed/sign record (hashes, signer thumbprint).
- `analyze_d.py`: the summariser that produced `samples.json` from the two `*-samples.tsv`
files (`python -I analyze_d.py idle-samples.tsv load-samples.tsv samples.json`).
- `run-cell.ps1`, `run-cells.sh`, `burners.ps1`, `idle-tally.txt`, `load-tally.txt`: the
runner, the run loop, the load generator and the per-run exit/outcome tallies.
- `SHA256SUMS`: SHA-256 of every other file in this directory (see Verification).
- `SOURCE-SHA256SUMS.txt`: the checksum list of the bundle as captured, before the
redaction and README changes described under Publication changes.

## Result

Measured 2026-10-14 on a single Windows machine (Windows 11 Home 10.0.26300, AMD Ryzen 7 5800H, 16 logical
cores), WebView2 runtime 155.0.4283.45, rustc 1.97.1, Bun 1.4.2, debug host built from
commit 045b4a45 of the S6c2a branch, https://github.com/gyldlab/keld/pull/722
(`--features kel135-profile-test-root`; later commits of the pull request leave the
measured path unchanged), signed as `hosts/new`
(sha256 83e9e60c5e891a9ba9f3b2b28bb38804e008bee2aa5b0be499a55a4be607ff40).

| subset | n | min | median | p90 | max |
|---|---|---|---|---|---|
| idle | 30 | 0.485 ms | 0.624 ms | 1.060 ms | 1.148 ms |
| full-core load | 30 | 0.739 ms | 1.035 ms | 68.985 ms | 218.510 ms |

Maximum over both subsets: 218.510 ms; four times it is 0.874 s, below the 10 s floor,
so **D = 10 s** (`HANDOVER_QUIT_DEADLINE` in `crates/keld-core/src/app_session.rs`).
Every run passed (60/60). `ui_end_us` (the handover request to the UI loop's return,
dominated by the liveness-gated `BrowserProcessExited` barrier) reached 29.1 s under
load; it is not part of D.

Note: a `cargo check -p keld-core --tests` (one light build) ran on the machine during
load runs 15 to 17; it adds load beside the burners and can only lengthen samples.

## Estimator note

The p90 column (and `p90` in `samples.json`) is `sorted(samples)[min(n - 1, int(0.9 * n))]`
(`analyze_d.py`), the zero-based element at index `int(0.9 * n)` of the ascending sort,
which for n = 30 is the 28th smallest sample. It is **not** the nearest-rank estimator
(the `ceil(0.9 * n)`-th smallest, the 27th for n = 30), so it can read one rank higher.
p90 is descriptive only: D is derived from the maxima, never from p90.

## Publication changes

This directory is the captured bundle plus these changes, made when it was published in
keld-benches; no sample value, timing, outcome or tally was changed.

- This `Estimator note` and the `Verification` section were added, the `Files` list
was completed, the per-run log name was corrected from `run-NN.utf8.log` to `run-NN.log`,
and the machine name in `Result` was replaced by a generic phrase.
- `HARNESS-CONTRACT.md` section 1 forbids absolute paths, home directories and hostnames in
committed files, so a byte-wise literal replacement was applied to the captured files:
the user profile directory (plain and JSON-escaped) became `%USERPROFILE%`, the Keld
worktree path became `<keld-worktree>`, the local evidence directory (also in
`run-cell.ps1`, `run-cells.sh` and `burners.ps1`) became `<evidence-dir>`, and the
machine name became `<redacted-hostname>` (in `environment.json`). The scripts therefore
need `<evidence-dir>` set to a real directory before they can be re-run.
Line endings of the captured files (CRLF in the logs, the TSVs, the tallies and the JSON
files) are preserved; `.gitattributes` marks this directory `-text` so a checkout does
not rewrite them.
- `SOURCE-SHA256SUMS.txt` lists the hashes of the unredacted captured files, so the
replacement can be audited by file; it is expected to disagree with the files that were
redacted and is not a verification list.

## Verification

```
cd windows/keld/handover-quit-deadline-2026-10-14
sha256sum -c SHA256SUMS
```

Every line must report `OK`. `SHA256SUMS` covers all files except itself, with `./`
relative paths, and is computed over the exact bytes in the repository.
75 changes: 75 additions & 0 deletions windows/keld/handover-quit-deadline-2026-10-14/SHA256SUMS
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
d108515d152b47486a126b700ee1b0dd19d033c310071f714dfec5ebbcdb621a ./README.md
609236977471dcb3130d3c3267107c4bb6df630b24ce32b1c3ffdc4fb260aa07 ./SOURCE-SHA256SUMS.txt
fe9bc053151d411e6a653236cdb05a97bd5a22d8a4dd4fe17047cd85fdc3a802 ./analyze_d.py
15595d473694efaad47fc5cca45db0f6d30ff890bf71d4943dbe0fdd8808a47c ./burners.log
bab91ae4d0ace019c38fe4f4d08878de08445ce1ce55cb0d07ead777933814e7 ./burners.ps1
296d250c17f8e329327d3d718c4498cda205b5bf07891dd9bdad649e756e5a18 ./environment.json
422c8afe95051dcd8528967dc176d5e5ebb2dadc631b2304e934bfed04de0eee ./host-record.json
0659c61126d34b811563c7cfac42f14b32c9cc0061a6b934d7b8a283b7e8bb26 ./idle-runs/run-01.log
9a04e92c012739b8d95bc803e1367d4bf3e3e29b83f8d273519041d9626946d3 ./idle-runs/run-02.log
4422f42a34fdfd2c743a3a08bc33055c07aa8715ba2335a6ae0be16e815d22ff ./idle-runs/run-03.log
43b004674b31348e619acdabd5173c85af12246e2178d341c91cf010fcaf5482 ./idle-runs/run-04.log
33532e3edab1ea5a0599b98c80ac8ee42082012f895d010246d05e0073c4e4cd ./idle-runs/run-05.log
d0ed47376055e67fa3207279779d635b93f7b02faa1b106205680ac8ef5a655c ./idle-runs/run-06.log
dee381f98099a6a794551879e732a315eaa8e4dabf6748f528f23fd5a8d3ffc2 ./idle-runs/run-07.log
6f8045dbc6121a1470015cd98d7e51bf98981f6050c41360c5f455548e94ec40 ./idle-runs/run-08.log
94940ce1839a322608aaeec14ff7b4e9c672c11291f5363503fb2c369a6f7638 ./idle-runs/run-09.log
d03a32050309e1a5fe5105087b2be71444dd36421222bc8c730a960c12305f1c ./idle-runs/run-10.log
c1a72ca2db2f33013f1b98d488ef2d9546b3c1125ec45af1f0d527c923314711 ./idle-runs/run-11.log
98d88487c08d850aeef95b1c7e568ca5d1478f9ba3286cc0da19e7838edd084e ./idle-runs/run-12.log
7c43cf73a9e44cb01e75d546272df3c730eec0a546fde891ea033499f31046ff ./idle-runs/run-13.log
16d2eb465820cb418e9dc2fcbe64c02e8054b19579452feae8a0377acb008ef0 ./idle-runs/run-14.log
1e8ff502dfa86e6fcd51dddf891e81319b53dc88c9c39584ea137165bea0cc74 ./idle-runs/run-15.log
7fa51e5b4ffab59fc36041bb09d441a63425f7740b9bc5be9f7a0322e1d8f92b ./idle-runs/run-16.log
fb82a593ed9d862c831f14ba803747323ac3f993d36ecbf7fcc1c7b31e7e21e1 ./idle-runs/run-17.log
e806647a4e4d71be7c414ab0226a61a41044d4168df13a35909843f3b95a23f7 ./idle-runs/run-18.log
bb47887a3cd02f88d3f5f8651ad010bb64d73eae9ffe5a0a8cd6bfe5ff9e3f13 ./idle-runs/run-19.log
56f0488e19a8d64e02666c1046a33d641852d6b1f39e1be8c1ebe4d5563f73e0 ./idle-runs/run-20.log
a5b8b3bf898e20b3538802dbde34adb875c32c4fe7b725db509009d3d1c9a982 ./idle-runs/run-21.log
215df99d843ef3d8c952c1e65f804f6a596f01fc609338ce605a5a4c639bdb98 ./idle-runs/run-22.log
acbdebb572ea14d5bbf2447d3ee5e6b37d2a887963e5de3584d8f79a72185bb8 ./idle-runs/run-23.log
79ad58b87b9da6237039f909dbe75c6d0613f528e30292397c342dbf4141a687 ./idle-runs/run-24.log
d6f75d456c3d9105e795e84cfc540cf4b5fa6b1e06070f888a740492554bda7f ./idle-runs/run-25.log
6f909c09d6cfae258e28b1b7acdca5740f6e0ac01d85a7a913f39b516a1630a0 ./idle-runs/run-26.log
2dcd5e1b725214a73b185f3c32a0fc42ef425cc995e9aca7407f7ed94f7018bf ./idle-runs/run-27.log
00832524ff139cd9557d6595567942a45842aa7120285f368f1d4dee22418704 ./idle-runs/run-28.log
f44cff376b5f75f461035956403708e11b96da07e651e486012be1e15b10658e ./idle-runs/run-29.log
f0ff9616cfd378f02a9dfa89c5b4f6e2c64e5664b9aab58c5fc73dec37e36538 ./idle-runs/run-30.log
7bb5f605b0cb82fecf501dea3cb995c7519c23530e51fb28414a1206e90a37b7 ./idle-samples.tsv
e9f697ca0d759d14fe28f3c983252887adeed618b2b01623b4644ee82429013f ./idle-tally.txt
3865ecd019ee5103e950e7f0ebdd722c0323439c1ad9ec739d7339f823a1d355 ./load-runs/run-01.log
e504f25c08199faa06708661d1731c3b3d58b404d56eeb738ecdbe5b2a1f306d ./load-runs/run-02.log
e0c146e90ee9a8b26c6980343b3da32cfe1e162a0b1207af98baf1659089a74c ./load-runs/run-03.log
612b76895998384f46d96a0ba3f0a60fa96022b99d89876ed24b64b006c7e049 ./load-runs/run-04.log
54222b3e8e03cab3eaf7d9aabe3ab424346e10e0d6ed45be11e5d47b31b5f3e8 ./load-runs/run-05.log
cc6a0f8228c50ae7c3e41ea3ad3fed9eb5d78d4fadbb25279adcbd66267ce9fe ./load-runs/run-06.log
f03c9dc0a32c746df1d9b3e7c76332115704a72b7dae65f61902edb14b00d14e ./load-runs/run-07.log
7cbdf19f45db6302b4cef369d093c8563c714f040060ea112506e0cff58aee96 ./load-runs/run-08.log
dd8af902bfae26df030ec6c60ee41787a1c47656d9126c739882ddfc86b34582 ./load-runs/run-09.log
59832492a13e91c8d0e6f76cc6a3fc7ee0ffbd17eabc545fcb6dbfa9cee35679 ./load-runs/run-10.log
265290993af3774c7280a25187f26beb35dd6e2cabdca4ede4adcab516315e1e ./load-runs/run-11.log
94211a95f031996064880b9cd926e6b53ddde5742e6d9683dff3fe9197a82151 ./load-runs/run-12.log
296cd9169410237b92f5956a2aede7e04a61023f1d9f822bdc50c200aa76f823 ./load-runs/run-13.log
fe1ddaf99f42ec7e4b71b6904d90a712920131a801d960696fc8cff033dac5db ./load-runs/run-14.log
02d1d439a8d393a80999c92334bf3ed29c62df8cc39b7c5d18db90963d8dadf0 ./load-runs/run-15.log
c4b9dcda96fad672f53aeb7342c5f1f438511ebc236774ea35ee46d9586db4b5 ./load-runs/run-16.log
e7ac35c3cd9085912b71b6d9e8c5647e1cd069022676f139aaf6bc6c5f7827f1 ./load-runs/run-17.log
b097323552908831f12ccf857b6f936fdc978f333e924d2ea5d3ca3701ca9113 ./load-runs/run-18.log
a46b0a9e07035623a61558ab2b469707283e6211b2e45e608d89ece69b4aa336 ./load-runs/run-19.log
cfc67853247b003c1de5ef3277f1ff4ae85573cee5139dc5ba20757a2fa71a4f ./load-runs/run-20.log
89e80164f8f8050304734d4ace702b35c8aefaea62a6c9a709dc4d20d5d1efbc ./load-runs/run-21.log
da0e5194ce757f1549f049f55e42314d8c3e9c3f04555ae4cce998c4c1f05936 ./load-runs/run-22.log
42500296ac47e4f66d9af3e969ed8de59c060d214b8299d40a446642a4b90a23 ./load-runs/run-23.log
f2b38359ded7e2d71b8c7186ea35c2a6808fa57cbb15c1c11126c8fc1f164323 ./load-runs/run-24.log
6f93fb177d865bc4c53ebdb54e840b827d4f8367ae44535936e482a0c3869da7 ./load-runs/run-25.log
149038628d3a66070d6f4549486bb9b47ab0524fc4aeb5c68eaf1bbcf205c040 ./load-runs/run-26.log
9f59a30b1aae93704ccae0dcdb61a9d6498850ac93e71793ff56b47c4d59427e ./load-runs/run-27.log
eacf6ba71d2ec74b3fce4253db5f95ffd5075d44c00d1796beae053ceaab9981 ./load-runs/run-28.log
d540b7bca355e7be37e23d17292514ca3728cbceb8a9047904512b0d73582005 ./load-runs/run-29.log
b46bdc28a5096fb48cf4d6f08f0b0355625c052f1c5ffe8013927525c0b96d0f ./load-runs/run-30.log
53775b7dc3488bf08607382f7c1cb563853f053d109e6be7d7362b8383371387 ./load-samples.tsv
f022432fee92d9dc52fca8a9f5f5fb4252a54de5c2fe5f3c4e189dbd69fd32ae ./load-tally.txt
ce394e0dead96d494ce2f15d432fa8c65ce4df953c3b58158ebcfe6f69ac5b1b ./run-cell.ps1
9a643244f190db814fff7cc45fff2d57fadc1ea6f9009c1df75a2d4f301ef270 ./run-cells.sh
ed8ba102e4808b364bdda65abc902db8493f8fcd5b0b21dc277212ca78faf5d1 ./samples.json
324c9bc4f2a8c338dae7be95242d154a021c29045c3a3aa0666d7aca22b462ce ./summary.txt
Loading
Loading