Publish owned runtime marker atomically - #2561
Merged
ymichael merged 1 commit intoAug 27, 2026
Merged
Conversation
Avoid exposing an empty or truncated owned-runtime.json while the producer write is still in progress.
ymichael
deleted the
bb/ci-flake-fix-appimage-owned-runtime-partial-json-thr_6w9nbpi9k4
branch
August 27, 2026 18:41
ymichael
added a commit
that referenced
this pull request
Sep 1, 2026
## Human comments ## What was wrong The Linux AppImage lifecycle smoke treated the server listener's first successful `/health` response as proof that the owned bb stack was ready. The listener opens before `pluginService.start()` settles, and the desktop returns from its initial server probe before `bb-app` has finished starting and connecting the host daemon. The smoke could therefore tear down the GUI while server startup work was still in flight, then misreport a later timed-out health request as `bb became unhealthy after the GUI mount teardown`. Fresh Intel x86_64 validation against current main (`2c9f82548471c7fb160ab343c7dd8ce74bbecbc1`) reproduced that exact signature on the first real AppImage run. It also showed that the original PR's daemon-connected condition alone was insufficient on current main: that version reproduced the exact failure in 3/5 real AppImage runs without synthetic load. A daemon can connect before plugin startup settles. The separate pre-runtime `SIGTRAP` fixed by [#2657](#2657) occurs before `owned-runtime.json` exists and is not this failure. ## What changed - Merged current main normally, retaining the atomic owned-runtime publication from [#2561](#2561), the Linux smoke sandbox/stdio fixes from [#2657](#2657), and packaged-smoke exit settlement from [#2663](#2663). - Before GUI teardown, the lifecycle smoke now requires the isolated host daemon's `/status` response to report `connected: true` for the expected server URL. - It then calls the existing `/api/v1/system/providers` endpoint, whose handler waits on `providerRegistry.whenRegistrationsSettled()`. This is the direct signal that asynchronous plugin startup has settled; plugin startup failure also settles accurately rather than hanging readiness. - If the GUI exits during this readiness phase, the smoke reuses the existing bounded stdio-flush diagnostic before reporting its exit. GUI and owned-runtime death still fail immediately. The post-teardown contract is unchanged: the owned runtime PID must remain live, its independent AppImage mount must remain active, and all three health requests must succeed. No timeout, polling interval, retry budget, protocol, product runtime, or packaged behavior changed, so no host-daemon protocol bump is needed. ## How you verified All reproduction, build, test, typecheck, smoke, and load work ran on Intel host `host_nwqfteeqz4` in a temporary local x86_64 Ubuntu 24.04 VM with working FUSE; the VM was deleted after a zero-leak process/mount/temp-root audit. - Red, current main: the first real x64 AppImage run reproduced `bb became unhealthy after the GUI mount teardown`. - Red, inherited daemon-only candidate: the exact failure reproduced in 3/5 real AppImage runs without synthetic load. - Green, final direct-settlement candidate: 5/5 consecutive real AppImage runs passed, then the official Turbo smoke passed after the exact-final AppImage rebuild. - Bounded load: 3/3 additional real AppImage runs passed while two of four guest CPUs ran at 75%; every load process was stopped after its run and every cleanup audit was empty. - `pnpm exec turbo run desktop:build:linux --filter=@bb/desktop --cache-dir=.turbo/cache --output-logs=new-only`: 13 tasks passed on the final commit. - `xvfb-run -a pnpm exec turbo run smoke:appimage-lifecycle --filter=@bb/desktop --force --cache-dir=.turbo/cache --output-logs=new-only`: passed on the final AppImage. - `pnpm exec turbo run test --filter=@bb/desktop --force`: 38 files, 248 tests passed on Linux. - `pnpm exec turbo run typecheck --filter=@bb/desktop`: 3 tasks passed. - `pnpm exec turbo run build --filter=@bb/desktop`: 12 tasks passed. - `node --check apps/desktop/scripts/smoke-linux-appimage-lifecycle.mjs`, focused `oxfmt --check`, and `git diff --check`: passed. > AGENT GENERATED: by GPT-5.6-Sol
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Human comments
What was wrong
The desktop owned-runtime supervisor wrote
owned-runtime.jsondirectly at its final pathname.writeFilemakes that pathname observable after creation/truncation but before all JSON bytes are written, so the AppImage startup poll could read an empty or truncated marker and fail immediately inJSON.parse, as captured in main CI run 33093605671. Investigation and implementation started from the independently verified main SHA47ba90e6c2f379615a76d9e4c2dc421f8da08aef.What changed
owned-runtime.jsonis not yet visible.The smoke reader, its assertions, and all polling intervals, deadlines, retry budgets, and wrapper clocks are unchanged. Persistent malformed JSON at the final pathname therefore remains a meaningful smoke failure instead of being treated as readiness. This is desktop-local filesystem publication only: no server/host-daemon wire contract changed, so
HOST_DAEMON_PROTOCOL_VERSIONremains 171.How you verified
test/owned-runtime-supervisor.test.tsdeterministically observedUnexpected end of JSON inputwhile the base producer write was paused (it was first run as a standalone publication test before consolidation).pnpm exec turbo run test --filter=@bb/desktop --force -- test/owned-runtime-supervisor.test.ts(4 tests).pnpm exec turbo run typecheck --filter=@bb/desktop --force.pnpm exec turbo run build --filter=@bb/desktop --forceand a final cached-upstreampnpm exec turbo run typecheck build --filter=@bb/desktop.pnpm exec oxfmt --check apps/desktop/src/owned-runtime-supervisor.ts apps/desktop/test/owned-runtime-supervisor.test.ts.Smoke Linux AppImage mount lifecycle, both package-smoke jobs, and every test/check job.bb-processAppImage supervisor test failed on this macOS host because/procis unavailable. The changed focused suite is green; no unrelated SIGTRAP behavior was exercised or changed.