[FIX] Fix-Required Dispatch Gate Cross-Registry Immunity#4086
Merged
Trecek merged 6 commits intoJun 12, 2026
Merged
Conversation
Add parametrized tests that exercise the real HOOK_REGISTRY against the real BACKEND_REGISTRY through the real _get_fix_required_hook_matchers gate function. This catches the invariant violation where a fix-required hook's script stems are not covered by a backend's applicable_guards, which silently bricks dispatch on that backend. The test fails immediately for the current state of HOOK_REGISTRY where skill_load_guard is fix-required but Codex's applicable_guards only covers write_guard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Defense-in-depth: if HOOK_REGISTRY contains a fix-required hook whose script stems are not covered by ANY backend's applicable_guards, the server will fail to start rather than accepting requests it will later crash on. The check is fail-closed — it runs synchronously in _autoskillit_lifespan before write_readiness_sentinel() so no dispatch requests are accepted while the invariant is violated. A fix-required hook that IS covered by at least one backend is valid and does not raise (checked against the union of all backends' guards, not any individual backend). The dispatch gate at tools_execution._check_backend_compat still uses per-backend coverage for fine-grained blocking — this check is the impossible-state guard that catches misconfigurations before runtime. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The same codex_status value ("fix-required") has different enforcement
semantics in HOOK_REGISTRY vs SKILL_CAPABILITY_REGISTRY:
- HOOK_REGISTRY fix-required: blocks dispatch via _check_backend_compat
when a backend's applicable_guards doesn't cover the hook's scripts
- SKILL_CAPABILITY_REGISTRY fix-required: advisory only, required_backends
returns frozenset() — skills declaring these capabilities are still
Codex-dispatchable
Add a comment block to SKILL_CAPABILITY_REGISTRY making this divergence
explicit so future engineers don't assume the two registries enforce
fix-required identically. Changing one registry to match the other would
either brick 80+ skills on Codex or break the dispatch gate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…evel The startup check added in fa0114b used function-local deferred imports for BACKEND_REGISTRY and HOOK_REGISTRY. The arch tests require IL-3 (server/) to use module-level imports for lower layers since there is no circular import risk. Hoists both imports and updates the schema version convention allowlist line number. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…checks
The assertion compared set(BACKEND_REGISTRY.keys()) to itself, making
it always pass. Replace with a minimum count guard (>= 2) and an
expected-set equality check against {"claude-code", "codex"} so the
test actually detects registry shrinkage or unexpected additions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…extual RuntimeError If any backend class constructor raises during run_startup_fix_required_coverage_check, the server now re-raises with a RuntimeError that identifies which backend class caused the failure, rather than letting the bare exception propagate without context. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
022121c to
133aa0d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The Codex backend is silently bricked whenever a
HookDefinHOOK_REGISTRYis reclassified tocodex_status="fix-required"and its guard script is not inBackendCapabilities.applicable_guardsfor the Codex backend. The dispatch gate in_check_backend_compat(tools_execution.py:150–163) refuses all Codexrun_skilldispatches when this cross-registry invariant is violated. CI does not catch it because every test exercising the gate uses monkeypatched synthetic registries — no test validates the realHOOK_REGISTRYagainst real backend capabilities.This is the fourth instance of the same bug class:
test_checkcapability misclassified asnot-applicable([FIX] Codex Capability Classification Immunity — test_check reclassification #3804)run_skillcapability misclassified asnot-applicable([RECLASSIFY] run_skill codex_status to works-as-is with exhaustive session-type matrix test #3838)skill_load_guardhook reclassified tofix-required, bricking Codex dispatch (current — Codex backend bricked by fix-required dispatch gate — reclassify skill_load_guard codex_status and add real-registry dispatch contract test #4082)The architectural weakness is that
codex_statusis a manually-declared static field validated only against its own internal consistency, not against actual runtime dispatch behavior. The fix must make cross-registry invariant violations fail at test time, not at runtime dispatch.Requirements
Conflict Resolution Decisions
The following files had merge conflicts that were automatically resolved.
Closes #4082
Implementation Plan
Plan file:
/home/talon/projects/autoskillit-runs/remediation-20260611-215147-829611/.autoskillit/temp/rectify/rectify_fix_required_dispatch_gate_cross_registry_immunity_2026-06-11_215739.md🤖 Generated with Claude Code via AutoSkillit
Token Usage Summary
* Step used a non-Anthropic provider; caching behavior may differ.
Token Efficiency
Model Usage Breakdown