Repository navigation
Queue/notification UI, Core: integrate P872, P883 and P904 read operations - #3566
Merged
163 commits merged intoOct 30, 2026
Merged
163 commits merged into
163 commits merged into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…b.com/OpenHCSDev/agent-comms into work/claude-nra--P872
ReadNotifications carried a caller-choosable viewer field so the MCP outcomes tool could reuse it under the caller's authority. That made the reader's authority an argument any caller could set, and the UI and MCP sides each restated who reads. Now a BusRead member owns its arguments and its read once, as read_as(comms, reader); the boundary supplies the BusReader. UiRead derives the UI's read() as the operator, and the MCP tool reads under its own ToolCaller, which is now a BusReader. OperatorOutcomes moves to bus_read beside the reader it serves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
) ContentCache stored mypy counts under a key of committed content and checker versions, but mypy also reads the installed packages, which no key names. Hosted #3538 restored debt-ratchet-src-71453f18 (saved by main cache job 40654054315 under a Core-only install, Pydantic 2.14.1) and compared that stored base count with a head count measured under the full stack (Pydantic 2.13.5). - CheckedRevision.findings runs the checker. TypeErrors inherits it and keeps mypy's own --cache-dir, which tracks dependency changes itself. - LintFindings.findings keeps the content-keyed memo unchanged: Ruff reads only the tree and the head's configuration. - Unformatted keeps its per-file blob cache unchanged. - ClientTypeErrors.findings calls checked directly. The client commit and src tree it computed only for the key are gone. Regression: one parameterized real-mypy test switches an installed PEP 561 dependency between two sys.path environments, with committed source, client and configuration unchanged and the same count-cache directory. The count must follow the dependency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
GoalHistory (tools.py) and GoalHistoryReply (runtime_requests.py) were
empty subclasses of RecordedGoalHistory, and recorded_history took the
result class as an argument so each caller picked its own empty wrapper.
Neither added a field or a behavior.
- RecordedGoalHistory now extends ToolResult (itself a DeclaredReply), so
the MCP tool and the owner socket return the same record.
- GoalHistory and GoalHistoryReply are deleted.
- GoalManagement.recorded_history(name, scope) returns RecordedGoalHistory;
the reply argument, its HistoryReply TypeVar and the TypeVar import are gone.
- CommsGoalHistoryTool and GoalHistoryRuntimeRequest return it directly;
tool name, declared runtime name, subject resolution, scope decoding and
the worker-thread execution are unchanged.
- tests/test_goal_execution.py compares against RecordedGoalHistory.empty().
The encoded record is unchanged: one populated history/failure payload
decodes and re-encodes byte-identically through GoalHistory,
GoalHistoryReply and RecordedGoalHistory before this commit and through
RecordedGoalHistory after it; empty() encodes as
{"failures": [], "history": []} on both sides.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…the owner (#3538) CommsInputDeliveryTool read goals.input_delivery in the connector's own process under UNOBSERVED_DELIVERY_SCOPE: it could not see the owner's live queue, yet returned an ordinary-looking delivery view. The UI and the owner socket each restated the same read again (ReadDeliveryOverview, InputDispositionsRuntimeRequest, with their own include_history). - BusRead is now an abstract capability of the existing ToolDeclaration family (no DeclaredFamily root of its own); UiRead still derives from it. - BusReader owns subject/own_thread/refuse_thread once; the copies on ToolCaller and NoThreadCaller are gone, refusal text and type unchanged. - OwnerReading: one exchange with one held owner incarnation; admit() defaults to any owner, OwnerLiveRead admits only native owners, so an external bridge (live PID, no socket) is refused instead of retried forever. - OwnerReplyConnection.held/answer: the one connection factory (exact incarnation, root, process; 3 s reply timeout, close in finally, no retry after dispatch) for OwnerRead and OwnerLiveRead. - OwnerLiveRead: MCP apply/read_as resolves caller.subject(thread) and asks the owner via asyncio.run on the tool's synchronous boundary; the owner answers in owned(ctx) with ctx.name and its own session. - InputDeliveryRead (comms_input_delivery, thread, include_history=True): the one declaration, in the ToolRequest/native catalogs by capability. owned() takes scope only from the owner's delivery_scope. - OwnerReadRuntimeRequest (owner_read) and ReadOwnerOperation: one generic runtime envelope and one generic UI envelope carrying the operation. - Deleted: CommsInputDeliveryTool, ReadDeliveryOverview, InputDispositionsRuntimeRequest, the input_dispositions request. - The connector encodes Refused, ConnectionError and TimeoutError from an owner read as a failed tool call instead of dropping the HTTP call. - tests/test_command_families.py: owner_read round trips for both history settings; a non-owner-live operation and a bad include_history refuse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
… a live owner (#3538) - test_observer_death: unavailable/stale owner reads are parametrized from ReadOwnerGoal plus ReadOwnerOperation over BusRead.members_with(OwnerLiveRead), not OwnerRead.__subclasses__(); refusal and observer-alive assertions kept. - test_input_delivery_history: the CLI test that asserted a declared owner with no process answers delivery state is deleted (that answer was the defect). The replacement starts the canonical owner socket, queues a prompt, records an off-queue notice, and asserts MCP invoke and the UI envelope both equal the owner's own projection for include_history False and True, that the off-queue notice is current only under the old unobserved projection, and that a stopped owner refuses the MCP read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…re handed (#3538) - OwnerReading.admit is the shared native-transport admission (owner.execution.require_native()). OwnerLiveRead.admit and ReadOwnerOperation.admit were identical restatements and are deleted. ReadOwnerGoal now reaches it too: an external bridge has a live PID and no RuntimeServer socket, and _connect_current waited for that socket forever before dispatch. It is refused before the wait. - OwnerReplyConnection.held compared the registry's incarnation with the supplied one, then OwnerConnection.__init__ read the registry again into _identity, so a replacement incarnation could be recaptured unchecked. held now constructs the connection and OwnerConnection.require_identity compares the captured _identity with the supplied witness before returning; the earlier separate comparison is deleted. No second identity field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ation, death, external controls (#3538) tests/owner_socket_fixture.py (registered in pytest_plugins) is the one fixture owner: runtime_processes (moved from test_runtime.py; it now yields the spawned children so a test can stop one through its own owner), declare_owner (native or external registration) and silent_socket (the real Unix-socket peer from test_dispatched_request_without_a_reply..., which receives one request and closes without replying). The existing reply-loss test is refactored onto it. New controls, nothing of ours patched, no fabricated reply: - MCP InputDeliveryRead without a reply, for include_history False and True: OwnerReplyLostError, exactly one received request decoding to OwnerReadRuntimeRequest(thread, InputDeliveryRead(thread, include_history)), durable inputs unchanged. The peer runs no domain body. - Root replaced under a held connection (rename to a sibling, new directory at the old path): OwnerIdentityChangedError, zero requests; root restored. - Same-name recreation (unregister, begin_delete, remove, declare): the held read and a new held() with the old witness both refuse; incarnations differ. - Held process death (runtime_processes child stopped through stop_sync): the read refuses with ConnectionError before any request; inputs unchanged. - External owner with a live child and no socket: MCP delivery refuses with RelationViolationError; through the observer, ReadOwnerGoal and the input-delivery envelope (derived from OwnerLiveRead membership) both refuse and the observer stays alive. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ps importing its transport (#3538) OwnerLiveRead extracted OwnerReadRuntimeRequest.declared_name and reached runtime/runtime_requests through two function-local imports to escape the cycle that extraction created, and OwnerReadRuntimeRequest.result returned Any because OwnerLiveRead had no Result default (hosted debt-src: FunctionLocalImport +2, FamilyFlattened +1, TypeErrors runtime_requests +1, BannedVocabulary +3). - OwnerLiveRead[Result: ToolResult = ToolResult]; operation fields stay the bare family class. OwnerLiveRead no longer inherits OwnerReading and has no socket read: owned/decode_reply are its answer and decoder. read_as builds OwnerReadRuntimeRequest(thread=owner.name, operation=self), sends it through OwnerReplyConnection.answer and decodes the reply. asyncio.run stays at the synchronous tool boundary. - OwnerReadRuntimeRequest moves from runtime_requests.py to bus_read.py as OwnerReading[object] + ResultRuntimeRequest; same owner_read action and operation field. Its read(owner) is the one socket exchange: owner.request(self.declared_name, operation=self.operation). - OwnerReading and OwnerReplyConnection move into owner_connection.py beside OwnerConnection. OwnerReading.read takes OwnerConnection. OwnerReplyConnection derives OwnerConnection directly (owner_read and goal_snapshot use the base proxy_payload; only PromptRuntimeRequest needs the ACP controller token). REPLY_TIMEOUT, held/answer/close and the require_identity check are unchanged. - The native transport check is OwnerReading.require_native_owner, called from held; RuntimeRequest.require_owner(entry) is untouched. - ReadOwnerOperation.read builds the envelope with owner.session_id and decodes through the operation; ReadOwnerGoal.read takes OwnerConnection; OwnerRead.ask loses its local import. All imports are module scope. - Old definitions deleted, no aliases. tests/test_runtime.py imports the moved names from bus_read/owner_connection, and the held root/recreation/death controls hand held() the real OwnerReadRuntimeRequest and await its read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…on lifecycle (#3538) Root's selection on 5c26262 ran 60 cases: 49 passed, 11 failed. One same-name control used remove() after begin_delete, which correctly refuses Deleting status; ten observer fixtures used the removed synchronous observer surface (`with`, readable()/results()/fileno(), sync close, NotificationWindow == {}). - test_runtime same-name control: deletion completes through edit.document.remove_originals((old,)) in registry.store.editing(), the path production uses (thread_management.py:537); the captured connection, old witness, zero-dispatch peer and both OwnerIdentityChangedError refusals stay. - test_observer_death: every observer is `async with`; empty-window checks compare .outcomes. The killed-observer test uses the real receiver: one read proves startup, SIGSTOP is confirmed with waitpid(WUNTRACED), the next read is shown pending, then SIGKILL; ObserverDied carries the child pid, -SIGKILL and signal text, and StopSidebar and a later read raise that same object. A stopped child is killed and a pending task cancelled in finally. The failed-observer test asks one real read on the not-a-wire route and requires exit status 1 and the original traceback. The readable() helper is deleted. - test_busy_history_loading: three `async with` sites, the close-once test's `async with process` and awaited repeated close, .outcomes comparisons; the Connection.close endpoint observation is unchanged. - test_deleted_thread_observation and test_unreadable_history_observation (the two readable() importers) start the receiver once with start_receiving and wait on tests/observed_queue.py, a test-local queue of delivered results that raises a receiver failure as its original exception. No manual pumping. No production change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ked for (#3538) Root's rerun on 9bb8b2e: 22 cases in 70.37 s, 20 passed, 2 failed, both the other_root=False stale-identity cases (goal and input delivery). held looked up the selected thread's process before any identity comparison, so a stale incarnation was refused as "no owner process" (RelationViolationError) instead of OwnerIdentityChangedError. a4702b1 had dropped the initial comparison when it added the constructor check. - OwnerReplyConnection.held: registry.require(owner.name), then thread.incarnation != owner -> OwnerIdentityChangedError, then reading.require_native_owner(thread), then require_process/socket path and construction, then connection.require_identity(owner). The two comparisons check two different registry reads (the selected thread and the constructor's capture); no identity field or cache is added. - ObservedQueue.until holds one 30 s bound over the whole match; next() keeps its own bound for direct callers. Before, each unrelated result restarted the bound, so a steady stream could keep a wait running indefinitely. - test_deleted_thread_observation restores one 30 s bound around waiting for both the missing-thread result and the retirement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…one (#3538) The notification read lived on the UI request: ReadNotifications held root and request_id beside its references, ReadRecordedNotifications subclassed it for the archive, and comms_message_outcomes built that UI envelope with str(comms.root) only to reach read_as. - notification_reads.py (new): NotificationRead(UiRead[NotificationWindow]) with changed_since; frozen LiveNotificationRead(references) and RecordedNotificationRead(references, source). Two members: archive identity and the change rule differ (live activity/evidence vs history revision). The module sits outside notification_read.py because presentation imports that module and bus_read imports presentation. - NotificationsRead and UnreadableNotificationsRead move unchanged into notification_read.py beside CapturedNotificationWindow. - ReadNotifications(ReadRequest) keeps root and request_id and carries operation: NotificationRead; it is no longer a UiRead. read() delegates to the operation (OperatorReader). ReadRecordedNotifications is deleted. NotificationReading asks request.operation.changed_since; read states stay keyed by the whole request. - CommsMessageOutcomesTool reads LiveNotificationRead((reference,)) under its caller; refusal, visibility, paging and its public schema are unchanged. - Callers migrated: observer fixtures carry LiveNotificationRead(()), test_thread_read_results reads the operation instead of a fake UI root, read-state tests call the operations. New controls: family/codec/pickle and request identity, archive change drops state, root validation per envelope, capability discovery, a foreign operation refused; a 125-message live batch across two window chunks; the recorded operation reads the archive (not live evidence) and a detached key refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
|
debt-src at a678243, every finding: |
…e says what it returns (#3538) NotificationsRead.activity spelled "this participant has no projection" twice: absence from the window's watched names, and a None value. observed_activity already omits registered humans and archived rows and answers DeletedThread for a deleted name, so the None was a second encoding of absence. - activity is Mapping[str, ObservedActivity | DeletedThread], keeping only the window's names that the projection actually returned. - live_changed re-projects the window's full activity_names() when ActivityView moved and compares the sparse maps, so omitted->observed, observed->omitted and observed->DeletedThread still invalidate. With no ActivityView change it does not project at all. - HistorySource.notification_references annotates references as Sequence[MessageReference] and returns NotificationWindow, the type MessageNotification.read_references already returns. That closes the Any that reached RecordedNotificationRead.read_as. - The read-state fixture that built {absent-participant: None} now settles a real #team read whose participants are an agent, a human, an archived agent and a deleted agent. New controls cover: omitted humans and archived agents, an archived agent declared again, a deleted participant, and zero or one projection by revision kind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
trissim
marked this pull request as ready for review
October 28, 2026 12:57
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
NotificationWindow.activity_names() comes from native-recipient outcomes, so the
#team fixture watches worker, archived and gone, never the agent sender or the
human. Two assertions expected sender and human, and failed in the root run
(29 passed, 2 failed). The window-names test now requires exactly
{worker, archived, gone} and excludes sender and human; only archived is omitted
from the sparse activity. The projection-count test requires archived as the one
watched-but-omitted name. No production change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…e no acquired evidence (#3538) A recipient-scoped thread read selected every claim of each broadcast by wire_seq alone, decoded them, and filtered recipients only afterwards: the saved six-tab desktop held 17,681 claims to show 15 rows. The same acquired graph (frozen audiences, decisions, WakeAssignment and activity rows) then travelled inside ThreadPresentation to the UI, twice over, through notification_window and through each notification's message, which was the backend record itself. Viewer captured once: - NotificationAssignmentRead carries its required OutcomeViewer. read, capture, missing_store and invalid_store take it, and the public missing store returns an empty read with that viewer; the private one still refuses. - capture builds the visible (recipient_lookup, wire_seq, message_id) keys through the viewer before any SQL. Claims are selected through the recipient/seq index by those keys, using TypedTable.requested_keys (factored out of select_keys, which now consumes it). HarnessDelivery.for_recipients gets the same keys. Rows keep the original wire_seq DESC, recipient order across batches. - delivery_window, project_delivery_window and for_sources read the captured viewer instead of taking a second one. for_deliveries skips invisible recipients before allocating an UnrecordedNotificationSource, and recorded_delivery_window allocates no placeholder activity for them. - NotificationAssignment.changed groups retained reads by their own viewer and re-reads each group's sources as that viewer. - SelectedParticipant captures its sent read as OwnerOutcomes of the owner, so the sender still sees every outcome. Public envelopes: - ThreadPresentation.with_sources and MessageNotification.for_sources attach source.envelope, the declared public Message, instead of the Delivered record. Acquired versus published: - ThreadPresentation keeps only the UI fields: status, binding, notifications and read_identity. - AcquiredThreadPresentation adds incoming_references, sent_references and notification_window. It is built by with_sources, supplies revision inputs and sent_summaries (replacing SentMessageSummary.recent), and published() derives the base from the declared fields. Pickling it raises a TypeError naming published(). - ThreadReadResult.published() defaults to itself and ThreadPresented projects its presentation. ThreadReading keeps the acquired results for its next change check and publishes only the changed results' projections. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ations (#3538) - test_outbound_transcript_source: - each recipient's own read decodes exactly one claim row (profiled AssignmentActivityEvidence._decode_row), equal to that recipient's rows and attempts in the operator read; the sender read equals the operator read; - invisible recipients allocate no UnrecordedNotificationSource, and the sender keeps all of them; - one claim transition refreshes only the retained reads whose viewer sees it: the recipient, sender and operator reads, not the other recipient's. - test_recipient_activity_index: - a viewer follows frozen lookups through rename and never into a rebirth; - a public root without a coordinator returns an empty read with the same viewer and projects only visible recipients; - a private root without one still refuses. - test_thread_read_results: - ThreadReading retains the AcquiredThreadPresentation and publishes its ThreadPresentation projection, with the same status, read_identity and notifications, whose messages are public envelopes; - the pickled observation carries no acquired evidence type, and sending the acquired result is refused; - after a second change, the UI's current and last-published rows reach no acquired evidence. - test_thread_presentation: absence publishes itself and summarises no sent message; its notification_window assertion read a field absence no longer has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
…ch and null-key controls (#3538) presentation_fields() returned dict[str, object], so expanding it into ThreadPresentation(...) and AcquiredThreadPresentation(...) erased every field's type: 10 new arg-type errors at thread_presentation.py:287/311. It is deleted. - with_sources builds shown = replace(self, notifications=..., read_identity=...) once and constructs AcquiredThreadPresentation from {declared.name: getattr(shown, declared.name) for declared in fields(ThreadPresentation)} plus its three acquisition fields. - AcquiredThreadPresentation.published constructs ThreadPresentation from the same inline mapping over itself, the ThreadStatusDisplay.status_display shape. There is no cast, Any, ignore or copied field roster. - test_outbound_transcript_source::test_a_forced_key_batch_captures_the_same_evidence_through_the_recipient_index: - setup: a second real #team original in the private _root fixture gives at least 4 distinct claim keys, plus a repeated original; - batching: on the fixture's own coordination connection, SQLITE_LIMIT_VARIABLE_NUMBER=6 (restored in finally) forces several key batches, with deduplicated bindings equal to the unlimited batch; - result: the whole capture equals the unlimited read in rows, attempts, evidence, order and viewer, with no duplicated assignment; - index: the traced claim statements' EXPLAIN QUERY PLAN SEARCHes wake_claims through the unique recipient_lookup/wire_seq index found by PRAGMA, never a SCAN of it. - round2 test_declared_table_family: select_keys selects the weight=None child through a None key once, even when the key is repeated, and stops selecting it once the weight is 3.25. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RnH6dS2Kmg1WxNnAc78YHA
# Conflicts: # src/agent_comms/installer/runtime_resolution.py
same_identity hand-compared recipient_lookup and canonical_thread, which FrozenRecipient already declares as its fields; it existed only because the direct-read path built a bare FrozenRecipientIdentity that dataclass equality would not match. Build the audience entry there, delete same_identity, and ask membership with not-in. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RecordedGoalHistory is the goal-history tool's reply once the GoalHistory wrapper is gone, so it is a ToolResult; WakeOnlyMonitor.confirm returns the MessageReference tuple MonitorEvidence declares. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # src/agent_comms/child_process.py # src/agent_comms/integration.py # src/agent_comms/owner_connection.py
Main (#3589/#3661) owns the commander wake on every bridge and hands the Monitor the original message, so the branch's Claude-only wake override goes, and with it WakeOnlyMonitor, the PendingMonitor family it was the second member of, the reception parameter threaded through monitor.py and shared.py, and the frame's displayed body. Their one test goes with them. CommanderUnitDetail is both the comms_commander_unit tool reply and a disclosed record, so it inherits ToolResult and DisclosedRecord. commander_pings imports the DeliveredOutcome main's notice returns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TestedSources.validate refused whenever live main differed from the tested merge's base, so on a fleet that merges every few minutes the PR's own base and debt jobs died with 'main moved; recapture' before measuring anything (two consecutive runs on #3566). The event owns the freshness answer: require_current_mains stays on TestedSources for the merge group and main push, and PullRequestSources answers that its captured bases stand, since the merge group re-proves currency before anything lands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Narrowing RegistrySnapshot.recipient to FrozenRecipient broke the observe_recipients caller (agent_activity.py:181, TypeErrors +1), and narrowing the evidence path instead would import audience_manifest into notification_evidence, a cycle. FrozenRecipientIdentity is the declaration that stays free of the projection writers; every runtime recipient is the FrozenRecipient audience entry, so membership still compares dataclasses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 30, 2026
trissim
disabled auto-merge
October 30, 2026 09:17
trissim
marked this pull request as draft
October 30, 2026 09:17
trissim
added a commit
that referenced
this pull request
Oct 30, 2026
debt-src/debt-tools named them (run 41028710035): I001 blocks, E501 lines, Black-dirty new files, F401/B007 in tools/module_layers.py, and B008 on the frozen page-window defaults. LatestPage, AtFrontier and LivePageSource are frozen value types, so ruff's flake8-bugbear immutable-calls owns that fact. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbFMSoWgC3ZwKzjT4SwMDu
trissim
added a commit
that referenced
this pull request
Oct 30, 2026
# Conflicts: # src/agent_comms/tool_caller.py
trissim
added a commit
that referenced
this pull request
Oct 30, 2026
The first pass fixed the ten files GitHub's annotation cap showed; the gate's full list named 32 more. Safe ruff fixes, Black on #3566's own line ranges only, explicit strict= on batched, unused loop names, no-op hooks that say so, wrapped strings. FirstRecipient and RecipientLimit are frozen values, declared in ruff's immutable-calls beside the transcript page defaults. Every changed src/tools file now has no more ruff findings than main and no Black-clean file on main became dirty. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbFMSoWgC3ZwKzjT4SwMDu
trissim
pushed a commit
that referenced
this pull request
Oct 30, 2026
…rders ReadCommanderUnit was deleted by #3566; main's test kept importing it, so the module failed at import. It now builds ReadOperation(root, CommanderUnitRead). OperatorReader only forwarded outcome_viewer to its DisplayCut: OperatorOutcomes is now the ReadAuthority, so the cut itself is the reader. BusRead.apply only renamed read_as: one abstract apply remains, the name the tool boundary calls. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XbFMSoWgC3ZwKzjT4SwMDu
This was referenced Oct 30, 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.
Source correction at 7924d42 — four files, +52/-42
This is an additional source checkpoint, not merged/installed/application acceptance. All prior source, review history, failures and unfinished P904/P942 obligations below remain retained at their original revisions.
ThreadPresentation.with_sourcesimports its consumer and activity module inside the method; the reader/presentation cycle exists at runtime. After:TranscriptSourceWindow.presentation(transcripts.py:646) owns acquisition/projection from its captured incoming and sent references;ThreadPresentation.read_sources(thread_presentation.py:251) consumes that behavior. Removedwith_sources, its three local imports, the unused window import and the no-longer-used absent-member override. The window now does its own work instead of phoning itself for directions.RequirementMarker(installer/runtime_resolution.py:376) decodes the external packaging Marker/null value once per requirement selection through MRO-declared handlers; both actual requirement readers use it. DeletedStackSources.requirement_activeand the foreign marker absence decision. Marker evaluation, extras and unmarked-requirement semantics are retained.ParticipantIdentity.require_canonical(participant_identity.py:26) retains its exact full-match regex and refusal, removing the nullable-match comparison; this is leaf text validation, not domain-state dispatch.with_sourcescaller. Four edited files parse;git diff --checkexits zero. Own correction is +52/-42, not the carrier's whole accumulated diff. Both existing remote refs read back exactly7924d42cc9f1dc0cc383552fa5e05e4c4f16ac8f.Summary
122 commits; 171 files; +10,344 / -2,291 against main
71840842f. This is the durable Core queue/notification carrier for P872, P883, P904 and P924, paired with ToAD #1319 at3a864eb45855f80f7271582ae98ab33404bc844f. Latest correctiond09e763b6is 1 test file, +2 / -0: prepare both heads on the fixture's existing Git reader before identity comparison. The precedingf8d56de40corrects 3 test files, +7 / -7: fixture URL and filesystem consumers use existingSourceRepository.remote_path, not remote aliasorigin. Production is unchanged by both corrections; the six ownership repairs at7035ada68remain carried. Main71840842fis included by normal merge. Current Core source head:d09e763b6f5b08c39e627e71bd288d5dbaf35206.This is published source, not a claim of merge, installation or live UI acceptance. The final paired application qualification remains with the integration owner. Older source approvals and test runs do not approve this head automatically.
Read authority and display ownership (P872)
Before: UI/MCP/owner entrypoints reconstructed read authority,
OperatorReadercarriedDisplayIdentity | NoDisplaySelection, and a class-bodyTYPE_CHECKINGannotation pretended to ownThreadReadTool.thread.After:
ReadAuthorityowns the caller-side read contract inread_basis.py; the SQLBusReaderremains a different acquisition role.ToolCallerandOperatorReaderinheritReadAuthority.DisplayIdentityandNoDisplaySelectioninheritDisplayCut; no-display behavior derives throughOperatorOutcomesrather than a duplicate return path. All members useoutcome_viewer(registry: Registration), with no catch-all parameter. Empty slots on both bases preserve the slotted display values.OwnerLiveReadinherits the realThreadReadToolfield. Runtime owner requests use the existing request declaration.NotificationReadowns live versus recorded notification requests;ReadNotificationscarries the operation andDisplayCut, not a second sibling union.Deliveredresolves through its realbus_publicationdeclaration. ToAD importsReadNotificationsfromui_model.observation; nonotification_readscompatibility export was added.bus_read.py's latest repair removes 73 lines and adds 16.notification_reads.pyremoves 27 and adds 11. These are deleted competing contracts, not compatibility aliases.Transcript source and painted-read lifetime
Before: nullable archive strings chose identity classes, position and through-cursor checks independently decided readability, and clients used
cursor is Noneto infer whether compaction needed a commit.After:
PageSourcehasLivePageSourceandRecordedPageSource(HistorySourceKey). Each acquires its namespace and produces the correct read identity.ResolvedPageSourcecarries the acquired stores.HistorySourceKeyhas its own nominal codec; archived notification and transcript requests carry it rather than an untyped identity string.PagePosition/PageLimitcarry latest/earlier/later/frontier/through behavior.TranscriptCursor.require_readableowns the runtime-and-offset contract.TranscriptReadIdentity.page_sourcederives the next request's source. ACP and observation consumers use the same family.requires_commit()rather than probing absence.TranscriptCursor.painted_read(callback, nothing)chooses acknowledgement work before a worker or write context is opened.UnreadTranscriptCursorreturnsnothingwithout calling the callback. A no-op after acquiring SQLite was too late.The unrelated Pi durable-store pagination token remains nullable: it is not a
TranscriptCursoror a commit decision. The review's original broad grep was corrected on that source evidence.The main transcript repair removes 85 lines and adds 75; the later painted-work dispatch adds nine lines. No old cursor-argument API or archive-string compatibility path is retained.
One response and one consumption fold (P904/P924)
Before: the publication producer and reply display scope separately decided who owed an answer; harness attempts and stored inputs were kept in parallel maps; optional answer references and optional timestamps could disagree.
After:
Message.awaits_answer_from(ThreadTarget)owns the obligation. Publication andRepliesDisplayScopeboth invoke it.ConsumptionEvidenceis implemented by the actual monitor/context facts.SourceEvidenceandNotificationAssignmentReadeach have one consumption mapping and one fold.RecipientSelection.entriessupplies the frozen key with its recipient. Native-input capture reuses it.AnsweredProgress(proof, response: AnsweredResponse)owns the sole reply fact.MessageNotification.answeris a derivedAssignmentResponseproperty; the separately stored field and disagreement exception are deleted.ContextualProgresspreserves an underlying answer while retaining its independent evidence. Workflow completion (CompletedProgress) is not itself proof of a reply.detail_texts()dispatches on the response, andAnsweredProgressderives its time label from the response it owns. The independent optionalanswered_at_msfield is deleted.NativeInputContext.context_columnsderives context-column construction from the existingFieldCodecplans andNativeContextdeclarations. The native writer no longer repeats a five-field wrapper roster or manually encodes the session-entry ID.Wake presentation must not change message identity
Before:
ClaudeBridge.wakeusedreplace(message, body=...)to present a short wake notice. Delivery storage then saw a different content-derived message ID from the original attempt. The wake-specific reception path made that retained-row mismatch visible; adding an evidence parent to the row was not a valid explanation for changing its key.After: the original
Messageis retained.PendingMonitor/WakeOnlyMonitorown the displayed frame body. The otherwise-unusedBoardWakeparent is deleted:WakeOnlyMonitorowns its notice text, and the collision control reads that actual owner instead of requiring test-only inheritance onClaudeBridge.MonitorIncomingFramecarries the reception member. A wake cannot become proof that the original packet entered model context, including when its text happens to equal the original body.Qualification and merge permission remain separate (P883)
IntegrationCheckout.materialize(source, repository, path)owns creation and preparation.IntegrationSourcetakes the nominalSourceCheckoutcapability for its irreducible preparation behavior;head_reviewno longer importsintegration, even underTYPE_CHECKING. The integration/todos import is module-level.toml_config_types["mypy_path"]lookup. It uses mypy's actual typedOptionsand native parser, retaining absent-versus-empty overrides and upstream string/list conversion. Parser diagnostics fail rather than silently selecting fallback roots.Native proof schema and resumed caller closure
The first attempted move at
144d49ed7was broken: making the journal inherit its file joined TypedTable and FILE family roots, and a real fresh import raisedTypeError: A declaration cannot belong to two families.That bad relationship is deleted, not hidden by a delayed import.Current structure:
NativeContextJournal(..., DurableTables)remains a table.NativeInputProof(DurableFile, ReconciledFile, PatternFile, DurableTables)is the file/schema owner;table_schema()returns the file class andschema_rows()declares(NativeContextJournal,). Neither family inherits the other. The filename, table, fields, indexes and guard are retained. Session files and bus-file controls consume the actual file owner.Core's transcript helper now consumes
operation.page_source; display controls pass their actual registry; the wake collision control uses its actual monitor owner. The native proof-context fixture is namednative_source, distinct from the deleted archive-selection API. The unrelated retained-result keyoriginal_historical_source_proofsis not an API alias. The two app/support callers originally attributed to Core belong to ToAD; its owner migrated them on #1319 at3a864eb4, without a helper or alias.Six retained P904 findings: declaration and consumer closure
arrival_count/arrival_label/input_detailmethods become zero. The harness control now asserts real consumption rather than dead presentation helpers.MessageInputandObservedMonitorinheritTimestamped;at_msowns rounding and derives units fromEventMilliseconds. Independent replies and their controls consume that projection, instead of disagreeing betweenintandround.NativeIntegerBounds.maximum.PositiveNativeIntegerBoundsowns the positive interval. Context records, input references and file-write artifacts inherit the capability; SQLite checks and default generation intervals derive it. The input-reference encode/decode round trip is deleted; the nullable session value is narrowed at its boundary._verify_contextis deleted.ContextCommitted.record_fornormalizes the optional event against the requiredNativeContextRecorddeclaration.NativeEvidenceRead.verify_contextjoins the original input event with the normalized record and checks the acquired durable journal. Historical and private-send callers use that reader'scorroborates_contextmethod. Exact generation, context, identity, file and byte-position equality remain required.notification_evidence, not re-exported byread_basis. A fresh interpreter disproved the earlier prescribed direction.FrozenRecipientIdentity(ParticipantIdentity)owns the frozen pair and validation;FrozenRecipientadds projection-writing capability without dragging bus tables into the lower cursor. Native proof records no longer import session files, events or entry readers, even underTYPE_CHECKING; proof opening takes the actual path, and lineage comparison takesNativeInputLocation.RecipientLimit(SingleFieldValue)owns scalar decoding, minimum/maximum, validation and schema. The tool, live/recorded reads, history/presentation APIs and direct controls all consume it. The repeated tool/selection validations are deleted. External wire size remains an integer.The main merge retained the renamed Tristan notice on
WakeOnlyMonitor, its actual owner, rather than resurrecting a second copy onClaudeBridge.Native session-value continuation
Before: reference acquisition fed an already nominal
PiSessionIdthrough the codec again, and group validation decoded the same reference fields before acquisition repeated that work. The first continuation wrongly gave every genericNativeColumna session capability throughNativeSessionIdValue. That abstraction and the column behavior are now deleted.NativeInputContext.reference_session_idacquires its raw column through the existingNativeContext(PiSessionId)directive.NativeRuntimeInputoverrides with its actualNativeSessionSelection;PiSessionIdreturns itself and the absent member refuses required identity. The generic column no longer claims to know anything about sessions. The group validates remaining columns, deriving reference membership from the acquired reference's declaration instead of maintaining a field roster.The existing native-reference controls now check retained nominal object identity, cursor-text acquisition, empty/wrong-type session columns and prior partial-group cases. They are UNRUN on this head. My initial claim that the old nominal re-decode would reject the value was false:
NominalSpelling.decodeoverrides strict text decoding and accepts string subclasses. That claim was withdrawn in bus40493; this change removes redundant decoding, not a demonstrated live rejection.Notification source invalidation: reads three, watches three
The prior
notification_pathswatched only coordinator commits whileNotificationAssignment.capture_detachedalso acquired independent bus replies and stored inputs. An open notification interest could therefore remain stale after those sources changed. MEMB-2: fact = notification evidence sources; atpresentation.py:799; derive by declaration onNotificationAssignment.source_paths(notification_assignment.py:173). That owner now declares coordinator, bus and input-disposition commit signals once;WireRevision.notificationsderives them. The registry dependency remains on its existing revision field.RecordedNotificationReadnow inheritsNotificationReaddirectly: live and recorded operations are siblings, not a false live subtype that overrides every live behavior.Two controls in
tests/test_notification_observation_sources.py, subsequently passed by root at6e1714992, keep a realObserveNotificationsinterest open throughObservationServiceand real pipe frames. One commits following-input model context only; one publishes an independent reply only. Both assert the coordinator signal stayed unchanged, inspect the refreshed actual outcomes and confirm another unchanged observation sends nothing. The input case checks exact context time without inventing a reply; the reply case checks the exact original response without inventing consumption. Shared private-root retirement is retained. Root's pass covers pipe observation, not filesystem watching or the installed application.Explicit Git acquisition: delete nine calls to the removed branch API
Hosted base job 40953172544/123726343570 failed at
integration.py:401before paired-source qualification:WorkBranches.require_commitsno longer exists. The whole-call inventory found six stale calls inintegration.pyand three inhead_review.py, not merely the two initially identified. All nine now callRepo.require_commits(checkout, repository.remote, exact captured commits), whose existing implementation atrepo.py:191fetches only missing commits and validates them. Branch/parent/message readers remainWorkBranches; there is no restored alias, fetching copy or relaxed gate. Removed the now-unused local branch reader fromMergedIntegrationSource.expected_tree.The existing actual ordinary-CI and combined PR/queue controls now create the synthetic tested merge only at their real local Git origin. They assert it is absent locally before acquisition and assert exact tree/parents after checkout creation. Existing companion materialization, current-head revalidation and no merge/promotion-write assertions remain. A new control refuses a foreign-origin-only commit and an unavailable commit without creating the destination or changing local HEAD/tree or remote refs. These changed/new controls are UNRUN; root owns their continuation selection:
tests/test_integration.py::test_actual_ci_cli_uses_verified_carrier_not_synthetic_message_and_revalidates(both events)tests/test_integration.py::test_actual_ordinary_ci_cli_captures_main_once_and_never_steals_an_unlinked_overlaytests/test_integration.py::test_integration_checkout_refuses_commits_absent_from_its_own_originThe retained targeted NRA syntax map and whole-src/tests/tools call inventory establish the owner/caller closure. No full-corpus rescan, import matrix, test, checker, provider or runtime operation was run for this correction.
Prepared-reader correction at d09e763
Root's continuation at
f8d56de40: 9 passed, 1 fixture failure, 2 root UV setup errors in 111.63s; 2 parameters unexecuted after maxfail3. The three original URL failures now pass. The remaining source omission wastest_companion_input_changes_the_identity_of_an_unchanged_local_patchcallingchange_identitywithout preparing its existingWorkBranchesreader.tests/test_head_review.py:549–550now callsreader.prepare_pull_request("main", head.head)for both actual local heads before reading identities. This captures the real remote publication through its existing owner; no lazy acquisition, fallback, guessed base, new reader or production edit. Unprepared publication reads still refuse. Root corrects its own UV interpreter setup and runs only the five remaining failed/setup/unexecuted cases, carrying the nine passes and earlier first pass. Author ran no controls. Git publication preparation now precedes the read; chronology is an underrated dependency.Fixture URL correction at f8d56de
Root's changed-owner run used combined Core
946a65a83and ToAD57e235e9: one passed, three failed at the fixture URL, eleven unexecuted after maxfail3. It did not reach the three failed cases' source-status behavior. The retained stack really containedgit = "origin"; production correctly refused it.tests/integration_source_fixture.py:86now writesclient.remote_path.as_uri(). Both plugin/client URL consumers attests/test_checker_stack.py:170/:175use the same owner. The whole-tests remote inventory also found four filesystem consumers intests/test_source_revision.py:52/:57/:58/:65: those now passsource.remote_pathas Git's working directory. The actual Git remote argument remainsorigin;SourceRepository.remote_path,Repo.acquire, validators, unknown UV settings, subdirectory and both-cut/incompatible-environment controls are unchanged. No second property or alias was added.Author execution: no tests, checkers, builds, provider, runtime or installer. The first continuation selected only the three failed and eleven unexecuted cases, carrying the passed first case unchanged; its newer result and remaining five cases are recorded above. The existing source publication control additionally changed is
tests/test_source_revision.py::test_seeded_source_publishes_descendants_and_merges_main_without_replacing_a_pr; root decides whether to include that exact newly corrected consumer. The earlier 35-Core pass and 12-ToAD partial run retain their original revision and interruption limits. Neither this fixture patch nor the growth table proves installed queue behavior.Review corrections retained from 7035ada
HeadVerdict.recordingattodos.py:4141owns merge withdrawal, source withdrawal, recording and final publication for both ordinary and carried verdicts.begin_review, the overriding secondpostpath and unboundHeadReview.postare deleted.UnderReviewHeadVerdictneeds no repeated final pending publication. Decided verdicts publish once after the record. Two permissions still require two pre-record withdrawals: the existing failed-permission-write and failed-final-rejection controls remain intact. This corrects the review's unsafe request to withdraw only merge permission; the counterexamples were supplied in native messages 41617/41631.LocalIntegrationSourceathead_review.py:259owns actual tested-head materialization and local ordinary-carrier validation; companion members retain their own reconstruction.IntegrationInput.localrequires exactly one local member andcompanionsderives membership from source declarations. Creation, validation, capture, canonical codec fixture and materialization consumers are migrated. Source-role selection no longer uses repository equality. Repository identity equality remains where it validates actual origins/carriers, not where it selects behavior.Repo.acquireatrepo.py:201derives this repository's checkout and remote. All nine corrected integration/head-review callers now use that instance. The explicit-remote class API remains for its real distinct use.OwnedTurndecodes its incoming session identity atowned_turn.py:140;OwnedSend.session_idcarriesAcpSessionId. Both consumer constructor casts inturn_input_source.pyare deleted. The existing native following-input route is unchanged; no queue or delivery API was added.StackSources.local_packagesatinstaller/runtime_resolution.py:422reads the actual source declarations once through its existing boundary. Both runtime compatibility andCheckerStack.local_namesconsume that owner; the separate hard-coded Core membership is deleted. A new control covers both documents, normalized spelling, branch/path sources and excluded registry entries.IntegrationFailedarm is removed from the catch whose parentToolRefusedErroralready covers it.ModuleBindingsoptimization and new old-scanner guard were removed with a revision-checked reverse patch. Compared against published audit Test the public fields that pinned Toad builds read from agent-comms #7d7401d6:scripts/audit/lexical.py:165ownsModuleScope, cached scope/declaration facts and decorator binding. Core debt_ratchet.py is only the CI entry; the pinned audit owns every measure #3606/claude-nra owns the replacement pin. No scanner wrapper, competing lexical owner or restoration of a deleted path was added. The obsolete local patch is retained only as review evidence in owned scratch.3a864eb4. That declaration is not a claim that hosted capture has selected it: the integration owner must read the actual captured SHA. Core-alone landing remains forbidden.All current controls are UNRUN by the author. Root's changed-owner continuation includes the two retained failure controls (
test_failed_permission_withdrawal_preserves_the_preceding_source_record,test_failed_final_rejection_status_leaves_the_member_pending_not_old_green), changed reviewing/qualification publication controls, local/companion canonical input and capture/materialization controls,test_local_package_membership_comes_from_both_source_declarations, and the acquisition controls listed above. No unchanged 35-control rerun, author checker, environment, provider, UI, service or installer action occurred.git diff --checkpassed. Both carrier refs were read back at the current head; the tree was clean after publication.Evidence
Root at previous
6e1714992: 35 selected Core controls passed in 17.53 seconds, including both new observer pipe controls, native references, ordinary/following proof, viewer/source provenance and generic partial-index/schema cases. This does not prove filesystem wakeup, real retained-store carry or installed behavior. Paired ToAD3a864eb4selection passed 12 cases before its 160-second limit interrupted the remaining queue cases; no clean full-head OK. The failing required hosted base above still blocked qualification; it is the reason for4a27c246a, not an environment excuse.Historical
6e1714992imports: eight independent fresh-process imports passed:native_input_proof,cli_bridges.shared,transcripts,bus_read,notification_assignment,read_basis,native_entries,pi_events. Reverse import order also passed after the main merge. This is import/binding evidence, not test or application acceptance.Historical
6e1714992syntax corpus: 1,842 modules, 8,570 classes, 33,204 selected sites, zero parse omissions; per-file hashes recorded. Core src/tests/tools are paired with immutable Git blobs from ToAD3a864eb4, not the author's reused checkout. This is not a debt score or a complete dynamic-binding proof.Exact paired ToAD source/test search found no callers of the deleted native helpers or qualified old viewer APIs. Locks are byte-identical to published
3a5e351a8(uv.lock0f41cbc2…; stack lock5bc260ec…).Earlier ordered six-file selection: 99 passed, 14 warnings, 75.39 s; exit 0. Includes real monitor delivery, automatic reply, following-context notification, historical notification, wake index and live-context notification controls. The board-wake exact-body-collision control remains intact. This predates the newer rule that channels never automatically receive finals: it does not qualify that rule or the permanent P924 Info-reply-loop repair.
Revision precision: pytest loaded
22c0ef74e; the subsequent nine-lined06847ad0cursor dispatch addition was published while that run was active. Its dispatch, the nominal archive codec and required imports were checked separately in a fresh process. Do not describe the 99-test result as a fresh full selection atd06847ad0.The earlier required four-module imports passed in forward and reverse order, and native mypy-options acquisition passed. These were before the resumed correction; they are not fresh import or runtime proof at
144d49ed7.AST map: 938 modules, 7,720 classes, no parse omissions. The final paired ToAD source root differs from the initial frozen root; these totals are coverage, not a before/after debt score. Dynamic
ResolvedPageSource.identityconstructors and protocol callbacks were traced semantically; this syntax census does not prove all interprocedural bindings or runtime execution.if TYPE_CHECKING: 271 current / 272 main. Nohistorical_source,TranscriptCursor | None,displayed_cursor is Noneorwork_cursorremains in Core production.Resumed AST coverage: retained map of 1,520 Core/test/tool/paired-production modules, 8,402 classes, no parse omissions. Targeted reproof at
144d49ed7parsed the 18 changed Python modules (267 classes, 359 selected sites, no parse omissions); no second full scan. Syntax evidence is not dynamic binding or application proof.Both carrier refs read back at
6e17149921b3f0617e8218a65fa4ed532ca19536. Existing Queue/notification UI, Core: integrate P872, P883 and P904 read operations #3566 remains the carrier. P883's released review/history was not rewritten. Earlier holder updates were refused while the order was under review. After the actual send-back, the corrected P904 delivery claim was recorded on order89c621070727at this head (messagec870115ffe15). That claim is not acceptance. Current-pair qualification and application proof remain open.No author pytest, checker, environment, provider, service or install operation ran under the resumed order.
git diff --checkand source inspection are not test acceptance.The retained hosted debt-tools run 40915225731 reported 14 new client diagnostics in seven ToAD files; debt-src was cancelled. They are old-pair diagnostics, not a current-head success or a demonstrated current-head failure. Current paired qualification belongs to root, without aliases to preserve obsolete client APIs.
One initial test invocation collected zero because an extra outer lease duplicated pytest's existing lease owner. That wrapper was removed; it is not counted as a test result.
Warnings include pytest trying to retire pre-existing foreign DQDock bind snapshots under
/tmp/pytest-of-ts/garbage-96d90360-4e92-4438-8a4d-7b9bf512a204and receiving EBUSY. Those mounts and their source data were not deleted or unmounted by this work.Retained source maps, consumer searches and result logs:
/home/ts/.cache/agent-scratch/queue-core-fix/. One-shot migration source was deleted after application.Remaining acceptance
The integration owner must review Core
d09e763b6with ToAD3a864eb4, include the current P872/audit replacement through its existing owner, execute only the five remaining failed/setup/unexecuted changed-owner cases above and require hosted base to reach actual qualification. Do not rerun the unchanged 35 Core controls as reassurance. Root also owns the unfinished ToAD queue-case diagnosis and current-pair debt/application qualification. Changed risks: fresh forward/reverse imports and persisted codecs; native proof file/schema membership, unchanged generated native contract and existing partial-index carry; integration/head-review materialization; open-window input-only/reply-only controls (tests/test_notification_observation_sources.py), native reference/session-value and partial-group controls (tests/test_native_context_reference.py); transcript pages and viewer-boundary controls; wake collision; historical/live/following independent replies. Existing 27/13 fixture corrections remain carried, not rerun here.P904 stays an application order. Ordinary/following/grouped model context must show Consumed with its actual time before the answer; weak acceptance/transcript persistence is insufficient. Original-reference/recipient/birth and source fences, arrived/waiting/unknown/passive facets, independent replies, exact context-ack equality and bounded pre-join windows remain required. Raw human read marks/unread/other viewers remain unchanged while the source-matching viewer's self-read is omitted only from the display. Root still owes archive/rename/recreated-incarnation controls, the real declared-index carry rehearsal and the installed copied-session mailbox/channel/DM common-queue journey. Source/agent mismatches refuse before mutation; unsupported actions remain explicit and programming errors escape. No original or uncertain input may be replayed.
No merged, installed, current-checker-green or whole-feature success is claimed. No live package or saved user session was modified.
The row did not go anywhere. We sent its stunt double.
Growth
Measured by the existing
WorkBranches.source_growth/CodeLines.ofowners against immutable main71840842f683e7453cdb0b635fb443671a5e5ab8at headf8d56de408858035ff8b82f4fe064a6884408994. 56 growing production files; +2,570 positive code lines; +2,072 net production code lines. Code lines exclude leading imports, module docstrings, comments and blanks; these are not physical diff additions. The earlier estimate of 57 files is not substituted for this exact owner result. Each row names the gained mechanism, including moved behavior; growth alone does not prove a new semantic authority.Production is byte-for-byte unchanged between measured
f8d56de40and currentd09e763b6(git diff --exit-code f8d56de40 d09e763b6 -- src/agent_commsreturned 0); the final commit changes only the fixture preparation above.src/agent_comms/agent_backend.pysrc/agent_comms/backend.pysrc/agent_comms/bus.pysrc/agent_comms/bus_read.pysrc/agent_comms/bus_tables.pysrc/agent_comms/child_process.pysrc/agent_comms/cli_bridges/monitor.pysrc/agent_comms/cli_bridges/shared.pysrc/agent_comms/cli_verbs/merge_review.pysrc/agent_comms/commander/judge.pysrc/agent_comms/connector.pysrc/agent_comms/following_inputs.pysrc/agent_comms/harness_delivery_states.pysrc/agent_comms/head_review.pysrc/agent_comms/historical_views.pysrc/agent_comms/history_views.pysrc/agent_comms/input_attempt.pysrc/agent_comms/input_disposition.pysrc/agent_comms/installer/runtime_resolution.pysrc/agent_comms/integration.pysrc/agent_comms/messages.pysrc/agent_comms/native_entries.pysrc/agent_comms/native_input_proof.pysrc/agent_comms/native_integer.pysrc/agent_comms/native_prompt_send.pysrc/agent_comms/native_runtime_input.pysrc/agent_comms/native_session_reopen.pysrc/agent_comms/native_transcript.pysrc/agent_comms/notification_evidence.pysrc/agent_comms/notification_progress.pysrc/agent_comms/notification_read.pysrc/agent_comms/notification_reads.pysrc/agent_comms/order_tools.pysrc/agent_comms/owned_send.pysrc/agent_comms/owned_turn.pysrc/agent_comms/owner_connection.pysrc/agent_comms/participant_identity.pysrc/agent_comms/phase_evidence.pysrc/agent_comms/pi_commands.pysrc/agent_comms/pi_events.pysrc/agent_comms/pi_native_backend.pysrc/agent_comms/private_send_claim.pysrc/agent_comms/private_send_stage.pysrc/agent_comms/private_sidecar.pysrc/agent_comms/read_basis.pysrc/agent_comms/recorded_time.pysrc/agent_comms/registry_provenance.pysrc/agent_comms/repo.pysrc/agent_comms/started_input.pysrc/agent_comms/thread_presentation.pysrc/agent_comms/todos.pysrc/agent_comms/transcripts.pysrc/agent_comms/turn_input_source.pysrc/agent_comms/turn_inputs.pysrc/agent_comms/typed_table.pysrc/agent_comms/work_branches.py