Skip to content

Annotate parameters in triage, cursor, Pi child and transcript modules - #2757

Merged
trissim merged 2 commits into
mainfrom
fix/annotate-params-2
Oct 23, 2026
Merged

trissim merged 2 commits into
mainfrom
fix/annotate-params-2

Conversation

@trissim

@trissim trissim commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Batch 2 of the parameter-annotation order: the worst files in src/agent_comms that no open PR touches. Each parameter gets its declared type, and the same functions get return types. No Any, object, cast, # type: ignore or Protocol is added (git diff -U0 | grep -E '^\+.*(\bobject\b|\bAny\b|cast\(|type: ignore|Protocol)' returns nothing).

Files: selected_triage, cursor_owner, native_child, native_input_record, transcripts, notification_assignment, plus proven_source_coverage, which holds the CoverageInput declarations whose missing types made cursor_owner's callers see None. The files of #2744, #2748, #2749, #2751, #2603, #2556 and #2469 were excluded (pi_payloads, external_transcript, turn_context and field_codec among them).

Counts (AST count of unannotated parameters, excluding self/cls)

Scope Before After
Batch files (7) 299 10
src/agent_comms (origin/main 252e32b vs this head) 1937 1648

Per file after: selected_triage 5, native_input_record 3, native_child 1, notification_assignment 1, the rest 0. Every return-less function in the batch now has a return type, except the nested column helper in _decode_row (see stops).

Method

The same pyright call-site probe as batch 1, two rounds (299 → 97), then a hand pass on the rest and on every new pyright error. Overrides with no return annotation take the one their base declares (same-file bases only).

Declarations corrected

  • PiSessionChild.start_command(argv: tuple[str, ...]): it said tuple[str, str], but AttachedChild.start (child_process.py:1531) and NativePiRpcLaunch.argv (native_pi.py:396) both declare tuple[str, ...].
  • NativeInputExecution.historical_proof (3 definitions) returns HistoricalNativeInput | None. It said FullHistoricalNativeInput | None although the triage member returns a triage proof, and the caller collects into list[HistoricalNativeInput] (historical_native_inputs.py:163).
  • TranscriptCursor.mark_read takes reads: TranscriptReadState, viewer: str in all four members. UnreadTranscriptCursor declared both as object.
  • CoverageInput.candidate/build/injected_for (proven_source_coverage.py) declare their types. The abstract candidate stub had none, so pyright inferred None for every publish caller.
  • PiSessionChild.request/send/send_fenced take command: PiCommand, the declared parent of Open, OpenHistory, Resume, CompactDurable, Prompt... (pi_commands.py:73).
  • The invalid_store consumers in transcripts and notification_assignment always raise, so they return NoReturn.

Dead code

None. A zero-caller sweep over src, tests and tools flagged TranscriptCursor.same_position and covers_incoming (transcripts.py:90, :108), but Toad calls both (toad/transcript_filter.py, toad/widgets/committed_presentation.py), so they stay. The content_* methods are reached through @projected.

Stops: left unannotated because the declaration is missing

  • selected_triage.py:195, :209, :220, :234 and native_input_record.py:225, :273, :352, historical_proof(**source): a keyword bag forwarded into the *HistoricalNativeInput(**source) constructors (IMPL-7). The fields have no declared record.
  • native_child.py:168 start_command(**state): the same bag, forwarded into the PiSessionChild dataclass fields.
  • selected_triage.py:242 RecordedTriageText.encode(value): the base TextRepresentation[V].encode declares value: object (field_codec.py:1268), not V, so the override cannot narrow it. field_codec.py belongs to Ratchet erased types and replace 106 explicit Any uses #2744.
  • notification_assignment.py:175 _decode_row(row) and its nested column: the base TypedRow._decode_row declares row: sqlite3.Row | tuple[object, ...] (typed_table.py:584), which this order may not write.

Exposed defects: new pyright errors where a correct annotation reveals an existing gap

