Repository navigation
Closed
Labels
area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.homelab-deploy, deploy-v2, manifests, and rollout flow.type: docsDocumentation-only change.Documentation-only change.wayfinder:grillingWayfinder ticket resolved by conversation (HITL)Wayfinder ticket resolved by conversation (HITL)
Description
Question
Which conditions on the settled decisions change the model, and how?
Find the claims behind the settled decisions that no source supports found 21 claims that hold only with a condition. The evidence is in docs/research/unsupported-claims.md, by claim id. Most are render details the rewrite simply carries. These need a choice first:
- Spread and parked (Decide how the model meets soft scheduling, spread, anti-affinity and parked replicas): with replicas equal to eligible nodes, a surging rollout under
across: nodeleaves the new pod Pending (C21); unparking ascheduledProcess starts one missed run at once, and parking does not stop a running Job (C22); behind one VIP only the announcing node's replica serves (C18). - Address pools and node agents (Decide how the foundation's HelmReleases are rendered and owned): a pool must name the nodes on its segment, and a Process that uses it must be placed there (C19); the GPU agents need host driver, toolkit and CDI state that the render does not install (C25, C26);
loki-canaryis a sixth per-node workload no catalog entry covers (C29). - Certificates and secrets (same decision): a Traefik that holds an ACME resolver is capped at one replica (C2) and shares Let's Encrypt's weekly allowance (C3); a static secret change reaches a workload only after
refreshAfter(C10); 14 pods request the injected Vault token, which VSO does not deliver (C12). - Handover order (Order the Project handovers and what the spec must settle before each): removing a HelmRelease deletes the CRDs its chart templates unless it is suspended first or carries the keep policy (C49).
- Derivations that will not reproduce live (Decide how the model meets the live needs no chapter covers): the priority class rule changes about eleven workloads (C32); a GPU request is one of four time-sliced shares (C30);
egress: internetmust also exclude the tailnet range (C36); the RabbitMQ lease lifetime is one setting per mount (C9).
For each, decide whether the model gains a field, a refusal or a derived value, or whether the condition is accepted and written down as a render detail or a runbook check. The remaining conditions (C6, C34, C44, C45, C47) are rewrite inputs unless this ticket finds otherwise.
Metadata
Metadata
Assignees
Labels
area: deployhomelab-deploy, deploy-v2, manifests, and rollout flow.homelab-deploy, deploy-v2, manifests, and rollout flow.type: docsDocumentation-only change.Documentation-only change.wayfinder:grillingWayfinder ticket resolved by conversation (HITL)Wayfinder ticket resolved by conversation (HITL)
Activity
ExtraToast commentedon Oct 12, 2026
Decide what each settled decision does about the claim under it that failed leaves four things for this ticket. Both tier proxies now hold an ACME resolver for the same names, so the one-replica limit (C2) and the shared allowance (C3) apply to two instances. A pool-kind L4 Address already names its site, which is where C19 starts; a node-kind one renders
hostPort. The Node Agent catalog stays host-privileged only, soloki-canary(C29) cannot enter it. The RabbitMQ lease lifetime per mount (C9) is read by the rotation drill.ExtraToast commentedon Oct 12, 2026
Resolution
Settled with the maintainer on 2026-10-12, under Re-state the goals and non-goals against the scale premise: the compiler derives everything procedural, and a refusal stays only where its hazard is real at this scale. Input:
docs/research/unsupported-claims.md, by claim id, fleet-infra at4e4a9bb, and two drills run for this ticket.Of the sixteen conditions, one adds a refusal, one adds a Platform-authored list, seven add or fix a derived value, and seven are accepted and written down. No Process gains a field.
The drills behind C21 and C22
Both ran on the live cluster (k3s
v1.35.2+k3s1) on 2026-10-12, in a throwaway namespace that was deleted afterwards. Every pod wasbusybox:1.36as user 1000 with all capabilities dropped.C21. One Deployment of two replicas, selected onto
enschede-gtx-960m-1andenschede-t1000-1, with the required anti-affinity term on the hostname and a rolling update of surge 1 and unavailability 0, which is the strategy a blue-green Process renders.0/6 nodes are available: 2 node(s) didn't match pod anti-affinity rules, 4 node(s) didn't match Pod's node affinity/selector. The rollout did not progress.matchLabelKeys: [pod-template-hash]on the term, the same change rolled out in 4 seconds. The two new pods ran one on each node. The API server stored the hash inside the term's selector (pod-template-hash In [5c978c9c59]), so the scoping is part of the pod and needs nothing from the controller.C21 is therefore settled by test for a plain Deployment. A promotion by Flagger was not part of it.
C22. Three CronJobs on a one-minute schedule with
concurrencyPolicy: Forbid: one with no deadline, one withstartingDeadlineSeconds: 20and one with300. All three ran at 10:59:00Z, were suspended at 10:59:54Z across three slots, and were resumed at 11:02:41Z, 41 seconds after a slot.So a deadline skips a missed run only when the slot is older than the deadline. Under
Forbid, the two catch-up Jobs were still active at 11:03:00Z and that slot was skipped for both (JobAlreadyActive); their pods ran on a node that took minutes to start them.Spread and parked
across: nodeterm is scoped to one revision. The required anti-affinity term carriesmatchLabelKeys: [pod-template-hash], derived, on every Process withacross: node. A surging rollout can then place its new pod when replicas equal eligible nodes. The cost is stated in chapter 18: while a rollout runs, an old and a new pod may share a node, so the one-per-node guarantee holds within a revision and not across two. The key must be on the term from the first render, because the term is checked from both sides: a running pod whose term lacks the key still excludes a new pod. No live workload carries a required term, so no handover meets that case.scheduledProcess derives a start deadline of 300 seconds. Every rendered CronJob carriesstartingDeadlineSeconds: 300. A run starts within 300 seconds of its slot or is skipped, whatever delayed it. Unparking therefore starts a run at once only when a slot fell within the last 300 seconds, as the drill showed, and otherwise waits for the next slot: it behaves as if it had happened up to five minutes earlier. The maintainer kept 300 seconds with that known, because a shorter value skips runs over a control-plane restart. Parking stops new runs and nothing else: a run in flight finishes. Chapter 11 states both.across: nodebehind a pool address is failover, not load sharing. No model change. Only the replica on the announcing node serves, and the other is a standby. Chapter 12 states it. adguard-ha stays one Process behind one address, as decided. The failover gap is measured before the utility Project hands over, and the question reopens with that number if the gap is too long for DNS.l4-speakeronly on the nodes of a site that has a pool; and a hard site pin on every Process that exposes on the address, a tier's proxy included. A placement term that contradicts the pin isE_PLACEMENT_UNSATISFIABLE. This is the shape of the node dataset pin.Node agents and GPUs
gpusentry asserts that the host is prepared. No model change. Chapter 15 states that a GPU fact asserts the driver, the container toolkit and the CDI specification on that host. nix-config owns that state until the generator chapter 15 describes exists. ThenodeProject's handover checks that each GPU node advertisesnvidia.com/gpu.gpu-devicecatalog entry. The entry fixes four time-sliced shares per GPU, beside its image and its privileges. Chapter 18 states what agpurequirement grants: one share, with no memory or fault isolation, of whichgpu-metricsholds one on every GPU node. There is no capacity refusal, because eligibility is not a capacity plan (chapter 40).loki-canaryis not rendered. Nothing in fleet-infra names it; the Loki chart enables it by default. Logs are tailed through the Kubernetes API and not per node, so a canary on every node tests nothing per node. No per-node replica concept enters the model. The observability handover diff records it as an explained removal.Certificates and secrets
acmetier may not declare more than one replica. This is a new refusal, on an authored hazard: a second instance issues the same names and draws on the same allowance. An edge proxy is delivery machinery and already derives arollingswitchover that never runs two copies, so an authoredreplicasis the only way to break the limit. The code is named in chapter 12's pull request.reconstructible. Chapter 12 and the runbook state the fact: both tiers issue the same wildcard, so five lost claims within seven days, counted across both, exhaust the allowance.hmacSecretData, which the restart needs. The three live intervals (ten minutes, one hour, one day) become one.selfpath and logs in with its service account. The estate already moved its Spring services to that after an injected token died 32 days into a pod's life. No manifest in fleet-infra and no application repository reads the token file today. Each of the fourteen pod templates that request the token gets one handover check: nothing in its image reads/vault/secrets/token.Handover
Derivations that do not reproduce live
machineryname does. The estate names auth-api, agents-api and knowledge-api, which keep the class they have. The data class stays derived from an engine with a backup. Seven knowledge-platform workloads therefore lose the data class. The handover diffs explain those and every other difference the rule makes, Vault's among them. Nothing is authored on a Process.egress: internetmeans public IPv4. The render allows0.0.0.0/0except a fixed set:10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,100.64.0.0/10(the tailnet),169.254.0.0/16and127.0.0.0/8. No range is authored, so a new LAN or a changed pod range cannot open a hole, and the cluster and LAN ranges are no longer Platform facts this rule reads. Chapter 16 states two limits: IPv6 is not allowed, and traffic to a pod's own node is always allowed.rabbitmqengine. The engine's catalog entry carries one lifetime, and the render writes the mount's lease configuration from it. A grant carries no lifetime, each consumer still gets its own role, and the bootstrap's role parameters that the API does not define are dropped. Consumers restart when the credential is replaced at its maximum, as tribelt does daily for Postgres. Drill a RabbitMQ dynamic credential rotation under a connected consumer confirms the value before chapter 17 is rewritten.The five that stay rewrite inputs
metallb.ioCRDs that join the bootstrap set carry a conversion webhook stanza that nothing calls while noBGPPeerexists. The foundation step decides whether to strip it./config, its own state on a host path. That directory becomes a claim at the media handover, with its data copied, and the derived volume group then applies. The media directories are node datasets and are not touched by this.grafanaadapter renders thedatasourcesmapping for a vendored dashboard (chapter 19).AlertmanagersetsalertmanagerConfigMatcherStrategy.type: None(chapter 19).Release-As: 1.0.0footer last in the squash commit's body.Consequences for other tickets
suspend: truecomes with a derived start deadline (decision 2).l4-speakerderives from a pool and its site, not from a pool alone (decision 4). Thegpu-deviceentry fixes the share count (decision 6).loki-canaryjoins what the render drops (decision 7). The proxy of anacmetier is refused a second replica (decision 8).node), nothing reads the injected token file (each Project among the fourteen), and the failover gap is measured (utility).docs/research/unsupported-claims.mdlists C21 and C22 under "Settle by drill". The drills are recorded above; the file is not edited for them.Record
This answer is recorded here, on the ticket. Nothing is written into
spec/v1,CONTEXT.mdor the register now. The chapter pull requests carry it:gpu-deviceentry, the critical-class list, the engine's lease lifetime, and what agpusentry asserts.across: nodeterm, the priority rule, and the GPU share.docs/runbooks/: suspend, then delete; the three handover checks.CONTEXT.md.