Skip to main content

ci_topo_node_names

Function ci_topo_node_names 

Source
pub fn ci_topo_node_names(cd: &CanteiroDag) -> Vec<String>
Expand description

Substrate-canonical per-Acao topological-order node-name projection every consumer of an owned canteiro_types::CanteiroDag that needs the parents-before-children flat list of author-declared node names keys off — folds the three-line let topo = cd.topo_order().expect(...); topo.iter().filter_map(|id| cd.nodes.get(id).map(|n| n.name.clone())).collect() chain onto one substrate primitive returning Vec<String> verbatim, running the topo_order() axis internally so consumers reach for one dispatch.

The topological-node-name projection carries the “in what order does the DAG hand back the author-declared node names?” surface every per-Acao downstream consumer fans on: the caixa_actions::RenderedAcao::node_names_topo artifact the M0 renderer’s validate returns (paired with the declared edge count from ci_declared_edge_count), the deferred sui-supercacheci::canteiro::emit_gha workflow renderer’s per-job jobs.<name> map key ordering (GitHub Actions preserves declaration order for readability, so an author-facing workflow whose jobs are emitted in parents-before-children topological order reads as a build-then-test-then-publish narrative rather than a hash-map-arbitrary-order jumble), a future feira lint --acao per-caixa admission verb’s per-repo topological-summary print, a future M4 acao.pleme.io/v1alpha1/Acao CR materializer’s admission webhook per-node ordering pin.

Prior to this lift the topo.iter().filter_map(|id| cd.nodes.get(id).map(|n| n.name.clone())) .collect() expression was inlined at three sites in the caixa-actions crate — the production [caixa_actions::validate]’s node_names_topo field construction at caixa-actions/src/lib.rs:155, plus two byte-parity pins in the same crate’s test module — and at two more sites in this crate’s own require_acao_view byte-parity test at caixa-core/src/render.rs:37769 / caixa-core/src/render.rs:37773 (which reconstruct the same list through the compound helper’s returned CanteiroDag to pin that the two paths agree). Five open-coded copies of the same three-line topo + filter_map + collect chain expressed no compile-time link back to a substrate primitive, so a future refactor of the projection shape (a promotion of the plain Vec<String> to a Vec<(String, EnvClass)> once consumers need the per-node env-class alongside the name, a per-:ci stable-tie-breaking pass that sorts sibling nodes lexicographically once the underlying shigoto_dag::Dag::toposort axis grows a tie-break axis, a per-node canonicalization pass that trims whitespace once the canteiro-types axis grows a per-node canonicalization step) would have had to be threaded through five open-coded copies in lockstep or the M0 renderer’s node_names_topo artifact would silently disagree with its own byte-parity pins. Lifting the projection to a typed function on the substrate primitive means every downstream consumer of the Acao’s topological-node-name surface reaches for exactly one typed dispatch.

Runs cd.topo_order() internally with an .expect(...) on the Err(_) arm carrying the substrate-canonical message every consumer would otherwise re-author verbatim — the Err(_) arm is unreachable-by-construction after a successful decompose_ci (documented on the peer decompose_ci docstring and the canteiro-types CanteiroDag::topo_order docstring: “decompose already rejects cycles, so an error here is an internal invariant break”). Panicking here surfaces any future substrate-contract regression at the call site rather than silently returning an empty Vec<String> that a consumer’s downstream logic would misread as “no nodes to render”.

Peer of the sibling ci_declared_edge_count usize-scalar projection on the borrowed canteiro_types::CiRun axis — extends the “one typed dispatch on the substrate primitive, thin projections at each consumer” discipline onto the owned canteiro_types::CanteiroDag axis (the sibling primitive projects through the borrowed run’s node-list shape; this primitive projects through the owned DAG’s topo-order + node-map shape). Together the two per-Acao scalar-projection primitives cover the two axes the M0 [caixa_actions::RenderedAcao] artifact carries (edge_count through the borrowed run, node_names_topo through the owned DAG), so every future per-Acao consumer that materializes a RenderedAcao-shaped view reads through two substrate one-liners.

§Panics

Panics if cd.topo_order() returns [Err(_)] — an unreachable arm after a successful decompose_ci (which rejects every cyclic input via CiDecomposeFailure). A caller reaching this panic has constructed a canteiro_types::CanteiroDag outside decompose_ci and passed one whose internal [shigoto_dag::Dag] is cyclic — a substrate-contract regression worth surfacing at the call site, not silently masking with an empty Vec<String>.