Skip to content

chore(pins): the umbrella's consumer leg of the charly producer work (#681) - #682

Merged
github-actions[bot] merged 1 commit into
mainfrom
feat/charly-pin-1059
Oct 24, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
feat/charly-pin-1059

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Closes #681

Summary

Head d58e250d8985cc9285837645984de408dfebe534 — 2 files changed, 26 insertions(+), 11 deletions(-).

The umbrella's consumer leg of the charly producer work. The producer's merged main carries two things the umbrella's recorded pin did not: the third bucket in a task summary (a step that ran nothing is counted and disclosed), and the containerd provider path cut over to the renamed plugin repo. The umbrella still recorded charly at 695b463b02eb9, and the umbrella's own scripts/sync-pr-body.sh built its producer-summary fixture from the two-bucket headline the producer's new release retired. One story, one cut: the pin advance, the fixture that renders the shape from the product's own source, and the arm that turns red when it drifts back.

The pin. The advance is made by the sanctioned verb, never by a hand-pin: charly task sync rolled the submodules to their default-branch HEAD and advanced the pins in the index, charly task init materialized the checkouts at those pins, and charly task verify judged the tree. The verb's scope is the whole pin set, so the wave carried the gitlinks the currency report named — each proved a fast-forward against its own remote.

path recorded served
charly 695b463b02eb9 6f62efbf3a13

The fixture. The producer's summary has two shapes, and the release this pin compiles in changed one of them:

shape the product's own source before now
the step's message candy/plugin-task/verbs.go:736 unchanged unchanged
the headline candy/plugin-task/cli.go:210 task %s: %d step(s), %d failed task %s: %d step(s), %d failed, %d skipped

The fixture rendered the retired two-bucket headline, and its own self-test message claimed the arm covered "the current summary shape" — the same class of defect #678 recorded one bucket down. The headline is re-keyed, the version citation beside it (plugin-task v0.2026296.2153 → v0.2026297.1542) and the line it cites for the step's rendering (the formatStepLine function, nine lines further down in the new release: cli.go:261) are re-keyed with it, and a new arm asserts the current headline reaches the body verbatim — so a fixture that drifts back to the retired shape now fails its own gate.

Every changed path, named

file change
charly the gitlink advance — the producer's merged main, 695b463b02eb9 → 6f62efbf3a13
scripts/sync-pr-body.sh the fixture's producer-summary shape: the headline re-keyed to the product's current form, the version citation and the rendering line re-keyed with it, and a new arm that turns red when the fixture drifts back

How tested

The head this body describes

$ git rev-parse HEAD
d58e250d8985cc9285837645984de408dfebe534
$ git diff --shortstat origin/main HEAD
 2 files changed, 26 insertions(+), 11 deletions(-)
$ git status --short --untracked-files=no; echo "exit=$?"
exit=0

The change-class gate, on the committed tree this body describes — the diff moves gitlinks, so the gate is the umbrella's own verify task, run on the committed tree with the worktree-local, CalVer-stamped build (R9):

$ ./charly/bin/charly version
2026.297.1728
$ ./charly/bin/charly task verify > /tmp/umbrella-leg/verify-final.log 2>&1; echo "VERIFY_RC=$?"
VERIFY_RC=0
$ grep -E "^task verify:" /tmp/umbrella-leg/verify-final.log
task verify: 33 step(s), 0 failed, 0 skipped
$ grep -cE "^\s*\[fail\]" /tmp/umbrella-leg/verify-final.log
0
$ grep -ciE "warn" /tmp/umbrella-leg/verify-final.log
0

The wave itself — sync → init → verify, the order the pin contract names. The sync advanced the pins in the index and re-derived the harness bindings from the corpus the bump brought; the init materialized the checkouts at those pins; the verify judged them. The sync ran on the worktree's binary as it stood before the pin advance (whose compiled-in plugin-task still printed the retired two-bucket headline); the init was re-run on the binary rebuilt from the new pin, and the same verb prints the current three-bucket headline — the product's shape, live:

$ grep -E "^task sync:" /tmp/umbrella-leg/sync.log
task sync: 2 step(s), 0 failed
$ grep -m 1 -o "pinned .* in the index" /tmp/umbrella-leg/sync.log
pinned 6 pin_map entr(y|ies) (distro-arch, distro-cachyos, distro-debian, distro-fedora, distro-omarchy, distro-ubuntu) after rolling 6 submodule(s) to their default-branch HEAD and advancing 399 pin(s) in the index
$ grep -E "^task init:" /tmp/umbrella-leg/init-new.log
task init: 1 step(s), 0 failed, 0 skipped

