apple-container
Skill6 starsChanged 26 days agoMITView on GitHub
Reproduce Linux-only pyre failures on macOS inside Apple's `container` CLI, using the Ubuntu 24.04 repro image in `tools/`. Invoked via `/apple-container`. Use this skill whenever a failure is visible on a Linux CI leg but not locally — a `CPython suite (gate)` row, an ubuntu-only `pyre/check.py` failure, a crash that only the linux runner sees — or when the user says "linux에서 재현해줘", "run this in the container", "ubuntu에서 확인", "apple container로 돌려줘". Also use it before claiming a Linux-only red is inherited or unreproducible.
4 other projects use a version of this.
Adopted by
Most recently taken up by
- RustPython/RustPythontheir own version, first seen Oct 8, 2026
- sanjay3290/ai-skillstheir own version, first seen Jul 6, 2026
- DonsWayo/skillstheir own version, first seen Jun 16, 2026
- jcordon5/apple-container-skilltheir own version, first seen Jun 15, 2026
Other versions4 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 4
- RustPython/RustPython★ 22ksame name
- sanjay3290/ai-skills★ 452same name
- jcordon5/apple-container-skill★ 6same name
- DonsWayo/skills★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository7 other files it gives its agents.
- AGENTS.mdAGENTS.md
- codex-reviewSkill
- paritySkill
- codex-reviewSkill
- mergeSkill
- paritySkill
- rebaseSkill
The file
We split this skill into the rules it gives an agent
8 rules. 0 are common, 6 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
6
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Only the CI legs on ubuntu-24.04 run some checks, and darwin/linux divergence is a recurring source of reds that cannot be judged from a …
- Distinctive: line 34
Never substitute Ubuntu's Python 3.12 for the required oracle.
- Distinctive: line 57
Check whether the container is already up — do not start a second one:
- Distinctive: line 66
Start it if absent, from the repository root.
- Distinctive: line 133
Run the thing that is red on Linux:
- Distinctive: line 150
Leave the container running.
- Distinctive: line 173
A Linux red is not automatically the branch's: Check main's own CI at your merge-base first, and diff your branch's row list against main's …
- Very specific: line 199
Leave LLBC_DEST unset inside the container.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Reproduce Linux-only failures with Apple container
Only the CI legs on ubuntu-24.04 run some checks, and darwin/linux divergence
is a recurring source of reds that cannot be judged from a macOS worktree. This
skill runs the same code under a Linux userspace on the same machine.
Use Apple's container CLI and nothing else. Never Docker, never Podman,
never colima. If container is missing, stop and say so — do not substitute
another runtime.
What this can and cannot reproduce
Verified 2026-10-31 against the image on this machine. Read this table before promising a repro:
| target | works? | why |
| A crash / wrong answer from a bench or script | yes | run the binary directly |
pyre/cpython_tests/run.py — the CPython suite (gate) job | yes | the runner needs no oracle |
pyre/check.py ratio + jitstats gates | yes | the image pins CI's CPython 3.15.2 and PyPy 8.0.0; container timings remain diagnostic |
pyre/extra_tests/parity_tests/run.py | yes | the same pinned oracles are available |
The image sets PYRE_CHECK_PYTHON3 and PYRE_CHECK_PYPY3 without replacing
Ubuntu's system Python. It also installs CPython 3.15.2t for free-threaded
spec checks. Older containers can use the same reproducible installer:
bash tools/ubuntu24-amd64-repro/install-oracles.sh, then export those
variables to /opt/pyre-oracles/bin/python3.15 and
/opt/pyre-oracles/bin/pypy3, matching the image's container-local paths.
Never substitute Ubuntu's Python 3.12 for the required oracle.
Images
tools/ubuntu24-amd64-repro/ holds the Dockerfile. Two variants matter:
- arm64 (
pyre-ubuntu24-arm64-repro) — native on Apple silicon, so builds and runs at full speed. Use it to answer "is this linux-vs-macos?". Its charon lives at$PYRE_SHARED_BUILD/charon/linux-aarch64. - amd64 (
pyre-ubuntu24-amd64-repro) — matches the GitHububuntu-24.04runner's architecture, and runs under--rosetta, so it is much slower. Use it only when the arm64 answer disagrees with CI, or when the failure is plausibly x86-specific (codegen, alignment, float formatting).
Build (per tools/ubuntu24-amd64-repro/README.md):
container build --platform linux/amd64 -m 8G -c 4 --progress plain \
-t pyre-ubuntu24-amd64-repro tools/ubuntu24-amd64-reproWorkflow
Check whether the container is already up — do not start a second one:
container list -a 2>/dev/null | rg pyre-linuxA
stoppedrow is not a missing container —container start pyre-linuxand keep the toolchain it already has.Start it if absent, from the repository root. Four mounts are required: the worktree; the shared build cache outside the worktree so sibling worktrees and container runs reuse one charon install; the main checkout at its own host path, because these worktrees are
git worktrees (see the trap below); and a per-container directory over/workspace/pyre/target/llbcso extraction never writes into the host's artefacts.mkdir -p "$(dirname "$PWD")/.pyre-build" \ "$(dirname "$PWD")/.pyre-build/llbc-container/pyre-linux" MAIN=$(sed -n 's|^gitdir: \(.*\)/\.git/worktrees/.*|\1|p' .git) # empty in a normal clone container run -d --name pyre-linux --platform linux/arm64 -m 12G -c 4 \ --mount type=bind,source="$(pwd)",target=/workspace/pyre \ --mount type=bind,source="$(dirname "$PWD")/.pyre-build",target=/workspace/.pyre-build \ --mount type=bind,source="$MAIN",target="$MAIN" \ --mount type=bind,source="$(dirname "$PWD")/.pyre-build/llbc-container/pyre-linux",target=/workspace/pyre/target/llbc \ pyre-ubuntu24-arm64-repro sleep infinity-mis the memory cap — the container is where the "always cap memory when running pyre" rule is enforced, so never drop it.Then mark both trees safe, or every
gitcall inside refuses on ownership:container exec pyre-linux sh -c "git config --global --add safe.directory /workspace/pyre git config --global --add safe.directory $MAIN"One-time per cache, inside the container:
container exec pyre-linux sh -c 'cd /workspace/pyre && python3 scripts/install-charon.py' container exec pyre-linux sh -c 'cd /workspace/pyre && charon toolchain-path'The first downloads a prebuilt charon into the shared cache, so it is nearly free after the first worktree does it. The second triggers the pinned nightly's install, and that lands in the container's own filesystem —
rustc-devalone is several hundred MB and takes many minutes. It survivescontainer stop/startbut notcontainer rm, so do not delete the container to "reset" something; stop it instead.Set
CARGO_TARGET_DIRto an absolute path for every build and run. The worktree is bind-mounted, so an unqualified Linuxcargo buildwrites into the sametarget/release/the macOS binaries live in and silently replaces them. It must be absolute:scripts/extract-llbc.pyruns charon once per crate with that crate's directory as the cwd, so a relative value scatters a separatetarget-linux/into every crate — 4.8 GB across four crates, untracked and outside.gitignore's anchored/target-linuxrule.container exec pyre-linux sh -c 'cd /workspace/pyre \ && export CARGO_TARGET_DIR=/workspace/pyre/target-linux CARGO_INCREMENTAL=0 \ && python3 scripts/extract-llbc.py \ && cargo build --release -p pyrex --bin pyre-cranelift \ --no-default-features --features cranelift'Extraction and the Linux
pyre-jit-tracebuild both read and write/workspace/pyre/target/llbcas usual; that is the step-2 mount.scripts/extract-llbc.pytakes no crate arguments — the bare form extracts the whole set. Naming a subset mixes fresh and stale artefacts. Budget for it: on this machine the extract alone ran ~35 min (four dev-profile charon passes) and the release build another ~20.Run the thing that is red on Linux:
# a bench or script container exec pyre-linux sh -c 'cd /workspace/pyre \ && RUST_BACKTRACE=1 ./target-linux/release/pyre-cranelift pyre/bench/synth/<name>.py' # the CPython suite gate job container exec pyre-linux sh -c 'cd /workspace/pyre \ && python3 pyre/cpython_tests/run.py --backend cranelift \ --binary target-linux/release/pyre-cranelift --filter <module>'- Report by comparing the two hosts explicitly: what macOS does, what Linux does, and whether that matches the CI leg. A repro that only reproduces on one architecture is itself the finding — say which.
Leave the container running. Remove it only when asked:
container rm -f pyre-linux
Traps
A
git worktreebreaks every git call inside the container, andscripts/extract-llbc.pyrunsgit ls-filesfor its fingerprint, so the extract dies before it starts:fatal: not a git repository: /Users/youknowone/Projects/pyre/.git/worktrees/pyre-6A worktree's
.gitis a file holdinggitdir: <absolute host path>into the main checkout's.git/worktrees/. Mounting only the worktree leaves that path unresolvable. The mount in step 2 maps the main checkout to the identical path inside the container, which is what makes the pointer resolve — a different target does not work, the path is baked into the.gitfile. This is not asafe.directoryproblem; that error is a different one and needs thegit configcalls above as well.- A Linux red is not automatically the branch's. Check main's own CI at
your merge-base first, and diff your branch's row list against main's before
attributing anything. The suite gate rides
cargo-test-linuxonubuntu-24.04, which is also where the baseline's verdicts are enforced, so a row the container disagrees about is a finding rather than a known skew. target-linux/must not be committed. Confirm it is ignored before building, or the worktree fills with Linux objects.- Timing measured in the container is not a measurement. It is a VM sharing the host's cores with whatever else is running. Use the container for crashes, assertions, and wrong answers — never to judge a perf ratio.
- The container sees your uncommitted edits, because the worktree is
bind-mounted. That is the point, but it also means a rebase or a sibling
session's edit changes what the container is building mid-run. It cuts the
other way too:
source=is a hash of the tree, so editing anything after an extraction marks the artefacts stale — do the extract last and leave the tree alone until whatever you are measuring has finished. - A container lacking the
target/llbcmount must not extract. The driver'sout_diris a fixed<repo-root>/target/llbcwith no override, and the worktree is bind-mounted, so an extract without the nested mount replaces the artefacts your macOS build reads. The step-2 mount is now mandatory; recreate a container that lacks it (container rmthencontainer run; the pinned nightly toolchain is reinstalled, see step 3) rather than runningextract-llbc.pyin it. Every field the freshness check compares is computed from the tracked tree and so agrees across hosts;platform=is the one that does not, andfail_if_llbc_stalenow refuses on it rather than letting the build fail somewhere downstream. LeaveLLBC_DESTunset inside the container.scripts/llbc_extract.py(llbc_dest_path) takes it as an output override and resolves a relative value against the repo root, i.e. the bind-mounted host worktree, so a setLLBC_DESTbypasses the step-2 mount; the Linuxpyre-jit-tracebuild reads the fixedtarget/llbcregardless.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

