Skip to content

fix: rebuild budget covers drift on every owned pod; dead-letter parks at a generation - #36

Merged
CMGS merged 6 commits into
mainfrom
review/night-2026-09-03
Sep 2, 2026
Merged

fix: rebuild budget covers drift on every owned pod; dead-letter parks at a generation#36
CMGS merged 6 commits into
mainfrom
review/night-2026-09-03

Conversation

@CMGS

@CMGS CMGS commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Whole-repo quality round (2026-09-03): every Go file read against the /code Style Self-Check and the judgment lenses; three commits.

  1. fix — the drift-delete path had no rebuild budget on main, sub-agent or toolbox pods. Any defaulter the spec does not pin (a namespace LimitRange with a cpu/memory default, a resource-rewriting webhook) makes podSpecMatchesAgent permanently false, so the pod was deleted and recreated every requeue (~2 s), one microVM built and destroyed per cycle, and no metric moved. Every terminal or drifted pod now goes through one budget keyed by pod name (rebuild.go): four attempts with 0/1/5/30 s backoff, then dead-letter with the SubAgentDeadLetter event and counter. A dead-lettered pod records the CocoonSet generation and stays parked until a spec edit (new generation) resets its budget; drift alone no longer lifts it, since a permanently rewritten pod would otherwise loop at the slower cadence. ensureToolboxes reports its pending backoff like ensureSubAgents; Reconcile picks the shorter. The history annotation prunes pods the spec no longer names (main, [1..replicas], toolboxes) and no longer mutates its input. Metric names are unchanged; their help text now covers every owned pod.
  2. reviewpodpatch (created yesterday) joins the repo import group in six files; no godoc on the Reconcile and logr Enabled interface methods.
  3. docs — the package tree lists podpatch/; docs/cocoonset.md names the current symbols; docs/observability.md describes the budget as it now works.

Held with reasons: podsHibernatedByCR listing twice per reconcile on the node-pinned + CR-hibernated main path (two in-cache reads; threading a memoized list touches 32 test call sites); RecoveredFromFailure re-firing while sub-agents churn (bounded now that drift converges); a pod label index for listOwnedPods (one namespace-scoped in-memory walk per reconcile; the repo already has the indexer pattern if density ever asks for it).

Gates: GOWORK=off make lint 0 issues on linux and darwin (Reconcile's complexity stays under the gocyclo cap via rebuildDriftedMain); make fmt-check clean; asl ./... clean on both GOOS; GOWORK=off go test -race -count=1 ./... green. Round diff: 22 files, +239/−222; comment lines +8/−9.

CMGS added 6 commits September 3, 2026 01:49
…a generation

The drift-delete path had no rebuild budget on main, sub-agent or
toolbox pods. Any defaulter the spec does not pin (a namespace LimitRange
with a cpu or memory default, a resource-rewriting webhook) makes
podSpecMatchesAgent permanently false, so the pod was deleted and
recreated every requeue, one microVM built and destroyed per cycle, with
no metric moving. Every terminal or drifted pod now goes through one
budget keyed by pod name: four attempts with 0/1/5/30 s backoff, then
dead-letter. A dead-lettered pod records the CocoonSet generation and
stays parked until a spec edit, which resets its budget; drift alone no
longer lifts it, because a permanently rewritten pod would otherwise loop
at the slower cadence. The history annotation keeps only pods the spec
still names.
…ethods

The package created yesterday sat in its own import group in six files.
Reconcile and the logr sink's Enabled implement documented interfaces.
… not recreated

History entries record the CocoonSet generation they were counted at,
so a spec edit resets every budget instead of only the parked pod's, and
a Count=4 entry left behind after the fourth delete cannot stamp a fresh
generation's pod straight into dead-letter. A missing pod whose name
exhausted its budget at the current generation stays absent (main
reports Failed, sub-agent slots and toolboxes are skipped), so
Kubernetes' terminated-pod GC removing a parked pod no longer restarts
the create/fail/park cycle. Comment and doc placement corrected.
…count

Count reaching the budget only means the last delete happened; the replacement
still has to be created. A parked flag in the history entry now marks the
dead-lettered name, the missing-pod gates read that flag, an existing toolbox is
always triaged, and an exhausted absent main reports Failed without a timer
requeue since only a generation or pod event can change the decision.
@CMGS
CMGS merged commit bd2d4fe into main Sep 2, 2026
@CMGS
CMGS deleted the review/night-2026-09-03 branch September 2, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant