Skip to content

Declare caller-owned types in the eight heaviest Toad modules - #1148

Merged
trissim merged 21 commits into
mainfrom
next/toad-types-05
Oct 23, 2026
Merged

trissim merged 21 commits into
mainfrom
next/toad-types-05

Conversation

@trissim

@trissim trissim commented Oct 23, 2026 •

Copy link
Copy Markdown

The eight selected modules now declare 420 formerly bare parameters against main aeef59ee093561b7a1e5a87d1f33ff952e8343ef. The complete projection consumer family is repaired as authorized; total src/toad reduction is 423. Head: 8d7a5be7ca537e9aa00b2818bc9eae244d5a094d. The branch includes current main; no ratchet baseline/configuration changes.

Original selected file Main unannotated Head unannotated
src/toad/acp/agent_process.py 53 11
src/toad/comms_root.py 56 14
src/toad/core/context_inspection.py 96 12
src/toad/transcript_preparation.py 53 17
src/toad/transcript_publication.py 56 12
src/toad/transcript_state.py 64 16
src/toad/widgets/presentation_window.py 94 19
src/toad/widgets/sidebar_tree.py 67 18
Original eight 539 119
All src/toad 2,000 1,577

Explicit Any remains 10. All 287 src/toad modules parsed without omissions. No previously annotated input from main was made bare. Genuine nullable inputs retain their old runtime defaults and become explicit IDEN-3 stops; no nullable annotation was invented for the count.

The three context defects:

  1. Wrong session-file argument — 09b9949. src/toad/core/context_inspection.py:547-552 now builds NativeSessionFiles through its existing for_identity factory, using NativeSessionIdentity.locate(thread.runtime.path), comms.root and the recorded owner. Caller now passes SessionRevision.observe(files). Callee: agent_comms/session_revision.py:59, observe(cls, files: NativeSessionFiles) -> SessionObservation; it reads files.session and files.input_proof. The old caller passed Thread.session_file: SessionFile, which owns neither resource. Test uses Core's create_fresh_private_session and verifies a new owner-proof file changes the observation. Fixture follow-ups: 7ff7198, bd5989c.
  2. Deleted bus.log read — STOPPED, aa5804a. The dead read is SavedContextInspection.saved_manifest at src/toad/core/context_inspection.py:703-705. It is still consumed by stopped-thread Context explorer recorded text, working-memory detail/search, copy and export through the saved recorded_source/recorded_segment overrides. Deleting only those overrides would expose the live socket implementations through inheritance. Under the user's explicit visible-feature exception, deletion of this item is stopped; its newly added annotation was restored to bare and the original path is retained. It is NOT repaired or claimed deleted. No test directly covers that saved reader family, so no test was deleted. The shared live annotation/navigation tests remain.
  3. False projection return contract — 35a7df3, dadc3c9. Core MroDispatch.dispatch_sync preserves the input type. Toad's consume_handlers_sync override instead returned a class, node, tab, load plan or None. MroProjection[Result].project_value now owns first-handler projection and declares its result. The incompatible pipeline override is deleted. All seven direct consumers and nine call sites migrate; side-effect fragment projections preserve first-handler-only behavior. Result types are NativeSegmentNode, type[ContextInspection], OpenTab, type[LineRole], OwnerPlan and None. ExistingOwnerPlan's nullable result becomes OwnerPlan with AvailableOwnerPlan/UnavailableOwnerPlan; all four callers ask availability and obtain the exact existing Core plan. This removes the old nullable projection result rather than duplicating its union in a generic base. project_value is distinct from HistorySessionEntry.project, which is the directory path.

Projection family caller inventory (final source): owner_preparation.py, session_entry.py, core/context_inspection.py, widgets/session_details.py and widgets/transcript_fragments.py. No projection consumer still calls dispatch_sync. Ordinary identity-preserving dispatch consumers are untouched.

Verification: six focused projection cases pass, covering different output type, first-handler precedence, context forwarding, override binding, None results, unmatched input, and live/unavailable owner-plan results. The new actual ContextInspection.read test passes (1 case). All 15 changed production modules import under python -I and compile in the owned environment synced with uv sync --locked --all-extras --no-editable. Both focused files run together against locked Core 7017468028ea2428ce71fe30261aa8d827aa222a: 7 passed in 4.78s. No broad suite run. The original installed-runtime checks also passed, before this exact locked-environment run. Hosted result on this exact head is reported below before ready.

