Files
harmony/docs/adr/drafts/topology-proliferation.md
2026-05-20 12:03:19 -04:00

84 lines
3.3 KiB
Markdown

# Working draft: Topology proliferation
**Not an ADR yet.** A concern noted in many places that doesn't
yet have a clean answer. Parked here so it doesn't get lost.
When the answer is clear, promote to a numbered ADR under
`docs/adr/`.
## The concern
Harmony has accumulated topology structs without a clear rule
for when a *new topology* is the right answer versus when a
*capability trait on an existing topology* is the right answer:
- `K8sAnywhereTopology` — dynamic discovery, the "any place
that runs k8s" default.
- `HAClusterTopology` — bare-metal HA with redundant
firewalls/switches.
- `K8sBareTopology` — minimal topology for ad-hoc Score
execution (introduced in this branch).
- `FailoverTopology<T>` — higher-order, primary/replica.
- `DecentralizedTopology<T>` — higher-order, multi-site.
- `FirewallPairTopology`, `SwitchTopology`, …
There is no written framework rule for which path to take. The
result is a slow drift toward "every new deploy shape becomes a
new topology struct," which is the opposite of ADR-015's
zero-cost higher-order composition direction.
## Where the concern is already noted
- `ROADMAP/12-code-review-april-2026.md` task 12.6 — "topology
proliferation."
- `ROADMAP/12-code-review-april-2026.md` task 12.1 — phased
topology (`LinuxHostTopology``KvmHostTopology` after
package install). Different angle on the same shape problem:
how does a topology *gain* capabilities at runtime?
- ADR-015 ("Higher-order topologies via blanket trait impls")
argues for capability composition, but doesn't lock the rule
"prefer capabilities over new topology structs."
- ADR-023 §6 references topology as compile-time-static —
closing the door on `Box<dyn Topology>` plugins but leaving
open which axis of variability is a new type and which is a
capability impl.
## Open question
Is the right rule:
- (a) **Capability-first**: a new deploy shape adds a capability
trait to an existing topology when possible; new topology
structs are reserved for genuinely new physical-shape
categories (single-host vs. HA vs. cloud). `K8sBareTopology`
arguably should have been a constructor on
`K8sAnywhereTopology`.
- (b) **Topology-first**: every coherent deploy environment is
its own topology. `K8sBareTopology` is correct; the concern
is just naming and documentation.
- (c) **A test-driven middle ground**: capability sets are
primary, topologies are bundles of capability-set + physical
context. Re-frames the existing types but doesn't break
anything.
The fleet platform work (ADR-024 draft, capability decomposition)
points toward (a) or (c). The framework as it stands runs on
(b)-by-default.
## What's needed before this can be an ADR
- A worked example of converting one of the existing topology
structs to its capability-first equivalent (probably
`K8sBareTopology` → constructor on `K8sAnywhereTopology` with
a feature-flag capability set).
- A look at whether ADR-024's capability decomposition for the
fleet platform suggests a generalization of the same
decomposition for the framework's topology layer.
- A look at how phased topology (task 12.1) fits — phase
transition is conceptually a *gain of capabilities*, which is
hard to express in (b) but natural in (a)/(c).
## Owner
Unassigned. Next time someone touches topology code and feels the
itch, this draft is the place to add their notes.