Skip to content

fix(power): show Bloom Shell shutdown lifecycle (UI-12) - #644

Merged
boburning merged 6 commits into
mainfrom
feature/ui12-bloom-shell-shutdown
Sep 1, 2026
Merged

boburning merged 6 commits into
mainfrom
feature/ui12-bloom-shell-shutdown

Conversation

@boburning

@boburning boburning commented Aug 31, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • recognizes MODE_BLOOM_SHELL in the physical power-hold shutdown path
  • asks Bloom Shell to exit through its normal SDL cleanup instead of waiting for the 30-second force-poweroff watchdog
  • treats an authenticated /tmp/.offOrder frontend return as an expected guarded shutdown
  • lets the existing runtime draw the built-in Shutdown lifecycle surface before the canonical clean power service runs
  • reopens UI-12 in the v3 ledger and records the signed post-fix(network): serialize developer SSH reconciliation #642 F1 regression checkpoint without publishing private ROM or framebuffer data

This is an independent UI-12 lifecycle correction based directly on current main. It is not stacked on another open implementation PR.

Fixes #643.

Root cause

system_state_update() already classified the frontend as MODE_BLOOM_SHELL, but keymon::deepsleep() handled MainUI, GameSwitcher, games, apps, and DraStic only. From Bloom Shell it set the shutdown order, left the frontend running, waited the full 30-second watchdog, and called the force-poweroff path. Because runtime.sh was still waiting for Bloom Shell, it never reached check_off_order "End" and never drew Saving or Shutdown. This exactly matches the maintainer's physical observation.

Validation

  • git diff --check
  • clang-format 21.1.8 dry-run: passed
  • JSON parse for the v3 ledger and new structured evidence: passed
  • canonical legacy manifest: 326 components
  • dependency inventory: 326 components, 1,967 files, 260,662,655 bytes
  • provenance policy: 7 components
  • transfer policy: 6 roots, 5 read-write, 1 read-only
  • focused lifecycle, runtime, GameSwitcher, platform, core-policy, RA-evidence, and ledger shell tests: 73/73
  • exhaustive shell integration: 819/819 across 8 shards in 122 seconds
  • native: 595/595 in 14.389 seconds
  • AddressSanitizer: 595/595 in 24.572 seconds; 29.3 seconds wall time
  • scoped cppcheck 2.19: passed with inherited informational/style findings only
  • Linux host compilation accepted every Bloom Shell source; final host link is unavailable because the checkout intentionally carries ARM SDL/sqlite libraries

Hosted CI passed the required affected ARM build. Hardware workflow run 33398942755 then built and signed exact source e9ce0c30269b083942f3da3d03a7079a083024cf in 6m33s using the pinned Miyoo toolchain.

Device evidence

Before this correction, signed installed version 0.1.0-dev-0b3b5d96 (tree-identical to merged a79d953416cd177d1927a2dd1172f3b184f5b425) passed a controlled post-recovery F1 regression gate on one Miyoo Mini Plus:

  • real gpSP RetroArch reached canonical RUNNING;
  • MENU opened GameSwitcher;
  • START opened and closed Quick Settings;
  • resume retained the same PID and request;
  • the 90-second smoke stopped gracefully, flushed saves, returned to Bloom Shell, and recorded Recent;
  • global RetroArch configuration remained byte-identical;
  • aggregate health remained healthy, update state known-good, network transaction idle, and the listener audit clean with only key-only SSH.

Structured evidence is in docs/validation/shell/plus-post-642-f1-20260831.json.

The installed-runtime boundary was real: the correction spans persistent runtime.sh, keymon, and Bloom Shell, while no supported Warm component may coherently replace that set. A signed Full checkpoint was therefore used. The 185,666,311-byte archive matched SHA-256 5aed74c2c75fce46d9a02eb8342dcd0c23391111ad76cb8da7b5f09033d4218e; Ed25519 metadata verification passed; on-device staging and preparation reverified it; and retained known-good 0.1.0-dev-0b3b5d96 remained the explicit rollback source. The exact candidate booted once as 0.1.0-dev-e9ce0c30 with green aggregate health, associated Wi-Fi, an idle network transaction, a clean key-only listener audit, one Shell and one keymon process, no active session or development overlay, and exact installed Shell/keymon/runtime hashes. That first candidate remained deliberately unconfirmed because the maintainer-observed physical power hold did not show Saving or Shutdown.

