Skip to content

docs: correct the test-pipe claim in the 2026.297.2014 record - #52

Merged
github-actions[bot] merged 1 commit into
mainfrom
feat/record-pipe-claim
Oct 24, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
feat/record-pipe-claim

Conversation

@aitrawog

@aitrawog aitrawog commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Closes #50

Summary

Head e18e3e09cf3576916ed7e429ad5b15257b9da0c5 — 1 file changed, 27 insertions(+), 12 deletions(-).

The landed record of PR #49 carried a false count, and this PR corrects the record. The entry CHANGELOG/2026.297.2014.md — written at merge time from the body of #49 — said "2. Every os.Pipe() in this repo's tests leaked its read end.", and its file table said the four captureStdin tests were the ones that leaked. The truth: five of the repo's eight test pipes leaked their read end — the three captureStdin tests and the runTask truncation test in runner_test.go, and the stdin-bytes test in stepenv_test.go. Three already closed both ends: the gating test in runner_test.go and both pipes in capture_test.go. "Every" was three pipes too many, and the file table's row named four captureStdin tests where the file has three — it missed the stepenv_test.go leak outright and called the runTask truncation test a captureStdin one.

What this PR changes is the RECORD, not the product. The code #49 landed is right: the audit below reports 8 pipes and 0 unclosed on the committed tree, at the scope that can see a leak. What was false was the prose about the tree BEFORE that change, and the file table's label; both are re-keyed here. The record's measurement block is REWRITTEN, not carried over: the landed record held ONE block, at the FILE scope, listing all eight pipes as closed — the after-state alone. It now holds TWO, at the FUNCTION scope: the tree before the change, where five of the eight leaked their read end, and the tree this change lands, where all eight close it. The product's own test sources — candy/plugin-task/runner_test.go and candy/plugin-task/stepenv_test.go — landed in #49, and this diff does not touch them.

The RCA is on the thread of the PR whose body carried the claim (#49): the mechanism, the missed control, the blast radius and the root fix are recorded there, next to the retraction of the two STATUS comments the claim reached.

What a gate still cannot read is filed, not hidden. The sweep behind the record's blocks looked for the read end's Close in the whole FILE, and the four tests in runner_test.go that open a pipe each name their read end r — so the gating test's one Close stood in for all four. On a tree with one close removed, that scope reports 0 unclosed where the function scope reports 1: it cannot fail on this. The measurement and the shape that would close it are FILED as #51, and the record now names the scope its sweep ran at.

file what it carries
CHANGELOG/2026.297.2014.md the corrected count of the pipes that leaked, the corrected file-table row, the sweep sentence naming the scope the audit ran at, the measurement block rewritten to carry a before-state at that scope, and the R1 bullet naming the file scope's weakness and the filed issue

How tested

The head this body describes

$ git rev-parse HEAD
e18e3e09cf3576916ed7e429ad5b15257b9da0c5
$ git diff --shortstat origin/main HEAD
 1 file changed, 27 insertions(+), 12 deletions(-)
$ git status --short --untracked-files=no; echo "exit=$?"
exit=0

The change-class gate, on the committed tree this body describes. The diff touches one file of prose — no submodule, no gitlink, no pin — so the gate that owns it is the documentation-only class's: the non-runtime standards, which are markdown integrity, the claim-keyed R5 sweep, cross-reference validation and the command-safety gate. No bed runs and no image builds, because a bed cannot fail on prose. The whole gate log is pasted here; every measurement in it carries the command that produced it and that command's own exit code, every sweep arm carries the exit code it must produce, and the last arm checks this body's own claims about the diff against the diff's file list — proved DISCRIMINATING, because it finds the claim in the body the validator rejected and finds nothing in this one.

=== the head this gate ran on ===
e18e3e09cf3576916ed7e429ad5b15257b9da0c5

=== the change class: the files the diff touches (against origin/main) ===
CHANGELOG/2026.297.2014.md
=== the diff's size ===
 1 file changed, 27 insertions(+), 12 deletions(-)

=== markdown integrity: the fence count is even and the headings are intact ===
fences=14
MARKDOWN_FENCES=EVEN
headings:
  1:# 2026.297.2014 — test(task): the stdin exclusion proves its precondition, and every test pipe is closed
  3:## Summary
  17:### RCA
  24:### The files this diff touches
  31:## How tested
  288:## Rulebook compliance
  304:## Change classification

=== the command-safety gate: the record's pasted commands name no forbidden operation ===
$ grep -nE '^$ .*(systemctl|podman|docker|sudo|--no-verify|--force|force-push)' CHANGELOG/2026.297.2014.md
grep exit=1

the four claim patterns were taken from the trees themselves
=== the claim-keyed R5 sweep: BEFORE (origin/main) ===
$ grep -nF -f /tmp/umbrella-leg/pt51/false-claim.txt /tmp/umbrella-leg/pt51/before.md
11:**2. Every `os.Pipe()` in this repo's tests leaked its read end.** The four `captureStdin` tests did; the file's newer gating test and `capture_test.go` already closed both ends, so this change applies the file's own pattern to its siblings rather than inventing one.
grep exit=0 (expected 0)

$ grep -nF -f /tmp/umbrella-leg/pt51/false-row.txt /tmp/umbrella-leg/pt51/before.md
29:| `candy/plugin-task/runner_test.go` | the four `captureStdin` tests close their pipes' read ends, the pattern the file's newer gating test already used |
grep exit=0 (expected 0)

$ grep -nF -f /tmp/umbrella-leg/pt51/true-claim.txt /tmp/umbrella-leg/pt51/before.md
grep exit=1 (expected 1)

$ grep -nF -f /tmp/umbrella-leg/pt51/true-row.txt /tmp/umbrella-leg/pt51/before.md
grep exit=1 (expected 1)

=== the claim-keyed R5 sweep: AFTER (the committed tree) ===
$ grep -nF -f /tmp/umbrella-leg/pt51/false-claim.txt CHANGELOG/2026.297.2014.md
grep exit=1 (expected 1)

$ grep -nF -f /tmp/umbrella-leg/pt51/false-row.txt CHANGELOG/2026.297.2014.md
grep exit=1 (expected 1)

$ grep -nF -f /tmp/umbrella-leg/pt51/true-claim.txt CHANGELOG/2026.297.2014.md
11:**2. Five of the repo's eight test pipes leaked their read end.** Four were in `runner_test.go` — the three `captureStdin` tests and the `runTask` truncation test — and the fifth was the stdin-bytes test in `stepenv_test.go`. The gating test in `runner_test.go` and both pipes in `capture_test.go` already closed both ends, so this change applies the file's own pattern to its siblings rather than inventing one.
grep exit=0 (expected 0)

$ grep -nF -f /tmp/umbrella-leg/pt51/true-row.txt CHANGELOG/2026.297.2014.md
29:| `candy/plugin-task/runner_test.go` | the four pipes in this file — the three `captureStdin` tests' and the `runTask` truncation test's — close their read ends, the pattern the file's newer gating test already used |
grep exit=0 (expected 0)

the record's PRE block and POST block were located
the mutation removes the read-end close at line 34: '\t_ = r.Close()'

=== the measurement: the tree BEFORE PR #49, audited at the FUNCTION scope ===
$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /tmp/umbrella-leg/pt51/pre --scope function > /tmp/umbrella-leg/pt51/pre-fn.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/pre-fn.txt
PIPES=8 UNCLOSED=5
PIPE_AUDIT_RC=1
live exit=1

=== the measurement: the tree BEFORE PR #49, audited at the FILE scope ===
$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /tmp/umbrella-leg/pt51/pre --scope file > /tmp/umbrella-leg/pt51/pre-file.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/pre-file.txt
PIPES=8 UNCLOSED=1
PIPE_AUDIT_RC=1
live exit=1

=== the measurement: the committed tree, audited at the FUNCTION scope ===
$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /home/atrawog/Sync/Atrapub/a/claude/opencharly/.worktrees/pt-record/plugin-task --scope function > /tmp/umbrella-leg/pt51/post-fn.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/post-fn.txt
PIPES=8 UNCLOSED=0
PIPE_AUDIT_RC=0
live exit=0

=== the measurement: the committed tree, audited at the FILE scope ===
$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /home/atrawog/Sync/Atrapub/a/claude/opencharly/.worktrees/pt-record/plugin-task --scope file > /tmp/umbrella-leg/pt51/post-file.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/post-file.txt
PIPES=8 UNCLOSED=0
PIPE_AUDIT_RC=0
live exit=0

=== the record's pasted blocks against the live runs ===
$ diff /tmp/umbrella-leg/pt51/record-pre.txt /tmp/umbrella-leg/pt51/pre-fn.txt
diff exit=0
$ diff /tmp/umbrella-leg/pt51/record-post.txt /tmp/umbrella-leg/pt51/post-fn.txt
diff exit=0

=== the scope the instrument ran, asserted by its EFFECT ===
the function scope on the tree before PR #49: PIPES=8 UNCLOSED=5
the file scope on the tree before PR #49:    PIPES=8 UNCLOSED=1
the two scopes disagree, so the --scope flag took effect

=== the instrument's discriminating power: one close removed from the committed tree ===
the mutation, in the tree the audit runs:
  	// MUTATION: the read end is not closed

$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /tmp/umbrella-leg/pt51/mutant --scope function > /tmp/umbrella-leg/pt51/mutant-fn.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/mutant-fn.txt
PIPES=8 UNCLOSED=1
PIPE_AUDIT_RC=1
live exit=1

$ python3 /tmp/umbrella-leg/pipeaudit/audit.py /tmp/umbrella-leg/pt51/mutant --scope file > /tmp/umbrella-leg/pt51/mutant-file.txt
$ tail -n 2 /tmp/umbrella-leg/pt51/mutant-file.txt
PIPES=8 UNCLOSED=0
PIPE_AUDIT_RC=0
live exit=0

=== the mutant: the product still builds and the suite still passes ===
$ (cd $W/mutant/candy/plugin-task && go build ./... && go test -count=1 ./...)
ok  	github.com/opencharly/plugin-task/candy/plugin-task	3.289s
?   	github.com/opencharly/plugin-task/candy/plugin-task/cmd/serve	[no test files]
?   	github.com/opencharly/plugin-task/candy/plugin-task/params	[no test files]
mutant build+suite exit=0

=== the landed record and the merged PR's body carry the same characters ===
$ diff <(tail -n +3 CHANGELOG/2026.297.2014.md) <(printf '%s' "$(gh pr view 49 --repo opencharly/plugin-task --json body --jq .body)")
diff exit=0

=== the cross-references the record makes ===
$ gh issue view 47 --repo opencharly/plugin-task --json number,state,title
issue #47 MERGED feat(task): a task's resolved values reach a step's process environment as DATA
exit=0
$ gh issue view 48 --repo opencharly/plugin-task --json number,state,title
issue #48 CLOSED the stdin-exclusion test does not assert its precondition, and five of the repo's eight test pipes leak their read end
exit=0
$ gh issue view 50 --repo opencharly/plugin-task --json number,state,title
issue #50 OPEN the landed record says every test pipe leaked its read end, but five of the eight did
exit=0
$ gh issue view 51 --repo opencharly/plugin-task --json number,state,title
issue #51 OPEN no control in this repo can fail when a test pipe's read end is not closed
exit=0
file candy/plugin-task/runner_test.go: present
file candy/plugin-task/stepenv_test.go: present
file candy/plugin-task/capture_test.go: present

=== the body's own claims against this diff ===
$ python3 /tmp/umbrella-leg/bodyclaims/check.py /tmp/umbrella-leg/pt51-body-old.md CHANGELOG/2026.297.2014.md
the body's diff-claims: 1 file(s) in the diff
the arm found 2 finding(s):
  FINDING line 9: the unchanged-claim ['untouched', 'already said'] names no file — name the file it is about, or drop the claim: **What this PR changes is the RECORD, not the product.** The code #49 landed is right: the audit below reports 8 pipes and 0 unclosed on the committed tree, at 
  FINDING line 200: the unchanged-claim ['untouched'] names no file — name the file it is about, or drop the claim: - **R4 — the product before the prose.** The product work landed in #49 and is untouched; the prose now says what the product's own test sources show, and the s
the rejected body: exit=1 (expected 1 — the arm must find the false claim)

$ python3 /tmp/umbrella-leg/bodyclaims/check.py /tmp/umbrella-leg/pt51-body.md CHANGELOG/2026.297.2014.md
the body's diff-claims: 1 file(s) in the diff
the arm found no finding
the body this PR pushes: exit=0 (expected 0)

GATE_RC=0

The two mechanical gates that judge this body against this diff, run on the committed tree and on this file:

$ python3 -I marketplace/scripts/pr_body_lint.py /tmp/umbrella-leg/pt51-body.md --head e18e3e09cf3576916ed7e429ad5b15257b9da0c5 --repo . --base origin/main
pr_body_lint: 0 finding(s)
$ node scripts/check-pr-body-diff.mjs --body /tmp/umbrella-leg/pt51-body.md --repo . --base origin/main
  PASS  every pasted `git rev-parse HEAD` names the head being pushed (e18e3e0)
  NOTE  the body pastes no evidence line that names a file and a line number — the evidence rule is inapplicable
  NOTE  the body states no count of the diff's new files — the count rule is inapplicable
  PASS  the file table lists exactly the 1 file(s) the diff changes (against origin/main)
check-pr-body-diff: OK

The reconciler's own NOTE is the honest limit of that gate, and it is the filed residual: the body pastes no line of the shape path:NN:text, because the audit's per-pipe lines live in the record's own blocks, and the two diff exit=0 arms in the gate log above show that the record's blocks ARE the live run's output, character for character. The claim is therefore reproducible by a reader, and the instrument that decides it is named in the record.

Rulebook compliance

  • R0 — skills first. /charly-internals:git-workflow, /charly-internals:root-cause-analyzer, /charly-internals:strict-policy and /charly-build:docs were loaded before the first tool action of this change, and this repo's own AGENTS.md was read for the class this change falls in.
  • R1 — every anomaly got a root-cause analysis, and every finding is fixed or filed. The finding this change exists for is the false count in test(task): the stdin exclusion proves its precondition, and every test pipe is closed #49's landed record, and it is fixed in both places it lived: the body, on that PR's thread, and the landed entry, here. The RCA — mechanism, missed control, blast radius, root fix — is on that thread. Two anomalies arose in this change's own work, and both were root-caused rather than worked around. The first is my own gate script: its --scope parser read the flag's presence and not its value, so every audit ran at the FILE scope, and the gate's own diff arm caught it — the record's PRE block names 5 unclosed pipes and the file scope reports 1. The root fix went into the parser, and the gate now asserts the scope by its EFFECT, because the two scopes must disagree on that tree. The second is the sweep's own pattern: the first version of the claim-keyed sweep retyped the claim, and the retype said "their" where the record says "its", so the arm that had to FIND the false claim found nothing and the gate passed without it. The root fix went into the sweep, which now takes every pattern from the tree it sweeps and asserts the exit code each arm must produce. The control gap the RCA exposed is FILED as no control in this repo can fail when a test pipe's read end is not closed #51. A third anomaly came from the validator itself: its BLOCK on this PR's first body named a sentence that said the measurement blocks of CHANGELOG/2026.297.2014.md were untouched, while the diff rewrites exactly those blocks. The mechanism was that the body was written from the shape of the change rather than from the diff's hunks, so the claim was not checkable by any gate. The missed control was the pre-push self-audit, which had no check that a body's claim about a diffed file's CONTENT agrees with the diff: the org's body linter has arms for a file's existence, a count and a diffstat, and none for a claim about its content, so that class of contradiction reaches the validator and costs a verdict. The root fix went into the control: the gate now carries an arm that checks every unchanged-claim in this body against the diff's file list, and the arm is proved DISCRIMINATING — it finds the rejected body's claim and finds nothing in this one. The org's linter has no such arm, and that gap is FILED as pr_body_lint has no arm that checks a body's claim about a diffed file's CONTENT against the diff (measured on plugin-task#52's first-push BLOCK) marketplace#577.
  • R2 — no duplication. The corrected claim is one claim, and the record now carries the same characters as the PR body it came from — proven by the diff above, not by a second wording of the same claim.
  • R3 — no workaround. The correction is a commit against the record. Nothing suppresses the false claim, retries around it, or hides it behind a flag.
  • R4 — the product before the prose. The product's test sources — candy/plugin-task/runner_test.go and candy/plugin-task/stepenv_test.go — landed in test(task): the stdin exclusion proves its precondition, and every test pipe is closed #49, and this diff does not touch them; the prose now says what those sources show, and the sweep above shows it.
  • R5 — legacy deleted. The false wording and the mislabelled file-table row are gone from the record, proven by the sweep above.
  • R6 — user work preserved. The change lives in the session worktree on feat/record-pipe-claim, branched from this repo's origin/main. The tree was clean before the commit, no submodule was edited, no published history was rewritten, and nothing was pushed to main.
  • R7 — behaviour proven. The coverage for a prose correction is the claim-keyed sweep, and it discriminates: on the tree before the commit the false wording is there and the corrected one is not, and on the committed tree the opposite holds. The measurement behind the corrected count is re-run on both trees and diffed against the record's own blocks, and the instrument that produced it is shown able to fail.
  • R8 — live or skip, never a mock. N/A — the change touches no live service boundary: it corrects one file of prose, and the claim is read from this repo's own test sources.
  • R9 — the binary equals source. N/A — the change is prose in this repo and ships no runtime binary; the gate it ran is this repo's own, read from this repo's checkout.
  • R10 — fresh disposable proof. The change-class gate ran on the committed tree this PR pushes: the documentation-only class's non-runtime standards, zero findings, with the whole log pasted above.

Change classification

  • Change class: documentation — a changelog record. No code, no schema, no gitlink, no pin, no behavioral configuration.
  • Verification gate: the documentation-only class's non-runtime standards — markdown integrity, the claim-keyed R5 sweep, cross-reference validation and the command-safety gate — run on the committed tree, plus the org's own body linter and the umbrella's body/diff reconciliation, both pasted above. No bed run and no image build: a bed cannot fail on prose.
  • Attribution tier: documentation reviewed — the diff is prose only, so no runtime tier is claimed.

Filed issues

Agent: charly

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

The record says "Every `os.Pipe()` in this repo's tests leaked its read
end" and names "the four `captureStdin` tests". Measured at the scope of
the function that opened each pipe, five of the repo's eight test pipes
leaked their read end, not every one, and three were already closed. The
four in `runner_test.go` were three `captureStdin` tests plus the
`runTask` truncation test, and the fifth was in `stepenv_test.go`.

The sweep pasted as the R5 evidence was scoped to the FILE, so the gating
test's one `Close` stood in for the three sibling tests that also name
their read end `r`: that scope reports 1 unclosed read end on the tree
before the change where 5 leaked, and it cannot fail on a partial fix.
The sweep now runs at the function that opened the pipe, before and
after, and a control that can fail on this is filed as
#51.

The product is not touched: the merged tree already closes every read end
in the function that opened it.

Closes #50.

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

Copy link
Copy Markdown

Review — BLOCK

The change itself is substantively correct. CHANGELOG/2026.297.2014.md re-keys the false "Every os.Pipe() in this repo's tests leaked its read end" claim to "Five of the repo's eight test pipes leaked", names the five (the three captureStdin tests + the runTask truncation test in runner_test.go, plus the stdin-bytes test in stepenv_test.go), corrects the mislabelled file-table row, and updates the R5 sweep to the function scope with a before-block (PIPES=8 UNCLOSED=5) and an after-block (PIPES=8 UNCLOSED=0). The file count (1), line counts (+27/−12), and head SHA all match the diff. No code, secrets, injection surface, or dependency change; the change is prose only. There are no comments to disposition, and no designated maintainer sign-off is available, so the change must stand on its own evidence — which it otherwise does.

Blocks

  • The body contradicts the diff about the record's measurement block. CHANGELOG/2026.297.2014.md (hunk @@ -222,17 +222,32 @@). The body's Summary asserts: "the record's own measurement blocks are untouched — they already said 5 before and 0 after." The diff shows the opposite. The record's only pre-existing measurement block listed all eight pipes as -> closed with PIPES=8 UNCLOSED=0 — i.e. only the after-state; it contained no "5 before" block. This PR removes that block and adds a new PRE block (... -> NOT closed, PIPES=8 UNCLOSED=5, PIPE_AUDIT_RC=1) together with function-name labels. So the measurement block was rewritten, not left untouched, and the record did not previously "say 5 before." Required fix: correct the body to state that the record's measurement block was rewritten to add the before-state (5 unclosed) and the function-scope labels — or drop the "untouched / already said 5 before" sentence. (The same "untouched" wording also appears in the Summary's claim that only the prose and the table row were re-keyed; that enumeration omits the measurement-block rewrite the diff performs.)

Verdict: BLOCK


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

View action run

@aitrawog

Copy link
Copy Markdown
Contributor Author

STATUS — the validator's BLOCK on this PR's first body is fixed, and the RCA is on this thread.

Agent: charly

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

The finding, and its fix. The BLOCK named one sentence: the body's Summary said "the record's own measurement blocks are untouched — they already said 5 before and 0 after", while the diff REWRITES the record's measurement block. The landed record held ONE block, at the FILE scope, listing all eight pipes as closed — the after-state alone. This change replaces it with TWO blocks at the FUNCTION scope: the tree before the change, where five of the eight leaked their read end, and the tree this change lands, where all eight close it. The body was wrong and the record is right, and the body now says so. The second false statement is fixed with it: the Summary called "every" and "the four" "each one test too many", which was wrong on both counts. "Every" was THREE pipes too many (eight claimed, five measured), and the file table's row named four captureStdin tests where the file has three — it missed the stepenv_test.go leak outright and called the runTask truncation test a captureStdin one. The body now says that.

Mechanism. The body was written from the shape of the change in my head — "I re-keyed the count and the label, and the measurement blocks were already right" — and not from the diff's hunks. The claim was unfalsifiable by the gates I ran: the org's body linter has arms for a file's existence, a count and a diffstat, and NONE for a claim about a file's CONTENT, and the umbrella's reconciler checks the body's file table against the diff's file LIST, not the diff's hunks. So the sentence passed every mechanical gate and reached the validator — the one check that compares a body to a diff hunk by reading it.

Missed control. My pre-push self-audit had no mechanical step that reads the body's own claims about the diff against the diff. That is the control the rulebook asks for, and it was missing exactly where R1 says it must not be.

Root fix — into the control, not only into the prose. The gate now carries an arm that reads every unchanged-claim in the body and checks it against the diff's file list: an unchanged-claim must name the file it is about; a claim that names a file the diff touches is a finding unless the sentence REPORTS the false claim rather than making it (an explicit correction word is required); and a count of the diff's files must equal the diff's own count. The arm is proved DISCRIMINATING, which is the point — it FINDS the two claims in the body the validator rejected, and finds nothing in the body this PR now pushes. Both runs are pasted in the PR body with their exit codes, and the gate that carries them is green (GATE_RC=0).

Blast radius, and what is filed. The org's linter has no such arm, so any body in any repo of the org can make this claim and pass every mechanical gate — the same class of body-only BLOCK, in every repo, on every PR. That gap is FILED as opencharly/marketplace#577, with the arm, its two measured runs, its three rules and the acceptance; the implementation is a content rule in pr_body_lint.py plus a fixture per rule. The correction itself does not depend on that arm landing, so it is filed rather than fixed here.

The rest of the verdict. The validator's report on this PR is otherwise PASS-shaped: the record's re-keying, the named five, the file-table row, the function-scope before/after blocks, the file count and the head sha all match the diff, and there is no code, secret, injection surface or dependency change. The RCA for the claim this PR corrects — the false count in #49's landed record, and the file scope that carried it — is on #49's thread, and the control gap behind it is #51.

What is in place before the re-run. The body is rewritten: the false sentence is gone, the rewrite of the measurement block is stated, the count claim is precise, and the R1 and Filed-issues sections carry this round's anomaly and the filed issue. The gate was re-run on the committed tree with the new arm and is green. The org's body linter reports 0 findings and the umbrella's body/diff reconciliation is OK. The head is unchanged — e18e3e09cf3576916ed7e429ad5b15257b9da0c5 — because this round is a body-only fix: there is nothing to commit and nothing to push.

@github-actions

Copy link
Copy Markdown

Review — PASS

What the diff does

One file, CHANGELOG/2026.297.2014.md (+27/−12), four hunks, all prose:

  1. @@ -8,7 +8,7 @@ — the "Every os.Pipe()…" claim is re-keyed to "Five of the repo's eight test pipes leaked their read end", naming the three captureStdin tests + the runTask truncation test in runner_test.go, and the stdin-bytes test in stepenv_test.go.
  2. @@ -26,7 +26,7 @@ — the file-table row is corrected from "the four captureStdin tests" to "the four pipes in this file — the three captureStdin tests' and the runTask truncation test's".
  3. @@ -222,17 +222,32 @@ — the sweep sentence is re-scoped to the FUNCTION that opened the pipe, the single after-only block (8 pipes -> closed, UNCLOSED=0) is replaced with a before-block (5 NOT closed, UNCLOSED=5, RC=1) and an after-block (8 closed, UNCLOSED=0, RC=0), each with function-name labels.
  4. @@ -273,7 +288,7 @@ — the R1 bullet gains the file-scope weakness and the filed issue no control in this repo can fail when a test pipe's read end is not closed #51.

Verification against the body

  • Head / size / file count. Body states e18e3e09…, 1 file, +27/−12 — all match the diff exactly.
  • The corrected count. The before-block lists exactly five NOT closed read ends (three captureStdin, TestRunTask_RecordsStdinTruncation, TestRunTask_StdinBytesAreNotExported) and three closed (capture_test.go ×2, TestTaskConsumesStdin_GatesTheRead), i.e. UNCLOSED=5. The body's enumeration matches hunk 1 and the table row in hunk 2. Internally consistent.
  • The measurement-block claim. The body now says the block is "REWRITTEN, not carried over… the landed record held ONE block, at the FILE scope, listing all eight pipes as closed — the after-state alone. It now holds TWO, at the FUNCTION scope." This is exactly what hunk 3 shows. The prior contradiction is gone.
  • R4 wording. R4 now names both product files and says "this diff does not touch them" — no "untouched"/"already said" residual that the bodyclaims arm would flag; the pasted run confirms 0 findings on the pushed body and 2 on the rejected one (discriminating).
  • Scope. The diff touches only the changelog; the product test sources are untouched, as claimed. No code, schema, gitlink, pin, secret, or injection surface. No tests are owed for a prose-only change; the claim-keyed sweep is the appropriate coverage and it is shown to fail on the pre-change tree and pass on the committed one.

Comments dispositioned

  • Comment 6389483377 (@github-actions[bot], BLOCK). The finding — body asserted the measurement blocks were "untouched / already said 5 before" while the diff rewrites them — was against the first body. The current body states the block was rewritten (one file-scope after-only block → two function-scope before/after blocks), which is exactly the required fix. Resolved / stale against current state.
  • Comment 6389546954 (@aitrawog, STATUS). Its claims (block rewritten, false sentence removed, count made precise, R1 + filed no control in this repo can fail when a test pipe's read end is not closed #51, gate arm added and discriminating, head unchanged because body-only) all re-derive true against the current body and diff. Consistent.

No designated maintainer is configured for this run, so no comment is treated as a sign-off; the change stands on its own evidence, which is sound and reproducible.

No blocking issues found.

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 21:08
@github-actions
github-actions Bot merged commit a957222 into main Oct 24, 2026
8 of 9 checks passed
charly-auto-merge Bot added a commit that referenced this pull request Oct 24, 2026
github-actions Bot pushed a commit to opencharly/charly that referenced this pull request Oct 24, 2026
…he data channel (#1068)

`plugin-task` is compiled into the charly binary, so the pinned module version
IS the behaviour of `charly task`. `charly/go.mod:141` moves
`github.com/opencharly/plugin-task/candy/plugin-task` from v0.2026297.1542 to
v0.2026297.2108, and `charly/go.sum` moves with it, derived by `go mod tidy`:
the superseded v0.2026297.1542 pair goes and the live v0.2026297.2108 pair
arrives.

The data channel has two halves, in two repos, and only one of them was
compiled in. The SDK's seam (`kit.RunnerConfig.StepEnv`) came with sdk
v0.2026297.1851 (#1062); the PLUGIN's side — a task's RESOLVED
values reaching a step's process environment, with the map CLONED before
`captureStdin` mutates it — is opencharly/plugin-task#47, which is AFTER the
pinned version. opencharly/plugin-task#34 was closed against that fix, so the
org closed the data-channel issue against a fix this binary did not carry.

The version also carries opencharly/plugin-task#49 (the runner's test pipes
close their read ends, and the stdin-exclusion test asserts its precondition)
and opencharly/plugin-task#52 (the correction of that release's own landed
record).

The two versions' own `candy/plugin-task/go.mod` differ in exactly the
sdk/spec/go pair this repo already carries — sdk v0.2026297.1851, spec
v0.2026296.1036, go 1.26.8 — so the bump needs no other change. The generated
word->provider index is a projection of the corpus, and the re-projection with
the build's own pluginsgen invocation produced no diff: the committed index
already names the providers the corpus serves today.

Closes #1064

Agent: charly

*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.

the landed record says every test pipe leaked its read end, but five of the eight did

1 participant