Skip to content

fix(ci): the first build runs the disk precondition the rest already do - #987

Merged
wenzowski merged 2 commits into
mainfrom
claude/bundle-b-verdict-config-r2
Sep 19, 2026
Merged

wenzowski merged 2 commits into
mainfrom
claude/bundle-b-verdict-config-r2

Conversation

@wenzowski

@wenzowski wenzowski commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Closes CLOUD-1329

What moved

[tasks."build:release"] gains depends = ["target-prune"].

Measured 2026-09-02: the session's first install:local died inside cargo build --release on ENOSPC with 0MB free, over a target/debug a previous session had
left at ~24GB. target-prune exists for exactly that input — its own header says it
"runs when the disk is SHORT" — and verify and every land lap call it. This entry
point, which runs before any of them, did not. The failure surfaced as a cargo IO
error naming neither the disk nor the floor.

Why depends rather than a guarded call in the body

House-style §5: the refusal a reader should see is target-prune's own pointer-only
line, naming free space and the floor. A body guard would print a second message over
the first — a second authority for a verdict the prune already rendered. depends
runs it before the body and propagates its exit verbatim. install:local resolves it
transitively, so it gains the precondition without naming it.

No cycle, checked rather than assumed: target-prune declares no depends of its
own, and its body tries the installed binary before falling back to cargo run
precisely so the reclaim needs no build in order to run. It does not reach inside
verify's lap: this task's callers are install:local and the two benches, while
verify, verify:gated and land reach the engine through cargo run -p batten
directly, so the two prune calls that bracket a lap keep their order.

The gate

Three cases in crates/batten/tests/it/session_provisioning.rs ask for an exact
dependency entry, not a substring of the task surface. The distinction is the whole
point and was caught in review on the first draft: task_surface concatenates run
and depends, so contains("target-prune") stays green over
run = "echo target-prune && cargo build …" with no depends at all — a case that
cannot tell the defect from its absence (CLOUD-418). So task_depends reads depends
alone and splits it into entries, sharing one task_block / task_value pair with
task_surface so there is no second extraction to drift.

The anti-vacuity mirror stays: the reclaim itself declares no dependency (which is
what makes the no-cycle claim checkable rather than asserted), and both surfaces are
non-empty, so an extractor that silently read nothing would fail rather than pass.

mise run verify green; mise run test:cargo exits 0.

Measured 2026-09-02: the session's first `install:local` died inside
`cargo build --release` on ENOSPC with 0MB free, over a `target/debug` a
previous session had left at ~24GB. The failure named neither the disk nor the
floor, and the recovery an agent reaches for from there is `rm -rf target/…` by
hand — the journal-poisoning route CLOUD-1218 measured three times.

`target-prune` exists for exactly that input; its own header says it runs when
the disk is SHORT. `verify` calls it and every `land` lap calls it. The one
build that runs before any of them did not, so every build the repository owns
sat behind the precondition except the first.

A `depends` rather than a guarded body call, and §5 is the reason: the refusal
a reader should see is the prune's own pointer-only line naming free space and
the floor. A body guard prints a second message over the first, which is a
second authority for a verdict already rendered. `install:local` resolves it
transitively and so gains the precondition without naming it.

Three properties checked rather than assumed, each written where the next
reader will be. `target-prune` declares no `depends` and tries the installed
binary before `cargo run`, so the edge cannot cycle. This task is reached by
`install:local` and the two benches while `verify` and `land` reach the engine
through `cargo run -p batten`, so the prune pair bracketing a lap keeps its
order. And `prune::Phase` is derived from the lap journal rather than declared,
so a build outside a `verify` toggles a boundary — which cannot move the floor,
a high-water mark, but can emit one `lap-close` describing no real lap.

Shown able to fail by hand, because no sweep can carry it: `mutate::sources_for`
resolves a gate to a shell task, a rego module, an engine module or a preset
directory, and this subject is `mise.toml`, which is none of them. A `//MUTANT`
row would read as coverage and apply nothing. With the `depends` line deleted
and nothing else changed, both new cases went red and the anti-vacuity mirror
stayed green; restoring it returned the suite to green. The demonstration is
recorded on the case.

Refs: CLOUD-1329
… mention

`task_surface` concatenates `run` and `depends` because the reachability scan
wants both and does not care which one a name came from. Asserting a DEPENDENCY
over that concatenation proves nothing: delete the `depends` line and write
`run = "echo target-prune && cargo build …"` and the `contains` assertion stays
green over a build that runs no precondition at all — the shape CLOUD-418 names,
a case that cannot tell the defect from its absence.

So split the extraction into `task_block` / `task_value`, one pair shared by
both readers so there is no second authority to drift, and add `task_depends`
reading `depends` alone and splitting it into entries. The three cases now ask
for an EXACT entry rather than a substring of the whole surface.

Refs: CLOUD-1329
@coderabbitai

coderabbitai Bot commented Sep 18, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: button-inc/batten/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 55010fc2-2e94-46c0-8278-b2a518c6e709

📥 Commits

Reviewing files that changed from the base of the PR and between 128ca4b and 3b5129d.

📒 Files selected for processing (2)
  • crates/batten/tests/it/session_provisioning.rs
  • mise.toml

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The release build task now depends on target-prune. Existing build entry points reach this dependency through build:release. Session provisioning tests extract task blocks and dependency values with module-level helpers. New tests verify the dependency edge, transitive reachability, cycle absence, non-empty task surfaces, and absent unknown tasks.

Area Changes
Task configuration Added target-prune to build:release dependencies.
Test helpers Extracted task manifest parsing and dependency helpers.
Test coverage Added assertions for dependency ordering and task reachability.

Priority: ⬇️ Low

Merge Risk: ⚪ Minimal · up to 3b512

The release build now runs the disk-reclaim prerequisite first, with tests guarding the dependency edge and cycle-free task graph. No merge-blocking issue remains.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 90.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 10 functions across 1 files. (1 skipped: 1 …
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the main change: the first build now runs the existing disk-space precondition before the other build-related steps.
Description check ✅ Passed The description directly explains the new build:release dependency on target-prune, its rationale, dependency behavior, tests, and verification results.
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@wenzowski
wenzowski force-pushed the claude/bundle-b-verdict-config-r2 branch from 3b5129d to 6b88311 Compare September 18, 2026 21:36
@wenzowski
wenzowski marked this pull request as ready for review September 18, 2026 21:36
@wenzowski
wenzowski marked this pull request as draft September 19, 2026 00:02
@wenzowski
wenzowski marked this pull request as ready for review September 19, 2026 00:02
@wenzowski

Copy link
Copy Markdown
Contributor Author

/fast-forward

@wenzowski
wenzowski merged commit 6b88311 into main Sep 19, 2026
27 of 39 checks passed
@wenzowski
wenzowski deleted the claude/bundle-b-verdict-config-r2 branch September 19, 2026 03:32
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