Dependency and test-layer corrections:

  • 077c680 changes uv.lock alone. Command: uv lock --upgrade-package agent-comms; no global --upgrade. Core resolves from 2e51f3b67 to 7017468028ea2428ce71fe30261aa8d827aa222a, current Core main when resolved (newer than 2ca56a535). Core's own declared metaclass-registry main source resolves to fb7c871a78c3087aa65c3a7199a1068cff858f33 as its required dependency. pyproject.toml and the ratchet remain unchanged.
  • Direct import proof in the synced environment: installed agent-comms direct_url.json commit_id equals the locked 7017468028ea2428ce71fe30261aa8d827aa222a. IncarnationThreadTarget imports from /home/ts/wt/toad-types/.venv/lib/python3.14/site-packages/agent_comms/channel_targets.py.
  • The new reader test lives in tests/app/test_context_reader_session_revision.py, moved in 8f5ef32. It asserts session/proof observation on a real workspace wire, not a pure model object. The original model-test file is unchanged against main. tests/guards/test_test_layers.py is untouched.

Every stopped parameter in the original eight files; nullable stops include the concrete None/default caller:

Declaration and parameter Missing capability / owner; nullable caller
src/toad/acp/agent_process.py:31 AgentProcess.__init__.agent Agent-facing session/controller/permission capabilities: Agent must declare a lower-layer capability composed by AgentProcess consumers. AgentBase lacks these attributes; importing Agent back through AgentProcess would close the existing cycle.
src/toad/acp/agent_process.py:53 AgentProcess.accepts_attachment.agent Agent-facing session/controller/permission capabilities: Agent must declare a lower-layer capability composed by AgentProcess consumers. AgentBase lacks these attributes; importing Agent back through AgentProcess would close the existing cycle.
src/toad/acp/agent_process.py:66 AgentProcess.start.agent Agent-facing session/controller/permission capabilities: Agent must declare a lower-layer capability composed by AgentProcess consumers. AgentBase lacks these attributes; importing Agent back through AgentProcess would close the existing cycle.
src/toad/acp/agent_process.py:98 AgentProcess.prompt.agent Agent-facing session/controller/permission capabilities: Agent must declare a lower-layer capability composed by AgentProcess consumers. AgentBase lacks these attributes; importing Agent back through AgentProcess would close the existing cycle.
src/toad/acp/agent_process.py:98 AgentProcess.prompt.content ACP prompt content: AgentController must produce the SDK block family that prompt.build already produces; its raw dictionaries have no shared decoded block parent.
src/toad/acp/agent_process.py:160 AgentProcess.read_text_file.line IDEN-3: SDK represents an omitted line as None. A nullable boundary parameter remains bare until its null-member owner is supplied. Nullable caller: ACP 0.12.1 acp/router.py:104-107 forwards model defaults; schema.py:48 declares line=None.
src/toad/acp/agent_process.py:177 AgentProcess.create_terminal.args IDEN-3: SDK represents omitted arguments as None; explicit nullable boundary stop. Nullable caller: ACP 0.12.1 acp/router.py:104-107 forwards schema.py:2899 args=None.
src/toad/acp/agent_process.py:177 AgentProcess.create_terminal.env IDEN-3: SDK represents omitted environment as None; explicit nullable boundary stop. Nullable caller: ACP 0.12.1 acp/router.py:104-107 forwards schema.py:2903 env=None.
src/toad/acp/agent_process.py:177 AgentProcess.create_terminal.cwd IDEN-3: SDK represents omitted cwd as None; explicit nullable boundary stop. Nullable caller: ACP 0.12.1 acp/router.py:104-107 forwards schema.py:2907 cwd=None.
src/toad/acp/agent_process.py:177 AgentProcess.create_terminal.output_byte_limit IDEN-3: SDK represents omitted output limit as None; explicit nullable boundary stop. Nullable caller: ACP 0.12.1 acp/router.py:104-107 forwards schema.py:2911 output_byte_limit=None.
src/toad/acp/agent_process.py:268 AgentProcess.stop.agent Agent-facing session/controller/permission capabilities: Agent must declare a lower-layer capability composed by AgentProcess consumers. AgentBase lacks these attributes; importing Agent back through AgentProcess would close the existing cycle.
src/toad/comms_root.py:121 Observation.failed.selected Selected/unselected route state: RouteSelection and UnselectedRoute need a meaningful shared route-state owner; no display union substituted.
src/toad/comms_root.py:133 Observation.attach.access Observation.attach invokes activate, but Observation does not declare that capability. Its actual subclasses must share the activation contract before this callback is typed.
src/toad/comms_root.py:133 Observation.attach.previous Same missing Observation.activate lifecycle contract; previously bare callback remains stopped as a whole, rather than invent an activation owner.
src/toad/comms_root.py:178 FailedObservation.write_order.root Actual nullable screen root from CommsSortControl.order_writer; no old parameter default. Route/root ownership needs a declared null member. Nullable caller: src/toad/session_sort.py:184 passes screen.coordination_root; src/toad/screens/session_view.py:48-49 declares its nullable result.
src/toad/comms_root.py:178 FailedObservation.write_order.channel Actual nullable channel from CommsSortControl.order_writer; no old parameter default. Channel selection needs a declared null member. Nullable caller: src/toad/session_sort.py:184 passes self.channel; :194 omits it, retaining the None default at :177.
src/toad/comms_root.py:190 FailedObservation.observe_sidebar.wanted FailedObservation.activate passes None. Sidebar-interest ownership lacks a declared null state; no original default exists. Nullable caller: src/toad/comms_root.py:188 explicitly calls observe_sidebar(None).
src/toad/comms_root.py:224 Observing.write_order.root Actual nullable screen root from CommsSortControl.order_writer; no old parameter default. Route/root ownership needs a declared null member. Nullable caller: src/toad/session_sort.py:184; nullable root result in src/toad/screens/session_view.py:48-49.
src/toad/comms_root.py:224 Observing.write_order.channel Actual nullable channel from CommsSortControl.order_writer; no old parameter default. Channel selection needs a declared null member. Nullable caller: src/toad/session_sort.py:184; None default retained by :194 and declared at :177.
src/toad/comms_root.py:271 Observing.views_changed.event CoreEventStream.subscribe erases the filtered OpenTabsChanged input to CoreEvent. The stream must retain the payload/subscription relationship. Nullable caller: src/toad/comms_root.py:239 calls views_changed() without an event.
src/toad/comms_root.py:271 Observing.views_changed.subscription IDEN-3: argumentless activation retains the original None default. The subscription owner needs an absent member. Nullable caller: src/toad/comms_root.py:239 calls views_changed() without a subscription.
src/toad/comms_root.py:296 Observing.observe_sidebar.wanted CoordinationAccess.update_sidebar_interest passes None when no interest remains. Sidebar-interest family lacks a declared null state. Nullable caller: src/toad/comms_root.py:525 passes wanted; :521 assigns None when interest ends.
src/toad/comms_root.py:308 AnsweringReads.views_changed.event Same filtered-event carrier contract gap; no fabricated broader input type substituted. Nullable caller: src/toad/comms_root.py:239 is the inherited activation call without an event.
src/toad/comms_root.py:308 AnsweringReads.views_changed.subscription IDEN-3: same subscription/default contract on this family member. Nullable caller: src/toad/comms_root.py:239 is the inherited argumentless activation call.
src/toad/comms_root.py:314 AnsweringReads.observe_sidebar.wanted Same nullable sidebar-interest request; no original parameter default or declared null-interest owner. Nullable caller: src/toad/comms_root.py:525 dispatches wanted; :521 assigns None.
src/toad/core/context_inspection.py:143 ReferenceNode.search_roots.current_roots ContextNode declares a static method while this override binds self; ContextNode.search_roots must align its descriptor/call contract.
src/toad/core/context_inspection.py:195 RecordedTurnNode.search_roots.current_roots Same static/bound descriptor contract split in ContextNode.search_roots.
src/toad/core/context_inspection.py:301 AnnotationNode.search_roots.current_roots Same static/bound descriptor contract split in ContextNode.search_roots.
src/toad/core/context_inspection.py:348 AnnotationSourceNode.search_roots.current_roots Same static/bound descriptor contract split in ContextNode.search_roots.
src/toad/core/context_inspection.py:432 SegmentNodes.messages.segment Messages plus segment operations: compose the capability on TranscriptSegment, CompactionSummarySegment and InjectionMessageSegment. NativeMessages and MeasuredNativeSegment are independent ancestors; neither owns both contracts.
src/toad/core/context_inspection.py:531 ContextInspection.read.cursor IDEN-3: initial explorer cursor is None. The caller-owned cursor family needs a null member. Nullable caller: src/toad/core/context_inspection.py:759-760 forwards cursor from acquire; src/toad/widgets/context_explorer.py:385-386 supplies self.intent.cursor, initialized None at :46.
src/toad/core/context_inspection.py:703 SavedContextInspection.saved_manifest.manifest VISIBLE-FEATURE STOP (TIME-6): stopped-thread Context explorer detail/search/copy/export depend on the dead bus.log read family. Deletion is stopped under the explicit user exception; its newly added input annotation is removed, original implementation retained. This read has NOT been repaired.
src/toad/core/context_inspection.py:749 InspectionState.acquire.cursor IDEN-3: same initial cursor passes through acquisition; no invented always-present cursor type. Nullable caller: src/toad/widgets/context_explorer.py:385-386 passes self.intent.cursor; :46 initializes it to None.
src/toad/core/context_inspection.py:806 DetachedInspection.acquire.cursor IDEN-3: same acquisition input contract on detached state. Nullable caller: src/toad/widgets/context_explorer.py:385-386 dispatches acquire on self.state with the same initial None cursor (:46).
src/toad/core/context_inspection.py:891 HoldingInspection.find.selected ContextTreeIntent.selected really can be None and had no old parameter default. Selection needs a declared null ContextNode member. Nullable caller: src/toad/widgets/context_explorer.py:545 passes selected from intent.selected at :480; :44 initializes None and :52 clears it.
src/toad/core/context_inspection.py:938 NativeInspection.receive_inspection.acquired Acquisition-state correlation: InspectionState.acquire/receive_inspection must declare when HoldingInspection inspection/revision are available. The current base also returns DetachedInspection; the override cannot truthfully narrow it.
src/toad/core/context_inspection.py:976 UnavailableNativeInspection.receive_inspection.acquired Acquisition-state correlation: InspectionState.acquire/receive_inspection must declare when HoldingInspection inspection/revision are available. The current base also returns DetachedInspection; the override cannot truthfully narrow it.
src/toad/transcript_preparation.py:63 PreparedTranscriptPage.__deepcopy__.memo External Python deepcopy memo: PreparedTranscriptPage.deepcopy receives Python’s heterogeneous identity memo. The general object contract is banned here; no truthful domain owner exists.
src/toad/transcript_preparation.py:74 PreparedTranscriptPage.measured.page Raw page operations: TranscriptPage, WirePage and UnreadTranscriptPage need a composed shared page capability. PreparedTranscriptPage is the prepared wrapper, not the raw page parent.
src/toad/transcript_preparation.py:74 PreparedTranscriptPage.measured.view Prepared-page constructor keywords: PreparedTranscriptPage.measured forwards **view with no declared keyword record; no production caller supplies kwargs from which to infer one.
src/toad/transcript_preparation.py:92 PreparedTranscriptPage.empty.page Raw page operations: TranscriptPage, WirePage and UnreadTranscriptPage need a composed shared page capability. PreparedTranscriptPage is the prepared wrapper, not the raw page parent.
src/toad/transcript_preparation.py:215 PageFragmentRange.__eq__.other External Python equality operand: PageFragmentRange.eq can receive any Python value. The general object contract is banned here; no truthful domain owner exists.
src/toad/transcript_preparation.py:369 PreparedPageSource.edge_reached.boundary Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:495 ReplaceablePageSource.replacement.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:518 SavedHistory.prefix.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:521 SavedHistory.replacement.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:536 SavedPrefix.__init__.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:540 SavedPrefix.replacement.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:627 ClosedHistory.has_more.page Raw page operations: TranscriptPage, WirePage and UnreadTranscriptPage need a composed shared page capability. PreparedTranscriptPage is the prepared wrapper, not the raw page parent.
src/toad/transcript_preparation.py:630 ClosedHistory.has_older.page Raw page operations: TranscriptPage, WirePage and UnreadTranscriptPage need a composed shared page capability. PreparedTranscriptPage is the prepared wrapper, not the raw page parent.
src/toad/transcript_preparation.py:633 ClosedHistory.edge_reached.boundary Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:639 ClosedHistory.prefix.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:642 ClosedHistory.replacement.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_preparation.py:686 ProjectedTranscriptSource.prefix.through Page cursor operations: PreparedPageSource and its native/wire members need a common cursor capability on TranscriptCursor and WireCut. No union or fake narrowing substituted.
src/toad/transcript_publication.py:87 BoundFrame.capture.args Subclass constructor tail: BoundFrame and Moment do not share the same positional constructor signature. The factory family must declare the actual constructor capability; a permissive forwarding annotation conceals it.
src/toad/transcript_publication.py:87 BoundFrame.capture.extra Subclass constructor keywords: BoundFrame.capture/Moment.capture forward fields owned by Moment.source and Restoration.revision. The factory family must declare its constructor contract; a second field roster or throwaway frame would repeat the schema.
src/toad/transcript_publication.py:228 CanonicalSourcePublication.read_past_history.read Keyword-based snapshot/update reads: TranscriptScope snapshot/updates and CanonicalSourcePublication need a declared read-call contract. Their differently returning bound methods have no existing keyword-call parent; Callable ellipsis would hide the gap.
src/toad/transcript_publication.py:228 CanonicalSourcePublication.read_past_history.whole Read keyword forwarding: CanonicalSourcePublication.read_past_history forwards **whole, but current callers supply no keyword record. The read owner must declare allowed bounds rather than guess from an empty call.
src/toad/transcript_publication.py:341 SourcePublicationRequests.resume._event IDEN-3: direct resume calls omit the event and retain its old None default; the wakeup owner needs a null event member. Nullable caller: src/toad/transcript_publication.py:327 submit calls resume() without an event; :917 retry does the same.
src/toad/transcript_publication.py:542 BoundView.Moment.capture.extra Subclass constructor keywords: BoundFrame.capture/Moment.capture forward fields owned by Moment.source and Restoration.revision. The factory family must declare its constructor contract; a second field roster or throwaway frame would repeat the schema.
src/toad/transcript_publication.py:568 BoundView.Restoration.refresh.publication BoundView.capture can return None when detached; no old parameter default. Publication results need a declared absent member, not a false always-present annotation. Nullable caller: src/toad/transcript_publication.py:681 schedules moment.refresh(publication); :680 captures it, with a None result at :694-695 for an unavailable view.
src/toad/transcript_publication.py:706 BoundView.request.owner Worker result ownership stop: publish returns bool, but the preexisting worker field declares Worker[None]. Restored the baseline field and left this formerly bare method input stopped; no new nullable field spelling or fake result type.
src/toad/transcript_publication.py:811 TranscriptPresentation.get_transcript_page.before IDEN-3: omitted initial/forward bound is None; the bound owner needs an absent member. Nullable caller: src/toad/transcript_publication.py:274-275 calls get_transcript_page(after=..., through=...) and omits before.
src/toad/transcript_publication.py:811 TranscriptPresentation.get_transcript_page.after IDEN-3: omitted older-page bound is None; the bound owner needs an absent member. Nullable caller: src/toad/widgets/presentation_window.py:241 uses the older-page loader; Core agent_comms/transcripts.py:91-93 calls it with before, omitting after.
src/toad/transcript_publication.py:811 TranscriptPresentation.get_transcript_page.through IDEN-3: unread initial load omits the snapshot bound; the bound owner needs an absent member. Nullable caller: Core agent_comms/transcripts.py:136-139 calls the unread-source loader without through; src/toad/widgets/transcript_history.py:1186 installs that loader.
src/toad/transcript_publication.py:929 TranscriptPresentation.source_work_finished.history Source/conversation relationship: TranscriptSourcePreparation publishes the event, while only LineHistory declares conversation. The source family/event publisher must own this relationship before the callback can ask it.
src/toad/transcript_state.py:57 TranscriptState.reserve.operation IDEN-3: default operation is currently None; operation selection needs a declared default member. Nullable caller: src/toad/transcript_source_preparation.py:119-120 forwards its old default None; :127 omits the operation.
src/toad/transcript_state.py:108 TranscriptState.for_projection.owner ProjectedTranscriptHistory.owner can be None; no old parameter default. Projection ownership needs an absent-owner member instead of a falsely required LineHistory. Nullable caller: src/toad/widgets/transcript_history.py:1252 passes _projection_owner(); its weak reference, created at :1222, returns None after collection.
src/toad/transcript_state.py:135 LiveTranscript.reserve.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:135 LiveTranscript.reserve.operation IDEN-3: same source operation selection contract. Nullable caller: src/toad/transcript_source_preparation.py:119-120 and :127, same source-state dispatch.
src/toad/transcript_state.py:141 LiveTranscript.check_edges.owner Edge preparation: TranscriptSourcePreparation and its lookahead owner must share the prepare_source contract. Lookahead currently asks for LineHistory; the source caller only owns TranscriptSourcePreparation.
src/toad/transcript_state.py:156 UnboundTranscript.mounted.owner Refresh plus conversation view: the source lifecycle owner TranscriptSourcePreparation lacks Widget refresh and ConversationHistory.view; LineHistory.on_mount supplies no view declaration.
src/toad/transcript_state.py:168 UnreadTranscript.rows_published.owner Committed publication plus view: TranscriptSourcePreparation rows_published dispatch needs CommittedHistory.publish_committed and ConversationHistory.view, currently split across descendants.
src/toad/transcript_state.py:212 LatestViewportRequest.reading.owner ReplacementViewportRequest narrows this owner to ConversationHistory for its replaceable page_source. The request/source family lacks the shared replacement-source capability.
src/toad/transcript_state.py:311 WorkingTranscript.__init__.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:329 WorkingTranscript.progressed.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:342 WorkingTranscript.delivered.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:378 WorkingTranscript.execute.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:409 WorkingTranscript.schedule.owner Worker scheduling: TranscriptSourcePreparation dispatches schedule but has no Widget.run_worker capability declaration; its composing worker owner must declare it.
src/toad/transcript_state.py:489 CommitTranscript.__init__.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:497 CommitTranscript.execute.owner Paging-window snapshot and operation dispatch: TranscriptSourcePreparation reserve/finish/execute callers lack LineHistory.paging_window. Put that source capability on the source family before typing its owner; do not narrow the caller to LineHistory.
src/toad/transcript_state.py:512 CommitTranscript.rows_published.owner Live-block retirement view: TranscriptSourcePreparation must expose the conversation presentation capability used by CommitTranscript; ConversationHistory alone currently declares view.
src/toad/widgets/presentation_window.py:93 PresentationBudget.fit.candidates Retained-resource accounting: OperationalSessionPresentation and SessionThreadSidebar need a shared resource-budget capability; their current parent does not own the accounted resources.
src/toad/widgets/presentation_window.py:109 PresentationBudget.runway.sequence Measured-row sequence: PresentationBudget.runway has no production caller establishing a sequence owner; its measured_rows consumer contract must be declared before choosing a type.
src/toad/widgets/presentation_window.py:147 PageEnd.has_more.through Page cursor operations: TranscriptCursor and WireCut need a shared cursor capability composed into both; PageEnd currently receives both without that parent.
src/toad/widgets/presentation_window.py:147 PageEnd.has_more.page Raw page operations: TranscriptPage and WirePage need a shared page capability (also UnreadTranscriptPage for empty preparation); no raw page parent currently exists.
src/toad/widgets/presentation_window.py:150 PageEnd.adjacent.page Raw page operations: TranscriptPage and WirePage need a shared page capability (also UnreadTranscriptPage for empty preparation); no raw page parent currently exists.
src/toad/widgets/presentation_window.py:179 PageEnd.load_page.loader No common declared keyword-callable owner for get_transcript_page and HistoricalSessions.load; Callable ellipsis discarded the contract.
src/toad/widgets/presentation_window.py:179 PageEnd.load_page.through TranscriptPageWork couples optional request and required snapshot cursors in one generic; the cursor positions need distinct contracts.
src/toad/widgets/presentation_window.py:205 PageEnd.walk.target Line measurement: LineHistory and Contents both implement line_width, but their common VerticalGroup does not own it; compose one line-measurement capability on both.
src/toad/widgets/presentation_window.py:240 OlderEnd.load_page.loader Same missing keyword-callable contract; no Callable ellipsis retained.
src/toad/widgets/presentation_window.py:240 OlderEnd.load_page.cursor Core TranscriptCursor.read_page requires a cursor for its bound while the work generic permits None. The paging/cursor owner must resolve that contract.
src/toad/widgets/presentation_window.py:240 OlderEnd.load_page.through Same optional request/required snapshot cursor contract gap.
src/toad/widgets/presentation_window.py:273 NewerEnd.has_more.through Page cursor operations: TranscriptCursor and WireCut need a shared cursor capability composed into both; PageEnd currently receives both without that parent.
src/toad/widgets/presentation_window.py:273 NewerEnd.has_more.page Raw page operations: TranscriptPage and WirePage need a shared page capability (also UnreadTranscriptPage for empty preparation); no raw page parent currently exists.
src/toad/widgets/presentation_window.py:276 NewerEnd.load_page.loader Same missing keyword-callable contract; no Callable ellipsis retained.
src/toad/widgets/presentation_window.py:276 NewerEnd.load_page.cursor Same optional bound versus required Core cursor contract gap.
src/toad/widgets/presentation_window.py:276 NewerEnd.load_page.through Same optional request/required snapshot cursor contract gap.
src/toad/widgets/presentation_window.py:341 PreparationDemand.prepare_ahead.page Raw page operations: TranscriptPage and WirePage need a shared page capability (also UnreadTranscriptPage for empty preparation); no raw page parent currently exists.
src/toad/widgets/presentation_window.py:377 MovingPreparation.prepare_ahead.history The actual LineHistory receiver reaches Textual.run_worker, whose generic callable contract infers Never for this None-returning partial. The work/worker result contract must be declared without a fake receiver type.
src/toad/widgets/presentation_window.py:377 MovingPreparation.prepare_ahead.page Raw page operations: TranscriptPage and WirePage need a shared page capability (also UnreadTranscriptPage for empty preparation); no raw page parent currently exists.
src/toad/widgets/sidebar_tree.py:136 RowReconciliation.sync.method Reconciliation receiver and correlated method signature: RowReconciliation must declare the capability composed by SidebarGroup and WelcomeEntries, which independently expose reconciliation_tree; the decorator also erases args/kwargs correlation.
src/toad/widgets/sidebar_tree.py:138 RowReconciliation.sync.synchronized.view Reconciliation receiver and correlated method signature: RowReconciliation must declare the capability composed by SidebarGroup and WelcomeEntries, which independently expose reconciliation_tree; the decorator also erases args/kwargs correlation.
src/toad/widgets/sidebar_tree.py:138 RowReconciliation.sync.synchronized.args Reconciliation receiver and correlated method signature: RowReconciliation must declare the capability composed by SidebarGroup and WelcomeEntries, which independently expose reconciliation_tree; the decorator also erases args/kwargs correlation.
src/toad/widgets/sidebar_tree.py:138 RowReconciliation.sync.synchronized.kwargs Reconciliation receiver and correlated method signature: RowReconciliation must declare the capability composed by SidebarGroup and WelcomeEntries, which independently expose reconciliation_tree; the decorator also erases args/kwargs correlation.
src/toad/widgets/sidebar_tree.py:178 KeyedRows.update_row.row Row/key type correlation: KeyedRows must own a row type parameter shared by its reconcilers. Widget does not preserve SidebarGroup/WelcomeEntries member contracts.
src/toad/widgets/sidebar_tree.py:187 KeyedRows.place_row.row Row/key type correlation: KeyedRows must own a row type parameter shared by its reconcilers. Widget does not preserve SidebarGroup/WelcomeEntries member contracts.
src/toad/widgets/sidebar_tree.py:254 SidebarGroup.__init__.row Header navigation: SidebarGroup accepts Static and CommsRow headers, but Widget does not own target_name. The header family must declare navigation capability instead of the navigation_header flag implying it.
src/toad/widgets/sidebar_tree.py:254 SidebarGroup.__init__.kwargs Textual constructor keywords: SidebarGroup/SidebarModelView must declare the Widget constructor contract, preserving keyword/value correlation; a bag of str/bool/None values cannot do that.
src/toad/widgets/sidebar_tree.py:531 SidebarModelState.serves.path Actual callers supply nullable ThreadIdentity.root_path()/CommsChatView._bound_root. The root/selection family needs a null member; there was no original default. Nullable caller: src/toad/widgets/thread_comms.py:355 passes identity.root_path(), whose base returns None at src/toad/thread_identity.py:65-66; src/toad/widgets/channel_activity.py:52 also passes nullable _bound_root.
src/toad/widgets/sidebar_tree.py:540 SidebarModelState.changes.changes Sidebar change request: SidebarModelView/SidebarModelState must own a declared sync-change record instead of passing raw keyword dictionaries among present/changes/apply.
src/toad/widgets/sidebar_tree.py:543 SidebarModelState.apply.changes Sidebar change request: SidebarModelView/SidebarModelState must own a declared sync-change record instead of passing raw keyword dictionaries among present/changes/apply.
src/toad/widgets/sidebar_tree.py:581 BoundSidebar.serves.path Same nullable root path and missing null-root owner. Nullable caller: src/toad/widgets/thread_comms.py:355 / src/toad/thread_identity.py:65-66; also src/toad/widgets/channel_activity.py:52 with _bound_root initialized None in src/toad/widgets/comms_chat.py:78.
src/toad/widgets/sidebar_tree.py:607 Current.apply.changes Sidebar change request: SidebarModelView/SidebarModelState must own a declared sync-change record instead of passing raw keyword dictionaries among present/changes/apply.
src/toad/widgets/sidebar_tree.py:620 Behind.changes.changes Sidebar change request: SidebarModelView/SidebarModelState must own a declared sync-change record instead of passing raw keyword dictionaries among present/changes/apply.
src/toad/widgets/sidebar_tree.py:632 SidebarModelView.__init__.kwargs Textual constructor keywords: SidebarGroup/SidebarModelView must declare the Widget constructor contract, preserving keyword/value correlation; a bag of str/bool/None values cannot do that.
src/toad/widgets/sidebar_tree.py:714 SidebarModelView.present.changes Sidebar change request: SidebarModelView/SidebarModelState must own a declared sync-change record instead of passing raw keyword dictionaries among present/changes/apply.
src/toad/widgets/sidebar_tree.py:801 TargetTree.row_for.selection Selection identity: TargetTree selection_for/row_for must share an owner across SidebarSelection and relationship identity tuples; no shared selection parent currently exists.
src/toad/widgets/sidebar_tree.py:895 TargetTree.session_selected.event CoreEventMessage.event is CoreEvent, losing the selected SessionSelected payload and previous_mode. The carrier must preserve that relationship.

