Skip to content

Master: MIMOLETTE provisioning revealed gaps vs asiago reference build server (2026-04-17) #38

@smartwatermelon

Description

@smartwatermelon

Context

Provisioned MIMOLETTE as a new mobile-build server on 2026-04-17 using this repo's automation. asiago.local is the reference working build box. MIMOLETTE came up mostly-correctly but several things needed manual fixing to reach parity with asiago. Filing this as a tracking epic for those gaps.

The underlying remit (per the user) is "replicate the working ASIAGO development environment" — so "parity with asiago" is the acceptance criterion for each item below.

Summary of gaps

Each item below either (a) ran but configured something differently from asiago, or (b) didn't run at all.

1. app-setup/node-setup.sh: npm prefix diverges from asiago

  • NPM_GLOBAL_DIR="${HOME}/.npm-global" (line 108) sets npm prefix to a user-level directory.
  • asiago has npm config get prefix/opt/homebrew, so npm i -g landed into Homebrew's tree and brew shellenv auto-covered the PATH. On MIMOLETTE the prefix was ~/.npm-global which is not in any PATH set by the dotfiles, so eas, ncu, corepack, etc. were all invisible to interactive shells.
  • Someone had compensated on MIMOLETTE by injecting export PATH="/Users/andrewrich/.npm-global/bin:${PATH}" into ~/.profile, masking the drift. (See item 7.)
  • Fix direction: default NPM_GLOBAL_DIR to /opt/homebrew (matches asiago and the default brew shellenv PATH) — or, if a user-level prefix is intentional, ensure dotfiles bash/path.sh adds ${HOME}/.npm-global/bin when that prefix is in use. The former is simpler and is what asiago actually runs.
  • Repro on MIMOLETTE: open a fresh terminal, run command -v eas → exit 127. User had to run ~/.npm-global/bin/eas login with absolute path to proceed.

