Repository navigation
fix(land): a gate that exits before reading stdin is not a refusal (CLOUD-995) - #673
Conversation
CLOUD-869 The front door tells the reader the repository is private and cites four documents they cannot open
Small, and it is the first thing a public reader sees. Three defects. The first two go false the moment CLOUD-585 lands; the third is false already. Claims that stop being true
A third defect, and it is the one a competitor would quote
That absence claim is contradicted. The Do not substitute another absence claim. The Aviator record proposes a narrower one (nobody gates the cost of verification; nobody carries the proof across the process boundary), and it is ungraded too — CLOUD-913 is what would grade it. The safe edit states what Batten does and drops the claim about the field, which needs no survey to be true and cannot go stale. This rides here rather than in its own row because it is the same file, the same Links no public reader can follow
Deliberately out of scope: the ~549 distinct Acceptance
Refinement — Ready Refinement gate: Definition of Ready & Done. This body carries only specializations.
CLOUD-913 Validate whether agentic repository conformance already exists
Why Whether an existing product or open-source project already provides Batten's proposed combination of agent tool-call interception, repository-state fact acquisition, exact-SHA completion predicates and receipts, cross-surface enforcement, deterministic payload-cost gates, and policy authoring over those facts. The category is occupied, so the question is no longer whether anything is there. Two rounds of search on this row have named roughly twenty-five candidates and nine academic precedents, and their standing answer is the second of the three conclusions below: the feature set is not unique, and no located system combines terminal repository-state inspection, exact commit and tree binding, local verification, remote CI verification, freshness, and mandatory blocking of the completion transition. That answer cannot be published as it stands. Its evidence is landing pages and README prose — advertises, appears to be, marked planned, may expand into — which under this project's grading is unattested until a source has been opened. The row's own instruction forbids concluding without evidence, and the standing conclusion is exactly the shape of claim a single counterexample refutes. What remains is grading, not searching. The six axes, against the surface each one names
A candidate is scored per axis, never per vendor. A product covering one seam well is not a competitor for the combination, and recording it as one is how a survey talks itself out of its own finding. Method Two tracks, and a claim carries which one produced it.
Every claim is graded well-supported, contested, or unattested. Every axis and candidate pair is filled or marked not applicable with its reason. Reconciliation is a named step, not a postscript. Where this sweep disagrees with the existing prior-art census, the agent-mediation census, the rules-engine defaults census, or the Aviator Verify record, the disagreement is recorded with which side the evidence supports. Those documents are read as prior claims to be tested, not as the search basis, and this row does not edit them. Not in scope No code change lands. A Batten defect the sweep surfaces is filed as its own row. The positioning statement and the differentiation properties the search produced belong to CLOUD-131 and CLOUD-211, which already own that frame; the re-grade of the novel-core claims belongs to CLOUD-916. Refinement — Ready Refinement gate: Definition of Ready & Done. This body carries only specializations.
Pre-flight, 2026-08-22 — the §7 evidence plan is runnable The capability §7 rests on was asserted from a citation and is now tested. A depth-1 clone of Agent Done Or Not exited 0 in this container and produced a real tree, carrying That listing is not a finding and must not be graded from here. It establishes that the clone worked, which is all the pre-flight asked. What those files do — whether that schema is a policy authority in this project's sense, whether the gate binds to an exact SHA — is Track A's job, and reading a verdict off a directory listing is the name-is-not-a-classification error §2 already warns about. The clone is retained in the session scratchpad so Track A need not re-fetch it. It dies with the container, which is why the register is the durable artifact and the clone is not. Acceptance
Dispatch prompt — the survey session that closes this rowThis row is blocked by CLOUD-915 and does not start until 915 closes. When it does, a human opens a session and pastes the block below verbatim. It is self-contained on purpose: CLOUD-728 measured five bundles coming up unsupervised because one pasted block dropped its workflow contract, and CLOUD-590 `fuzz/Cargo.lock` records the crate's own version, so every release leaves a clone that dirties itself and fails `tree-clean`
Why
Measured 2026-08-14, twice in one session while landing the open-PR backlog. On PR #333 the file read This is exactly the class CLOUD-223 and CLOUD-221 closed for The cost is small and recurring, which is what makes it worth a row rather than a third refresh: an agent mid-landing sees Refinement — Ready
Acceptance
CLOUD-858 Three Todo rows carry no readable Ready block, so `graph-check` refuses the whole board and the ready frontier cannot be computed at all
Why CLOUD-595's sweep ran
The two §6 defects the sweep found — CLOUD-854's Why this is a defect rather than the board being honest
Each of the three is a different repair, which is why they cannot be swept as one:
What was deliberately not doneNot repaired under CLOUD-595. That row's §1 states "No issue's §1–§5, §7 or §8 content is an input to this pass or an output of it", and its §3 states the pass is "tracker content only … so nothing here is a permission-bearing act". Writing three Ready blocks and moving a column are both outside that, and narrowing a sibling row's scope to fit is the shape this repository refuses. Refinement — Ready (2026-08-21)
Acceptance
Found by CLOUD-595's sweep — by running the predicate over the whole column rather than over the three rows the incident named. CLOUD-995 `land` reports a gate as REFUSING when it exits before reading stdin, so `BATTEN_FILED_HERE_BYPASS` reddens the lap it is meant to let through
Why
Measured 2026-08-23 against It is deterministic, which is what separates it from the neighbours. CLOUD-426 and CLOUD-449 are both load-sensitive Diagnosis The case sets the PR body to
CORRECTION — this is a production defect, not only a test-harness one, and the first version of this row said otherwise. The original text here reasoned that the real gates drain stdin so only the stub is exposed. That is true of
So setting the documented bypass makes the gate refuse. MEASUREMENT — it is deterministic, not a race. 30 runs of the case against unmodified The repair Convert all three call sites to here-strings, matching the precedent the file sets for itself at line 1033: mise run deferral-check <<<"$body"That removes the pipeline, so there is no The fix must keep CLOUD-774's guarantee intact: the body still has to reach Not in scope CLOUD-426 and CLOUD-449's load sensitivity. Different cases, different mechanism. Refinement — Ready Refinement gate: the Definition of Ready & Done. This body carries only specializations.
Acceptance
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (4)
Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughThe workflow guidance adds manual validation for prescribed repairs and makes Acceptance authoritative during conflicts. Installation messages now state that GitHub authentication is optional and that rate limiting can cause release API failures. Landing checks receive pull request bodies through Bash here-strings. Tests cover tasks that exit before reading input and verify that pipeline Merge Risk: ⚪ Minimal · up to This PR fixes a gate pipeline failure mode and updates related tracking and installer text; no actionable merge-blocking risk remains based on the current changes and reported verification. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
8e5bffc to
8d9f009
Compare
8d9f009 to
d0d5c1d
Compare
CLOUD-858 prescribed converging CLOUD-134's Ready dialect. Executed literally that yields a block which PASSES ready-lint, while CLOUD-858's own last acceptance bullet forbids a block that papers over open questions -- and CLOUD-134 has one, its Decision section gating on a named consumer that does not exist. The prescription and the acceptance sat four paragraphs apart in one body. Nothing compares them and ready-lint structurally cannot: it decides a block's clauses against each other, never a body's prose against its own acceptance. Refs: CLOUD-858
…rivate Three sites in install.sh: the header comment, the --help text, and the failure message when the release API cannot be read. All three said a GitHub token is required while the repository is private. CLOUD-869 corrected the same claim across README.md, AGENTS.md and the sandbox memory, and those have since landed. install.sh was missed because that row's acceptance greps are scoped to markdown and to the tracker links, so no predicate on the row could see a shell string — including the --help text, which is the copy a stranger actually reads. The token is optional by construction and always was. What it buys is a higher rate limit on the unauthenticated release API, which is what all three sites now say. Refs: CLOUD-869
`land` runs under `pipefail` and piped the PR body into three gates. Two of them can exit before they read it: `filed-here-check` returns 0 at its line 173 when BATTEN_FILED_HERE_BYPASS is set, and again on a missing git dir or a detached HEAD, but does not read stdin until 288; `closing-key-check` exits 2 on three could-not-read paths before its own read. When that happens the producer takes EPIPE and pipefail promotes it to a failed pipeline, so `land` reports the gate as having refused. The bypass therefore inverts the gate it is meant to switch off: setting BATTEN_FILED_HERE_BYPASS makes the lap die with "filed a row that was never groomed to Ready". Reproduced directly: a 200KB body piped to a consumer that exits 0 without reading reddens the pipeline under pipefail. Here-strings remove the pipeline, so the status is the gate's own and no longer depends on whether it drains first. `land.sh:1033` already prescribes exactly this for the same reason. This does NOT fix the parallel-suite failure that led here. That one does not reproduce in isolation -- 30/30 green on unmodified main once the harness ran through mise -- and belongs with CLOUD-426 and CLOUD-449. Refs: CLOUD-995
The fix in the previous commit had no case. This adds one, and it is shown able to fail: against the piped shape it reddens with bash's own diagnosis, "printf: write error: Broken pipe", followed by land reporting a gate that never refused anything. A new stub lever, task_exits_undrained, models the thing the real gates do -- filed-here-check returns 0 under its bypass before it reads at line 288, closing-key-check exits 2 on its could-not-read paths. The lever sits ahead of every read in the stub so the EPIPE is real, and only a case that asks for it is affected, so what CLOUD-774 pins is untouched. The body is 100k because the size is load-bearing. A short body fits the kernel pipe buffer, the producer finishes before the reader is gone, and the old shape passes -- which is also why the original failure only appeared under the parallel suite, where scheduling decided the race. Bigger than the buffer makes the EPIPE certain and the case deterministic in both directions. Refs: CLOUD-995
d0d5c1d to
ebf4f07
Compare
|
|
/fast-forward |



