v0.7.16 — Per-Target OperatorBox and MuxReconciler
Per-target operatorBox
Each serve.target.entries entry can now declare its own operatorBox — resources, lifecycle hooks, and preReconcile gates (enqueueGate / reconcileGate). The reconciler selects the active box from serve-alias / serve-target annotations on the CR at reconcile time.
serve:
target:
entries:
v2-enabled:
operatorBox:
enqueueGate: "{{ isBusinessHours }}"
reconciler:
hooks: true
v2-ctor:
operatorBox:
reconciler:
default: false # use a dedicated constructor from ReconcilerRegistry
reconciler.default: false wires the target’s constructor from ReconcilerRegistry at load time. A missing registry entry is a load-time error — the Runtime refuses to start rather than falling back silently.
Surface switches are detected via orkestra.orkspace.io/last-surface and cleaned up with a label-selector sweep (SweepOwnedNamespaced / SweepOwnedClusterScoped) rather than template expansion, which is immune to spec fields being cleared before cleanup runs. keepPreviousSurface: true skips the sweep when set.
EffectiveOwnerKey stamps and checks ownership as <name>.<alias> for target-mode CRs, allowing per-surface resource isolation.
MuxReconciler and pkg/intent/target/
MuxReconciler holds one domain.Reconciler per registered target. At reconcile time the kordinator reads the target annotation and dispatches to the matching reconciler, falling back to the CRD-level reconciler when no target-specific one is registered. The kordinator sees one reconciler; the routing is internal.
Target resolution and CR construction move into a dedicated pkg/intent/target/ package, separating the intent layer from the gateway API package. target.go and its tests follow.
ork serve apply --override
Routing conflict detection (409) is still enforced when a target switch is attempted without an explicit override. Pass --override (or ?override=true on the API) to route to the new target and trigger surface cleanup of the old one.
Fixture: 03-hooks-targets
pkg/kubeclient/fixture/03-hooks-targets — three targets on one CRD proving each dispatch path end-to-end:
v2-enabled— hooks with anenqueueGate(business hours),featureEnabled: truev2-disabled— same hook binary,featureEnabled: false, no gatev2-ctor—reconciler.default: false, dedicated constructor
Documentation
documentation/concepts/reusability/ — new section covering Reusability and Composition in Orkestra.
lifecycle: block — maturity, deprecation, compatibility, and platform policy
A new top-level lifecycle: block on every Katalog and Komposer file replaces the old metadata.deprecation: approach with a first-class lifecycle model.
lifecycle:
maturity: beta # alpha | beta | stable | deprecated
deprecation:
message: "Replaced by task-runner"
migratedTo: task-runner:v1.0.0
timeline:
from: "2026-01-01"
to: "2027-01-01"
compatibility:
orkestra: ">= 0.7.0"
kubernetes: ">= 1.28"
Maturity — four levels: alpha, beta, stable, deprecated. The presence of a deprecation: block is the primary signal; maturity: deprecated without a block emits a warning rather than an error. maturity: deprecated with a block is always valid.
Deprecation — a deprecated Katalog always blocks startup when run directly. Consumers acknowledge it via lifecycle.accept.patterns on their Komposer, not by a field on the Katalog itself.
Compatibility — declares minimum orkestra and kubernetes semver constraints. ork validate rejects patterns that declare versions below the installed runtime.
Kind boundary — lifecycle.accept.patterns belongs on a Komposer. Declaring lifecycle.accept on a Katalog is a validation error.
Komposer-level lifecycle acceptance — lifecycle.accept.patterns
Komposers accept deprecated Katalogs at the point of composition:
lifecycle:
accept:
patterns:
- name: webapp-operator
version: ">= 1.0.0, < 2.0.0" # optional semver range
- name: cache-operator
version: scopes acceptance to a semver range. Acceptance without a range applies to any version of that pattern.
Platform policy — policy.lifecycle.minMaturity
Operators can declare a minimum maturity floor for all imported patterns:
policy:
lifecycle:
minMaturity: beta # alpha | beta | stable; deprecated is rejected
ork validate rejects any Katalog whose maturity is below the declared floor. minMaturity: deprecated is itself a validation error — the policy is a quality floor, not a filter.
policy: is structured as policy.<area>.* so security, registry, and user-defined policy categories can grow alongside lifecycle: without flattening.
Registry guide examples 13–16
Four new self-contained steps extend the registry guide:
- 13-deprecation-accept — accept a deprecated Katalog via Komposer
lifecycle.accept.patterns; scoped version acceptance - 14-lifecycle-maturity — maturity progression from
alphathroughstable;ork inspectoutput at each stage - 15-lifecycle-compatibility — declaring
orkestraandkubernetesversion constraints; validation rejection behaviour - 16-komposer-accept —
lifecycle.accept.patternson a Komposer composing both a deprecated and an alpha Katalog; scopedversion:range