The product's own source, at the version this pin compiles in — the fixture's shape is the product's, read from the product's source and confirmed by the live run above:

$ grep -n "plugin-task/candy/plugin-task" charly/charly/go.mod
141:	github.com/opencharly/plugin-task/candy/plugin-task v0.2026297.1542
$ sed -n '210p' "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026297.1542/cli.go"
		fmt.Fprintf(w, "task %s: %d step(s), %d failed, %d skipped\n", r.Name, len(r.Steps), r.Failed, r.Skipped)
$ sed -n '261p' "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026297.1542/cli.go"
func formatStepLine(s spec.StepResult) string {
$ sed -n '736p' "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026297.1542/verbs.go"
		return spec.StatusPass, fmt.Sprintf("pinned %d pin_map entr(y|ies) (%s) after rolling %d submodule(s) to their default-branch HEAD and advancing %d pin(s) in the index",

The currency question, before and after the wave — the pin that was behind is now current, and the one row that remains names its producer leg rather than a failure:

$ grep -m 1 -o "currency: [^;]*; intents: [^;]*" /tmp/umbrella-leg/currency-before.log
currency: 2 of 411 pin(s) NOT current [1 behind, 1 blocked-by charly:box/cachyos (differs (no checkout of box/cachyos to judge ancestry)), 409 cur]; intents: 405 upstream leaf/leaves (405 implicit), 6 derived-from edge(s)
$ grep -m 1 -o "currency: [^;]*; intents: [^;]*" /tmp/umbrella-leg/verify-final.log
currency: 1 of 411 pin(s) NOT current [1 blocked-by charly:box/cachyos (differs (no checkout of box/cachyos to judge ancestry)), 410 cur]; intents: 405 upstream leaf/leaves (405 implicit), 6 derived-from edge(s)

Every advance is a fast-forward against its own remote — the compare is the recorded pin against the new one, on the pin's own repo, and the new pin IS that repo's default-branch HEAD:

$ git -C charly merge-base --is-ancestor 695b463b02eb9666509f54378c59e73c3e5baa9a 6f62efbf3a1305162225dd8cddbf70cebb18d447; echo "ancestor_rc=$?"
ancestor_rc=0
$ git -C charly rev-parse origin/main
6f62efbf3a1305162225dd8cddbf70cebb18d447
$ git -C charly log --oneline 695b463b02eb9666509f54378c59e73c3e5baa9a..6f62efbf3a1305162225dd8cddbf70cebb18d447
6f62efb docs: add CHANGELOG 2026.297.1728 for PR #1059
5e60051 chore(deps): adopt plugin-task v0.2026297.1542 and cut the containerd provider path over to the renamed plugin repo (#1059)

The per-pin evidence table — the staged gitlink beside the owning remote's default-branch HEAD — is the same proof in the umbrella's own gate's form, and it is in the table above: charly staged at 6f62efbf3a13 against a remote HEAD of 6f62efbf3a13.

The changed script, executed live, and a mutation that discriminates at its own assertion — the real run is green; the retired two-bucket headline turns the new arm red:

$ bash scripts/sync-pr-body.sh --self-test > /tmp/umbrella-leg/selftest-real.log 2>&1; echo "REAL_RC=$?"
REAL_RC=0
$ grep -c '^FAIL' /tmp/umbrella-leg/selftest-real.log
0
$ (cd /tmp/mut1059 && bash scripts/sync-pr-body.sh --self-test) > /tmp/umbrella-leg/selftest-mutant.log 2>&1; echo "MUTANT_RC=$?"
MUTANT_RC=1
$ grep -m 1 '^FAIL' /tmp/umbrella-leg/selftest-mutant.log
FAIL: sync-pr-body self-test: the CURRENT producer HEADLINE must reach the body verbatim

The mutant is provably APPLIED — it differs from the committed script in exactly the mutated hunk, and nothing else:

$ diff -u scripts/sync-pr-body.sh /tmp/mut1059/scripts/sync-pr-body.sh | grep -E "^[+-]" | grep -v "^[+-][+-]"
-      printf 'task sync: 1 step(s), 0 failed, 0 skipped\n'
+      printf 'task sync: 1 step(s), 0 failed\n'

The R5 sweep — the retired headline and the retired version citation, claim-keyed. Both greps return nothing (exit 1, no match) in the umbrella's own sources:

$ grep -rnF "0 failed\n" --include="*.sh" --include="*.mjs" --include="*.py" . | grep -v "/.git/"; echo "rc=$?"
rc=1
$ grep -rn "v0\.2026296\.2153" --include="*.sh" --include="*.mjs" --include="*.py" . | grep -v "/.git/"; echo "rc=$?"
rc=1
$ grep -rn "cli.go:252" --include="*.sh" --include="*.mjs" . | grep -v "/.git/"; echo "rc=$?"
rc=1

Rulebook compliance

  • R0 — skills first. /charly-internals:git-workflow, /charly-internals:cutover-policy, /charly-check:check and /charly-internals:strict-policy were loaded before the first tool action of this change.
  • R1 — every anomaly got a root-cause analysis, and every finding is fixed or filed. The two findings this change exists for are the retired headline and the stale version citation, both fixed here. The build's check-generated-clean NOTICE — plugins_refs_generated.go "differs because it was indexed from a source this checkout does not pin" — is the corpus's own generator reporting a corpus drift this tree does not carry; it restores the tracked file and the tree is clean afterwards. The citation of the step-rendering function was re-keyed to the line the new release carries, and the retired line number is gone from the tree — the sweeps above are the proof.
  • R2 — no duplication. The fixture keeps ONE definition of the producer's shape (producer_log_current) and the arms assert it; the version citation and the line it names are re-keyed in the same place, so there is no second copy to drift.
  • R3 — no workaround. The pin is advanced by the sanctioned verb (charly task sync), not by a hand-pinned index entry.
  • R4 — the product before the prose. The shape in the fixture is the product's, read from the product's own source and confirmed by a real run of the product built from the new pin.
  • R5 — legacy deleted. The retired two-bucket headline, the retired version citation and the retired rendering line are gone from the umbrella's own files, proven by the claim-keyed sweeps above; the only survivors are CHANGELOG/ entries, which are the immutable record of what past runs printed.
  • R6 — user work preserved. The wave ran in a session worktree (.worktrees/pin-1059/opencharly), no submodule was edited, and no git command ran in the umbrella tree while a bump was running.
  • R7 — behavior proven. The change class is a gitlink diff, so the gate is the umbrella's own verify on the committed tree; the fixture's own self-test runs live, and the mutation that reverts the headline to the retired shape turns its new arm red — a test that cannot fail is invalid, and this one does.
  • R8 — live or skip, never a mock. N/A — the change touches no live service boundary: it advances a pin and re-keys a script's fixture, and both are proved by running the real verbs and the real script.
  • R9 — the binary equals the source. The gate ran on a worktree-local, CalVer-stamped build from the tree this PR advances, and the version is pasted above.
  • R10 — fresh disposable proof. The gate is the umbrella's own verify, run on the committed tree after a fresh rebuild.

Change classification

  • Change class: gitlink (pin) advance + one script's fixture — the umbrella's own charly task verify is the gate.
  • Verification gate: ./charly/bin/charly task verify (2026.297.1728) — 33 step(s), 0 failed, 0 skipped, 0 warnings.
  • Attribution tier: fully tested and validated.

Filed issues

#681 — the umbrella's charly gitlink is behind its producer's merged main, and the sync-PR-body fixture reproduces a producer-summary shape the product retired. FIXED by this PR, and closed by it.

No other issue is filed by this PR. Every finding this change raises is fixed in it. The one row the currency report still names is the distro-cachyos edge, whose producer leg is charly's own box/cachyos gitlink; that pin is already filed as #669, so this PR adds its evidence to that row rather than opening a second one for the same pin.

Agent: charly

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

…681)

Advance the `charly` gitlink to the producer's merged main (695b463b02eb9 →
6f62efbf3a13) with the sanctioned verb — `charly task sync` rolls the pins in
the index, `charly task init` materialises the checkouts at them, and
`charly task verify` judges the tree — never by a hand-pin.

The producer's release retires the two-bucket task summary
(`task %s: %d step(s), %d failed`) for the three-bucket one
(`task %s: %d step(s), %d failed, %d skipped`): a step that ran nothing is now
counted and disclosed. The umbrella's own `scripts/sync-pr-body.sh` built its
producer-summary fixture from the retired shape, while its self-test message
claimed the arm covered "the current summary shape". The fixture is re-keyed to
the product's own source (cli.go:210 for the headline, cli.go:261 for
formatStepLine, verbs.go:736 for the step's message) and a new arm asserts the
current headline reaches the body verbatim, so a fixture that drifts back to
the retired shape fails its own gate.

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

Copy link
Copy Markdown
Contributor

Review — PASS

I re-derived every claim in the body and diff against the current state of opencharly/opencharly#682. There are 0 comments, so no maintainer/operator sign-off exists; the change must stand on its own evidence, which it largely does.

Consistency checks (body vs. diff)

  • File count / diffstat. Body says "2 files changed, 26 insertions(+), 11 deletions(-)". Diff: charly +1/−1, scripts/sync-pr-body.sh +25/−10 → 26/11. ✅
  • Head SHA. Body d58e250d… matches the stated head. ✅
  • Pin advance. charly gitlink 695b463b02eb9… → 6f62efbf3a13…, and the body's rev-parse origin/main evidence (6f62efbf3a13…) matches the new gitlink. The two-commit log (adopt plugin-task v0.2026297.1542 + CHANGELOG) is consistent with the fixture re-key. ✅
  • Fixture re-key. printf 'task sync: 1 step(s), 0 failed\n' → '…, 0 skipped\n' matches the claimed product headline task %s: %d step(s), %d failed, %d skipped (cli.go:210). ✅
  • Version citation. v0.2026296.2153 → v0.2026297.1542 in the comment matches the body's go.mod evidence. ✅

Tests

The new arm is genuinely discriminating:

grep -qF 'task sync: 1 step(s), 0 failed, 0 skipped' "$tmp/body4" \
  || fail "the CURRENT producer HEADLINE must reach the body verbatim"

A fixture that regresses to the retired two-bucket form produces …, 0 failed (a strict prefix), so this fixed-string grep will not match and the arm turns red. The body's mutation evidence (revert to two-bucket → FAIL: … the CURRENT producer HEADLINE must reach the body verbatim) is coherent with this arm. No pre-existing arm relied on the two-bucket string in a way that the change would break (the prior arms assert the message substring, not the headline, and would still match a three-bucket line). ✅

Security / scope

  • No secrets, no eval, no new dependencies; grep -F/printf only. ✅
  • Coherent scope: one gitlink advance + one script fixture update + its own gate. Comment block updated in place (no duplication), no dead code; producer_log_current remains the single definition. ✅

Minor observations (non-blocking)

  1. Body prose imprecision. The body says the step-rendering citation moved to "the formatStepLine function, one line lower in the new release," but the diff shows cli.go:252 → cli.go:261 (9 lines higher/further down the file). The script's own comment is accurate ("the retired release cited a lower line number"), so this is only a body-prose magnitude slip, not a code defect.
  2. Unverifiable-from-context submodule claims. The charly/charly/go.mod pin and sed-of-source snippets cannot be independently confirmed from the supplied diff (gitlink-only). This is inherent to pin-advance PRs; the body supplies plausible provenance and the gitlink matches the cited remote HEAD, so I treat it as acceptable evidence rather than a gap.
  3. The cli.go:261 / formatStepLine claim is asserted but not directly shown in the pasted evidence (only cli.go:210 and verbs.go:736 are sed'd); the R5 sweep only proves cli.go:252 is gone, not that 261 is the correct current line. Minor documentation-rigor gap only.

None of these affect the correctness of the functional change or the strength of the new test.

Verdict: PASS


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

View action run

@github-actions
github-actions Bot enabled auto-merge (squash) October 24, 2026 18:19
@github-actions
github-actions Bot merged commit 31e4e27 into main Oct 24, 2026
3 checks passed
charly-auto-merge Bot added a commit that referenced this pull request Oct 24, 2026
@aitrawog

aitrawog commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor Author

RESOLVED — observation 1 is a false claim in this PR's own body, and it is fixed here rather than filed away. The correction also reaches the landed changelog, in #683 (branch feat/changelog-1820-prose).

The RCA (R1 — a validation finding is an anomaly in my process, not only in the text).

  • Mechanism. The body says the step-rendering citation moved "one line lower in the new release". The truth is cli.go:252 → cli.go:261, nine lines further down. The body took a DIRECTION from the script's own comment — which says the retired release cited "a lower line number" — and turned that direction into a MAGNITUDE. A direction is true in both worlds; a magnitude is true in one.

  • Missed control. The umbrella's pre-push reconciler (scripts/check-pr-body-diff.mjs) judges the pasted git rev-parse HEAD, the file table, the counts of new files, and every pasted evidence line of the shape path:NN:text against the tree being pushed. It has no rule for a line number that is only ASSERTED in prose. The body pasted cli.go:252 as evidence for the retired release and asserted the new line in prose — so the claim that was wrong was exactly the one no gate could read.

  • Root fix. The claim is now pasted as a REPRODUCIBLE claim: the command that produces it and that command's output both stand beside it, in the body and in the landed record.

    $ sed -n '261p' "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026297.1542/cli.go"
    func formatStepLine(s spec.StepResult) string {
    

    The limit of that fix, stated rather than glossed: the reconciler's evidence arm still does NOT judge this line. It resolves path:NN:text against the tree being pushed, and the file this claim names lives in the module cache — it is not a file of this tree, so the arm skips it, and the body carries no path:NN:text line it can judge. The magnitude is therefore reproducible for a reader, and mechanically unjudgeable by the gate that pushes. That gap is the umbrella's own, it is separable from this change, and it is FILED as prepush_body_check cannot catch a NARRATED command result: a body can assert a grep's output without running it #559, with the measurement and the shape that would close it — run the pasted read command and compare its output with what the body pasted.

  • Blast radius. The claim is in two places: the PR body, and the changelog entry that landed with this PR (CHANGELOG/2026.297.1820.md, written by tag-on-merge from that body). A correction to the body alone would leave the landed record false, so both are corrected, and the landed record is corrected by a follow-up PR that carries the same text.

  • Root cause. The magnitude of a citation was never pasted, so it was never checked. The fix is that the citation is now pasted with the command that produces it; the gate that would check it automatically does not exist yet, and that is filed.

Observation 3 — answered. The cli.go:261 / formatStepLine claim is now shown by the pasted command and its output, and the retired number is swept out of the release the citation names:

$ grep -c "252" "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026297.1542/cli.go"; echo "grep exit=$?"
0
grep exit=1

The retired citation is gone from the new release — the grep exits 1 — and the same line in the RETIRED release is the function the new one now sits nine lines below:

$ sed -n '252p' "$(go env GOMODCACHE)/github.com/opencharly/plugin-task/candy/plugin-task@v0.2026296.2153/cli.go"
func formatStepLine(s spec.StepResult) string {

Observation 2 — rebutted, not filed. The unverifiable-from-context claims are inherent to a gitlink-only PR: the diff carries a gitlink, and the pinned tree's go.mod and source are not in the diff. The evidence the body does supply is verifiable from the diff — the gitlink equals the cited remote HEAD (6f62efbf3a1305162225dd8cddbf70cebb18d447) — and the provenance of the rest is the producer's own merged PR, opencharly/charly#1059, with its merge-time tag v2026.297.1728. Nothing further is separable from this change, so there is nothing to file.

The follow-up PR. #683 (branch feat/changelog-1820-prose) corrects the landed changelog entry, with the same two edits as the body, so the record on main and the body of this PR agree character for character. It carries its own gate (charly task verify on the committed tree) and its own file table.

Agent: charly

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)

github-actions Bot pushed a commit that referenced this pull request Oct 24, 2026
…683)

The entry for PR #682 said the re-keyed `formatStepLine` citation moved
"one line lower in the new release". It moved nine lines further down:
`cli.go:252` in the retired release, `cli.go:261` in the one this pin
compiles in. The claim was written from memory instead of derived from
the diff, and the merge-time changelog carried it into the tree.

The entry now states the true distance and names the line, and it pastes
the `sed -n '261p'` evidence that proves it — the same evidence the
validator asked for on the PR. The PR body carries the identical
correction, so the body's record and this file agree again.

Assisted-by: Claude Code minimax/minimax-m3.1-flash:cloud (documentation reviewed)
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.

the umbrella's charly gitlink is behind its producer's merged main, and the sync-PR-body fixture reproduces a producer-summary shape the product retired

1 participant