Orchestrata Ultimate › Gates › wiring
Gate: wiring
At a glance
| Purpose | Refuse an artifact this branch or working tree added but left inert: an unregistered .claude/hooks/ file, an uninstalled git hook, an unreachable src/ module, an uninvoked ruling-declared gate. |
| Where it runs | The scripts/gates.py battery (registered as wiring); scripts/health_check.py. |
| Trigger | A battery run whose fingerprint changed, or whose last cached verdict was not ok; a health check. |
| Exact command | python scripts/check_wiring.py [--repo-root PATH] [--rulings-dir PATH] [--json] |
| Blocks | Exit 1 on any W1–W4 finding; exit 0 clean or skipped with a printed reason (not a repo, no git, no master ref). |
| Ruling / ADR | RUL-023 — a feature means the thing is wired; RUL-012 — done means wired and deployed; ADR-0042 — wiring gate supersession by the ruleset engine. |
| Last recorded verdict | ok: true in the primary checkout's .cache/gates.json (file last written 2026-09-22 10:01 local). wt-MAP-PRECOMMIT has no .cache/gates.json. |
What it refuses
An artifact this branch added but left inert: a .claude/hooks/ file registered
nowhere, a git-hook script the installer never references, a new src/ module
reachable from no production entrypoint, a ruling-declared gate script no runner
invokes.
Why it exists
Module docstring, quoting the ruling verbatim and the incident:
"Wiring gate — RUL-023 ('when I ask for a feature that means wiring the damn thing not just code vomit', verbatim, 2026-07-27).
See
~/workspace/knowledge-wiki/rulings/RUL-023-feature-means-wired.mdfor the ruling text and the incident (in a single session three capabilities were built and reported complete while inert: a git hook whosecore.hooksPathpointed elsewhere, a.claude/hooks/script registered only in a worktree's trackedsettings.json, and a gate no runner invoked). RUL-012 already defines done as wired+deployed; this mechanically checks it for the artifact classes that are easiest to leave inert."
The four checks
| Check | An artifact added in this diff… | …must be |
|---|---|---|
| W1 | under .claude/hooks/ |
registered in .claude/settings.json |
| W2 | under scripts/hooks/ (other than the installer) |
referenced by scripts/hooks/install-git-hooks.sh |
| W3 | a new .py module under src/ |
TRANSITIVELY reachable from a production entrypoint — "the same reachability BFS the AST toolkit's orphans query runs… An import from a file that is itself unreachable does not count — this does NOT hand-roll a second reachability engine" |
| W4 | a scripts/*.py file some ruling declares as its gate mechanism |
invoked by scripts/health_check.py, a .claude/hooks/ file, a scripts/hooks/ file, or scripts/run_tests.py |
How it runs
- Command:
python scripts/check_wiring.py [--repo-root PATH] [--rulings-dir PATH] [--json] - When it fires: the
scripts/gates.pybattery (registered aswiring);scripts/health_check.py. - Scope: "everything this gate flags is scoped to the current branch's diff
against
master", so it grades what THIS change added, never the tree's accumulated history. No diff against master → exit 0, nothing to grade. Since5740b332c(2026-08-12) the diff is no longer the commit rangemaster...HEADalone.diff_entries()unions three sources against the merge base ofmasterandHEAD: (1)<merge-base>..HEAD, (2)git diff --name-status <merge-base>for staged and unstaged work, and (3)git ls-files --others --exclude-standardfor new untracked files, gradedA. Its docstring records why: with the commit range only, "147 files changed vs master, and the gate graded ZERO of them" (measured 2026-08-12). - RULINGS_DIR (for W4) is resolved via the same mechanism as
rulings_lint.py("imported from there, not reimplemented") — "a machine without the knowledge-wiki clone must not go false-red: W4 is skipped, W1–W3 still run." - Inputs: fingerprint roots
_SRC = ("src", "scripts", "tests", "pyproject.toml")(theGATESentry"wiring": ([sys.executable, "scripts/check_wiring.py"], _SRC)inscripts/gates.py, read through the AST toolkit on 2026-10-23). An earlier version of this page said a 2026-08-28 audit droppedtestsand added.claude/settings.jsonand.claude/hooks; the registry carries neither change. - Caching — no git state, no
.clauderoots. An earlier version of this page described a{".py", ".sh", ".json"}mask plus aGATE_GIT_STATEHEAD/master/merge-base string mixed into the fingerprint. Neither exists:git log --all -S GATE_GIT_STATE -- scripts/gates.pyand the same search forGATE_MASKSfind no commit that ever contained them (checked 2026-10-23)._fingerprint()hashes only file paths and bytes with suffixes.py,.toml,.pl,.json,.md,.shunder the roots above. Consequences, derived from the code and not measured by a run: after a cached PASS, (1) a new.claude/hooks/*.shor a.claude/settings.jsonedit does not re-run the gate, though W1 reads exactly those; (2) a new commit, a fetch or master moving does not re-run it either, though the merge base decides what it grades. - Disclosed residual blind spot (registry comment): W4 also reads the EXTERNAL rulings directory — "a SEPARATE git repository from this one… No root in THIS repo's fingerprint can ever see a ruling added or edited there… Left undecided deliberately."
Typical failures and how to fix them
- Exit codes: "Exit 0 clean (or skipped, with a reason). Exit 1 on any violation, one line per finding: check id, artifact path, and the exact wiring site it is missing. Not a git repository, git unavailable, or no divergence from master: exit 0 with a printed reason, never crash."
- State over time: on 2026-08-29 the cached battery verdict was
ok: false(a branch carrying unwired additions); the primary checkout's.cache/gates.json, last written 2026-09-22 10:01, recordsok: true. - Un-blocking: wire the thing — register the hook, reference the script in the installer, connect the module to an entrypoint, invoke the gate from a runner. The fix is never to delete the check.
- W1 and RUL-035 pull in different directions.
check_w1_claude_hooks()still requires a new.claude/hooks/file to be registered "under a PreToolUse/ PostToolUse/Stop matcher in .claude/settings.json". RUL-035 / ADR-0070 put hook registration at the user level (~/.claudeor the orchestrata plugin) and never in a repo's.claude/settings.json. This run did not find a recorded resolution; check the ruling before adding a repo-level registration just to satisfy W1. - A hook or settings change that the battery reports as unchanged, or a branch
rebased onto a newer master. Because of the caching gaps above, run the gate
fresh:
python scripts/gates.py --only wiring --all, or the command directly.
Wiring (of the wiring gate itself)
- Invokers:
scripts/gates.py(battery),scripts/health_check.py. - Tests:
tests/scripts/test_check_wiring.py.
Related
- Gates master index
- Development workflow
- RUL-023 — A feature request means the thing is WIRED
- RUL-012 — Done means wired and deployed
- RUL-035 — hooks at user level only and ADR-0070
- ADR-0042
- feature-loss — "code that exists but was never CONNECTED, not code that was DELETED after being connected" (that gate's own demarcation of this one)
- plugin-drift — wiring's delivery-path sibling: registered here, mirrored there
- Session-hooks family — the artifacts W1 protects