jobq: Scheduler::new_job is gone

It handed out exactly the builder JobBuilder::new is pub(crate) to
withhold, which was agreed against more than once. I had left it in
place with a docstring naming it as the hole and folded the fix into an
open question. It was not an open question.

It only survived because two hive-c0re tests minted a builder by hand to
simulate a MetaLock growing its cascade. The grown thing is a template,
so the fix is the same as for the deploy graft and the reconcile
fan-out: call it.

exec.rs's MetaLock arm looped rebuild_nodes inline -- the second and last
construction site declaring nodes inside an executor. It is now
templates::grown_rebuilds, so a test can assert what a sweep declares by
calling the same function production calls.

grown_subgraph_roots_on_emitter_and_rebases_local_deps and
meta_update_grows_cascade_in_dag differed only in RebuildOpts; they are
one test over the declared shape, checking a root chain per agent, a
build each, and a drain each because a boot sweep is graceful.

With those gone, CompleteNode::new_job, CompleteNode::complete_node_growing
and drain_meta_syncs had no callers either. hive-jobq's own two growth
tests use JobBuilder::new() directly -- in-crate, so the wall holds.
grep for new_job across the workspace now returns nothing.
This commit is contained in:
atlas 2026-08-02 21:01:08 +02:00 committed by mara
commit 009e9fafae
4 changed files with 77 additions and 183 deletions

View file

@ -338,26 +338,6 @@ impl<N, R: Clone + Eq + Hash> Scheduler<N, R> {
self.release_ready();
}
/// A fresh builder for a **running** node to declare more work into.
///
/// The node runs outside this scheduler's lock — often for minutes — so it
/// cannot hold a graph reference while it works. It doesn't need one: a
/// builder is pure local state (locally-minted guids, resolved to
/// [`NodeId`]s only at insert), so it can be filled in freely and handed
/// back to [`Scheduler::complete_growing`], which inserts it under the lock.
///
/// ⚠️ **This has no non-test caller left, and it is the hole in
/// [`JobBuilder::new`]'s `pub(crate)` wall** — it hands out exactly the
/// builder that fn withholds. [`Scheduler::claim_next`] mints one per
/// running node itself, so production never asks. Kept only so the host's
/// graph-growth tests can still declare work by hand; the fix is a venue
/// question (move those tests here vs. a closure-form completion), not a
/// rename.
#[must_use]
pub fn new_job(&self) -> JobBuilder<N, R> {
JobBuilder::new()
}
/// [`Scheduler::complete`], plus whatever the node declared into the builder
/// it was handed while running.
///
@ -728,7 +708,7 @@ mod tests {
let n = s.append("emitter", vec![], None).expect("insert");
assert_eq!(s.settle(), vec![n]);
let grown = s.new_job();
let grown = JobBuilder::new();
grown.node("child-a");
grown.node("child-b");
s.complete_growing(n, Outcome::Done, grown)
@ -754,7 +734,7 @@ mod tests {
let n = s.append("emitter", vec![], None).expect("insert");
assert_eq!(s.settle(), vec![n]);
let grown = s.new_job();
let grown = JobBuilder::new();
grown.node("never-runs");
s.complete_growing(n, Outcome::Failed("boom".to_owned()), grown)
.expect("growth is dropped, not rejected");