From 4b9c46251ee1d4e947a50df776d7cd153f1a63d9 Mon Sep 17 00:00:00 2001 From: Cyd Date: Fri, 10 Jul 2026 12:40:09 -0500 Subject: [PATCH] SiteConfigMerge: frame checks as plan tripwires; exit 3 on warnings Per operator: under the SiteLink IP plan there should never be GUID/MAC/IP conflicts. Reframed the merge checks accordingly - they are tripwires for plan drift (un-renumbered site) or stale inventory (same pod recorded in two site files), not expected events. The merge now exits 3 when any warning fired (master still written) so event-day scripts can gate on a clean merge; 0 = clean, 1 = usage, 2 = hard error. Verified: same-file-twice merge exits 3, clean merge exits 0. Co-Authored-By: Claude Fable 5 --- tools/SiteConfigMerge/Program.cs | 17 ++++++++++++++++- tools/SiteConfigMerge/README.md | 26 +++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/tools/SiteConfigMerge/Program.cs b/tools/SiteConfigMerge/Program.cs index 169bb91..a108b9a 100644 --- a/tools/SiteConfigMerge/Program.cs +++ b/tools/SiteConfigMerge/Program.cs @@ -149,10 +149,25 @@ Usage: SiteConfigFile.Write(output, merged, binder); Console.WriteLine($"wrote {output}: {merged.Count} squad(s), {merged.Sum(s => s.Pods.Count)} pod(s) " + $"(identity: {binder.CapturedAssembly ?? TeslaBinder.DefaultAssembly})"); + if (mWarnings > 0) + { + // Under the SiteLink IP plan none of the consistency checks should ever + // fire; a warning means plan drift (un-renumbered site) or stale + // inventory (same pod in two site files). Exit 3 so event scripts can + // gate on a clean merge. + Console.Error.WriteLine($"{mWarnings} warning(s) — master written, but resolve these before the event."); + return 3; + } return 0; } - private static void Warn(string message) => Console.Error.WriteLine("WARNING: " + message); + private static int mWarnings; + + private static void Warn(string message) + { + mWarnings++; + Console.Error.WriteLine("WARNING: " + message); + } private static string FormatMac(byte[] mac) => mac == null || mac.Length == 0 ? "none" : BitConverter.ToString(mac).Replace('-', ':'); diff --git a/tools/SiteConfigMerge/README.md b/tools/SiteConfigMerge/README.md index ab4155b..ad57e49 100644 --- a/tools/SiteConfigMerge/README.md +++ b/tools/SiteConfigMerge/README.md @@ -29,12 +29,28 @@ Merge sites into one config: - The output declares the TeslaConsole assembly identity captured from the first input, so the console accepts it as its own. -Warnings (merge proceeds; read them): -- duplicate pod GUID or MAC across inputs — same pod imported twice? -- same IP at two sites — expected until sites renumber into their `10.0..0/24`; - it must be resolved before actually linking. +### Consistency checks -Hard error: duplicate post-rename squad name (same site file given twice). +**Under the SiteLink IP plan, none of these should ever fire.** They are tripwires +for plan drift, checked for free at the natural checkpoint (merge time, right before +an event): + +- **same IP at two sites** — a site hasn't renumbered into its `10.0..0/24` + yet (e.g. still on legacy `200.0.0.x` or flat `10.0.0.x`); +- **duplicate pod GUID or MAC** — orthogonal to the IP plan: GUIDs are minted at + provisioning and MACs are burned into NICs, so a hit means *stale inventory* — + the same physical pod recorded in two site files (pod changed hands without + re-provisioning, or a siteconfig was copied as a template). + +The master is still written, but the exit code reflects the result so event +scripts can gate on a clean merge: + +| Exit code | Meaning | +|-----------|---------| +| 0 | clean merge | +| 1 | usage error | +| 2 | hard error (unreadable file, duplicate post-rename squad name — same site file given twice) | +| 3 | merged, but with warnings — resolve before the event | ## Build