Repository navigation
Add the updater scaffolding and own the silent-check stamp - #271
Conversation
Every product backend re-implemented the same updater flow: background worker, phase state box for the RVT1 update-state event, error mapping, and the silent-check throttle stamp — with three different write-time semantics, one of which silenced four hours of launches after a single offline start. The scaffolding module binds config, destination, and a settings adapter; check and download settle synchronously against the deadline-bounded updaters while the phase box feeds the RVT1 layer, and transport hooks stay injectable for deterministic tests. The stamp is written only when a check settles — answer or definitive failure — and silent-check-due? reads it through the product's settings interface.
…ucket Three defects the full-suite runs exposed: 1. The test helper sorted the keyword list without sorting the value list, so keyword-apply silently swapped #:fetch into #:settings' slot on every fetch-only call (the CI red on Racket 9.0/core). The helper now sorts (keyword value) pairs together; a second site used apply with a keyword list, feeding keywords as positional arguments — replaced with a direct keyword call. 2. The public-api expectation missed four exports of the new module (updater-runtime?, updater-settings-adapter?, and two accessors) and duplicated struct:updater-config, which made the list comparison fail no matter what shipped. 3. Two assertions disagreed with the module's real contract: downloaded_path is stored as a string (the test re-wrapped it in path->string), and the failure-settle scenario compared the stamp against an injected clock while the runtime stamps current-seconds. resolve-rollout-bucket! and draw-rollout-bucket join the module (issue #240's settings-interface proposal covers the bucket as well as the throttle stamp): one 0-99 value per installation, drawn from OS entropy, recovered on later runs, redrawn on corrupt stored values, degrading to an unpersisted draw when the store cannot write. The writer binding cannot be named set! — (set! key value) parses as the assignment form and silently rebinds the parameter instead of calling the adapter.
5c953ef to
6af1521
Compare
|
Taking over the finishing pass (the branch had been idle since 2026-10-16 12:55 with two red Racket jobs). Pushed to this branch, rebased onto current main:
Full suite green locally: 10002 tests. One gem from the fix pass: the writer binding inside |
Closes #240 and #251.
Scaffolding (): a runtime binds the updater config, destination directory, settings bridge, and injectable transport hooks. fetches, selects, and drives the download while the phase box ( + percent + message + downloaded path) feeds the product's
update-stateevent — the 109 duplicated lines across products collapse into one tested module, with the same extraction move as keel.Throttle stamp (#251): the stamp is written only when a check settles — an answer or a definitive failure — so a threadly-macOS-style pre-check stamp (one offline launch = silent for 4 h) and the movebit no-stamp behavior both end.
silent-check-due?reads through the product's settings adapter; hosts stop hand-rolling timestamps in three languages.Acceptance for product deletions lands in the products as they rebase on the next rivet release.