Skip to content

chore(deps): adopt spec v0.2026302.327 (a step renders on ONE line, so a reader can pair its status with its id) - #1086

Merged
github-actions[bot] merged 1 commit into
mainfrom
feat/spec-pin-report-one-line
Oct 29, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
feat/spec-pin-report-one-line

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

github.com/opencharly/spec is compiled into the charly binary, so the pinned module version IS
the behaviour of charly check run — of the bed record every R10 proof rests on.

At the pinned version (v0.2026296.1036) a step whose text carries a newline spanned SEVERAL
lines of the child's report: spec/report's renderStep wrote step.Text verbatim, so the
step's [id] bracket landed on a line of its own and no line carried both the status and the
id. plugin-check's reader matches ONE line per step, so it credited nothing for that step, the
child's report carried 21 step lines against the 22 its own rollup counted, and — since
plugin-check#134 — a report that disagrees with itself is refused WHOLE. Every check phase of
the bed then SKIPs and the run exits 3.

That is exactly what opencharly/layer-docs-site#13's check-docs bed hit: all five of its check
phases SKIP with "the child's report could not be read: 21 step line(s) against the 22 step(s)
its own rollup counted"
. The base tree of that repo, WITHOUT that repo's own change, produces
the identical skip with the identical numbers and the identical exit code 3 — so the defect is
pre-existing and lives in the PRODUCER of the report format, not in the change that found it.

The producer is fixed, producer-first, in opencharly/spec#283 (squash 4266c8b, module tag
v0.2026302.327): spec/report now renders every step on EXACTLY one line — the text and the
message flattened through one rule — so the status and the id are on the SAME line, and
truncate cuts on a character boundary so a report line is always decodable. The producer's own
tests assert that invariant and FAIL against the old renderer.

This change carries that version into the binary. Head cfcbfe7a461bd89c6d714e8ff3bb50394d78ee42
— 8 files changed, 12 insertions(+), 12 deletions(-) — moves github.com/opencharly/spec in
charly/go.mod:142 from v0.2026296.1036 to v0.2026302.327, and moves the three lockstep
modules with it (tools/generate-packages, tools/golden-cloudinit, tools/golden-compile),
because tools/gomod-canonical's TestContractPinsMatchShared requires every in-repo module
that requires a contract module to list the SAME shared sdk and spec pins.

The sdk pin is unchanged at v0.2026297.1851. That module requires spec v0.2026296.1036
itself, but Go's minimal version selection takes the MAXIMUM of the requirements in the graph,
so v0.2026302.327 is the version the graph selects — the sdk does not have to move for this
change, and no sdk release is required by it.

How tested

The work happened on feat/spec-pin-report-one-line in this repository's own session worktree,
off fresh origin/main (be7a505f). Every gate below ran on the committed tree this PR
carries — the same tree the head sha names.

$ git status --short; echo "STATUS_RC=$?"
STATUS_RC=0
$ git rev-parse HEAD
cfcbfe7a461bd89c6d714e8ff3bb50394d78ee42
$ git diff --shortstat origin/main...HEAD
 8 files changed, 12 insertions(+), 12 deletions(-)
$ bash /tmp/lds13/charly-gate.sh <this repo's worktree> /tmp/lds13/charly-gate-committed.log
=== go version ===
go version go1.27.3-X:nodwarf5 linux/amd64
GATE_START 2026-10-29T03:42:55Z

=== go test ./charly/... ===
ok  	github.com/opencharly/charly/charly	181.954s
ok  	github.com/opencharly/charly/charly/internal/pluginsgen	141.662s
TEST_RC=0

=== go vet ./charly/... ===
VET_RC=0

