diff --git a/04-ISSUES/030-asking-what-a-machine-should-be-re-signed-its-certificate/00-report.md b/04-ISSUES/030-asking-what-a-machine-should-be-re-signed-its-certificate/00-report.md new file mode 100644 index 0000000..dedb8a3 --- /dev/null +++ b/04-ISSUES/030-asking-what-a-machine-should-be-re-signed-its-certificate/00-report.md @@ -0,0 +1,56 @@ +--- +status: fixed +opened: 2026-09-01 +located-in: [mesh-control] +fixed-by: mesh-control 38d4e77 +amended-design: +--- + +# 030 — Asking what a machine should be re-signed its certificate + +## Symptom + +Every machine carrying a certificate reported as *waiting* — not running what the mesh would send +it — for ever. Pushed seconds ago, already behind again. Nothing wrong, nothing failed, nothing +quiet; only a comparison that never came out equal. + +It surfaced as the one red test in four consecutive runs, and wore three other faults' clothes +first: a test racing the apply it asserted on, a status command that wrote to the database it was +reading, a machine starved at its default size. Each was real; each was fixed; the symptom stayed. + +## Cause + +The mesh signs a certificate for a machine's internal name as part of composing its declaration — +and signed **anew on every composition**. Same authority, same key, same name, same validity +window; a fresh random serial each time, because that is what signing does. So the declaration +composed to answer *is this machine current* differed from the declaration sent by exactly one +serial number, every time, deterministically. + +The comparison is a digest, so one changed byte is as unequal as a different world. + +## How it was found, which is the lesson + +Not by deduction — deduction produced the three wrong theories above. The suite was run once with +its scenario kept standing, and the standing mesh was asked twice: `plan`, `plan`, diff. Two +answers seconds apart, identical to the byte but for one serial, in the certificate file. The +diff had one line where four theories had none. + +A verdict machine that can be kept and interrogated is worth more than the verdict. + +## The rule it broke, third find of its kind + +**Issued once and kept.** The port had it, the secret had it, the certificate did not — composed +fresh on every asking, by the same code that holds the other two still. And like +[`028`](../028-two-things-want-one-port-and-nothing-says-so/00-report.md)'s ReleasePorts, the +keeping was designed and never wired: the serving-key migration added a column *"and what was +issued for it"*, and nothing wrote it. + +A kept certificate stands while the name, the key and the clock agree. A node that rejoined with +a new key or changed its name gets a fresh signing exactly as if nothing were kept; so does one +whose certificate is into its last tenth of life. + +## Verified + +Live, on the kept mesh, before any suite run: one push with the fixed binary and the machine +settled; the second machine likewise; then the mesh's own sentence — all doing what they were +told, running what the mesh would send them.