Files
bikoret/scripts/bikoret-settings
Scott KarpandClaude Fable 5.1 4acd56c4b6 kohen: fallback for Claude Code when the gate is down
Every Claude Code session on the dev VM goes through bikoret.ch; when
the pod is not ready the session cannot reach Anthropic (2026-10-15:
Doorpost drift → 503 → the transmitter locked out, recovered by hand).
An `env` entry in ~/.claude/settings.json overrides the shell
environment (verified), so `env -u … claude` is not a recovery while
the gate is armed there.

- scripts/claude-direct: start straight to Anthropic via a --settings
  JSON on the command line, which outranks every settings file.
- scripts/claude-bikoret: probe the gate first; if it does not answer,
  say so and exec claude-direct (BIKORET_STRICT=1 refuses instead).
- scripts/bikoret-settings on|off|status: arm/disarm the gate for every
  launcher; `on` writes the key (kohen only), `off` is the recovery.
- KOHEN.md: the fallback and the order of recovery.

Tested 2026-10-15: dead gate armed in settings → plain claude hangs,
claude-direct answers; probe at a dead host → fallback + answer; live
gate → answer with the fringe.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-15 19:12:04 +00:00

34 lines
1.5 KiB
Python
Executable File

#!/usr/bin/env python3
# Arm or disarm the gate in Claude Code's settings.json (the `env` block is
# applied to EVERY launcher — desktop, background jobs, the plain `claude`).
#
# bikoret-settings on put ANTHROPIC_BASE_URL + ANTHROPIC_CUSTOM_HEADERS in
# bikoret-settings off remove them (the fallback when the gate is down)
# bikoret-settings status say which
#
# `on` writes the courtyard key into a config file, so the transmitter runs it:
# the builder is not allowed to write a credential there. `off` writes none.
import json, os, sys
p = os.path.expanduser("~/.claude/settings.json")
KEYS = ("ANTHROPIC_BASE_URL", "ANTHROPIC_CUSTOM_HEADERS")
mode = sys.argv[1] if len(sys.argv) > 1 else "status"
d = json.load(open(p))
env = d.get("env", {})
if mode == "on":
k = [l.split()[1] for l in open(os.path.expanduser("~/.config/shorashim/api_keys")) if l.startswith("courtyard")][0]
env.update({"ANTHROPIC_BASE_URL": "https://bikoret.ch/gate/anthropic",
"ANTHROPIC_CUSTOM_HEADERS": "X-Bikoret-Key: " + k})
d["env"] = env
elif mode == "off":
for key in KEYS:
env.pop(key, None)
if env: d["env"] = env
else: d.pop("env", None)
elif mode != "status":
sys.exit("usage: bikoret-settings on|off|status")
if mode in ("on", "off"):
json.dump(d, open(p, "w"), indent=2)
os.chmod(p, 0o600)
armed = all(k in d.get("env", {}) for k in KEYS)
print("gate in settings.json:", "ARMED (every launcher goes through bikoret.ch)" if armed else "off (direct to Anthropic)")