From 3dfe9cd8ef681051be2948ddd843d728d7d1b48a Mon Sep 17 00:00:00 2001 From: Claude Agent Date: Wed, 15 Jul 2026 01:02:52 +0000 Subject: [PATCH] reload_dshackle.sh: gate the reload on the 1:1 invariant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Insert validate-dshackle-1to1.py between the overrides weave and the HUP signal: a dshackle config routing >1 node for the same chain is REFUSED (exit 1) so the live config stays active. Structural enforcement of 1 dshackle = 1 node/chain — we can't attribute traffic to multiple nodes behind one proxy (no per-upstream request metric; conn-seconds biases it). See /root/proxy-1to1-invariant-plan.md. Co-Authored-By: Claude --- reload_dshackle.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/reload_dshackle.sh b/reload_dshackle.sh index 8d2bc934..eb4d0f44 100755 --- a/reload_dshackle.sh +++ b/reload_dshackle.sh @@ -5,5 +5,17 @@ # survive every configure-drpc regeneration. See apply-dshackle-overrides.py. [ -f /root/rpc/apply-dshackle-overrides.py ] && python3 /root/rpc/apply-dshackle-overrides.py +# 1:1 invariant (2026-07-15): refuse to ACTIVATE a dshackle config routing >1 node for the same +# chain — we can't attribute traffic to multiple nodes behind one proxy (no per-upstream request +# metric; conn-seconds biases it), and the attribution model + planner assume 1:1. The validator +# reads /root/rpc/main_configs/*.yaml; on violation it exits 1 and we keep the live config. +# See /root/proxy-1to1-invariant-plan.md + rpc/validate-dshackle-1to1.py. +if [ -f /root/rpc/validate-dshackle-1to1.py ]; then + python3 /root/rpc/validate-dshackle-1to1.py /root/rpc/main_configs || { + echo "reload_dshackle.sh: REFUSING reload — 1:1 invariant violated (above); keeping live config" >&2 + exit 1 + } +fi + docker ps -q -f "name=dshackle" | xargs -r docker kill --signal=HUP docker ps -q -f "name=dshackle-free" | xargs -r docker kill --signal=HUP