pyright on src/agent_comms, keyed by (file, rule, message): 16 new and 11 gone. The new ones:

  • private_send_stage.py:103 (5 errors): **self.execution.binding_fields() spreads dict[str, NativeColumn] into the NativeRuntimeInput constructor, so every keyword parameter sees NativeColumn. That is an IMPL-7 parameter bag; the execution's columns need a declared record.
  • pi_native_backend.py:307-309 and pi_durable_backend.py:249: request() returns PiResponseData, and callers read .summary, .first_kept_entry_id, .tokens_before and .outcome from subclasses. PiCommand does not declare its response type, so a command cannot say which data it answers with.
  • cursor_owner.py:119: store.session.boundary(...). boundary exists only on NativeCoordinationSession (coordination_session.py:121), while Coordination.session is declared CoordinationSession.
  • native_input_record.py:184: InputDisplay(user.input_id, None), where MessageEntry.input_id is str | None and InputDisplay requires str.
  • transcripts.py:367: RecordedTranscriptReadIdentity.resolve_source receives historical_source: str | None, the shared family signature, though a recorded identity always has one. A None stands for "live" (IDEN-3).

Proof

  • PYTHONPATH=src .venv/bin/python -I imports all seven modules: OK, after merging origin/main 252e32b.
  • python -m compileall -q on the seven files: clean.
  • No pytest was run (per the order).

Assumed:

  • A new pyright error is acceptable when a correct annotation exposes an existing declaration gap; each one is listed above instead of being widened away.
  • ruff check --select I001 --fix and ranged ruff format touched only these seven files; this reordered proven_source_coverage's existing out-of-order import block.
  • refactor-audit submodule was initialised locally only to import agent_comms.pinned_audit; no submodule change is committed.
  • Toad's use of same_position/covers_incoming was checked in the local toad-wt worktrees, not on Toad's main branch.

🤖 Generated with Claude Code

trissim and others added 2 commits October 23, 2026 07:34
Give declared types to 289 of the 299 unannotated parameters in
selected_triage, cursor_owner, native_child, native_input_record,
transcripts, notification_assignment and proven_source_coverage, with
return types on the same functions. src/agent_comms drops from 2452 to
2163 unannotated parameters on this branch.

Declarations corrected where the existing one was wrong:
- PiSessionChild.start_command takes argv: tuple[str, ...], the type
  AttachedChild.start and NativePiRpcLaunch.argv declare (was tuple[str, str]).
- NativeInputExecution.historical_proof returns HistoricalNativeInput | None;
  the triage member returns a triage proof, and the caller collects into
  list[HistoricalNativeInput] (was FullHistoricalNativeInput | None).
- TranscriptCursor.mark_read takes reads: TranscriptReadState, viewer: str
  in every member (one member declared both as object).
- CoverageInput.candidate, build and injected_for declare their types, so
  callers no longer see an inferred None.
- Raise-only invalid_store consumers return NoReturn.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trissim
trissim marked this pull request as ready for review October 23, 2026 11:36
Copilot AI balanced review requested due to automatic review settings October 23, 2026 11:36

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.

@github-actions

Copy link
Copy Markdown

debt-src at 9cee346, every finding:

grew LintFindings:src/agent_comms/cursor_owner.py +15
grew LintFindings:src/agent_comms/native_input_record.py +4
grew LintFindings:src/agent_comms/notification_assignment.py +5
grew LintFindings:src/agent_comms/selected_triage.py +13
grew LintFindings:src/agent_comms/transcripts.py +5
grew NoneAbsence:src/agent_comms/cursor_owner.py +3
grew NoneAbsence:src/agent_comms/native_child.py +7
grew NoneAbsence:src/agent_comms/native_input_record.py +3
grew NoneAbsence:src/agent_comms/selected_triage.py +7
grew NoneAbsence:src/agent_comms/transcripts.py +11
introduced NoneAbsence:src/agent_comms/cursor_owner.py at lines [165, 252, 294]
introduced NoneAbsence:src/agent_comms/native_child.py at lines [314, 314, 359, 385, 436, 442, 442]
introduced NoneAbsence:src/agent_comms/native_input_record.py at lines [227, 275, 354]
introduced NoneAbsence:src/agent_comms/selected_triage.py at lines [152, 163, 175, 195, 209, 220, 234]
introduced NoneAbsence:src/agent_comms/transcripts.py at lines [169, 268, 268, 334, 334, 366, 366, 404, 410, 600, 600]

@trissim
trissim merged commit 05964c8 into main Oct 23, 2026
10 of 14 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