Expand Flux reconciler scope to the Sirens lanes, so a hand-rolled config shows as drift instead of an invisible divergence #876
Labels
No labels
burndown-2026-06
burndown-2026-08
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/advocate
role/director
role/exec
role/frontend
role/gamedev
role/human
role/platform
role/qa
role/science
role/sysadmin
state
ambient
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/infrastructure#876
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Continues the staged adoption in
docs/flux-gitops.mdand#366. Kai's call, prompted by a concrete near-miss on stream day.What prompted it
Telemetry from the 2026-08-19 Temporal stream shows Sirens Dowel calling five MCP servers that do not appear in
sirens-dowel-mcp-roster.ymloncoilyco-bridge/deploy@main:fetch,scratchpad,moxn,calculator,skills.That was not drift. Kai was rolling changes in realtime during demo prep, which is legitimate and worked. The problem is that the divergence was invisible: nothing distinguished "deliberately rolled ahead of main" from "quietly stale," and there was no surface where either showed up.
It cost something the same morning. An assessment of the lane's dependencies read the git roster, concluded Dowel had no moxn dependency, and reported that as fact. The deployed lane was calling
owl-glass.moxn.devand failing against it ten times during the stream. The reasoning was sound and the source was wrong.Where adoption currently stops
Reading
clusters/kai-server/as it stands:appsreconciles./deploy/_flux/appsfrom this repo, owning the scoped Forgejo runner pools.prune: false.bridge-deployGitRepository exists and points atcoilyco-bridge/deploy, branchmain.bridge-deployKustomization issuspend: true,path: ./services,prune: false.The doc explains the suspension precisely:
So the mechanism is already built and deliberately parked. This issue is about finishing Stage 3 for the Sirens lanes specifically, not about inventing anything.
Prerequisites, which are real and ordered
Stage 2 is not done. The doc gates Stage 3 behind flipping
prune: trueonappsonce drift correction is trusted, unsuspending theinfrastructureKustomization, and addingdependsOn: [{name: infrastructure}].apps.yamlstill carriesprune: falseand nodependsOn. Jumping to the Sirens lanes without that ordering skips the layer that proves drift correction works on something cheap.The imperative-writer check is the hard one here. Stage 3 requires confirming "no imperative writer overlaps before more
services/<name>/slices are enrolled." The Sirens lane has at least two:scripts/rollout-sirens-dowel.sh- the normal rollout path.scripts/refresh-moxn-token.sh- mints a token, writes SSM and a local store, waits for the ExternalSecret to sync, then restarts the deployment. Its own comments record that ordering is load bearing and that getting it wrong crashloops the pod on a 2m connect timeout.Neither is a plain
kubectl applyof a manifest Flux would re-apply identically, which is the case the doc's break-glass section says does not fight.rollout-sirens-dowel.shfolds the lane's manifests into a config hash so that editing a ConfigMap rolls the pod. Flux applying the same ConfigMap would not reproduce that roll, so a naive adoption silently breaks the edit-rolls-the-pod property the lane depends on.The tension worth deciding deliberately
Reconciliation and realtime rolling are in direct conflict, and the conflict peaks exactly when it hurts most.
With
bridge-deployactive on a 10m interval, a hand-rolled change ahead ofmaingets reverted within ten minutes. On 2026-08-19 that would have undone Kai's prep mid-window. The behaviour that made today's divergence invisible is the same behaviour that made today's prep possible.Options, and none is obviously right:
prune: falseand treat Flux as a drift detector first. Reconcile, but pair it with an alert on divergence rather than trusting silent correction. Makes the invisible visible without taking away the realtime path. Probably the right first step given Stage 2 is unproven.bridge-deploytodemo-lockdown.shalongside the controller sweep, so realtime rolling is an explicit, logged mode rather than a permanent hole.Scope note
The
.ward/ AOS boundary inaos#778is not touched here. This is about which manifests Flux reconciles, not about who owns policy.Related:
#366(origin and staged-rollout checklist),#367(Tangled knot, separate workstream),coilyco-bridge/deploy#712(a dead third-party MCP wedging this lane's rollout, which is the failure mode adoption has to not make worse).