Skip to content

[FIX] Fix-Required Dispatch Gate Cross-Registry Immunity#4086

Merged
Trecek merged 6 commits into
developfrom
codex-backend-bricked-by-fix-required-dispatch-gate-reclassi/4082
Jun 12, 2026
Merged

[FIX] Fix-Required Dispatch Gate Cross-Registry Immunity#4086
Trecek merged 6 commits into
developfrom
codex-backend-bricked-by-fix-required-dispatch-gate-reclassi/4082

Conversation

@Trecek

@Trecek Trecek commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

The Codex backend is silently bricked whenever a HookDef in HOOK_REGISTRY is reclassified to codex_status="fix-required" and its guard script is not in BackendCapabilities.applicable_guards for the Codex backend. The dispatch gate in _check_backend_compat (tools_execution.py:150–163) refuses all Codex run_skill dispatches 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 real HOOK_REGISTRY against real backend capabilities.

This is the fourth instance of the same bug class:

  1. test_check capability misclassified as not-applicable ([FIX] Codex Capability Classification Immunity — test_check reclassification #3804)
  2. run_skill capability misclassified as not-applicable ([RECLASSIFY] run_skill codex_status to works-as-is with exhaustive session-type matrix test #3838)
  3. Severity promotion of semantic rule broke all fleet dispatches ([FIX] Severity Promotion Dispatch Gate Immunity — Part A #3949)
  4. skill_load_guard hook reclassified to fix-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_status is 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 Model count uncached output cache_read peak_ctx turns cache_write time
resolve_review* sonnet 10 3.0k 136.6k 15.9M 109.9k 608 628.2k 1h 6m
dispatch:44d3705c-3f62-459b-af5b-9678f2bbcb64* sonnet 1 114 3.6k 1.2M 94.6k 28 94.9k 23m 9s
plan* opus[1m] 10 9.8k 210.3k 14.0M 136.8k 432 818.6k 2h 19m
verify* sonnet 9 4.0k 112.3k 4.2M 74.1k 227 385.5k 58m 16s
implement* MiniMax-M3 9 17.2M 106.9k 0 0 558 0 58m 39s
audit_impl* sonnet 9 6.1k 71.6k 2.0M 49.5k 141 266.9k 43m 44s
prepare_pr* MiniMax-M3 8 1.9M 18.0k 0 0 115 0 7m 59s
compose_pr* MiniMax-M3 8 1.6M 13.2k 0 0 103 0 6m 21s
review_pr* sonnet 14 2.1k 347.6k 13.6M 101.1k 618 770.8k 1h 26m
dispatch:0145c757-e69c-4878-929a-ba4acb07e3d1* sonnet 1 322 13.7k 3.0M 86.3k 84 62.0k 42m 39s
fix* sonnet 4 640 28.9k 4.4M 98.2k 210 202.0k 21m 12s
dispatch:341f411a-3d76-4fcf-88a3-15a64c6d7bd4* sonnet 1 354 10.0k 3.4M 86.4k 89 62.0k 1h 18m
dispatch:7e27c189-e656-4ec2-b528-b128157c59a8* sonnet 1 490 17.2k 5.0M 98.3k 122 73.9k 1h 26m
dispatch:36a96fbc-6c25-4316-a068-66f069a326ac* sonnet 1 386 14.1k 3.8M 89.9k 102 65.5k 1h 14m
dispatch:540912dc-04a8-4bda-b6dd-1ba4a533b68f* sonnet 1 418 12.6k 4.1M 89.9k 106 65.5k 1h 27m
dispatch:726982d8-8d44-4345-91ee-7c36d41bf8c0* sonnet 1 330 11.6k 3.1M 84.9k 82 60.5k 1h 10m
dispatch:c51e35aa-e1dc-42fd-91a6-8cadbf463f94* sonnet 1 418 12.6k 4.1M 90.7k 107 66.3k 1h 36m
dispatch:136d06d2-7313-45ac-b80d-f17a96a36af8* sonnet 1 322 10.0k 3.0M 83.9k 80 59.5k 1h 8m
Total 20.7M 1.2M 84.7M 136.8k 3.7M 18h 37m

* Step used a non-Anthropic provider; caching behavior may differ.

Token Efficiency

Step LoC Changed cache_read/LoC cache_write/LoC output/LoC
resolve_review 100 159103.9 6282.2 1366.2
dispatch:44d3705c-3f62-459b-af5b-9678f2bbcb64 0
plan 0
verify 0
implement 1182 0.0 0.0 90.5
audit_impl 0
prepare_pr 0
compose_pr 0
review_pr 0
dispatch:0145c757-e69c-4878-929a-ba4acb07e3d1 360 8363.5 172.2 38.2
fix 20 219002.4 10100.2 1446.6
dispatch:341f411a-3d76-4fcf-88a3-15a64c6d7bd4 446 7548.5 139.0 22.5
dispatch:7e27c189-e656-4ec2-b528-b128157c59a8 235 21444.0 314.5 73.2
dispatch:36a96fbc-6c25-4316-a068-66f069a326ac 0
dispatch:540912dc-04a8-4bda-b6dd-1ba4a533b68f 0
dispatch:726982d8-8d44-4345-91ee-7c36d41bf8c0 0
dispatch:c51e35aa-e1dc-42fd-91a6-8cadbf463f94 844 4875.8 78.5 14.9
dispatch:136d06d2-7313-45ac-b80d-f17a96a36af8 0
Total 3187 26565.6 1155.3 361.1

Model Usage Breakdown

Model steps uncached output cache_read cache_write time
sonnet 14 19.0k 802.5k 70.7M 2.9M 15h 4m
opus[1m] 1 9.8k 210.3k 14.0M 818.6k 2h 19m
MiniMax-M3 3 20.7M 138.1k 0 0 1h 13m

Trecek and others added 6 commits June 11, 2026 23:46
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>
@Trecek Trecek force-pushed the codex-backend-bricked-by-fix-required-dispatch-gate-reclassi/4082 branch from 022121c to 133aa0d Compare June 12, 2026 06:47
@Trecek Trecek added this pull request to the merge queue Jun 12, 2026
Merged via the queue into develop with commit aa6b884 Jun 12, 2026
3 checks passed
@Trecek Trecek deleted the codex-backend-bricked-by-fix-required-dispatch-gate-reclassi/4082 branch June 12, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant