Repository navigation
Refuse connector sends before maintenance-held locks - #1999
Merged
Merged
Conversation
MaintenanceHeldError composes relation and tool refusal behavior; connector consumers catch the one owning family. Remove the explicit exception tuple and union. Tighten real copied-bus proof to 0.1 seconds.
This was referenced Oct 19, 2026
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.
Connector maintenance refusal
Owner: pi-install-gate. Direct maintenance order 2932, resumed after the main install. P255's recorded-check interpreter correction remains separate with claude-code.
Head:
354b3aeec7e3375d27325a23de10b053aa19e80a, including mainb793c7325c99c3a0f721df0ac85978daa3eb2763.Where the request waited
Connector.opened_wireenteredclient_wire, which constructedCommswithout asking the maintenance barrier.Registration.__init__atsrc/agent_comms/registration.py:72immediately calledself.store.read(), so an install holding the registry could park the request there. A request reachingMessaging.sendalso waited on the wire lock atsrc/agent_comms/messaging.py:57, before its existing maintenance check.The HTTP boundary correctly catches
ToolRefusedError;MaintenanceHeldErrorfailed to declare that it belongs to this family. The initial attempted fix enumerated both errors in the connector, which was wrong (MEMB-2). That tuple, union annotation and connector import are deleted.MaintenanceHeldError(RelationViolationError, ToolRefusedError)now declares the fact once.Owner and consumers
client_wirenow calls the existing barrier'sassert_open_unlockedbefore borrowing the default route or constructingComms. Thus connector, CLI and other one-shot consumers share the early check rather than repairing just one send handler.ToolRefusedErrorcatch and parameter annotation handle the subclass automatically. Runtime C3 isMaintenanceHeldError -> RelationViolationError -> ToolRefusedError -> ValueError -> Exception -> BaseException -> object; existing relation-error consumers remain valid.CoreErrorstill produces the exactheldresponse. No new status mapping, maintenance state, timeout, retry, worker or queue is introduced.rg -n 'Maintenance holds ingress' src/agent_commsfinds the refusal text only atmaintenance_barrier.py:51; the phase family still owns it.Before/after source inventories used the existing refactor-audit Package parser: all 381 Core modules parsed, zero omissions. Original declarations, imports, inheritance, writes, checks and executable consumers were read across connector, composition root, maintenance barrier, registry/store locking, messaging and protocol owners. Existing callbacks and dynamic MCP dispatch are not claimed statically resolved. Private before/after site receipts remain local. No new class or alternate decoder is added.
Actual connector proof on the pushed head
tests/verify_connector_maintenance.pystarts the installed connector entrypoint and interpreter with this checkout's Core source selected for an isolated loopback server. This is a candidate-source proof, not an update of the installed live connector.The script seeds a real private protocol bus, copies it, starts the real authenticated server, advances the copy to Installing, then holds its wire and registry locks exclusively throughout one curl
comms_send:isError=true.Maintenance holds ingress: the bus is under maintenance.Three focused HTTP cases also pass on the final head: Draining, Paused and Installing, additionally holding the default-route directory exclusively. These cover both an explicit independent root and a selected default root.
Checks
Src-Budget: 8mechanism covers the six net added production lines. No checker/baseline changes, suppressions, casts or Any annotations.cutover.backupin its child. The deselected older proof writes another owner's scratch directory; the new real HTTP proof above ran instead.Storage and remaining delivery
The attempted nested dependency worktree violated the path rule and was refused. The dependency checkout is now in the permitted P2 path, pinned to the same existing main submodule object. The two owned checkouts plus sole scratch directory total about 100 MiB, well below the 3 GB cap. P2 remains needed for these checks; pi-cn-phase3 reported that its read-only borrowing has ended. Retirement must preserve actual borrowers and the required checkout creation order.
Not merged or installed by this work. This remains draft, with
install-rehearsalfailed: full two-machine practice-install acceptance is still incomplete, and the 3 GB cap forbids the approximately 26 GiB desktop copy. Only commit outcomes are published; private copies and logs remain local.Assumed: no installation, restart, environment modification or large rehearsal is authorized. P255's correction is not a dependency of this connector repair.