Skip to content

docs(corpus)!: advance the corpus and the plugin-build pin, and regenerate the site on --stage-parallelism - #198

Merged
github-actions[bot] merged 1 commit into
mainfrom
feat/corpus-pin-wave-196
Oct 29, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
feat/corpus-pin-wave-196

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Refs #196

Summary

Head 67a7eaa546134bb7eae29dd99c63f537f3f78581 — the commit this PR pushes: 21 files changed, 322 insertions(+), 284 deletions(-).

The site's last carriers of the retired build-concurrency knob go with it, and the site stops teaching a flag the CLI rejects. Two pins move, and the pages the pins project are regenerated:

  • this repo's marketplace gitlink moves 99a1bb4a6f10112f67e3ddd73d3e86b3f6bc3417 → 5feb9c8b8350849fd2d46d252b486844c18bd0a4, the corpus's merged main tip. That corpus names the six build-family owners directly — plugin-box at v2026.301.1542 among them — instead of the drained layer-charly-build, so the build family's projected body is now the owner's own file.
  • the wiring candy's plugin-build pin (.github/docs-corpus/pins.tsv) moves v2026.242.0525 → v2026.296.1104, the newest plugin-build tag and the first whose candy/plugin-build/schema/build.cue carries stage_parallelism?: int. That is what the site's reference/plugin/** and reference/candy/** sections project, so the site's last podman_jobs?: int goes with the old pin.

The projection carries a second retirement with it, and the body names it. The pull recipe drops both --platform rows — the table row and the flag's own entry in the flag list. That is the corpus being FAITHFUL, not a docs-side edit: plugin-box#40 deleted --platform from the grammar and the pull skill's body still documented it, so plugin-box#66 deleted those rows from the body, and this page projects that body. The flag was already gone from the CLI before this PR; the site was the last place still teaching it, and the pin advance is what stops it.

The claim, before and after. The retired name is absent from the published tree and from the built site, and the new name is carried:

$ git grep --cached -nE "podman-jobs|podman_jobs|PODMAN_JOBS" -- src/content/docs
$ echo "rc=$?"
rc=1
$ grep -rnE "podman-jobs|podman_jobs|PODMAN_JOBS" src/content/docs
$ echo "rc=$?"
rc=1
$ grep -rl "podman-jobs" dist/
$ echo "rc=$?"
rc=1

and the new name is carried in exactly the four files the table names, counted per file from the ADDED lines of this diff alone:

$ for f in $(git diff --name-only -M origin/main...HEAD); do
    c=$(git diff -M origin/main...HEAD -- "$f" | grep '^+' | grep -v '^+++' \
        | grep -cE "stage-parallelism|stage_parallelism|CHARLY_STAGE_PARALLELISM")
    o=$(git diff -M origin/main...HEAD -- "$f" | grep '^+' | grep -v '^+++' \
        | grep -cE "podman-jobs|podman_jobs|PODMAN_JOBS")
    if [ "$c" != "0" ] || [ "$o" != "0" ]; then echo "$c new / $o retired  $f"; fi
  done
11 new / 0 retired  src/content/docs/recipes/build/build.md
1 new / 0 retired  src/content/docs/recipes/check/check/beds-and-r10.md
2 new / 0 retired  src/content/docs/recipes/internals/agents/parallel-bed-testing.md
1 new / 0 retired  src/content/docs/reference/plugin/github-com-opencharly-plugin-build-v2026-296-1104/plugin-build.md

The retired name appears in no ADDED line of any file in this diff, and every other file is a prose-only refresh that carries neither name.

and the LIVE site is still teaching it, right now, because this PR has not merged:

$ curl -s --max-time 30 -o /tmp/live-build.html -w 'http=%{http_code}\n' 'https://opencharly.ai/recipes/build/build/'
http=200
$ grep -o -- '--podman-jobs' /tmp/live-build.html | wc -l
17
$ grep -o -- '--stage-parallelism' /tmp/live-build.html | wc -l
0

Seventeen occurrences of --podman-jobs and none of --stage-parallelism, on the page every reader of the site is sent to for building an image. The shipped binary rejects that flag with rc=80 (opencharly/charly#1082; opencharly/plugin-box#66 renamed it), so a reader who follows the published page gets a failure, not a build.

Why the site taught the retired flag again — the root cause, measured. The published site taught the retired flag before, then stopped, then taught it again:

$ for c in 81da73e c0e7db9 98a5f6c; do
    git show $c:src/content/docs/recipes/build/build.md \
      | grep -cE 'stage-parallelism|podman-jobs'; done
7 0    # 81da73e — opencharly/docs#167
0 7    # c0e7db9 — opencharly/docs#176
0 7    # 98a5f6c — opencharly/docs#197

The pin moved FORWARD in time at every one of those steps, and the CONTENT moved BACKWARD. The corpus's own refs list says why:

$ for c in 602324e 1c15651 99a1bb4a 5feb9c8; do
    git -C marketplace show $c:candy/charly-marketplace/charly.yml \
      | grep -oE '@github.com/opencharly/layer-charly-build:v[0-9.]+'
    git -C marketplace show $c:build/skills/build/SKILL.md \
      | grep -cE 'stage-parallelism|podman-jobs'
  done
602324e   layer-charly-build:v2026.292.2017   7 0
1c15651   layer-charly-build:v2026.296.0919   0 7
99a1bb4a  layer-charly-build:v2026.296.0919   0 7
5feb9c8   (no ref — the family is named from plugin-box:v2026.301.1542)   7 0

layer-charly-build was DRAINED by the build-family split, and at the tag the corpus named it has no .agents/ tree at all — its own manifest says it "owns NO skill: entity any more". So the corpus's build/skills/build/SKILL.md at 1c15651 and 99a1bb4a could not have been sourced from the tag the corpus's own refs list names: it was an ORPHAN body, and it was rewritten at the Oct-23 refresh rather than merely left on disk:

$ git -C marketplace show 8cca914:build/skills/build/SKILL.md > a.md
$ git -C marketplace show 885ff98:build/skills/build/SKILL.md > b.md
$ diff a.md b.md | head -6
6a7,8
> <!-- GENERATED by `charly marketplace generate` — DO NOT EDIT. Edit the candy's skill:/hook:/marketplace: entities and regenerate. -->
>
13c15
< `charly box build` generates Containerfiles from `charly.yml` and layer definitions, then builds images in dependency order with **BuildKit**, charly's only image builder. …
---
> `charly box build` generates Containerfiles from `charly.yml` and layer definitions, then builds images in dependency order using the configured build engine (Docker or Podman). …

The Oct-23 body is older prose than the Oct-16 body — the layer carried the BuildKit prose from v2026.289.0211 onward and the drain removed the skill entirely at v2026.296.0855. So the Oct-23 regeneration emitted text that exists at no tag the corpus named, read from a source the refs list does not name, and the site published that body faithfully for five days.

Why no gate saw it — three controls, three different questions, none of them this one:

  • the provenance check compares a projected body against the owner's file at the named tag, so it has nothing to compare an orphan against, and is silent exactly where the defect lived;
  • the site's drift gate compares the committed tree to the pinned inputs, and a faithful projection of a regressed input is "no drift";
  • the corpus currency report asks whether the PIN is behind the corpus's merged main — a third question — and answered cur at every step.

The new pin has no orphan. The corpus's body at 5feb9c8 is plugin-box's file at v2026.301.1542 plus the generator's own header, and nothing else:

$ git -C marketplace show 5feb9c8:build/skills/build/SKILL.md > corpus.md
$ git --git-dir=$GD/plugin-box show v2026.301.1542:.agents/skills/build/SKILL.md > owner.md
$ diff owner.md corpus.md
6a7,8
> <!-- GENERATED by `charly marketplace generate` — DO NOT EDIT. Edit the candy's skill:/hook:/marketplace: entities and regenerate. -->
>

No page is hand-edited. The generation workflow is this repo's SOLE owner of generation: it clones the pinned charly, the pinned umbrella and the pinned plugin-docs, writes the wiring candy from the pins file, and regenerates the pages. The pages below are its OUTPUT for the advanced pins, and the drift gate in How tested proves the committed tree matches those inputs exactly — including untracked files.

file what it changes what the diff says so
.github/docs-corpus/pins.tsv the wiring candy's plugin-build pin, advanced v2026.242.0525 → v2026.296.1104 +1/−1; the one added line is plugin-build v2026.296.1104
marketplace this repo's marketplace gitlink, advanced 99a1bb4a → 5feb9c8 +1/−1; the gitlink moves to the corpus's merged main tip
src/content/docs/recipes/build/build.md the build recipe, regenerated — the renamed knob +69/−107; 11 added line(s) carry stage-parallelism / stage_parallelism; 0 carry the retired name
src/content/docs/recipes/build/docs.md the docs recipe, regenerated — the corpus's R4 operationalization +35/−5; 0 added line(s) carry either name; the diff adds the ## R4 — documentation never routes around a defect section
src/content/docs/recipes/build/generate.md the generate recipe, regenerated — the plugin-side build dispatch +3/−3; 0 added line(s) carry either name; the diff adds the **Build dispatch** paragraph
src/content/docs/recipes/build/migrate.md the migrate recipe, regenerated — the corpus's own migrate skill body +53/−58; 0 added line(s) carry either name; the diff adds the charly migrate # apply the table to every reachable config form
src/content/docs/recipes/build/pull.md the pull recipe, regenerated — the engine-run prose, and the retired --platform rows +7/−8; 0 added line(s) carry either name; the diff DROPS both --platform rows (the flag left the grammar; the body outlived it) and adds Runs the configured engine's pull directly
src/content/docs/recipes/build/settings.md the settings recipe, regenerated — the engine.run selection +32/−6; 0 added line(s) carry either name; the diff adds the engine.run row and engine.run selects the engine that RUNS containers`
src/content/docs/recipes/check/check/beds-and-r10.md the beds-and-R10 recipe, regenerated — the renamed knob +1/−1; 1 added line carries --stage-parallelism; 0 carry the retired name
src/content/docs/recipes/internals/agents.md the agents recipe, regenerated — the backend-script remedy +1/−1; 0 added line(s) carry either name; the diff adds the **Remedy.** paragraph
src/content/docs/recipes/internals/agents/parallel-bed-testing.md the parallel-bed-testing recipe, regenerated — the renamed knob +5/−4; 2 added line(s) carry --stage-parallelism; 0 carry the retired name
src/content/docs/recipes/internals/git-workflow.md the git-workflow recipe, regenerated — the command-discipline prose +4/−2; 0 added line(s) carry either name; the diff adds the A pasted commit id is the 40-character output bullet
src/content/docs/recipes/internals/git-workflow/branch-and-pr-loop.md the branch-and-PR-loop recipe, regenerated — the charly task sync scope +3/−1; 0 added line(s) carry either name; the diff adds it advances EVERY pin the umbrella declares
src/content/docs/recipes/internals/git-workflow/pin-intent-and-currency.md the pin-intent recipe, regenerated — the bump mode's scope +3/−1; 0 added line(s) carry either name; the diff adds bump is the ADVANCE — it moves EVERY pin the umbrella declares`
src/content/docs/recipes/internals/git-workflow/umbrella-mechanics.md the umbrella-mechanics recipe, regenerated — the charly task pins scope +5/−4; 0 added line(s) carry either name; the diff adds the pin-contract pin operation over EVERY declared path
src/content/docs/recipes/internals/marketplace.md the marketplace recipe, regenerated — the ownership prose +18/−17; 0 added line(s) carry either name; the diff adds the GENERATED by charly marketplace generate — DO NOT EDIT banner paragraph
src/content/docs/recipes/internals/repo-setup.md the repo-setup recipe, regenerated — the charly task sync scope +4/−1; 0 added line(s) carry either name; the diff adds it is an ORG-WIDE wave, not a one-repo operation
src/content/docs/reference/candy/github-com-opencharly-plugin-build-v2026-242-0525/plugin-build.md the candy reference page for the OLD plugin-build pin, removed +0/−49; the page is gone with the pin that produced it
src/content/docs/reference/candy/github-com-opencharly-plugin-build-v2026-296-1104/plugin-build.md the candy reference page for the NEW plugin-build pin, added +56/−0; the install surface at v2026.296.1104
src/content/docs/reference/plugin/github-com-opencharly-plugin-build-v2026-242-0525/plugin-build.md → src/content/docs/reference/plugin/github-com-opencharly-plugin-build-v2026-296-1104/plugin-build.md the plugin reference page, moved to the new pin — the renamed knob +18/−11; 1 added line carries stage_parallelism?: int, where the old page carried podman_jobs?: int
src/content/docs/reference/providers.md the provider index — the plugin-build rows follow the pin +3/−3; 3 added line(s) point at the v2026-296-1104 page, 3 removed ones at v2026-242-0525

How tested

1 — the head, the diff, and the state of the tree. Every fence below was run in the session worktree .worktrees/docs-196/docs, on the commit this body names.

$ git rev-parse HEAD
67a7eaa546134bb7eae29dd99c63f537f3f78581
$ git diff --shortstat origin/main...HEAD
 21 files changed, 322 insertions(+), 284 deletions(-)
$ git diff --numstat -M origin/main...HEAD | awk '{a+=$1; d+=$2} END {print a" insertions, "d" deletions"}'
322 insertions, 284 deletions
$ git diff --numstat -M origin/main...HEAD -- src/content/docs/recipes/build/migrate.md
53	58	src/content/docs/recipes/build/migrate.md
$ git status --porcelain=v1
$ echo "rc=$? (an empty status = the tree is clean at the commit this body names)"
rc=0

The headline diffstat and the per-file table below are two readings of the SAME diff, and they agree: the sum of the per-file numstat rows is 322/284, and migrate.md — the file a reader's arithmetic most easily slips on, because its patch carries two hunks (@@ -1,124 +1,119 @@ and @@ -127,5 +122,5 @@) — is 53/58, which is what the table says.

2 — the drift gate, before and after the commit. The gate compares the committed tree to this repo's pinned inputs, so it is RED on the working tree before the commit and a no-op after it — the before/after pair is the gate's own discrimination:

$ bash .github/docs-corpus/check_drift.sh > /tmp/drift-before.log 2>&1; echo "DRIFT_RC=$? (before the commit)"
DRIFT_RC=1
$ grep -c '^diff --git' /tmp/drift-before.log
18
$ tail -1 /tmp/drift-before.log
DRIFT: the committed site does not match its pinned generation inputs.
$ bash .github/docs-corpus/check_drift.sh; echo "DRIFT_RC=$? (after the commit)"
content: committed tree matches the pinned inputs (regeneration is a no-op).
DRIFT_RC=0

3 — the corpus pin, and that it is a MERGED ref reached through the submodule's own path.

$ git ls-remote origin refs/heads/main
5feb9c8b8350849fd2d46d252b486844c18bd0a4	refs/heads/main
$ git ls-tree HEAD marketplace
160000 commit 5feb9c8b8350849fd2d46d252b486844c18bd0a4	marketplace
$ git submodule update --remote marketplace; echo "rc=$?"
rc=0
$ git status --porcelain=v1
$ echo "rc=$? (the sanctioned advance is a no-op: the recorded pin IS the remote's main tip)"
rc=0
$ grep -A3 'path = marketplace' .gitmodules
	path = marketplace
	url = https://github.com/opencharly/marketplace.git
	branch = main

4 — the plugin-build pin, and why that tag.

$ git ls-remote --tags --refs https://github.com/opencharly/plugin-build | awk '{print $2}' | sed 's#refs/tags/##' | sort -V | tail -4
v2026.287.2220
v2026.293.0443
v2026.293.0926
v2026.296.1104
$ git --git-dir=$GD/plugin-build show v2026.296.1104:candy/plugin-build/schema/build.cue | grep -n 'parallelism\|podman_jobs'
28:	stage_parallelism?: int
$ git --git-dir=$GD/plugin-build show v2026.242.0525:candy/plugin-build/schema/build.cue | grep -n 'parallelism\|podman_jobs'
27:	podman_jobs?:      int

5 — the corpus's body is its owner's file, at the pin (the orphan is gone).

$ git -C marketplace show 5feb9c8:build/skills/build/SKILL.md > corpus.md
$ git --git-dir=$GD/plugin-box show v2026.301.1542:.agents/skills/build/SKILL.md > owner.md
$ diff owner.md corpus.md
6a7,8
> <!-- GENERATED by `charly marketplace generate` — DO NOT EDIT. Edit the candy's skill:/hook:/marketplace: entities and regenerate. -->
>
$ git -C marketplace show 5feb9c8:candy/charly-marketplace/charly.yml | grep -c 'layer-charly-build'
1
$ git -C marketplace show 5feb9c8:candy/charly-marketplace/charly.yml | grep -n 'layer-charly-build'
165:            # The `build` family's fifteen skills used to live in `layer-charly-build`.

(the one hit is the comment that RECORDS the family's history — the drained owner is no longer a pin.)

6 — this repo's own gates, on the committed tree.

$ python3 .github/scripts/check_step_timeouts.py; echo "rc=$?"
check-step-timeouts: OK (1 workflow file(s) asserted; every job and every step carries a deadline)
rc=0
$ python3 .github/scripts/check_step_timeouts.py --self-test; echo "rc=$?"
check-step-timeouts self-test: OK (unbounded steps, jobs and traps are all caught, and the org-distributed copy is reported)
rc=0
$ python3 .github/scripts/test_check_step_timeouts.py | tail -1
test_check_step_timeouts: OK (5 mutants; every one of them turns the self-test red)
$ python3 .github/scripts/check_dependency_advisories.py; echo "rc=$?"
check-dependency-advisories: OK (no known advisory in the production tree or the dev tree)
rc=0
$ python3 .github/scripts/check_dependency_advisories.py --self-test; echo "rc=$?"
check-dependency-advisories self-test: OK (a production finding, a dev finding and a clean tree are all told apart, and an unauditable tree is an error)
rc=0
$ python3 .github/scripts/test_check_dependency_advisories.py | tail -1
test_check_dependency_advisories: OK (5 mutants; every one of them turns the self-test red)
$ python3 .github/docs-corpus/test_check_drift.py | tail -1
OK
$ bash .github/docs-corpus/test_check_corpus_currency.sh | tail -1
test_check_corpus_currency: OK (every state is reported, and none of them fails)
$ bash .github/docs-corpus/check_corpus_currency.sh .; echo "rc=$?"
corpus pin: 5feb9c8b8350849fd2d46d252b486844c18bd0a4 is cur — at the corpus's merged main (merged main: 5feb9c8b8350849fd2d46d252b486844c18bd0a4)
rc=0

7 — the site's own build, and the built site's content.

$ npm ci --no-audit --no-fund && npm run build | tail -3
01:14:08 [build] 1699 page(s) built in 45.19s
01:14:08 [build] Complete!
$ test -f dist/index.html && echo "dist/index.html: present"
dist/index.html: present
$ find dist -name '*.html' | wc -l
1699
$ grep -rl "podman-jobs" dist/; echo "rc=$? (1 = the retired name is in no built page)"
rc=1
$ grep -rl "stage-parallelism" dist/ | head -3
dist/recipes/build/build/index.html
dist/recipes/check/check/beds-and-r10/index.html
dist/recipes/internals/agents/parallel-bed-testing/index.html

Rulebook compliance

Change classification

  • Change class: a pin change (this repo's marketplace gitlink, plus the plugin-build pin in .github/docs-corpus/pins.tsv) plus the generated pages that the pins project. The bumped submodule carries content — the corpus the site is generated from — so this is not the documentation-only submodule-pointer class, and the tier is a runtime tier.
  • Diffstat: 21 files changed, 322 insertions(+), 284 deletions(-).
  • Gate run: this repo's own generation workflow on the committed tree — the corpus projection, the drift check (content: committed tree matches the pinned inputs), the corpus-currency report, the dependency-advisory gate, the step-deadline gate and the Astro build — every step, zero failures, zero warnings.
  • Attribution tier: fully tested and validated — the change-class gate passed on the final tree, and the changed path (the corpus the site is generated from) was executed live, with the "before" retained.
  • No rebuild leg applies: this change touches no disposable: true target; the site is built by the real Astro build, pasted above.

Filed issues

  • corpus: a projected body whose source is ABSENT at the named tag is published silently — the build family's orphan shipped --podman-jobs to the site for five days marketplace#592 — the corpus published a projected body whose source is ABSENT at the tag its own refs list names, and nothing in the org reported it: the build family's body at the corpus's Oct-23 and Oct-28 commits carried --podman-jobs and the pre-BuildKit prose while the refs list named layer-charly-build:v2026.296.0919, a tag at which that owner has no .agents/ tree and owns no skill: entity at all. The mechanism, the missed control (a provenance check has nothing to compare an orphan against; the generator's stale-orphan check sees only files ABSENT from the emissions map), the blast radius (the published build family and every page naming the flag — which is how this repo's site taught a rejected flag for five days) and the root fix (the generation must fail loud when a named source's skill body is absent at that tag) are on that issue, with the measured evidence. Not blocking here: this change's claim is that the SITE no longer carries the retired name, which the drift gate and the built site prove on their own, and the corpus's content is CORRECT at this pin — its body is byte-identical to plugin-box's file at v2026.301.1542 plus the generator's header. Filed and CLAIMED (assigned aitrawog).
  • the site's own charly and umbrella pins are 91 and 373 commits behind their merged mains, and nothing reports it #196 — this repo's other two pins are still far behind their remotes and nothing says so: charly is pinned at bafd8dbc3110904872831998fb4caa701cc2990c (91 commits behind its merged main) and the umbrella at e631aacf32df4e26a66f2cb6a75fc9e85e212399 (373 commits behind its merged main), both valid behind states, and the repo's currency report watches only the corpus. Not blocking here: this change's claim is the corpus's advance reaching the site, and the advance of each of the other two pins is a separate producer-first leg with its own pages — separable by construction. The scope stays on the site's own charly and umbrella pins are 91 and 373 commits behind their merged mains, and nothing reports it #196, which this PR does NOT close.

Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

…erate the site on --stage-parallelism

This repo's `marketplace` pin moves from 99a1bb4a6f10112f67e3ddd73d3e86b3f6bc3417 to
5feb9c8b8350849fd2d46d252b486844c18bd0a4 — the corpus's merged `main` tip, advanced
through the submodule's own remote-tracking path, never a hand-set gitlink. The
corpus is what decides which projection of the guidance corpus the site serves, and
at this tip it names the `build`-family owners DIRECTLY — plugin-box at
v2026.301.1542 among them — so the recipe pages it projects teach the renamed knob.

The wiring candy's own `plugin-build` pin moves from v2026.242.0525 to
v2026.296.1104 — the newest plugin-build tag, and the first one whose
`candy/plugin-build/schema/build.cue` carries `stage_parallelism?: int`. That is what
the site's `reference/plugin/**` and `reference/candy/**` sections project, so the
site's last `podman_jobs?: int` goes with the old pin.

THE REGRESSION THIS REPAIRS, AND ITS ROOT CAUSE. The published site taught the
retired flag before, then stopped, then taught it again — measured on this repo's own
history:

    $ for c in 81da73e c0e7db9 98a5f6c; do
        git show $c:src/content/docs/recipes/build/build.md \
          | grep -cE 'stage-parallelism|podman-jobs'; done
    7 0    # 81da73e — PR #167, the corpus pin at layer-charly-build:v2026.292.2017
    0 7    # c0e7db9 — PR #176, the corpus pin at layer-charly-build:v2026.296.0919
    0 7    # 98a5f6c — PR #197, the corpus pin at the corpus's merged main of Oct 28

The pin moved FORWARD in time every time, and the CONTENT moved BACKWARD. The
mechanism, measured on the corpus's own refs list and on the owner's tree at the tag
the corpus named:

    $ for c in 602324e 1c15651 99a1bb4a 5feb9c8; do
        git -C marketplace show $c:candy/charly-marketplace/charly.yml \
          | grep -oE '@github.com/opencharly/layer-charly-build:v[0-9.]+'; done
    602324e  layer-charly-build:v2026.292.2017   # the body teaches --stage-parallelism
    1c15651  layer-charly-build:v2026.296.0919   # the body teaches --podman-jobs
    99a1bb4a layer-charly-build:v2026.296.0919   # the body teaches --podman-jobs
    5feb9c8  (no ref — the build family is named from plugin-box:v2026.301.1542)

`layer-charly-build` was DRAINED by the build-family split, and at its tag
v2026.296.0919 it has no `.agents/` tree at all — its manifest says it "owns NO
`skill:` entity any more". So the corpus's `build/skills/build/SKILL.md` at 1c15651
and 99a1bb4a COULD NOT HAVE BEEN SOURCED from the tag the corpus's own refs list
names: it was an ORPHAN body, carried in the corpus's tree from before the drain.
The corpus published a body that no tag it named could supply, and the site
published that body faithfully.

The MISSED CONTROL is exactly there. A provenance check that compares a projected
body against the owner's file AT THE NAMED TAG has nothing to compare an orphan
against, so it is silent precisely where the defect lived. The site's drift gate is
downstream of the same blindness: it compares the committed tree to the pinned
inputs, and a faithful projection of a regressed input IS "no drift". The corpus
currency report asks a third question — is the PIN behind the corpus's merged main —
and answered `cur` throughout.

The BLAST RADIUS: the published `build` family and every page naming the flag. The
site told its readers to pass `--podman-jobs`, a flag the shipped binary REJECTS with
rc=80 since opencharly/charly#1082 landed (opencharly/plugin-box#66 renamed it).

THE NEW PIN HAS NO ORPHAN. The corpus's body at 5feb9c8 is plugin-box's file at
v2026.301.1542 plus the generator's own header, and nothing else:

    $ git -C marketplace show 5feb9c8:build/skills/build/SKILL.md > corpus.md
    $ git --git-dir=$GD/plugin-box show v2026.301.1542:.agents/skills/build/SKILL.md > owner.md
    $ diff owner.md corpus.md
    6a7,8
    > <!-- GENERATED by `charly marketplace generate` — DO NOT EDIT. … -->

THE CLAIM, MEASURED. The retired name is gone from the published tree, and the new one
is carried:

    $ grep -rnE "podman-jobs|podman_jobs|PODMAN_JOBS" src/content/docs
    (no output; exit 1)

    $ git grep --cached -nE "podman-jobs|podman_jobs|PODMAN_JOBS" -- src/content/docs
    (no output; exit 1)

Four carriers carried it at HEAD: the `build` recipe (the flag line, the
`Parallelism: --jobs vs --podman-jobs` section, the `defaults.podman_jobs` /
`podman_jobs_cap` example), the `beds-and-r10` recipe, the `parallel-bed-testing`
recipe, and the plugin-build reference page's schema block. The last is the pin
advance; the first three are the corpus advance.

No page is hand-edited. The pages are the generator's output for the advanced pins,
and the drift gate proves the committed tree matches this repo's own pinned inputs
exactly — RED on the working tree before this commit, a no-op after it.

Refs #196
Refs opencharly/opencharly#785

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)
@github-actions

Copy link
Copy Markdown

Review — PASS

I reviewed the complete PR state: the body, all 21 file diffs, the single commit, and the comment thread (0 comments — nothing to disposition; no maintainer sign-off present, so the change must stand on its own evidence).

What the diff actually shows

  • Both pins advance as claimed. .github/docs-corpus/pins.tsv moves plugin-build v2026.242.0525 → v2026.296.1104 (one added line, exactly as stated). The marketplace gitlink moves 99a1bb4a… → 5feb9c8… (one-line gitlink move).
  • The rename is carried through. Every --podman-jobs / podman_jobs / PODMAN_JOBS occurrence in build.md, parallel-bed-testing.md, beds-and-r10.md, and the plugin-reference page is replaced by --stage-parallelism / stage_parallelism / CHARLY_STAGE_PARALLELISM. I scanned every added line across all diffs: no added line carries the retired name; the removed lines are exactly the retired-name lines.
  • engine.build is retired consistently across build.md, settings.md, and pull.md, replaced by the engine.run (+ containerd.namespace) model and the BuildKit builder. This matches the pin advance's stated intent.
  • Reference pages follow the pin: the old …v2026-242-0525 candy page is removed, the …v2026-296-1104 candy page is added, the plugin reference page is renamed to the new pin with podman_jobs?: int → stage_parallelism?: int, and providers.md repoints the three words (box/ensure/generate) to the new page (3 added → 296-1104, 3 removed → 242-0525, exactly as the table says). The pre-existing …v2026-287-2220 rows are preserved, matching the prior two-rows-per-word shape.
  • Rule renumbering is self-consistent: R4→R3, R3→R2 across build.md/docs.md/generate.md, and the new docs.md "R4 — documentation never routes around a defect" section, all agree with the R2/R3/R4 semantics the body's own Rulebook-compliance section uses.

The change is coherent and complete for its stated purpose: no hand-edited page, no leftover legacy path, no dead code, no security surface (static docs site). The retired name does not survive into any added line.

Non-blocking observations (not grounds to block)

  1. Diffstat off-by-one. The body's headline is 322 insertions / 284 deletions, but summing the per-file ± headers gives 323/285. The discrepancy is traceable to migrate.md: the body's table says +53/−58 while the file header says +54/−59. A ±1 arithmetic slip in the reported diffstat; the file count (21) is correct and the substance is unaffected. Worth correcting for exactness given the body leans on precise numbers as evidence, but not material.
  2. --platform documentation is dropped from pull.md (row + option) with no explicit call-out in the summary table beyond "the engine-run prose." This is a faithful projection of the regenerated corpus (the drift gate would catch a non-faithful tree), so it is the corpus's change, not a defect introduced here — but the body could name it.
  3. The body's line-count claims for "added lines carrying stage-parallelism" (11 in build.md) count marginally differently under a strict scan (~12), another harmless ±1.

Verdict rationale

The body's substantive claims — the two pin advances, the flag rename, the removal of engine.build, the reference-page moves — are all reproduced by the diff. The retired name is absent from every added line and the new name is carried where claimed. The only concrete inaccuracy is a ±1 diffstat/table arithmetic slip, which does not undermine the change's correctness, scope, or honesty at a material level. No security, test-coverage, or cleanliness defect is present for a generated-content pin wave.

Verdict: PASS


ollama-cloud/deepseek-v4.1-flash — action-review.

View action run

@aitrawog

Copy link
Copy Markdown
Contributor Author

STATUS

Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0

The validator's three non-blocking observations are disposed: one is FIXED in the body, two are REBUTED with the measured evidence. The head does not change — 67a7eaa546134bb7eae29dd99c63f537f3f78581 — so this round is a body-only update.

Observation 2 — FIXED: the --platform drop is now named

The review is right that the body did not name it. It does now, in Summary and in the pull.md row of the file table:

The projection carries a second retirement with it, and the body names it. The pull recipe drops both --platform rows — the table row and the flag's own entry in the flag list. That is the corpus being FAITHFUL, not a docs-side edit: plugin-box#40 deleted --platform from the grammar and the pull skill's body still documented it, so plugin-box#66 deleted those rows from the body, and this page projects that body. The flag was already gone from the CLI before this PR; the site was the last place still teaching it, and the pin advance is what stops it.

Measured on this diff, the pull page loses exactly the two --platform rows and adds the engine.run prose — nothing else changes there:

$ git diff -M origin/main...HEAD -- src/content/docs/recipes/build/pull.md | grep -E '^[-+].*platform'
-| Override platform | `charly box pull jupyter --platform linux/arm64` | Pull a specific platform |
-- `--platform <platform>` — Target platform (default: host). Passed to
-  `podman pull --platform`.

Observation 1 — REBUTED: the diffstat is 322/284, and the per-file sum agrees with it

The review reads the body's headline (322 insertions(+) / 284 deletions(-)) against a per-file sum of 323/285, and attributes the difference to migrate.md (+53/−58 in the table, +54/−59 in the file header). Measured, on this tree, with three independent readings:

$ git diff --shortstat origin/main...HEAD
 21 files changed, 322 insertions(+), 284 deletions(-)
$ git diff --numstat -M origin/main...HEAD | awk '{a+=$1; d+=$2} END {print a" insertions, "d" deletions"}'
322 insertions, 284 deletions
$ git diff --numstat -M origin/main...HEAD -- src/content/docs/recipes/build/migrate.md
53	58	src/content/docs/recipes/build/migrate.md
$ git diff --numstat -M origin/main...HEAD | awk '{a+=$1; d+=$2} END {print a" insertions, "d" deletions"}'
322 insertions, 284 deletions

The shortstat, the sum of the per-file numstat rows, and the file's own numstat row all say the same thing: migrate.md is 53/58, and the total is 322/284. The body's headline and its table row are both correct as written.

The migrate.md patch is where a hand-sum goes wrong, and it is worth naming why: the file's diff carries two hunks, @@ -1,124 +1,119 @@ and @@ -127,5 +122,5 @@. Adding the two hunks' NEW-side counts (119 + 5 = 124) against the OLD side (124 + 5 = 129) gives a net of −5, which is right, but a reader who adds one hunk's header and forgets the other lands on ±1. Counting the lines themselves settles it:

$ git diff -M origin/main...HEAD -- src/content/docs/recipes/build/migrate.md | grep '^+' | grep -vc '^+++'
53
$ git diff -M origin/main...HEAD -- src/content/docs/recipes/build/migrate.md | grep '^-' | grep -vc '^---'
58

There is no \ No newline at end of file marker in that patch and the file ends with a newline in both revisions, so the line counts and the numstat row cannot diverge.

The body now carries this evidence, so the headline and the table are self-verifying rather than asserted — §1 of How tested now pastes the numstat sum and migrate.md's own row.

Observation 3 — REBUTED: build.md carries the new name on exactly 11 added lines

The review puts this at "11 in build.md" versus "~12" under a strict scan. Measured, counting ADDED lines only (the claim is about added lines):

$ git diff -M origin/main...HEAD -- src/content/docs/recipes/build/build.md \
    | grep '^+' | grep -v '^+++' | grep -cE "stage-parallelism|stage_parallelism|CHARLY_STAGE_PARALLELISM"
11
$ git diff -M origin/main...HEAD -- src/content/docs/recipes/build/build.md \
    | grep '^+' | grep -v '^+++' | grep -nE "stage-parallelism|stage_parallelism|CHARLY_STAGE_PARALLELISM"
4:+charly box build --stage-parallelism N [image...]    # Max concurrent stages within a single build (0=auto: min(NCPU, defaults.stage_parallelism_cap))
7:+## Parallelism: `--jobs` vs `--stage-parallelism`
8:+| `--stage-parallelism N` | `CHARLY_STAGE_PARALLELISM` | `stage_parallelism` (+ `stage_parallelism_cap`) | **Inner** concurrency: …
9:+`--stage-parallelism` / `CHARLY_STAGE_PARALLELISM` / `defaults.stage_parallelism` are all unset) is
10:+CPU-proportional, capped at `defaults.stage_parallelism_cap`: `min(NCPU, cap)`.
13:+  stage_parallelism: 0       # inner: 0 = auto = min(NCPU, stage_parallelism_cap)
14:+  stage_parallelism_cap: 8   # ceiling for the auto calc
15:+charly box build <image> --stage-parallelism 16       # fully parallel stages (override)
16:+CHARLY_STAGE_PARALLELISM=8 charly update <image> --build  # via env
17:+charly box build <image> --stage-parallelism 1        # fully serialised, worst-case debugging
21:+Covered by `buildkit/build_helpers_test.go` (`TestResolveStageParallelism`). The outer `--jobs` knob and the inner `--stage-parallelism`

Eleven lines, listed. The same loop over the whole diff gives the four-file table, and it is the loop the body now pastes:

$ for f in $(git diff --name-only -M origin/main...HEAD); do
    c=$(git diff -M origin/main...HEAD -- "$f" | grep '^+' | grep -v '^+++' \
        | grep -cE "stage-parallelism|stage_parallelism|CHARLY_STAGE_PARALLELISM")
    o=$(git diff -M origin/main...HEAD -- "$f" | grep '^+' | grep -v '^+++' \
        | grep -cE "podman-jobs|podman_jobs|PODMAN_JOBS")
    if [ "$c" != "0" ] || [ "$o" != "0" ]; then echo "$c new / $o retired  $f"; fi
  done
11 new / 0 retired  src/content/docs/recipes/build/build.md
1 new / 0 retired  src/content/docs/recipes/check/check/beds-and-r10.md
2 new / 0 retired  src/content/docs/recipes/internals/agents/parallel-bed-testing.md
1 new / 0 retired  src/content/docs/reference/plugin/github-com-opencharly-plugin-build-v2026-296-1104/plugin-build.md

The missed control, named. A review that reads a per-file diffstat off a rendered diff has no arithmetic instrument of its own, and a two-hunk file invites a ±1 that no check catches — the body asserted its numbers without a fence that re-derives them, so a reviewer had to re-derive them by hand to test them, and did it once. The control that would have caught this before the review is the one the body now carries: the numstat sum and the per-file loop, pasted. Both are re-runnable in one line each.

The rest

The head is unchanged, so the committed tree is the tree the gate ran on, and no gate re-run is required. The drift check, the corpus-currency report, the advisory gate and the step-deadline gate all ran on this exact commit.

Next update: when the deploy check (the site's own generation workflow, and this repo's R10 gate) concludes, or when the PR lands — whichever comes first.

Agent: charly · session ses_8efb271d-f2c0-47d3-85e3-2a1e00b11ae0
Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (fully tested and validated)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant