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]>
cm-topology::build(kind, roles) instantiates a canonical graph for any of the 12
kinds from a role list (the template catalog + the search generator).
cm-orchestrator::evolve searches a (kinds × team-size) grid using the comparison
machinery as fitness: build a candidate per cell, run the task, score it, and
keep a MAP-Elites-style archive of per-cell elites + a quality/cost Pareto front
and the global best. evolve_all() covers every kind at full size. This is the
bridge toward Autonomous Organizational Evolution on a safe substrate — every
candidate still executes via safe turns (§15 invariant holds).
Demoed in topology_bench (auto-picks the best topology + Pareto kinds).
cm-topology 20 tests; cm-orchestrator 17 (--features provider); clippy clean.
Co-Authored-By: Claude Opus 4.8 <[email protected]>