Repository navigation
docs(sdk): the buildkit file header names the knob that exists - #476
Conversation
The contract renamed the inner-concurrency knob from `podman_jobs` to `stage_parallelism` (spec `4e61d3d`), and this repo's own rename leg moved the helper, its fallback constant and their doc (CHANGELOG/0.2026287.2213.md). The file header was left behind: it still described the file as doing "podman-jobs resolution", naming the retired knob as what the code resolves today. RCA — mechanism: that leg's sweep was keyed to the retired SYMBOL names (`PodmanJobs`, `podman_jobs`) plus the retired driver's flag spelling (`podman build --jobs`); the header's spelling is the CLI's hyphenated form (`podman-jobs`), which no pattern in that list matched. Missed control: the pattern list was name-keyed rather than knob-keyed — it enumerated the identifiers of the deleted symbols instead of every name derived from the knob, and the CLI's own spelling of that knob was one derivation away. Blast radius: one line — the map of what build_helpers.go contains, in the file that implements the knob's successor. Root fix: the header names the knob the file resolves, and the sweep for this leg is knob-keyed and case-insensitive, so it matches the hyphenated spelling the old list missed. Documentation-only: no behaviour change, no exported-surface change. Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)
Review — PASSChange under review. A single-line comment edit in Body honesty / internal consistency. The body's central numeric claim — "1 file changed, 1 insertion(+), 1 deletion(-)" — is exactly reproduced by the diff (one Correctness. The edit makes the header describe what the file now resolves. It introduces no symbol, no behaviour, no exported surface change; the diff is confined to a Tests. Not applicable and correctly not claimed: a comment-only change has no runtime path. The body classifies it as documentation-only and substitutes a claim-keyed grep sweep (with a calibrated positive/negative, parts A–E) for a runtime test, which is the appropriate instrument for this class. No test is owed. Security. No secrets, no injection surface, no dependency, pin, or privilege change — a prose line in a comment. Scope & cleanliness. Minimal and coherent: one stale phrase, one file, one line. No leftover legacy path introduced, no duplication, no dead code. The change does not attempt to sweep the negative references, which would have been scope creep and would have erased rename history; the body justifies that boundary. Comments. The comment thread is empty (0 comments), so there is no sign-off to weigh and no third-party claim to re-derive. With no designated maintainer comment present, the change stands on its own evidence — and its own evidence (the diff vs. the body) is consistent. Residual note (non-blocking). The "How tested" gate output and the grep transcripts are not independently reproducible from this read-only context (no shell). They are, however, internally coherent: part B shows the defect present on the base tree at line 18, part C shows it gone on HEAD, and part D's Verdict: PASS ollama-cloud/deepseek-v4.1-flash — action-review. |
…s producers (#791) The umbrella's currency report on this wave's base named SIX pins that were not current, and every one of them had a producer that had already landed. This is the consumer leg of that wave: the umbrella's tree changes only in its gitlinks, and what those gitlinks now carry is the `stage_parallelism` rename and the guidance it republished. currency: 6 of 409 pin(s) NOT current [2 behind, 403 cur, 4 differs (no checkout to judge ancestry)]; intents: 403 upstream leaf/leaves (403 implicit), 6 derived-from edge(s); NOT CURRENT: charly: behind; intent upstream:main (implicit: .gitmodules branch=); recorded 874a8b113e; served be7a505f47 (branch); layer-charly-check: differs (no checkout to judge ancestry); intent upstream:main (implicit: .gitmodules branch=); recorded cbd44f223d; served c77ecbb77a (branch); marketplace: behind; intent upstream:main (implicit: .gitmodules branch=); recorded 99a1bb4a6f; served 5feb9c8b83 (branch); plugin-box: differs (no checkout to judge ancestry); intent upstream:main (implicit: .gitmodules branch=); recorded b9ed1216c8; served 803541c15d (branch); plugin-marketplace: differs (no checkout to judge ancestry); intent upstream:main (implicit: .gitmodules branch=); recorded ba254d57ee; served 12242956b6 (branch); sdk: differs (no checkout to judge ancestry); intent upstream:main (implicit: .gitmodules branch=); recorded d71b9abb4b; served 352755df2e (branch); producer-first legs: charly (874a8b113e -> be7a505f47) -> marketplace (99a1bb4a6f -> 5feb9c8b83) WHAT EACH ADVANCE CARRIES. charly 874a8b113e -> be7a505f47 (4 commits, 6 files) opencharly/charly#1082 compiles in the plugin-box that spells the knob `--stage-parallelism`, and #1084 adopts the landed `stage_parallelism` vocabulary in the project manifest. The umbrella's effective binary now ACCEPTS `--stage-parallelism` and REJECTS `--podman-jobs` (rc=80). layer-charly-check cbd44f223d -> c77ecbb77a (2 commits, 2 files) opencharly/layer-charly-check#55 republishes the authoring-gotchas reference so it names the knob that exists: `--stage-parallelism`, and the outer `--jobs` beside it. marketplace 99a1bb4a6f -> 5feb9c8b83 (6 commits, 26 files) opencharly/marketplace#591 republishes the umbrella's own guidance from its post-fix tag, so the corpus teaches `--stage-parallelism` and the pin-advance verb's true scope. #586 and #590 ride along. plugin-box b9ed1216c8 -> 803541c15d (8 commits, 9 files) opencharly/plugin-box#66 is the rename's producer; #68, #70 and #72 are the follow-up that makes the skill-body control read the TREE (so a newly added body is covered without a hand-maintained slice) and gives the vacuity guard its own red arm. plugin-marketplace ba254d57ee -> 12242956b6 (2 commits, 5 files) opencharly/plugin-marketplace#55 replaces the false family->owner table with the mechanism that cannot go stale. sdk d71b9abb4b -> 352755df2e (1 commit) opencharly/sdk#476 names the knob that exists in the buildkit file header. THE SCOPE IS DERIVED, not hand-listed: the product's own currency report on this wave's base names the pins that are not current, and its own producer-first line is the wave's work list. The wave ran in the sanctioned order on a light tree: `charly task sync` (the pin moves in the index; the checkouts that exist are rolled), then `charly task init` to materialize the advanced paths AT the pins the index records, then the gate. The verb's own report is the scope control: 6 pin(s) moved — 6 pin_map entries moved 0, 396 index-only advances moved 4, and 2 of the 7 rolled leaves moved. The six `derived-from:charly` EDGES stay `cur`: the two `charly` trees record identical `box/*` twins, so advancing the leaf changes what the edges are judged against, not what they are worth. Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
Summary
Head
40e889cf3d875b004e85d3226fda09442eef29ca— the commit this PR pushes: 1 file changed, 1 insertion(+), 1 deletion(-).The defect. The header of
buildkit/build_helpers.gomaps what the file holds:podman-jobsis the retired name of the inner-concurrency knob. The contract renamed it —podman_jobs→stage_parallelism(opencharly/specspec/schema/box.cue:120-121, spec commit4e61d3d) — and this repo's own rename leg moved the helper (ResolvePodmanJobs→ResolveStageParallelism), its fallback constant, and their doc (CHANGELOG/0.2026287.2213.md).The header was left behind: it still told a reader that this file resolves a knob that no longer
exists.
The RCA.
PodmanJobs,podman_jobs) and to the retired driver's flag spelling (podman build --jobs). The header'sspelling is the CLI's HYPHENATED form, one derivation away from every pattern in that list.
identifiers of the deleted symbols instead of every name derived from the knob. The same
changelog had already generalised the lesson — "knob-keyed, not name-keyed: search for the knob
itself and every name derived from it" — and the pattern that carried it was still name-keyed.
the file holds. No behaviour, no exported surface, no call site, no schema, no build output.
knob-keyed and case-insensitive, so it reaches the hyphenated spelling the old list missed. The
calibration is pasted below.
What this change does NOT do. The rename-history notes stay exactly where they are: the
constant's own doc ("the knob the contract renamed from
podman_jobstostage_parallelism"), thenote on what the value used to drive ("it was
podman build --jobs N"), the daemon-side note inbuildkitdrive/paths.go("the semantic successor ofpodman build --jobs N"), and the historicalentry in
CHANGELOG/0.2026239.1643.md(--podman-jobs 1). Their subject IS the rename — theyname the predecessor in order to explain the successor — and this repo's own prior sweep
classified exactly those lines as negative references and quoted them in its changelog. The finding
here is a header that presents a retired name as CURRENT; deleting the notes would erase the only
record of what the knob used to be.
This is leg 6 of opencharly/opencharly#785, the fan-out of the
stage_parallelismrename. Itdepends only on the contract, which is landed, so it is independent of the producer leg and of the
other consumer legs.
How tested
Everything below ran on the committed tree this PR pushes.
1. The repo's CI gate, reproduced locally under CI's own toolchain.
.github/workflows/ci.ymlinstalls Go from
go-version-file: go.mod(→ go 1.26.8) and runsgofmt,go vet,golangci-lintv2.13.2,go testand the cross-compile matrix. That is the gate below, on thetree above.
The lint arm needed the pair, and #466 carries the RCA: the linter must be BUILT with
a Go new enough for the tree's dependency build constraints (
golang.org/x/netv0.58.0 ships//go:build go1.27files, so a go1.26-built linter panics on them) and RUN under the toolchaingo.modpins, so the export data it reads is the one CI reads. The gate above is green under thatpair, and the same pair reproduces CI's own configuration.
2. R5's claim-keyed sweep — the retired knob's spellings, before and after. The claim: every
occurrence of the retired knob's name in this module is either the defect this PR fixes or a
reference whose subject is the rename itself. The predicate is knob-keyed — every spelling derived
from the knob, case-insensitive — and it is CALIBRATED against a known positive, the defect
itself, before it is used to decide anything (parts A and B below).
What the calibration shows. Part A is the pattern the prior sdk sweep used; on the base tree it
returns the four surviving references and does NOT return the defect. Part B is this leg's
knob-keyed pattern; on the same base tree it returns those four AND the defect. That is the
instrument's proof — it reaches the thing the claim is about. Part C is the same pattern on the
committed tree, where the defect is gone and the four negative references remain.
The claim, in the committed tree. The retired knob's spelling has no matches in any Go
source: the grep that decides it and its
exit=1are pasted in part D above. Every surviving hitof the knob-keyed pattern (part C) is classified:
buildkit/build_helpers.go:38podman_jobstostage_parallelism"buildkit/build_helpers.go:43podman build --jobs N"buildkit/build_helpers.go:61podman build --jobslives"buildkitdrive/paths.go:102podman build --jobs N"CHANGELOG/0.2026239.1643.md:9--podman-jobs 1, a historical entry about a box rebuildThis repo's own prior leg (
CHANGELOG/0.2026287.2213.md) drew exactly this line between acomment that presents a retired name as what the code resolves NOW (the defect this PR fixes) and
a comment that presents it as the predecessor (the four hits above).
Rulebook compliance
/charly-internals:strict-policy,/charly-internals:cutover-policy,/charly-internals:git-workflowand/charly-internals:gowere loaded before the first sourceread and before the first git action.
control, blast radius, root fix) is in the Summary above and in the commit message. The
local lint arm failed twice before it was run under the CI's toolchain; that anomaly was RCA'd
separately and its record is golangci-lint v2.13.2 cannot decode the Go 1.27.3 stdlib export data — the local lint gate is red on
maintoo #466, which this session added the working pair to(see Filed issues). Zero warnings in every gate above: no
gofmtoutput, nogo vetoutput,
go testrc=0 across 19 packages,golangci-lint"0 issues", four cross-compilesrc=0.
beside the existing one; the prior leg's pattern list is superseded by the knob-keyed one.
retired name is deleted from the header rather than tolerated.
contract already carries it, and this change brings the prose onto it. No documented command
changes.
calibration, and every surviving hit is classified there.
git statuswas clean before every action; this PR is one commit onfeat/build-helpers-stage-parallelismofforigin/main(d71b9ab); no force-push, no amendafter the push, no direct push to
main, no hook bypass.claim-keyed sweep, and it is shown failing on the pre-change tree and passing on the committed
tree (parts A/B against the base, part C against the head, and the defect's own spelling at
exit=1in part D). A prose change has no runtime path to execute live.file, and every gate above runs on the host against the committed tree.
against the committed tree of this checkout.
zero behaviour change), so the gate is the non-runtime standards — this repo's own CI gate,
reproduced locally under CI's toolchain and pasted in How tested. This repo carries no
per-repo candy bed (its
AGENTS.mdsays so), so there is no disposable target to run.Cutover. One cutover, one PR: the stale phrase in the one file that carries it. The
rename-history notes are not in scope, and the reason is stated in the Summary — they are the
rename's own record, and this repo's prior leg drew the same line.
Landing. PR-only; the org's
charly/pr-validatoris the merge gate and arms nativeauto-merge on PASS. No agent merges this PR.
Change classification
documentation reviewed— comments changed and every non-runtime standardpassed. No code, pin, script or behavioural config changed, so a runtime tier would be a false
claim.
it depends only on the landed contract, not on the producer leg.
Filed issues
name remains in consumer repos after the BuildKit cutover". The fan-out's RCA and the ordered leg
list; it already names this repo's site (
sdk/buildkit/build_helpers.go:18). This PR is its leg6, and it closes that site.
maintoo #466 — "golangci-lint v2.13.2 cannot decode the Go 1.27.3 stdlib export data —the local lint gate is red on
maintoo". The finding behind this PR's lint arm: the linterbuilt with the tree's own go1.26.8 panics on
golang.org/x/netv0.58.0's//go:build go1.27files, and the one built with go1.27.3 cannot read the go1.27.3 stdlib's export data. The pair
that works — a linter built with a newer Go, RUN under the toolchain
go.modpins — wasmeasured here and added to that issue as evidence; the lint arm in How tested is green under
it. Non-blocking for this PR (it is the environment's gate, not this repo's tree), and it is
tracked there.
Agent: charly · session
ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)