refactor(topology): make the 12-kinds-to-5-patterns collapse explicit
TopologyKind describes twelve distinct intents, but the orchestrator implements five planners and mapped the kinds onto them inside plan_steps. So Market never auctions, StarMoe never routes to experts, Ring never cycles and Holacratic never self-organizes -- each silently runs as whichever pattern it collapses to, while kind::description() and the UI catalog kept promising the distinct behaviour. Rather than delete variants that appear in persisted rows, the collapse is now named: ExecutionPattern + TopologyKind::execution_pattern() in cm-topology, with plan_steps dispatching on the pattern instead of re-listing the mapping. One source of truth, and the two cannot drift. GET /api/topologies now reports `executes_as` and `distinct_at_execution` so a UI can stop offering aliases as if they behaved differently. Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b1bdfbbf87
commit
d94487d3ba
@@ -30,7 +30,7 @@ pub use provider_executor::ProviderExecutor;
|
||||
pub use workflow::{run_workflow, WorkflowRecord};
|
||||
|
||||
use cm_domain::GatedCategory;
|
||||
use cm_topology::{TopologyGraph, TopologyKind};
|
||||
use cm_topology::{ExecutionPattern, TopologyGraph, TopologyKind};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Errors from planning or running a topology.
|
||||
@@ -175,18 +175,19 @@ pub struct RunProgress {
|
||||
pub totals: RunMetrics,
|
||||
}
|
||||
|
||||
/// Map every topology kind onto one of five execution patterns. The match is
|
||||
/// exhaustive, so adding a `TopologyKind` upstream forces a decision here.
|
||||
/// Dispatch to the planner for this graph's execution pattern.
|
||||
///
|
||||
/// The kind→pattern collapse lives on `TopologyKind::execution_pattern` so the
|
||||
/// catalog API and this dispatch cannot disagree about what a kind actually
|
||||
/// does. The match is exhaustive, so adding an `ExecutionPattern` upstream
|
||||
/// forces a decision here.
|
||||
fn plan_steps(graph: &TopologyGraph) -> Result<Vec<plan::PlanStep>, OrchestratorError> {
|
||||
Ok(match graph.kind {
|
||||
TopologyKind::Hierarchical
|
||||
| TopologyKind::HubSpoke
|
||||
| TopologyKind::StarMoe
|
||||
| TopologyKind::Market => plan::hierarchical(graph)?,
|
||||
TopologyKind::Pipeline | TopologyKind::Ring => plan::pipeline(graph)?,
|
||||
TopologyKind::Swarm | TopologyKind::Flat | TopologyKind::Holacratic => plan::swarm(graph)?,
|
||||
TopologyKind::Mesh | TopologyKind::Blackboard => plan::mesh(graph)?,
|
||||
TopologyKind::Debate => plan::debate(graph)?,
|
||||
Ok(match graph.kind.execution_pattern() {
|
||||
ExecutionPattern::Hierarchical => plan::hierarchical(graph)?,
|
||||
ExecutionPattern::Pipeline => plan::pipeline(graph)?,
|
||||
ExecutionPattern::Swarm => plan::swarm(graph)?,
|
||||
ExecutionPattern::Mesh => plan::mesh(graph)?,
|
||||
ExecutionPattern::Debate => plan::debate(graph)?,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user