## Forking + branding while staying upstream-compatible

This doc describes a **recommended hstack workflow** for maintaining:

- an **upstream-compatible** branch/worktree (no branding changes; safe to upstream later)
- a **branded fork** branch/worktree (custom app name/bundle id/icons/Firebase/EAS, etc)

The goal is to keep day-to-day development clean and to make syncing changes reliable.

---

## Core idea

- **Do product/feature work on an upstream-compatible branch** (example: `happier-dev/dev`).
- **Keep branding + fork-only config on a separate branch** (example: `happier-dev/happier`).
- Periodically **merge** upstream-compatible changes into the branded fork branch.

The branded branch should ideally contain only:

- assets (icons/splash/logos)
- configuration files that are *unavoidably different* (Firebase, EAS linkage)
- optional small “glue” needed to make config configurable via environment variables

Everything else should stay identical to the upstream-compatible branch so merges stay low-conflict.

---

## Golden rules (hstack)

- **Do not develop in the stable checkout** (typically `<workspace>/main`). Use `<workspace>/dev` or worktrees under `<workspace>/{pr,local,tmp}/...`.
- **Use `hstack` entrypoints** (not raw `yarn`, `expo`, etc) when you’re running stack/dev/build/test commands.
- **Do not commit generated native directories** for Expo apps:
  - `apps/ui/ios/`
  - `apps/ui/android/`
  These are generated by `expo prebuild` and should be treated as build artifacts.

---

## Recommended branch/worktree layout

Example (Happier monorepo):

- Upstream-compatible dev checkout:
  - `<workspace>/dev`
  - Branch: `dev`
- Branded fork worktree (example):
  - `<workspace>/local/<owner>/happier`
  - Branch: `feature/happier-branding` (or similar)

Pin your branded stack to the branded worktree (recommended):

```bash
hstack stack wt happier -- use local/happier
```

Keep your stable/main stack on defaults, and use `happier` (or another stack) for branded testing/building.

---

## How to keep merges low-conflict

### Keep fork-only changes “small and isolated”

Prefer fork-only changes to live in these buckets:

- **Brand assets**:
  - `apps/ui/sources/assets/images/*` (icon/splash/logo/favicon, etc)
- **Fork-only identity/config** (when not configurable via env):
  - Firebase files (`google-services.json`, `GoogleService-Info.plist`)
  - EAS project linkage (projectId/updates URL/channel)

Avoid sprinkling branding changes throughout core logic; it increases conflict surface area.

### Prefer configuration via environment variables

When possible, drive identity via environment variables so the upstream-compatible branch keeps upstream defaults.

For Expo identity, a common pattern is:

- Keep defaults in `app.config.js`
- Allow overrides via generic Expo-style vars (examples):
  - `EXPO_APP_NAME`
  - `EXPO_APP_BUNDLE_ID`
  - `EXPO_APP_SCHEME`
  - `EXPO_APP_SLUG`
  - `EXPO_APP_OWNER`
  - `EXPO_EAS_PROJECT_ID`
  - `EXPO_UPDATES_URL`
  - `EXPO_UPDATES_CHANNEL`
  - `EXPO_ANDROID_GOOGLE_SERVICES_FILE`
  - `EXPO_IOS_GOOGLE_SERVICES_FILE`

Then set those **per stack** (in the stack env file) so the behavior is isolated to your branded stack.

---

## Day-to-day workflow

### 1) Do feature work on the upstream-compatible branch

Work in:

- `<workspace>/dev`

Keep it upstream-friendly:

- no branding changes
- no fork-only credentials/config

### 2) Periodically sync branded fork branch with upstream-compatible branch

In the branded worktree:

```bash
hstack wt git happier-dev/happier -- merge happier-dev/dev
```

Resolve conflicts (if any), then continue.

### When merges conflict

Conflicts usually mean a file is changing in both branches.

Best practice:

- **Move shared “configurability logic” into `dev`**, so it only has to merge one way.
- Keep branded values/assets in `happier`.

If a file must remain fork-only and conflicts often, consider:

- extracting brand-specific settings into separate files referenced by env, or
- cherry-picking specific commits from `dev` instead of merging (for a short period), then returning to merges.

---

## Mobile + EAS specifics

### Prebuild is local-only; don’t commit the generated dirs

Local:

```bash
hstack stack mobile happier --prebuild --platform=ios --clean --no-metro
```

This regenerates `apps/ui/ios` and installs pods. Treat this as build output.

### EAS builds are easiest when identity comes from env

Use the EAS wrapper (stack-scoped):

```bash
hstack stack eas happier whoami
hstack stack eas happier build --platform ios --profile production --no-wait
```

For cloud builds, ensure your EAS project has the correct environment variables configured on expo.dev (or in `eas.json` profile `env`).

---

## What should live only on the branded branch?

As a rule:

- **Yes (fork-only)**:
  - icons/splashes/logos
  - Firebase app configs (matching your bundle id/package)
  - App Store / Play Store metadata
  - any integrations that cannot reasonably be driven by env/config

- **No (should stay shared / upstream-compatible)**:
  - core app logic
  - shared tooling changes (anything under `apps/stack/scripts/` that improves workflows)
  - general configurability hooks (e.g. “support `EXPO_*` overrides”)

---

## Quick checklist

- **Upstream-compatible branch (`dev`)**:
  - can be upstreamed
  - runs with upstream defaults
  - minimal / no fork-only config

- **Branded fork branch (`happier`)**:
  - pinned to its own stack
  - overrides identity via env
  - contains only necessary fork-only files
  - periodically merges from `dev`