=== tools/* modules (GOWORK=off, -count=1) ===
== tools/generate-packages/ ==
?   	github.com/opencharly/charly/candy/generate-packages/cmd/serve	[no test files]
== tools/golden-cloudinit/ ==
?   	github.com/opencharly/charly/tools/golden-cloudinit	[no test files]
== tools/golden-compile/ ==
?   	github.com/opencharly/charly/tools/golden-compile	[no test files]
== tools/gomod-canonical/ ==
ok  	github.com/opencharly/charly/tools/gomod-canonical	0.001s
== tools/ledger-validate/ ==
ok  	github.com/opencharly/charly/tools/ledger-validate	0.002s
TOOLS_RC=0

=== gofmt ===
gofmt: clean
GOFMT_RC=0

=== golangci-lint ===
0 issues.
== lint tools/generate-packages/ ==
0 issues.
== lint tools/golden-cloudinit/ ==
0 issues.
== lint tools/golden-compile/ ==
0 issues.
== lint tools/gomod-canonical/ ==
0 issues.
== lint tools/ledger-validate/ ==
0 issues.
LINT_RC=0

=== R9 build: bin/charly version ===
bootstrap-charly: regenerating compiled-in plugin wiring
bootstrap-charly: building bin/charly
bootstrap-charly: built ./bin/charly (2026.302.0338)
BOOT_RC=0
2026.302.0338
VERSION_RC=0

GATE_END 2026-10-29T03:47:23Z

The affected target, re-proved live. The change is a behaviour change in the binary, so the
proof that it works is a REAL bed on a REAL disposable target — not a unit test. The check-docs
bed of opencharly/layer-docs-site (disposable: true, charly.yml:275) ran against that
repo's committed tree fa50b946f868a442d3c3868c0a2c5b539e6c9e8f with the binary this change
builds. Before this pin, every check phase SKIPped with the reason above and the run exited 3;
after it, the bed is green:

$ bash /tmp/lds13/run-bed.sh <layer-docs-site worktree> <charly worktree>/bin/charly /tmp/lds13/bed-green.log
BINARY /home/atrawog/Sync/Atrapub/a/claude/opencharly/.worktrees/charly-spec282/charly/bin/charly
2026.302.0338
BED_START 2026-10-29T03:40:16Z
charly check run check-docs: [image-build] START (charly box build; log: .check/check-docs/2026.302.0340/image-build.log)
charly check run check-docs: [image-build] PASS after 1m22.55s (log: .check/check-docs/2026.302.0340/image-build.log)
charly check run check-docs: [check-image] START (charly check box; log: .check/check-docs/2026.302.0340/check-image.log)
charly check run check-docs: [check-image] PASS after 14.846s (log: .check/check-docs/2026.302.0340/check-image.log)
charly check run check-docs: [deploy-add] START (charly deploy add; log: .check/check-docs/2026.302.0340/deploy-add.log)
charly check run check-docs: [deploy-add] PASS after 4.307s (log: .check/check-docs/2026.302.0340/deploy-add.log)
charly check run check-docs: [config] START (charly config; log: .check/check-docs/2026.302.0340/config.log)
charly check run check-docs: [config] PASS after 1.67s (log: .check/check-docs/2026.302.0340/config.log)
charly check run check-docs: [start] START (charly start; log: .check/check-docs/2026.302.0340/start.log)
charly check run check-docs: [start] PASS after 1.483s (log: .check/check-docs/2026.302.0340/start.log)
charly check run check-docs: [wait-ready] START
charly check run check-docs: [wait-ready] PASS after 127ms
charly check run check-docs: [bring-up-members] START
charly check run check-docs: [bring-up-members] PASS after 17ms
charly check run check-docs: [check-live] START (charly check live; log: .check/check-docs/2026.302.0340/check-live.log)
charly check run check-docs: [check-live] PASS after 7.651s (log: .check/check-docs/2026.302.0340/check-live.log)
charly check run check-docs: [feature-run] START (charly check feature; log: .check/check-docs/2026.302.0340/feature-run.log)
charly check run check-docs: [feature-run] PASS after 3.322s (log: .check/check-docs/2026.302.0340/feature-run.log)
charly check run check-docs: [update] START (charly update; log: .check/check-docs/2026.302.0340/update.log)
charly check run check-docs: [update] PASS after 18.451s (log: .check/check-docs/2026.302.0340/update.log)
charly check run check-docs: [rebuild-ready] START
charly check run check-docs: [rebuild-ready] PASS after 133ms
charly check run check-docs: [check-live-rebuild] START (charly check live; log: .check/check-docs/2026.302.0340/check-live-rebuild.log)
charly check run check-docs: [check-live-rebuild] PASS after 7.229s (log: .check/check-docs/2026.302.0340/check-live-rebuild.log)
charly check run check-docs: [wait-ready] START
charly check run check-docs: [wait-ready] PASS after 174ms
charly check run check-docs: [feature-run-rebuild] START (charly check feature; log: .check/check-docs/2026.302.0340/feature-run-rebuild.log)
charly check run check-docs: [feature-run-rebuild] PASS after 3.698s (log: .check/check-docs/2026.302.0340/feature-run-rebuild.log)
charly check run check-docs: [cleanup] START (charly remove; log: .check/check-docs/2026.302.0340/cleanup.log)
charly check run check-docs: [cleanup] PASS after 11.02s (log: .check/check-docs/2026.302.0340/cleanup.log)
charly check run check-docs: [cleanup-members] START
charly check run check-docs: [cleanup-members] PASS after 0s
charly check run check-docs: PASS (steps=16)
BED_RC=0
BED_END 2026-10-29T03:42:55Z

The same bed, on the same committed tree of that repo, with the binary built from the PREVIOUS
spec pin, SKIPped every check phase and exited 3 — the evidence that the pin bump is what
turned it green:

charly check run check-docs: [check-image] SKIP after 14.907s: the child's report could not be read: 21 step line(s) against the 22 step(s) its own rollup counted
charly check run check-docs: [check-live] SKIP after 7.458s: the child's report could not be read: 24 step line(s) against the 25 step(s) its own rollup counted
charly check run check-docs: [feature-run] SKIP after 3.455s: the child's report could not be read: 21 step line(s) against the 22 step(s) its own rollup counted
charly check run check-docs: SKIP (steps=16)
BED_RC=3

**The superseded pin is gone from every live surface.** The sweep is claim-keyed: it looks for
the exact version this change supersedes, everywhere except `CHANGELOG/`, which is history by
the repository's own rule.

$ git grep -n "v0.2026296.1036" -- . ':(exclude)CHANGELOG'
exit=1


The surviving mentions are all in `CHANGELOG/`, which records history and is never edited
retroactively. No alias, shim, deprecated path or fallback branch is introduced by this change.

## Rulebook compliance

- **R0** — this repository's own `AGENTS.md` was read before acting in it (umbrella Part II #4),
  and `/charly-internals:git-workflow`, `/charly-internals:root-cause-analyzer`,
  `/charly-internals:strict-policy` and `/charly-internals:go` were loaded before the first edit
  and before the git actions. The change is Go dependency work in the core module, whose gate
  that `AGENTS.md` names.
- **R1** — the anomaly was analysed before the remediation: the mechanism (the report format's
  producer let a step occupy more than one line), the missed control (nothing asserted "a step
  is one line", in either the producer or the reader), the blast radius (every bed whose plan
  carries a multi-line step, and the TAP report), and the root fix (the producer guarantees the
  shape it publishes). The defect was NOT introduced by the change that found it — the base tree
  reproduces it identically — and it is fixed in the repo that owns the format
  (opencharly/spec#283). This change carries the version that reaches the binary: the consumer
  leg of that fix. No warning was tolerated — the test run, the vet run, the tools sweep, the
  linter, the build and the bed each report zero.
- **R2** — one implementation: the shared pin lives in `charly/go.mod` and is derived into every
  lockstep module by `charly task mods-tidy`, the repository's own sweep. No module carries a
  second, hand-written copy of the pin.
- **R3** — no workaround: no sleep, no retry, no suppression, no fallback branch, no hand-edited
  gitlink and no hand-written version string. The version was moved by `go get` and `go mod
  tidy`, and the lockstep modules by the repository's own verb.
- **R4** — the product came first: the fix lives in the producer (opencharly/spec#283) and was
  merged and tagged there before this leg moved the version. The only prose this change touches
  is the commit message and this body, and it describes controls that exist.
- **R5** — the superseded pin is gone from every live surface; the claim-keyed sweep above
  returns nothing outside `CHANGELOG/`. The only surviving mentions of the old version are in
  `CHANGELOG/`, which is history.
- **R6** — the work happened in this repository's own session worktree, on
  `feat/spec-pin-report-one-line`, off fresh `origin/main`; no other session's work, branch or
  worktree was touched, no destructive git action was taken, and nothing is amended or
  force-pushed after the first push.
- **R7** — the coverage for the FIXED behaviour is the producer's, in opencharly/spec#283: its
  new tests fail against the old renderer and pass against the new one. This change's own
  coverage is the gate below, and the behaviour it introduces is proven by the bed, on the real
  target, with the real output pasted above.
- **R8** — nothing live is mocked: the bed runs against a real `disposable: true` pod deployment
  of the real image, and the changed path — the report the check engine prints and the reader
  that parses it — executed inside it.
- **R9** — the binary was rebuilt from this worktree's own tree with `scripts/bootstrap-charly.sh`
  and is invoked through that worktree's `bin/`, never a shared install; `bin/charly version` is
  in the gate output below. The build's own generated-file guard passed, so the tree carried no
  unexplained generated change.
- **R10** — the change class is a core dependency pin, so the gate is this repository's own core
  gate (`go test ./charly/...`, `go vet ./charly/...`, the `tools/*` sweep, gofmt,
  golangci-lint) plus the R9 build, and it ran on the committed tree with zero warnings. The
  affected `disposable: true` target — the `check-docs` bed — was rebuilt fresh and re-proved
  live above.

## Change classification

A core dependency pin that changes the binary's behaviour: the report format's producer now
guarantees the shape the format's consumers parse, and this binary is where that producer reaches
the beds. It removes nothing that was usable and adds no new surface, so no cutover machinery
applies — the report's contract is unchanged in name and in field, and only the shape of a
rendered step's text is corrected, to the shape the readers already require. The merge gate is
the org-wide `charly/pr-validator`.

## Filed issues

None filed by this change. The producer-side fix and its RCA are opencharly/spec#282 (filed,
fixed and merged as opencharly/spec#283); the consumer-side consequence is
opencharly/layer-docs-site#13, whose `check-docs` bed is green with this version. This change's
own scope is recorded in opencharly/charly#1085, which this PR resolves.

Closes #1085

Agent: charly

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

…o a reader can pair its status with its id)

`github.com/opencharly/spec` is compiled into the charly binary, so the pinned module
version IS the behaviour of `charly check run` — of the bed record every R10 proof rests
on.

At the pinned version (v0.2026296.1036) a step whose text carries a newline spanned
SEVERAL lines of the child's report: `spec/report`'s `renderStep` wrote `step.Text`
verbatim, so the step's `[id]` bracket landed on a line of its own and no line carried
both the status and the id. `plugin-check`'s reader matches ONE line per step, so it
credited nothing for that step, the child's report carried 21 step lines against the 22
its own rollup counted, and — since plugin-check#134 — a report that disagrees with
itself is refused WHOLE. Every check phase of the bed then SKIPs and the run exits 3.

That is exactly what opencharly/layer-docs-site#13's `check-docs` bed hit: all five of
its check phases SKIP with "the child's report could not be read: 21 step line(s)
against the 22 step(s) its own rollup counted". The base tree of that repo, WITHOUT
that repo's own change, produces the identical skip with the identical numbers and the
identical exit code 3 — so the defect is pre-existing and lives in the PRODUCER of the
report format.

The producer is fixed, producer-first, in opencharly/spec#283 (squash 4266c8b, module
tag v0.2026302.327): `spec/report` now renders every step on EXACTLY one line — the text
and the message flattened through one rule — so the status and the id are on the SAME
line, and `truncate` cuts on a character boundary so a report line is always decodable.
The producer's own tests assert the invariant and FAIL against the old renderer.

`charly/go.mod:142` moves `github.com/opencharly/spec` from v0.2026296.1036 to
v0.2026302.327. The three lockstep modules move with it — tools/generate-packages,
tools/golden-cloudinit and tools/golden-compile — by `charly task mods-tidy`, because
tools/gomod-canonical's TestContractPinsMatchShared requires every in-repo module that
requires a contract module to list the SAME shared sdk and spec pins.

The sdk pin is unchanged (v0.2026297.1851, which requires spec v0.2026280.2244):
v0.2026302.327 is the maximum the module graph selects, so no sdk move is behind it and
no cascade follows.

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 against the current state.

Scope & correctness

  • The change is exactly what the body describes: a pure dependency-pin bump of github.com/opencharly/spec from v0.2026296.1036 to v0.2026302.327, carried consistently across the core module (charly/go.mod/go.sum) and the three lockstep tool modules (tools/generate-packages, tools/golden-cloudinit, tools/golden-compile), plus their go.sum files.
  • Arithmetic checks out: 4 × (+1/−1) go.mod + 4 × (+2/−2) go.sum = 12 insertions / 12 deletions across 8 files, matching the body's stated 8 files changed, 12 insertions(+), 12 deletions(-).
  • The sdk pin is untouched at v0.2026297.1851 in every file, consistent with the body's explanation that Go MVS selects the max (v0.2026302.327) so the sdk need not move. This is correct Go semantics.
  • The spec .../go.mod hash line (VrjzjP2glMbDwP4JNm50OV0MraHFZnFKTl+bVlouoso=) is unchanged while the module h1: hash changes — consistent with a fix confined to source/tests rather than the dependency's own go.mod. No contradiction.
  • The tools/gomod-canonical TestContractPinsMatchShared lockstep requirement is honoured: every in-repo module that requires the contract module was bumped in the same commit, and the gate reports TOOLS_RC=0.

Honesty of the body

  • File count, insertion/deletion count, old→new versions, and the sdk-stays-put claim are all reproduced by the diff. The gate and bed transcripts are internally consistent (the check-docs bed lists exactly 16 steps, matching steps=16; the before/after SKIP-vs-PASS contrast is coherent). Nothing in the body contradicts the diff.
  • The claim that the superseded pin survives only in CHANGELOG/ is consistent with the diff — all live go.mod/go.sum references are updated and no other live file in this PR still carries the old version.

Tests

  • A version bump cannot carry tests for upstream behaviour in this repo; the body is explicit (R7) that the invariant test lives in the producer (fix(report): a step renders on ONE line, so a reader can pair its status with its id spec#283) and that the consumer leg's proof is the full core gate plus a real disposable: true bed on the affected target, with the before (exit 3 / all-SKIP) and after (green / exit 0) outputs shown. That is adequate evidence for a pin bump.

Security

  • No secrets, injection, or privilege changes. The only risk surface is a dependency version bump to a newer tagged module, which is the intended remediation.

Cleanliness

  • Minimal, coherent, no alias/shim/fallback/dead-code introduced. Single source of truth for the pin (derived into lockstep modules).

Comments

  • No comments were provided, so no sign-off to weigh; the change stands on its own evidence.

No blocking findings. The diff does exactly what the body claims, with consistent and complete evidence.

Verdict: PASS


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

View action run

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