@@ -9,6 +9,126 @@ The format is based on the regulated environment requirements:
99
1010---
1111
12+ ## [ 2026-06-24 11:00] - Silence RUSTSEC-2026-0173 (proc-macro-error2 unmaintained) with justification
13+
14+ ** Author:** Erick Bourgeois
15+
16+ ### Changed
17+ - ` .cargo/audit.toml ` and ` deny.toml ` : ignore ` RUSTSEC-2026-0173 ` with a documented
18+ justification (kept in sync across both tools).
19+
20+ ### Why
21+ CI ` cargo audit ` started failing on ` proc-macro-error2 ` being ** unmaintained** (a
22+ maintenance-status advisory, not a vulnerability). It is reached only transitively via
23+ ` jiff 0.2.29 -> defmt -> defmt-macros ` , and ` defmt ` is jiff's optional embedded/no_std
24+ feature — ` cargo tree -e features -i defmt ` prints "nothing to print" for the host
25+ target, so the crate is never compiled into the 5-Spot binary; it exists only as a
26+ ` Cargo.lock ` entry. No runtime or build exposure. Removal awaits upstream (kube bumping
27+ jiff, or defmt-macros dropping proc-macro-error2). Verified ` cargo audit ` passes.
28+
29+ ### Impact
30+ - [ ] Breaking change
31+ - [ ] Requires cluster rollout
32+ - [x] Config change only
33+ - [ ] Documentation only
34+
35+ ## [ 2026-06-24 10:30] - Idempotency sweep: 409 AlreadyExists / duplicate finalizers no longer Error the ScheduledMachine
36+
37+ ** Author:** Erick Bourgeois
38+
39+ ### Changed
40+ - ` src/reconcilers/helpers.rs ` (` create_dynamic_resource ` ): treat a ` 409 AlreadyExists `
41+ from ` api.create(...) ` as success instead of propagating it. The bootstrap config,
42+ infrastructure object, and CAPI Machine are all created through this helper; a prior
43+ reconcile having created them IS the desired state.
44+ - ` src/reconcilers/helpers.rs ` (` add_finalizer ` ): only append our finalizer if it isn't
45+ already present — a double-call can no longer write a duplicate (which would wedge GC).
46+ - ` src/reconcilers/helpers_tests.rs ` : +3 unit tests (create 409 → Ok; create 500 still
47+ propagates; add_finalizer writes exactly one copy).
48+ - Audited the rest of the codebase for idempotency and confirmed it already holds: the
49+ only other ` .create() ` is a ` SelfSubjectAccessReview ` (a virtual auth check, never
50+ 409s); all ` .delete() ` sites swallow 404; the kata ConfigMap uses ` Patch::Apply ` (SSA);
51+ Events go through the kube ` recorder ` ; status/spec writes use ` Patch::Merge ` /` Apply ` .
52+
53+ ### Why
54+ On every reconcile after the first, ` add_machine_to_cluster ` re-issues the create and
55+ got ` 409 AlreadyExists ` (e.g. ` k0sworkerconfigs "…" already exists ` ). That bubbled up as
56+ ` MachineCreationFailed ` , flipping the ScheduledMachine into the ** Error** phase — which
57+ skips ALL Active-phase work, including node-taint reconciliation. On the k0smotron
58+ workshop tier this presented as ** Flag 1 (worker joins) passing but Flag 2 (the Node
59+ carries the spot taint) never happening** : the SM was wedged in Error, so it never ran
60+ ` handle_active_phase ` . Idempotent create is standard controller behavior and fixes it.
61+
62+ ### Impact
63+ - [ ] Breaking change
64+ - [x] Requires cluster rollout
65+ - [ ] Config change only
66+ - [ ] Documentation only
67+
68+ ## [ 2026-06-24 03:10] - Fix Mermaid flow diagrams broken by special characters
69+
70+ ** Author:** Erick Bourgeois
71+
72+ ### Changed
73+ - ` docs/architecture/calm/architecture.json ` : escaped Mermaid-hostile characters in
74+ three flow transition descriptions using Mermaid entity codes (which render as the
75+ literal characters):
76+ - ` flow-emergency-reclaim ` t1: ` reclaim-requested="true" ` → ` reclaim-requested=#quot;true#quot; ` .
77+ The embedded double quotes terminated the Mermaid label string early, causing a parse
78+ error that left the ** Emergency Reclaim** diagram blank on the docs site.
79+ - ` flow-kata-config-delivery ` t2: ` /etc/5spot/kata-config/<key> ` → ` …/#lt;key#gt; ` .
80+ - ` flow-kata-config-delivery ` t5: ` restart <restartService> ` → ` restart #lt;restartService#gt; ` .
81+ Raw ` <…> ` placeholders were parsed as HTML tags and silently dropped from the rendered label.
82+ - ` docs/src/architecture/flows.md ` : regenerated via ` make calm-diagrams ` (auto-generated;
83+ not hand-edited).
84+ - ` docs/src/concepts/kata-config-delivery.md ` : hand-written ` sequenceDiagram ` — replaced a
85+ ` ; ` with ` , ` inside a ` Note over Agent,Host: … ` label. Mermaid treats ` ; ` as a statement
86+ separator even inside note text, so it split the note mid-string and failed the whole
87+ diagram to parse.
88+
89+ ### Why
90+ The ` flows.md.hbs ` template emits transition descriptions verbatim into ` flowchart ` node
91+ labels (` t1["…"] ` ). Mermaid cannot contain an unescaped ` " ` inside a quoted label, and
92+ treats ` <…> ` as HTML — so these characters either broke parsing (Emergency Reclaim) or
93+ ate label text (Kata Config Delivery). Fixing at the source-of-truth ` architecture.json `
94+ keeps the diagrams correct after every regeneration. The ` phase -> … ` arrows in other
95+ flows contain only ` > ` and render fine, so they were left unchanged.
96+
97+ ### Impact
98+ - [ ] Breaking change
99+ - [ ] Requires cluster rollout
100+ - [ ] Config change only
101+ - [x] Documentation only
102+
103+ ---
104+
105+ ## [ 2026-06-24 02:30] - Surface the real cause of child-cluster connection failures (error_chain)
106+
107+ ** Author:** Erick Bourgeois
108+
109+ ### Changed
110+ - ` src/reconcilers/helpers.rs ` : new ` error_chain(&dyn Error) ` helper that flattens an
111+ error's ` source() ` chain into one string, and wired it into all six child-cluster
112+ failure logs (taint GET/PATCH/reconcile, kata clear/stamp). These previously logged
113+ only the terse top-level ` Display ` ("client error (Connect)"), hiding the real cause.
114+ - ` src/reconcilers/helpers_tests.rs ` : +2 unit tests for ` error_chain ` (multi-level
115+ source chain; single error with no source).
116+
117+ ### Why
118+ A k0smotron-hosted control plane (workshop k0smotron tier) exposes a self-signed API
119+ server cert that ** rustls** (5-Spot's TLS backend, kube 3.1 default) rejects where
120+ OpenSSL/curl ` -k ` accept it — so 5-Spot's child client fails to taint/drain the worker
121+ Node with ` client error (Connect) ` , with no visible cause. Logging the full chain makes
122+ the exact rustls reason (unknown issuer / SAN mismatch / unsupported signature) visible
123+ so the fix can target it (a proper cert, ` tls_server_name ` , or ` insecure-skip-tls-verify `
124+ on the child kubeconfig — kube already honors the latter via ` Config::accept_invalid_certs ` ).
125+
126+ ### Impact
127+ - [ ] Breaking change
128+ - [ ] Requires cluster rollout
129+ - [ ] Config change only
130+ - [x] Diagnostics only (no behavior change)
131+
12132## [ 2026-06-23 11:45] - Ship the spot-schedule provider binaries in the image (ADR 0009 providers were unrunnable)
13133
14134** Author:** Erick Bourgeois
0 commit comments