Closes CLOUD-995.
Closes CLOUD-869.
DO-NOT-CLOSE CLOUD-858
CLOUD-858 is served by the memory commit but not completed by it: the rule that
commit records was measured on CLOUD-858, while that row's headline acceptance
—
graph-checkover the whole Todo closure — has still never been run. Closingit here would move a row a column ahead of its own evidence.
CLOUD-869 does close. An earlier draft of this body said
Refs:instead, on thereasoning that its acceptance greps already pass on
mainso closing it fromhere would take credit for another branch's landing. That reasoning strands the
row, which is the defect CLOUD-674 exists to catch, and the gate caught it: the
row is open, its last unmet piece is the
install.shcommit below, and afterthis lands there is nothing left in it to do.
landreported a refusal that never happenedlandruns underpipefailand piped the PR body into three gates. Two of themcan exit before they read it:
filed-here-checkreturns 0 at its line 173 whenBATTEN_FILED_HERE_BYPASSisset, and again on a missing git dir or a detached HEAD — but does not read
stdin until line 288.
closing-key-checkexits 2 on three could-not-read paths, all before its read.The producer then takes
EPIPE,pipefailpromotes it to a failed pipeline, andlandreports the gate as having refused. So the bypass inverted the gate itexists to switch off:
BATTEN_FILED_HERE_BYPASS=1made the lap die with "fileda row that was never groomed to Ready".
Here-strings remove the pipeline, so the status is the gate's own and no longer
depends on whether it drains first.
land.sh:1033already prescribes exactlythis, for exactly this reason; the three call sites were the shape its comment
warns about.
Shown able to fail
The new case reddens against the piped shape with bash's own diagnosis:
and passes against the fix. The 100k body is load-bearing: a short one fits the
kernel pipe buffer, the producer finishes before the reader is gone, and the old
shape passes too.
That size dependence is also why this surfaced when it did. Case 1350's body
is short, so the write normally completes — under the parallel four-worker suite
the scheduler decided the race the other way. Mechanism and trigger are separate
here: the mechanism is
SIGPIPEunderpipefail, the trigger is load. Theload-sensitivity itself stays with CLOUD-426 and CLOUD-449.
Correcting the record
CLOUD-995 was filed claiming
mainwas red and the case failed deterministicallyin isolation. Both were wrong, and the row now says so at the top. The isolated
runs behind "deterministic" invoked
batsdirectly, bypassingmise, somise.toml [env]never applied and all 60 runs died on an unsetCI_REQUIRED_CHECKS— an artefact of the harness. Throughmise exec, the caseis 30/30 green on unmodified
main, andmainadvanced twice while this branchwas open, so the fleet was landing throughout.
Also here
install.sh—Refs: CLOUD-869. Three sites still said a token is requiredbecause the repository is private: the header comment, the
--helptext, andthe release-API failure message. That row's own acceptance greps are scoped to
markdown and tracker links, so nothing on it could see a shell string. Its
markdown half landed from another branch while this one was open.
mem:workflow/board-states—Refs: CLOUD-858. Where a row's prose prescribesa repair and its own Acceptance says otherwise, the Acceptance wins.
Verification
CLOUD-995case passes on this branch, fails against the piped shapegrep -in private install.sh— emptymise run verifygreen before readying