Repository navigation
Type Command by its owners' context and result; drop remaining dead Any - #2762
Conversation
|
Handoff at ca35aa2 on next/remaining-explicit-types. Main including merged #2764 is merged and pushed; no uncommitted edits remain. The implemented change removes the Any cast around dataclasses.Field.metadata in tools/debt_ratchet.py:420-425, using the actual descriptor via inspect.getattr_static. No further family correction has been implemented. Remaining inventory at this head: physical src tree has 42 Any uses, including one audit-test fixture; tools has 1. The remaining families are: publication clients (acp.py:294; input_drain.py:605,612,617; transcript_updates.py:32,39; runtime.py:254); native task result ownership (backend.py:267; runtime.py:217 twice; turn_runner.py:99,300,331); Command context/result (command.py:17 twice); launch forwarding (child_process.py:1871); dispatch handlers (mro_dispatch.py:8,34,39,58,62); metaclass SDK namespace/options (declared_family.py:34,38); retained registry fields (registry_document.py:508); FieldCodec decoder generics and Any sentinels (field_codec.py:430,1473,1486,1490,1491,2089,2169,2245,2295,2312,2439,2459,2515,2560,2587,2733,2795); the runtime typing.Any comparison (tools/debt_ratchet.py:1864). No parse omissions were found. Check the current open PR file ownership before editing: #2763 holds field_codec.py; #2765 holds native_pi.py/locked_store.py and installer file ownership. The annotation batch exclusions remain in order-busdel-any2.md. Exact next edit: begin the missing publication receiver contract at controller.py:21, then migrate SocketClient (runtime.py:75), RuntimeServer (runtime.py:201), and all publication consumers listed above together. Source investigation: ACP SDK owns the full typed SessionNotification record (acp/schema.py:5599); its session_update method manually declares a 13-member external union (acp/agent/connection.py:109-130). Do not copy that union or replace the clients with BaseModel/object/Protocol. Choose a contract consuming the existing SessionNotification, using the inherited ACP connection and existing SDK notification API, and migrate the complete family; no source patch for that shape exists yet. RuntimeServer publication binding is also erased by an object sentinel at runtime.py:67 and _expected_client at :254; working_memory_worker.py:37-39 is its sole bound publisher. Preserve its client/thread/socket checks rather than narrowing the annotation dishonestly. If that coherent publication edit conflicts with an active owner, Command is the independent next family: AST found direct roots in runtime_requests.py:70, cli_commands.py:458/749, connector.py:835, relationships.py:596, goal_actions.py:116, todos.py:2743, cli_native_package.py:26. Parameterize the existing Command contract with each real context/result and migrate every root, rather than hiding Any. Run no tests: the review fork owns testing under the latest order. The carry deletion is a separate pending order: only after the commander confirms install 22 applied it on the live bus, open a fresh-main PR deleting tools/cutover/carry_selected_tool_slots.py and its tests. That confirmation has not arrived; leave the carry untouched until then. |
Command.apply took `ctx: Any -> Any`, so every command family's context and result lived only in the subclass overrides and the base contract said nothing. Command is now generic over Context and Result, and each root binds the types its members already declare: - RuntimeRequest: RuntimeRequestContext -> Awaitable[None] - TargetEdit: Comms -> CliResult - CliExecution/CliCommand: Comms -> Answer, the family's own type parameter, so a command's declared answer is also its Command result - ConnectorVerb: ConnectorStore -> int | str - RelationshipEdit: RelationshipEditContext -> tuple[RelationshipDocument, Collaboration | None]; its three apply overrides now say so instead of returning unannotated - GoalAction[Result]: GoalActionContext -> Result - TodoCommand: Todo -> Todo - NativePackageVerb: None -> None Also drops the unused Any imports in session_lifecycle.py and queued_input.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
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.
|
debt-tools at e2b743b, every finding: |
|
debt-src at e2b743b, every finding: |
debt-src caught the first cut restating facts: - RelationshipEdit bound `Collaboration | None` as every member's result, which is the union of two members' answers written on the parent. Retaining edits always publish a Collaboration; removal always answers None. The family is now generic in its result, like GoalAction, and each branch binds its own. The abstract apply that restated Command's is deleted. - TodoCommand spelled Todo as "Todo" strings. Todo stores these commands, so it must be declared after them; a PEP 695 alias reads it lazily instead of binding by spelling. - The RuntimeRequest header is wrapped to the line limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
upgrade() keeps main's command scope and completes an interrupted restore first inside it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removes the explicit Any from the Command contract and the metadata ratchet. Each Any is replaced by the type its owner already declares.
What changed
Command (command.py):
apply(self, ctx: Any) -> Anyis nowCommand[Context, Result]withapply(self, ctx: Context) -> Result. Each root binds what its members already declare:Dead imports: unused
Anyimports removed from session_lifecycle.py and queued_input.py.Metadata ratchet (tools/debt_ratchet.py:419-425): reads the real
MemberDescriptorTypewithinspect.getattr_staticinstead of castingdataclasses.Fieldthrough Any.Counts
rg -n '\bAny\b' src: 68 lines before, 64 after. Python code uses: 42 before, 38 after.Verified
get_original_basesshows each root's binding.CliCommand.result_type()resolves for the same 14 commands and refuses the same 74 as main.Found, not fixed here
Two CliCommand members already break the family's
Answer: CliResultbound:AsyncIterator[Message]dict[str, JsonValue]Every remaining Any site (file:line) and the unannotated-parameter scan (1673 parameters in 186 files) are owned by draft #2774.
🤖 Generated with Claude Code