Additional moved projection-boundary stops: core/projection.py:8, MroProjection.project_value.value / args / kwargs. The selected input families and per-call context are heterogeneous; object, Protocol and permissive Callable types are not substituted. The existing handler declarations and their concrete typed outputs remain authoritative.

Assumed:

  • The stopped-thread Context explorer invokes the visible-feature exception: retiring that feature or replacing its dead store reader needs its own owner decision. No live-socket fallback is introduced.
  • Nullable caller ownership is a separate order. Old defaults stay unchanged while these inputs remain counted as stops.
  • Behavior changes are limited to the three authorized context/projection defects and their complete consumers; annotation-only changes preserve prior bodies/defaults.
  • Imports against the exact locked Core wheel and the seven focused cases support this patch. They are not a fresh installed UI qualification or a claim that the whole existing suite passes.

@trissim
trissim marked this pull request as ready for review October 23, 2026 11:59
Copilot AI balanced review requested due to automatic review settings October 23, 2026 11:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

@trissim
trissim marked this pull request as draft October 23, 2026 12:02
@trissim

trissim commented Oct 23, 2026

Copy link
Copy Markdown
Author

Handoff at 30d8240 on next/toad-types-05.

Done: the original eight-file annotation batch is 539 -> 119 bare parameters; src/toad is 2000 -> 1577. All genuine nullable inputs are explicit stops in the PR body, with caller locations. Native session observation is fixed at src/toad/core/context_inspection.py:547-552 using NativeSessionFiles; MroProjection.project_value owns the output contract at src/toad/core/projection.py:8, with all seven consumers migrated. The locked Core is 7017468028ea2428ce71fe30261aa8d827aa222a (lock-only commit 077c680); IncarnationThreadTarget imports from that exact installed wheel. Seven focused tests passed against that lock, and all 15 changed production modules import under python -I.

