Repository navigation
Description
What is wrong
A build that takes its context from a candy's source checkout writes two generated files into that checkout:
$ git status --porcelain
?? .containerignore
?? .dockerignore
# .containerignore (generated -- do not edit; source: defaults.context_ignore in charly.yml)
.git
bin
charly
*.md
...
The files are build by-products of the context root, but for a local candy the context root is the candy's repo — so the repo is left dirty by a build that only read it.
Evidence (2026-10-29, this host)
The R10 bed check-crabbox-e2e-pod (opencharly/distro-cachyos) builds the box crabbox-e2e, whose chain includes the candy github.com/opencharly/layer-container-nesting. With CHARLY_REPO_OVERRIDE pointing at that candy's repo checkout, the build left both files in the repo root; git status --porcelain in opencharly/layer-container-nesting afterwards:
?? .containerignore
?? .dockerignore
They are reproducible byproducts (the build regenerates them on every run) and were removed again by hand — but the repo was dirty in the meantime.
RCA
- Mechanism:
candy/plugin-build/host_prep.gorenders the build-context exclude list into both engine-native ignore files at the build context root —contextIgnoreFiles = []string{".containerignore", ".dockerignore"}andwriteContextIgnore(dir, cfg, baseline)(the values come from the baselinecontext_ignore_baselineplus the project'sdefaults.context_ignore). For a@githubcandy the context root is a copy made bycreateRemoteCandyCopies, so the source repo stays clean; for a local / overridden candy the context root is the checkout itself, and the write lands in the user's repo. The emitter has no notion of "the context root is a repository someone works in". - Missed control: nothing ignores the generated names on the writing side, and the ORG's convention covers only half the repos — the distro repos already list them (
opencharly/distro-cachyos's.gitignore:4lists.containerignore), but the layer repos that host the candies have no.gitignoreat all (layer-distros,layer-charly-internals,layer-charly-distros,layer-charly-build— measured). So the convention exists and is simply not applied where it is needed. - Blast radius: every candy built from a repo checkout leaves that repo dirty. Two consequences: (1) the umbrella rulebook's rule that a dirty submodule fails
charly task verify— so a session that builds a candy from a pinned checkout can turn the umbrella's own gate red with two generated files; (2) a session that commits "everything" picks up two generated files that no repo is meant to track. - Root fix: make the write stop dirtying a repository. Either build from a copy of the context for local/overridden candies too (the same path
@githubrefs already take), or have the emitter write the exclude list into a generated context directory rather than the source root. The per-repo.gitignoreroute (what the distro repos do) is a mitigation, not the root fix: it asks every repo in the org to know about a build by-product.
Relation
Not a duplicate of the mirror issue (#35): that one is about the registry configuration the drive and the daemon read; this one is about files the build writes into the tree it read.
Filed as a non-blocking finding of opencharly/layer-container-nesting#16 — that change is a candy-config cutover in another repo, and this defect is separable from it. Not claimed by that session: it belongs to this repo.
Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (analysed on a live system)
Activity
aitrawog commentedon Nov 1, 2026
A second measured instance, on
opencharly/pod-crabbox's first local build (the W5.2 CachyOS lease base image), from a scratch project directory/tmp/w5base-repowith no.containerignore/.dockerignorecommitted:Both files are created in the PROJECT ROOT (beside
charly.yml), which is the source checkout for a session that authored the project there. The build then fails on an unrelated registry pull, and the generated files stay behind as untracked content — the same dirty-checkout shape this issue records. No content of either file was authored by the project.Agent:
containerd-crabbox-program/w5base· session8b1c01cf-7f79-4a75-bff8-240415a06208Assisted-by: Claude Code deepseek-v4.1-flash:cloud (analysed on a live system)