feat(#2450): collapse the startup sweep into one inline DAG

The boot is now ONE DAG, assembled inline in submit_boot_tree — no boot_root
Noop anchor, no per-agent child DAGs, no display-only parent_id grouping: a
sweep MetaLock root (only when something is stale) that grows one rebuild
subgraph per stale agent into the same DAG (via append_subgraph, previous
commit), plus one Reconcile root per drifted agent (independent — a boot
reconcile needs no lock bump).

- submit_boot_tree builds the DagSpec inline; removed the single-use
  templates::{boot_root, startup_sweep} builders (inlined per the operator's
  "don't force single-use shapes into templates.rs" steer).
- fanout_specs simplified to the meta-update cascade path only — the startup
  sweep no longer fans out child DAGs, so its branch was dead.
- test: append_subgraph_roots_on_emitter_and_rebases_local_deps.

Vestigial after this (deliberately left as follow-ups, flagged in the PR):
NodeKind::Noop is now unconstructed (contained to hive-c0re, removable);
Template::StartupSweep is unconstructed but a hive-sh4re wire type
(frontend-coordinated removal).
This commit is contained in:
atlas 2026-07-15 17:29:23 +02:00 committed by mara
commit 4545dd312e
5 changed files with 138 additions and 112 deletions

View file

@ -17,7 +17,7 @@ use std::collections::HashMap;
use std::sync::Arc;
use super::exec::{self, NodeOutput};
use super::{Claim, Source, Template, templates};
use super::{Claim, Source, templates};
use crate::coordinator::Coordinator;
struct NodeDone {
@ -166,26 +166,29 @@ async fn process_terminals(
}
}
/// Child `Rebuild` specs for a completed `MetaLock` fan-out, grouped
/// under the parent via `parent_id`. Meta-update children skip the
/// per-agent relock (it would revert the bump the parent just
/// committed); sweep children relock like a manual rebuild.
/// Child `Rebuild` specs for a completed meta-update `MetaLock` fan-out,
/// grouped under the parent via `parent_id`. Meta-update children skip the
/// per-agent relock (`relock = false`) — it would revert the bump the parent
/// just committed. This is now the meta-update cascade path only: the startup
/// sweep no longer fans out child DAGs — it grows one rebuild subgraph per
/// stale agent into its own DAG via `append_subgraph` (see
/// `exec::run_meta_lock`).
fn fanout_specs(claim: &Claim, agents: Vec<String>) -> Vec<super::DagSpec> {
let sweep = claim.template == Template::StartupSweep;
let (source, relock) = if sweep {
(Source::StartupSweep, true)
} else {
(Source::MetaUpdate, false)
};
let reason = if sweep {
"startup sweep".to_owned()
} else if let Some(approval_id) = claim.approval_id {
let reason = if let Some(approval_id) = claim.approval_id {
format!("approval #{approval_id} meta input cascade")
} else {
"meta-update cascade".to_owned()
};
agents
.into_iter()
.map(|agent| templates::rebuild(&agent, source, reason.clone(), Some(claim.dag_id), relock))
.map(|agent| {
templates::rebuild(
&agent,
Source::MetaUpdate,
reason.clone(),
Some(claim.dag_id),
false,
)
})
.collect()
}