# Repo-specific traps Things that look correct and are not. Each cost real time or shipped broken. Read this before implementing; skim the headings, read the ones you're about to touch. The repo's own `CLAUDE.md` documents structure, Dockerfile conventions, `updater.json`, CI workflows and lint rules — that is not repeated here. ## Contents - [Environment and workspace](#environment-and-workspace) - [Measurement](#measurement) - [Passing values into base-image services](#passing-values-into-base-image-services) - [Shell and bashio](#shell-and-bashio) - [Dockerfile and architecture](#dockerfile-and-architecture) - [Versioning](#versioning) - [Chromium / Electron under Xvfb](#chromium--electron-under-xvfb) - [CI and review bots](#ci-and-review-bots) --- ## Environment and workspace **The checkout is probably on the wrong branch.** Checkouts under `/data/claude` are shared and persistent; another session leaves them wherever it finished. A stale branch looks entirely normal. Compare the add-on's `config.yaml` `version` against the running `$BUILD_VERSION` before trusting anything you read. `scripts/preflight.sh` does this. **Never run `git stash` under `/data/claude`.** `refs/stash` is shared across every worktree and concurrent session, so it is *not* isolated even in your own worktree. A bare `stash` / `stash pop` pair in a clean worktree once restored another session's stash, producing conflict markers in six untouched files. To compare a file against another revision use `git show : > /tmp/x`. If a pop does go wrong: a conflicted pop **keeps** the stash entry, so nothing is lost — confirm `git rev-parse HEAD` matches what you pushed, then `git reset --hard HEAD`. **Work in a worktree under `/data`, not `/tmp`** — `/tmp` is `noexec`, so scripts there won't run. ```bash git worktree add --detach /data/claude/.work/ origin/master ``` **You cannot test the Docker build.** dockerd does not start in this environment. CI is the only gate. One observed run took ~3 hours, with 20+ runs queued against 2 executing — that was account runner contention, not the diff. Check `gh run list` before concluding your PR is stuck. Poll in a background task, and never claim the build is verified when it hasn't run. ## Measurement **Summed RSS overstates savings.** Shared library pages are counted once per process, so removing a duplicate frees its *private* memory, not its RSS. Measured example: four MCP shims summed to 882 MB RSS but 643 MB PSS / 564 MB private, and per-process private ranged 54 MB down to 2 MB — which completely changes which duplicate is worth removing. Quote private when arguing "removing this saves N MB". **A large mapping is often not resident.** SysV/tmpfs segments are lazily populated. Xvfb's 506 MB framebuffer shows `Rss: 0` in `/proc//smaps`. Check before calling anything a leak. **`/proc/meminfo` and `free` show host figures** — there is no memory cgroup namespace here. Never attribute those totals to the add-on. **`rtk` filters some command output.** For a complete listing, redirect to a file and read that (`ps ... > $SP/ps.txt`), or use `rtk proxy `. ## Passing values into base-image services The plumbing has four stages. `scripts/env_trace.sh ` walks all four and tells you which one drops the value — use it rather than reasoning about this from memory. 1. `/data/options.json` — the user's saved options. 2. **Injected export block** — `.templates/00-global_var.sh` writes a literal `export