The final signed candidate v0.1.0-dev-c1fc6624 from commit c1fc66240475a0763d132da84342b8fb3cdeb66c passed hardware workflow 33455349733. It excludes the legacy battery-header renderer from the fixed Saving and Shutdown surfaces and keeps framebuffer ownership for the complete bounded dwell. The maintainer physically observed both screens, the device powered off, and it returned on the same exact candidate. Installed payload hashes persisted across two boots. Aggregate health, five verified save snapshots, idle network transaction, inactive recovery lease, clean key-only SSH listener policy, and inactive development overlay were then verified before the candidate was confirmed known-good. Structured evidence is in docs/validation/ui/plus-ui12-shutdown-c1fc6624-20260831.json.
A malformed validation login briefly sourced inherited /etc/profile and exposed a pre-existing interactive-SSH Telnet launcher. The exact process was terminated and independent listener audits were clean before staging and after candidate boot. Issue #645 owns that listener-lockdown gap; the candidate's network/SSH/listener binaries are byte-identical to the installed known-good build and this PR does not modify them.

Limitations

  • Remote SSH/process/framebuffer evidence does not certify tactile controls, physical LCD quality, audio, or gameplay.
  • The device evidence covers Miyoo Mini Plus only, not Mini V1-V4 or Mini Flip/my285.
  • The test used a maintainer-owned local game selected by file type; no ROM path, title, hash, save, or private framebuffer was published.
  • No Wi-Fi profile, radio preference, credential, SSH key, listener, or network transaction was changed.

@boburning

Copy link
Copy Markdown
Owner Author

Pushed follow-up �20bd7e2 after the failed physical gate.\n\nFocused correction:\n- Bloom Shell shutdown now selects the Saving-to-Shutdown lifecycle path.\n- �ootScreen End_Save runs synchronously before shutdown hooks.\n- �ootScreen End runs synchronously afterward and receives a bounded two-second physical dwell.\n- The prior asynchronous renderer race is removed; clean power remains the final operation.\n- Sanitized evidence records that the first signed candidate stayed unconfirmed.\n\nVerification retained for this exact head:\n- focused lifecycle/evidence shell tests: 14/14;\n- exhaustive shell integration: 823/823;\n- native: 595/595;\n- AddressSanitizer: 595/595;\n- manifest/dependency/provenance/transfer gates passed;\n- diff and shell syntax checks passed.\n\nThe earlier candidate remains unconfirmed. I will use a new signed exact-head candidate for the next physical gate.

@boburning

Copy link
Copy Markdown
Owner Author

Second signed Mini Plus physical gate failed on v0.1.0-dev-8aa37619.

Observed by the maintainer:

  • neither Saving nor Shutdown was visible;
  • the candidate remained unconfirmed;
  • the third candidate boot triggered the supported automatic rollback.

Verified recovery:

  • installed version returned to signed v0.1.0-dev-0b3b5d96;
  • update state recorded 8aa37619 as the failed version;
  • aggregate health is green, the network transaction is idle, and key-only SSH is running;
  • the recovered baseline was explicitly confirmed known_good.

Follow-up commit c1fc6624 targets the shared renderer failure point: Saving and Shutdown no longer enter the legacy battery-header path, and bootScreen now retains framebuffer ownership for 1.5s/2.5s inside the renderer rather than exiting before an external shell sleep. Focused lifecycle checks pass 14/14 and the changed bootScreen source compiles with the pinned Miyoo ARM toolchain. A new signed candidate will remain unconfirmed until the next physical LCD/power gate passes.

@boburning

Copy link
Copy Markdown
Owner Author

Physical Mini Plus gate: PASS

  • Signed candidate: v0.1.0-dev-c1fc6624 from commit c1fc66240475a0763d132da84342b8fb3cdeb66c
  • Hardware workflow: https://github.com/boburning/BloomOS/actions/runs/33455349733
  • Maintainer physically observed both the Saving and Shutdown screens; the device completed poweroff and returned on the same exact candidate.
  • Installed bootScreen and runtime.sh hashes matched across the two boots.
  • After the physical cycle, aggregate health was green, five save snapshots were verified, the network transaction was idle with an inactive recovery lease, listener audit was clean with only reviewed key-only SSH, and the development overlay was inactive.
  • The candidate is now confirmed known_good.
  • Focused shutdown and critical-surface tests passed 14/14.

Structured evidence: docs/validation/ui/plus-ui12-shutdown-c1fc6624-20260831.json

Scope remains Mini Plus only; no video capture, non-Plus hardware, audio, gameplay, save-semantics, or soak claim is made.

@boburning
boburning merged commit 35ca069 into main Sep 1, 2026
6 checks passed
@boburning

Copy link
Copy Markdown
Owner Author

Merged as 35ca0698c93004d2c65b39cc404999b940fc5267.

The physically verified implementation commit c1fc66240475a0763d132da84342b8fb3cdeb66c is an ancestor of merged main. The only paths changed between that signed/confirmed implementation commit and the merge are the structured evidence, device-support/program documentation, and focused evidence assertions; no runtime source, release manifest, dependency inventory, or device payload changed. The Mini Plus therefore remains on the exact signed v0.1.0-dev-c1fc6624 build that passed the physical Saving/Shutdown gate and was promoted to known-good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI-12: route Bloom Shell power hold through lifecycle shutdown

1 participant