Left: PR #1148 remains draft until Debt ratchet succeeds on this exact head. The prior run's source comparison passed; its remaining surface-guard failure at tests/guards/test_test_layers.py:42 found a preexisting workspace-backed model test. The latest commit moves tests/model/test_recorded_transcript_reader.py unchanged to tests/app/test_recorded_transcript_reader.py (100% rename). Our new real-wire test is already at tests/app/test_context_reader_session_revision.py:8. Wait for the latest head's hosted result; no further source edits are currently identified.

Stopped item: src/toad/core/context_inspection.py:703-705 still reads deleted bus.log. Deletion was stopped under Tristan's visible-feature exception: stopped-thread Context explorer detail/search/copy/export depend on this family. Do not delete only the saved overrides: that would inherit the live socket fallback. This needs its own feature-owner decision.

Exact next action: gh pr checks 1148 -R OpenHCSDev/toad. If Debt ratchet is green on 30d8240, update the PR body with that run and current head, then gh pr ready 1148 -R OpenHCSDev/toad. If red, read only the failing job and fix its named site. No known next source edit. The PR body currently identifies an earlier head; refresh those head links when reporting the final check. Slice 3 remains parked, clean, on next/toad-types-06 in /home/ts/wt/toad-types-06 until #1148 is green and ready.

The moved application test still called CoordinationTranscriptReader.snapshot
with a root and thread name, the signature P401 replaced with a TranscriptScope
(a751354). Pass the KnownTranscript that already declares that address.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trissim
trissim marked this pull request as ready for review October 23, 2026 12:53
@trissim
trissim merged commit 336cf3e into main Oct 23, 2026
2 checks passed
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.

2 participants