Skip to content

Read launch-time test hooks only in development builds - #488

Merged
ymote merged 4 commits into
mainfrom
fix/launch-input-test-hooks
Oct 11, 2026
Merged

ymote merged 4 commits into
mainfrom
fix/launch-input-test-hooks

Conversation

@ymote

@ymote ymote commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

On a phone, Home's main activity is exported (the app drawer entry, the Home app, a share target and a deep-link target), so any installed app can start it with intent extras, and Makepad's Android glue copies makepad.<NAME> extras into the environment. OpenHarmony passes makepad.* launch parameters on the same way. OctoSense code read several of these in release builds: test actions, Mail's demo mailbox, module-open settings, the kernel's launch proxy and AppCard's provisioning and seeding hooks.

This hardens them. On a phone (Android, OpenHarmony), launch-time test, demo and provisioning hooks are read only in a development build (cfg(dev_mode): a debug build, or --features dev-mode; never a store build); a release build ignores them and logs once that it did, without the value. On a desktop they are read in every build, because a desktop's environment is the local user's own, the same trust as a command-line flag — this keeps MAKEPAD_APP_CONFIG='{"mail_demo":true}' and the other documented desktop flows working. Desktop --test-action arguments are unchanged.

A separate change closes the one channel Makepad itself acts on in a release build (the Studio connection and the OCTOS_PROXY app proxy), which a shell-side gate cannot reach.

Changes

Shell / apps (this repo)

  • crates/shell/src/launch_input.rs (new): the one reader of MAKEPAD_APP_CONFIG. honoured keys on cfg(native_mobile) — a phone gates on dev_mode, a desktop always reads. run_test_actions, Mail's mail_demo and apps::module_open go through it. A test checks no other shell source reads the variable directly.
  • apps/appcard (opt-in): every MAKEPAD_* hook goes through launch_var/launch_flag, with the same desktop/phone split (launch_set_in(mobile, development, …)). Launch-time provisioning never applies in a phone release build; the QR scan with its PIN is unchanged.
  • crates/kernel: the Android launch proxy (makepad.OCTOS_PROXY) applies only in a development build.
  • New dev-mode feature on octosense-kernel, octosense-ai-host, octosense-appcard and octos-app, forwarded from the shell's dev-mode.

Makepad (companion PR + stacked runtime patch)

The Studio connection (makepad.STUDIO_HOST/STUDIO_CRATE) and the OCTOS_PROXY JVM proxy are things Makepad itself acts on, so they are gated in the Makepad fork: OctoSense-org/makepad#119 honours them from launch input only when the build opts into launch-time development input (debuggable, or the manifest meta-data dev.makepad.LAUNCH_STUDIO), never persists Studio settings in a non-debuggable app, and clears any already saved. To protect a release Home now, without waiting for a makepad sweep, the same change is carried here as the next stacked runtime patch (tools/runtime-patches/makepad-launch-input-hardening.patch) over the pinned makepad base. (The OpenHarmony part of #119 is not carried here — Home builds its own OpenHarmony entry ability, already gated.)

Test builds and docs

  • Android: rom/scripts/build-home.py --dev-mode (App Studio's, App Studio on the phone (ADR 0006 milestone 1): #313 rebased, reviewed, re-validated #477) builds the dev-mode feature: standalone only, never the installed Home's identity under its signer, and refused by ROM staging. Give it a test --package-name dev.makepad.octosense.<suffix>. OpenHarmony: build-home-ohos.py --dev-mode builds a development HAP, which needs its own --bundle-id.
  • Docs and scripts that drove phone test packages with launch extras now name a development build; desktop docs keep the plain cargo run. English and Chinese together. AGENTS.md states the desktop/phone split.

Testing

  • New unit tests: launch_input::tests (a phone release/store build ignores test_actions; a desktop build in every profile and a phone development build read them; malformed input; single reader), launch::tests::only_a_development_build_takes_the_launch_proxy (kernel), AppCard launch_input_tests, rom/tests/test_home_build.py (OpenHarmonyLaunchParameterTests; the Android --dev-mode rules are App Studio on the phone (ADR 0006 milestone 1): #313 rebased, reviewed, re-validated #477's tests). The makepad gate decision is unit-tested in Repin the runtime to makepad 4531e695 (terminal tabs and fonts, system font fallback) #119 (app_main::tests::only_debuggable_or_opted_in_builds_honour_launch_dev_input).
  • tools/ci-local.sh --only desktop,phone,apps --linux-host --offload on the branch head: see the local-CI comment. Covers the shell tests with mobile-apps from phone/ (the new launch_input tests ran there), the opt-in AppCard tests, the kernel tests, AppCard clippy -D warnings, and the desktop/Home cargo check lines.
  • AppCard cargo test -p octos-app (not in CI) on the Linux build host: passes.
  • rom unit tests (JDK 17), generate-agent-aidl.py --check, the workflow bash -n lines, tools/ unittests, setup.py --check --cargo, native_apps.py --check, and build-home.py --dev-mode … --dry-run.
  • makepad Repin the runtime to makepad 4531e695 (terminal tabs and fonts, system font fallback) #119: cargo test -p makepad-platform --lib app_main and cargo check --target aarch64-linux-android -p makepad-platform.
  • The runtime patch applies cleanly from the pinned base to the recorded tree (setup.py reproduces it).
  • Unverified: no device/emulator/DevEco run; no --dev-mode APK or HAP built (the Android plan was checked with --dry-run); no GUI run. The Java and ArkTS changes in Repin the runtime to makepad 4531e695 (terminal tabs and fonts, system font fallback) #119 are not exercised here.

Rebased onto #477

#477 (App Studio) landed first with its own build-home.py --dev-mode, so this PR was rebased onto it (main 0209df1):

Note for merge

This PR touches rom/, so the two-run local-CI gate applies; the coordinator runs it.

🤖 Generated with Claude Code

@ymote
ymote force-pushed the fix/launch-input-test-hooks branch from 7e61173 to 9c90385 Compare October 11, 2026 14:18
ymote and others added 4 commits October 11, 2026 09:59
Home's main activity is exported, so any installed app can start it with
intent extras, and Makepad copies `makepad.<NAME>` extras into the
environment. OctoSense code read several of them in release builds.

- shell: `launch_input` is the one reader of MAKEPAD_APP_CONFIG. Its test
  actions, Mail's demo mailbox and module open parameters apply only in a
  development build (cfg(dev_mode): debug or --features dev-mode); a
  release build ignores them and logs that once. Desktop --test-action
  command-line flags are unchanged.
- kernel: the launch proxy (makepad.OCTOS_PROXY) applies only in a
  development build; new `dev-mode` feature, forwarded from the shell
  through ai-host.
- AppCard: every MAKEPAD_* hook (provisioning, seeding, auto prompt, fake
  GPS, proxy, dumps) goes through `launch_var`, development builds only;
  new `dev-mode` feature, forwarded from the shell through the module.
- OpenHarmony: EntryAbility forwards no launch parameters unless
  build-home-ohos.py --dev-mode stages it (a separate bundle id required).
- Android: Home's `dev-mode` feature comes from build-home.py's
  `--dev-mode` (App Studio's, #477): standalone only, never the installed
  Home's identity under its signer, and ROM staging refuses it. So a build
  that reads launch input is never the installed Home.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Docs and scripts that passed `makepad.*` launch extras to release packages
now name a development test build: `rom/scripts/build-home.py --dev-mode`
under a separate package name on Android, `build-home-ohos.py --dev-mode`
on OpenHarmony, `--features dev-mode` for the desktop mail demo, and
`DEV_MODE=1` / `--features dev-mode` for AppCard's own tools.
`provision-appcard-llm.sh` requires PACKAGE=dev.makepad.octosense.<suffix>.
AGENTS.md states the rule; English and Chinese docs change together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A desktop's environment is the local user's, like a command-line flag, so
`MAKEPAD_APP_CONFIG` (test actions, Mail's demo mailbox, module-open
settings) and AppCard's `MAKEPAD_*` hooks are read in every desktop build.
The gate applies only on Android and OpenHarmony, where a launch Intent extra
or launch parameter can come from another app: there a release build ignores
them and only a development build reads them.

- crates/shell/src/launch_input.rs: `honoured` keys on `cfg(native_mobile)`;
  tests say a phone release build ignores it while a desktop build (any
  profile) and a phone development build read it.
- apps/appcard: `launch_set_in(mobile, development, ...)` — a desktop reads
  the hooks, a phone only in a development build.
- Docs restored to plain desktop `cargo run` commands; the phone and
  OpenHarmony guidance keeps the development-build note. AGENTS.md states the
  desktop/phone split.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Protects a release Home now, without waiting for a makepad sweep: the shell's
pinned makepad gains the Studio/OCTOS_PROXY launch-input gate from
OctoSense-org/makepad#119 as the next stacked runtime patch over the pinned
base, so a shipped Android Home ignores a Studio host or app proxy from an
Intent extra. The OpenHarmony template part of #119 is not carried here, since
Home builds its own OpenHarmony entry ability.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ymote
ymote force-pushed the fix/launch-input-test-hooks branch from 9c90385 to 5b8e4ec Compare October 11, 2026 18:16
@ymote
ymote marked this pull request as ready for review October 11, 2026 18:16
@ymote
ymote merged commit 509d97c into main Oct 11, 2026
4 of 11 checks passed
ymote added a commit that referenced this pull request Oct 11, 2026
Local CI passed on the merge train's head 37008bb (#488 → #501 → #495): two runs, the Linux host and the Mac with rom, plus GitHub's embedded-browser acceptance on this head. See the PR comment.
ymote added a commit that referenced this pull request Oct 11, 2026
Local CI passed on the merge train's head 37008bb (#488 → #501 → #495): two runs, the Linux host and the Mac with rom, plus GitHub's embedded-browser acceptance on this head. See the PR comment.
@ymote

ymote commented Oct 11, 2026

Copy link
Copy Markdown
Contributor Author

Merged in a train (#488 → #501 → #495) on two local runs of the train head 37008bb, which contains this PR's head 5b8e4ec. Merged in order with gh pr merge --admin --merge --match-head-commit; main's tree after the last merge equals the tested tree.

  • Run 1: tools/ci-local.sh --only all --linux-host --offload, PASSED in 22m21s (55 PASS, 8 SKIPPED). On the Linux build host: 53 steps, among them the ubuntu jobs (apps.yml services and kernel-security) and the Linux process sandbox (Landlock, seccomp). Its 8 skips are rom.yml's Linux steps, which need a JDK, the Android SDK and node; run 2 ran them.
  • Run 2: tools/ci-local.sh --only all on the Mac with JDK 17, Android SDK 35 and node 24, PASSED in 23m32s (59 PASS), nothing skipped. The train touches rom/ (Read launch-time test hooks only in development builds #488), so the two-run rule applies to it.
Run 2's table
Job Step Result Time
ci-local / drift The local mapping fits the workflows PASS -
desktop.yml / desktop Prepare the pinned framework sources PASS 1s
desktop.yml / desktop Compile the desktop with the shared runtime PASS 3m15s
desktop.yml / desktop One copy of every shell source PASS -
desktop.yml / desktop Desktop tools and scripts PASS 14s
desktop.yml / desktop In-app updater and installer handoff PASS 4s
desktop.yml / desktop One Makepad, App Hub, octos and Rinx in the locked graph PASS 5s
desktop.yml / desktop The native apps' generated places match native-apps.json PASS 0s
desktop.yml / native-host-api Prepare the pinned framework sources PASS 0s
desktop.yml / native-host-api Build the native acceptance host and pinned Hub CLI PASS 9s
desktop.yml / native-host-api Signed app tool calls a real OS permission API PASS 3s
phone.yml / home Prepare pinned sources and the reviewed runtime patch PASS 0s
phone.yml / home Validate launcher icons and Apple asset catalogs PASS 3s
phone.yml / home Compile Home and its bundled modules PASS 3m17s
phone.yml / home Verify the single runtime graph PASS 3s
phone.yml / home The native apps' generated places match native-apps.json PASS 0s
phone.yml / home The pinned octos revision PASS -
phone.yml / home Build octos (unless cached) PASS -
phone.yml / home Build Home, App Hub admission and runtime policy tests PASS 43s
phone.yml / home Test Home, App Hub admission and runtime policy PASS 40s
phone.yml / home Two-lane scenario (real kernel, scripted model) PASS 31s
phone.yml / home Build opt-in AppCard tests PASS 34s
phone.yml / home Test opt-in AppCard PASS 6s
phone.yml / home Build craft-engine relay and system-chat tests PASS 39s
phone.yml / home Test craft-engine relay and system chat PASS 50s
phone.yml / home Build linked Terminal tests PASS 32s
phone.yml / home Test linked Terminal PASS 6s
phone.yml / home Build Wasm and runtime policy tests PASS 8s
phone.yml / home Test Wasm and runtime policy PASS 16s
apps.yml / services python3 tools/setup.py PASS 1s
apps.yml / services Shared system app interface PASS -
apps.yml / services Kernel service PASS 21s
apps.yml / services OctoSense release updater PASS 6s
apps.yml / services App peers PASS 26s
apps.yml / services AI providers config PASS 10s
apps.yml / services Connected provider protocols and Linux host adapter PASS 32s
apps.yml / services L0 in-card chat (sys.chat, host side) PASS 12s
apps.yml / services System toolbox (workflow templates) PASS 1m57s
apps.yml / kernel-security python3 tools/setup.py PASS 1s
apps.yml / kernel-security The pinned octos revision PASS 0s
apps.yml / kernel-security Build octos (unless cached) PASS -
apps.yml / kernel-security Real-kernel tests PASS 30s
apps.yml / apps python3 tools/setup.py PASS 1s
apps.yml / apps Host services (Mail, AI providers, News) PASS 1m12s
apps.yml / apps Connected accounts and Rinx editor PASS 1m14s
apps.yml / apps Shell AI services (crates/ai-host) PASS 2m29s
apps.yml / apps AppCard runtime setup safeguards PASS 0s
apps.yml / apps AppCard clippy (own crates; shared runtime compiles) PASS 52s
apps.yml / apps AppCard transport and store PASS 15s
apps.yml / apps One Makepad, App Hub, octos and Rinx in the locked graph PASS 4s
rom.yml / product python3 -m unittest discover -s tests -v PASS 38s
rom.yml / product Check generated Agent Binder client PASS 0s
rom.yml / product bash -n scripts/stage-forks.sh scripts/publish-release.sh scripts/apply-to-tree.sh scripts/build-rom.sh PASS -
rom.yml / web-installer npm ci --ignore-scripts --no-audit --no-fund PASS 7s
rom.yml / web-installer npm test PASS 1s
rom.yml / web-installer npx playwright install --with-deps chromium PASS 1s
rom.yml / web-installer npm run test:browser PASS 5s
rom.yml / web-installer python3 -m unittest discover -s tests -p test_installer_manifest.py -v PASS 0s
rom.yml / web-installer bash -n scripts/release.sh PASS -

Notes:

  • GitHub runs Python 3.12; this run used Python 3.9.6
  • apps.yml:services runs on ubuntu-latest in GitHub; here on macOS, so #[cfg(target_os = "linux")] code in it is not exercised (--linux-host runs it on Linux)
  • apps.yml:kernel-security runs on ubuntu-latest in GitHub; here on macOS, so #[cfg(target_os = "linux")] code in it is not exercised (--linux-host runs it on Linux)

Run 2's first attempt on the same head stopped at one failure outside this train: crates/wasm-host/tests/runtime.rs an_endless_loop_stops_at_its_deadline_and_spends_the_instance measured 189.8 ms against its 190 ms floor (its deadline fired a tick early). The rerun passed every step.

GitHub's native Windows acceptance (embedded-browser.yml, which local CI cannot replace) passed on this head: run 38163146546. Main after the train: cf06ac5, whose tree equals the tested tree.

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.

1 participant