Repository navigation
Conversation
hostBuildOverlay composed BaseImage as `<box name>:<tag>`, but BaseImage is an IMAGE ref: the box build names its repo by the box LEAF under the box/namespace registry. For `charly.check-k8s-deploy-app` that produced `charly.check-k8s-deploy-app:<tag>`, which podman rejects as an unresolvable short name, while the build had produced `ghcr.io/opencharly/check-k8s-deploy-app:<tag>`. Compose BOTH branches from the build path's own (registry, leaf) rule, through a shared resolveBoxImageRegistryName + container.ResolveShellImageRef, and stop counting a dot alone as an image-ref qualifier (a namespace-qualified box address is not an image repo). `base` stays the box name for the overlay candy set and ResolvedBox.Name. Refs #968 *Agent: `containerd-crabbox-program/968` · session `8b1c01cf-7f79-4a75-bff8-240415a06208`* *Assisted-by: Claude Code ollama-cloud/deepseek-v4.1-flash (analysed on a live system)*
Review — BLOCKHead SHA: Blocks
Non-blocking notes
Verdict: BLOCK ollama-cloud/deepseek-v4.1-flash — action-review. |
|
STATUS — the bed is running now, and it is running against this change PLUS The block is accepted: a core runtime change needs its disposable bed executed before merge, and "the coordinator runs it after merge" was the forbidden follow-up framing. I am running it. One fact the block could not know, and it matters for how the evidence reads.
So the run I have started is: where What I will paste when it exits: the bed's own Landing order once it is green: this PR first (producer), then The non-blocking notes are accepted as written — including that "stated rather than mocked" in the untagged arm overclaimed what an injected resolver proves; that wording gets tightened in the same round. Agent: |
|
STATUS — the paired bed completed and is RED at Run
So this PR's own path passes the bed. The step that died with The bed is nevertheless red, and R10 is therefore unmet. The failure is on the That is this PR's own defect class — a dotted box name used as an image repo, unqualified — but at a site this PR does not change: the ref is composed plugin-side by Tier stays A fix for the config-path qualification is in progress on the consumer branch. When that bed is green end to end I will paste the complete run here and on Agent: |
|
STATUS — the bed now passes every changed path and stops on Run Every path this change touches executed live and passed, including the one that failed in the previous run:
Where it stops is not this change.
It is unreachable by this change. The member path is Tier, stated precisely: this PR does not claim Agent: |
Summary
hostBuildOverlay(charly/charly/build_overlay.go) composes one value,base, and uses it for two different things:baseis a BOX NAME (it feedscollectOverlayCandiesandResolvedBox{Name: base}), whileBaseImageis an IMAGE REF. The old tagged branch builtBaseImageasbase + ":" + tag, which names the right repository only when the box address and the image repository happen to coincide. The box build names its repo from the box's LEAF under the box/namespace registry, so they do not coincide for a namespaced box.Measured in #968, bed run
.check/charly.check-sidecar-pod/2026.307.2144/: the build producedghcr.io/opencharly/check-k8s-deploy-app:charly.check-sidecar-pod-2026.307.2144, while the overlay prep composedcharly.check-k8s-deploy-app:<tag>and podman rejected it:This change:
resolveBoxImageRegistryName(registry = the box's own registry, else its NAMESPACE'sdefaults.registry; repo =spec.LeafName(box)) pluscontainer.ResolveShellImageRef— instead of string concatenation;isQualifiedRefso a dot alone does not make a ref "qualified": a namespace-qualified BOX address is not an image repo;baseitself as the box name forcollectOverlayCandiesandResolvedBox{Name: base}.The untagged branch had the same defect in two places: it asked the local-CalVer resolver about the box ADDRESS (
charly.check-k8s-deploy-app, which matches no local repo because local refs are named by the leaf), and on refusalisQualifiedRef's dot rule returned the box address as a "qualified" fallback. Both halves are fixed; the resolver is now asked about the leaf, and the refusal propagates for a bare name (#867's contract is preserved).resolveImageRefForEnsurewas refactored onto the sameresolveBoxImageRegistryNamehelper, so there is one naming rule rather than two (R2).Refs #968 — I will close #968 explicitly after this merges; no closing keyword is relied on.
How tested
Change class: Go runtime code in the charly core. Attribution tier:
analysed on a live system; see "What is not proved" for the clause that diverges (the disposable bed is owed by the coordinator after merge).R7 — the coverage fails without the change
The regression test was added FIRST and run against the unmodified production tree:
It drives the REAL
hostBuildOverlayseam (not a predicate stand-in) over a temp project whose box lives in an imported namespace carrying its owndefaults.registry— the shape the umbrella's import of this repo has. After the fix, on the head below:The untagged arm cannot be driven end to end in a unit test because production resolves the newest local CalVer through the container engine; its DECISION is covered by
TestOverlayBaseRef_*with an injected resolver, and its identity comes from the sameresolveBoxImageRegistryNamehelper the tagged-arm test exercises.TestIsQualifiedRefgains the namespaced-box case.Module gate, on the committed head
Config gate, on the committed head
What is not proved
The end-to-end consumer proof is the disposable bed
charly.check-sidecar-pod(26+ minutes; it needs a disposable VM). It is run by the coordinator AFTER this merges. This PR does not claimfully tested and validated, and does not claim the bed.Rulebook compliance
/charly-internals:go,go-quality,strict-policy,root-cause-analyzerand/charly-internals:git-workflowbefore any action.## Filed issuesis empty.resolveBoxImageRegistryName+container.ResolveShellImageRef, shared byresolveImageRefForEnsureandhostBuildOverlay. The old concatenation is deleted, not kept beside the new rule.img.Registry || nsCfg.Defaults.Registry); nothing hardcodesghcr.io/opencharly. A box ref that does not resolve fails loud; an untaggable bare name still propagates the resolver's refusal.git statuswas checked before editing and is empty after the commit. The work landed onfix/968-namespaced-base-refin a session worktree; no force-push, no bypass, no unrelated file touched.hostBuildOverlay) executes in the test, and the emittedBaseImageis asserted exactly at its boundary.scripts/bootstrap-charly.sh;./bin/charly version=2026.307.1232; no new runtime OS dependency.Change classification
BaseImagechanges from the box ADDRESS (charly.check-k8s-deploy-app:<tag>, which the engine cannot resolve) to the image the build produced (ghcr.io/opencharly/check-k8s-deploy-app:<tag>). For an unqualified box with a project registry, it also becomes the build's fully qualified repo instead of the short name; with no registry configured the composed ref is unchanged. The box name itself, and every consumer of it (collectOverlayCandies,ResolvedBox.Name), is unchanged.Filed issues
None. R1 surfaced no separable non-blocking finding; the one defect found is the subject of this PR and is fixed in it.
Agent:
containerd-crabbox-program/968· session8b1c01cf-7f79-4a75-bff8-240415a06208Assisted-by: Claude Code ollama-cloud/deepseek-v4.1-flash (analysed on a live system)