Skip to content

Move the root probes into .sh files, and group the flat package - #312

Merged
okhsunrog merged 3 commits into
mainfrom
refactor/shell-to-resources
Aug 25, 2026
Merged

Move the root probes into .sh files, and group the flat package#312
okhsunrog merged 3 commits into
mainfrom
refactor/shell-to-resources

Conversation

@okhsunrog

Copy link
Copy Markdown
Owner

Two backlog items, both hygiene, no behaviour change intended.

The shell. ~700 lines of it lived inside Kotlin """…""" blocks with every $ written as ${'$'}. That cost a release: an apostrophe in a comment inside a single-quoted block ended the quoting, the batched command stopped parsing, and every forensic section vanished from bug reports until someone read a bundle closely (#306). Nothing could have caught it — the only check was a contains("emit_file …") assertion, and shellcheck cannot read Kotlin.

The scripts are now files under app/src/main/resources/shell/, and CI shellchecks them beside the module scripts. Parameters (paths, framing prefixes, two feature flags) arrive as a generated assignment prelude, so values stay defined once in Kotlin while the script stays something you can lint and run.

  • root_snapshot.sh, debug_snapshot.sh, hook_counters.sh, package_inventory.sh (now a function its callers invoke)
  • equivalence checked by executing the old and new commands and comparing the sections they emit: 48 identical sections for the root probe, 60 for the debug probe, same order
  • shellcheck immediately found a dozen unquoted expansions and a pattern-matching ${FRAC%${FRAC#???}}; the eval-body quoting rule is suppressed per file with the reason
  • verified the scripts are packaged into the built APK

The package. 96 files sat flat. Moved the cheap leaves — picker/, diagnostics/, settings/, debug/, statistics/, startup/ — each grouping a feature's screen, cache and pure model. 42 files stay at the root deliberately: the vocabulary several features and both processes share. dashboard/ and agent/ are left alone, where the import churn stops being worth it.

AndroidManifest.xml and scripts/measure-startup.py follow the activity to .startup.MainActivity; verified against the built APK. AGENTS.md gains a layout table.

~700 lines of shell lived inside `"""…"""` blocks with every `$` written
as `${'$'}`. That cost a release: an apostrophe in a comment inside a
single-quoted block ended the quoting, the batched command stopped
parsing, and every forensic section vanished from bug reports until
someone read a bundle closely (#306). Nothing could have caught it —
the only check was a `contains("emit_file …")` assertion, and shellcheck
cannot read Kotlin.

The scripts are now files under `app/src/main/resources/shell/`, verified
to be packaged into the APK, and CI shellchecks them beside the module
scripts. Parameters (paths, framing prefixes, the two feature flags)
arrive as a generated assignment prelude, so the values stay defined once
in Kotlin and the script stays something you can lint and run.

Equivalence was checked by executing the old and new commands and
comparing the section sequences they emit: 48 identical sections for the
root probe, 60 for the debug probe, same order.

- root_snapshot.sh, debug_snapshot.sh, hook_counters.sh, and the shared
  package_inventory.sh (now a function the callers invoke)
- shellcheck found what it was brought in for: a dozen unquoted
  expansions and a pattern-matching `${FRAC%${FRAC#???}}`. The `eval`-body
  quoting rule is suppressed per file with the reason
- tests assert against the prelude and the script's use of a variable
  rather than an interpolated literal
Two of the cheap leaves from the flat 96-file package: nothing else in the
module reaches into them beyond a handful of entry points, so the move is
mechanical and the tree gains two names that say what they hold.

- startup/: MainActivity, StartupCoordinator, StartupTrace and the
  blocking screen. The manifest and scripts/measure-startup.py follow the
  activity to `.startup.MainActivity` — verified against the built APK,
  which carries dev/okhsunrog/vpnhide/startup/MainActivity
- statistics/: the screen, its cache and the pure counter model

No logic touched; the diff is package lines and imports.
The rest of the cheap moves out of the flat package: picker/ (the Hiding
tab), diagnostics/ (the check suite and its report), settings/ and debug/.
Each holds a feature's screen, its cache and its pure model together, so
the tree says what the module is made of instead of listing 96 files.

42 files stay at the root on purpose — the vocabulary both processes and
several features share (StorageConfig, ShellUtils, RootSnapshotCache,
HookRegistry, DashboardData, the agent bridge). Moving those would be
import churn with nothing gained; dashboard/ and agent/ are left alone for
the same reason.

No logic touched: package lines, imports, and a layout table in AGENTS.md.
@okhsunrog
okhsunrog merged commit fd89279 into main Aug 25, 2026
35 checks passed
@okhsunrog
okhsunrog deleted the refactor/shell-to-resources branch August 25, 2026 11:16
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