2. app-setup/node-setup.sh: globals list is narrower than asiago's

  • Currently installs only eas-cli and npm-check-updates (lines 103-104).
  • asiago additionally has: n, netlify-cli, puppeteer, url-decode-encode-cli.
  • n in particular is non-optional: mobile/lib/build-preflight.sh in kebab-tax explicitly checks command -v n and uses it to switch Node versions during preflight. Without n on the box, that branch silently fails to upgrade even when upgrade is needed.
  • Fix direction: add n, netlify-cli, puppeteer, url-decode-encode-cli to the globals array. (andrewrich and dependencies also appear in asiago's node_modules/ — those are detritus from old broken installs and should NOT be replicated.)

3. app-setup/android-setup.sh: system-image not installed → emulator unusable

  • Script installs platforms;android-${SDK_VERSION} and build-tools;${SDK_VERSION}.0.0 (lines 221-222) but not any system-images;android-N;google_apis_playstore;<abi>.
  • Without a system-image, emulator -list-avds returns empty and no AVD can be booted. On MIMOLETTE I had to manually sdkmanager "system-images;android-36;google_apis_playstore;arm64-v8a" before avdmanager create avd would succeed.
  • Fix direction: add system-image install to the SDK packages array. Recommended default: system-images;android-${SDK_VERSION};google_apis_playstore;arm64-v8a (Apple Silicon boxes only run arm64 images performantly).

4. app-setup/android-setup.sh: no AVD creation

  • Setup never creates an AVD. asiago has Medium_Phone_API_35 and Medium_Phone_API_36.1 from Android-Studio-driven manual creation.
  • On MIMOLETTE I had to avdmanager create avd -n Medium_Phone_API_36 -k 'system-images;android-36;google_apis_playstore;arm64-v8a' --device medium_phone by hand.
  • Fix direction: add a create_default_avd step at the tail of android-setup.sh, idempotent (skip if emulator -list-avds | grep -q "${AVD_NAME}"). Reasonable default: Medium_Phone_API_${SDK_VERSION} using medium_phone device profile.

5. app-setup/android-setup.sh: SDK_VERSION default is 34, current is 36

  • SDK_VERSION="${ANDROID_SDK_VERSION:-34}" (line 59). API 34 is two releases behind.
  • kebab-tax currently builds against API 36 (current Google Play requirement as of early 2026).
  • Fix direction: bump default to 36 (or latest-stable at the time of setup). Keep the env-var override so older projects can pin.

6. app-setup/android-setup.sh: no cmdline-tools-path → ~/Library/Android/sdk symlink

  • _determine_android_home() (lines 118-119) checks for ${HOME}/Library/Android/sdk first, then falls back to Homebrew cmdline-tools.
  • Dotfiles' bash/path.sh:113-117 is hardcoded to only detect ${HOME}/Library/Android/sdk. So if the box has cmdline-tools installed via Homebrew only (no Android Studio), dotfiles silently no-op on Android — adb, emulator, avdmanager missing from interactive-shell PATH.
  • On MIMOLETTE I worked around this by ln -s /opt/homebrew/share/android-commandlinetools ~/Library/Android/sdk.
  • Fix direction (pick one):
    • a. Have android-setup.sh create the symlink when Homebrew is the install origin, so the dotfiles find it at the expected path.
    • b. Patch dotfiles bash/path.sh to probe both locations. (I've filed that under smartwatermelon/dotfiles#69.)
    • Either fixes this gap; (a) is more local to this repo.

7. .profile gets corrupted with compensating PATH entries

  • MIMOLETTE's ~/.profile had been hand-edited by something (not our dotfiles, which symlink .profile → a one-liner that sources .bash_profile) to include export PATH="…/.npm-global/bin:…", export ANDROID_HOME=/opt/homebrew/share/android-commandlinetools, and eval "$(/opt/homebrew/bin/brew shellenv)".
  • These compensate for items 1 and 6 above but silently drift out of sync with dotfiles, creating maintenance confusion.
  • Root cause: when NPM_GLOBAL_DIR=~/.npm-global or cmdline-tools isn't symlinked into ~/Library/Android/sdk, something is motivated to patch .profile to make the box usable. Fixing items 1 and 6 removes the motivation.
  • Fix direction: resolve items 1 and 6; add an audit step at the end of setup that refuses to modify .profile and warns if it's not the canonical one-liner.

8. Project secrets / credentials: no handoff mechanism

Several gitignored files need to be on the build box for builds to succeed — setup has no automation for any of them:

  • kebab-tax/mobile/google-service-account.json — required by EAS --submit for Android. Missing on MIMOLETTE; user manually rsync'd from asiago.
  • kebab-tax/.claude/secrets.op — maps REVENUECAT_TEST_STORE_KEY via op://Automation/RevenueCat/Test Store Key for the claude-with-identity wrapper. Must exist on the target box for emulator launches to get the test key.
  • kebab-tax/mobile/.env.local — optional offline fallback.

These are PROJECT-scoped, so a general setup repo may not want them hardcoded. Fix direction: document a post-setup checklist (or a helper script) that lists "files you must manually copy or rsync from the reference box for each project you intend to build", and point prep-airdrop/first-boot flows at it. Or extend prep-airdrop.sh's credential-staging mechanism to accept a manifest of per-project secret files to migrate.

9. eas login not automated

  • EAS login is inherently interactive (terminal prompt or browser OAuth), so full automation is not feasible, but setup exits silently without a final "you need to run eas login" hint. User discovered it by running eas whoami after the fact.
  • Fix direction: at end of node-setup.sh (after eas-cli install), check eas whoami — if it returns "Not logged in", print a numbered post-setup checklist item.

10. ~/.semgrep/settings.yml lacks api_token: line → pre-push hook crashes

  • After semgrep --version first-runs, the generated settings.yml has only has_shown_metrics_notification and anonymous_user_id — no api_token line.
  • Dotfiles' git/hooks/pre-push has a set -euo pipefail bug that aborts the hook when grep finds no api_token line (distinct from it finding a malformed one). Already tracked at smartwatermelon/dotfiles#62 (as a pre-existing tech-debt) with an evidence comment from my MIMOLETTE hit.
  • Not strictly a mac-dev-server-setup bug — logging here only because setup could proactively inject a bare api_token: line into settings.yml as part of app-setup to prevent the downstream hook crash until dotfiles#62 lands.
  • Fix direction: optional. Wait for dotfiles#62 fix. Or, if that's slow, add a one-shot ensure-semgrep-settings.sh that writes api_token: to ~/.semgrep/settings.yml if no api_token line is present.

Proposed acceptance for this epic

Close this issue when a fresh Mac mini, provisioned only via this repo's prep-airdrop.sh + post-boot automation, can:

  • eas whoami returns a name (item 9 — post-setup check prompts for login)
  • command -v eas resolves without ~/.npm-global/bin being in any PATH (items 1 + 2)
  • command -v n netlify-cli puppeteer all resolve (item 2)
  • emulator -list-avds returns at least one AVD (items 3 + 4)
  • adb, avdmanager resolvable in a fresh interactive shell without .profile edits (items 1 + 6 + 7)
  • Default SDK_VERSION is 36 or current (item 5)
  • Post-setup checklist (README or script output) documents the per-project credential files the operator must rsync/populate manually (item 8)

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requesttech-debtTechnical debt to address

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions