Skip to content

Use shared forms for all advertised session settings - #1748

Merged
trissim merged 5 commits into
mainfrom
work/codex-live--P181--toad
Nov 12, 2026
Merged

trissim merged 5 commits into
mainfrom
work/codex-live--P181--toad

Conversation

@trissim

@trissim trissim commented Nov 12, 2026 •

Copy link
Copy Markdown

One declaration per configuration field

Focused evidence: 79 Core cases passed; the remaining original gate case exposed an existing user-notice fallback, which is repaired and passed unchanged separately. All 10 advertisement/model-picker cases passed. No CI wait or full-suite claim. An earlier native-bearing attempt stopped during pinned-Pi preparation, so it supplies no native-run result. The migrated native editor/queue consumer was read, not rerun.

Rule policy is a configuration record

RuleGateSettings owns mode, read batch, prompt count and context-refresh thresholds. DealRecord inherits those fields; both CLI addresses inherit the same fields and writer. The native thread menu offers the existing deal through the normal command form. Reading/audit evidence survives edits; widening and re-dealing preserve policy. Invalid bounds are rejected from those annotations at the writer.

Stored session fields supply catalog presentation

Thread inherits ThreadSettings. Model, thinking and service-tier catalog implementations inherit their low field roles; labels, help and current values derive from the actual fields. Three handwritten current-value getters and three copied presentation declarations are gone. Dynamic catalog acquisition, cancellation/auth invalidation and actual native write effects remain with their existing owners. Decoder choice capability selects finite editors; record payloads and flag combinations remain unrestricted.

Every ACP advertisement reaches the shared form

Paired Toad PR: #1748

The session menu uses ObjectState/FormBridge like preferences and command dialogs. Unknown select fields and booleans need no new frontend class. The projected fields retain their original advertisement and writer; duplicate ids and ambiguous built-in roles refuse. Model search/recents/provider setup are a form editor using the original shared picker. Editing leaves the form open; thinking is edited there instead of a second ad-hoc popup. Hidden forms remain lazy and refresh from their retained source when reopened.

Original gate failure repaired at its owner

UserThreadRole replaced a task's empty user-fact answer with a default, turning Core notices into human prompts. TaskAttachment now owns the default; OwnerNotice's empty override survives. The original assertion was retained and passed.

Assumed: built-in ACP roles must be unambiguous when queried; arbitrary external field identity and value remain supplied by the actual advertisement. Native thread gate editing requires an existing dealt session and never fabricates one. Local preferences and served session policy keep their distinct storage and authority.

@github-actions

github-actions Bot commented Nov 12, 2026 •

Copy link
Copy Markdown

debt-src at 35bddb6 blocks on 23 lines:

grew ForeignAbsenceProbe:src/toad/widgets/model_selection.py +2
grew NoneAbsence:src/toad/widgets/model_selection.py +11
grew PlainStrIdAnnotation:src/toad/core/configuration_events.py +1
grew PlainStrIdAnnotation:src/toad/widgets/model_selection.py +4
grew StringIdentity:src/toad/widgets/model_selection.py +2
grew TypeErrors:src/toad/acp/agent_configuration.py +8
grew TypeErrors:src/toad/forms/editors.py +1
grew TypeErrors:src/toad/widgets/model_selection.py +6
grew TypeErrors:src/toad/widgets/model_switcher.py +4
grew UnannotatedParameter:src/toad/acp/agent_configuration.py +1
grew UnannotatedParameter:src/toad/widgets/model_switcher.py +1
found ForeignAbsenceProbe:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:331 src/toad/widgets/model_selection.py:318
found NoneAbsence:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:331 src/toad/widgets/model_selection.py:330 src/toad/widgets/model_selection.py:318 src/toad/widgets/model_selection.py:252 src/toad/widgets/model_selection.py:148 src/toad/widgets/model_selection.py:148 src/toad/widgets/model_selection.py:141 src/toad/widgets/model_selection.py:141 src/toad/widgets/model_selection.py:135 src/toad/widgets/model_selection.py:135 src/toad/widgets/model_selection.py:100
found PlainStrIdAnnotation:src/toad/core/configuration_events.py at src/toad/core/configuration_events.py:8
found PlainStrIdAnnotation:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:135 src/toad/widgets/model_selection.py:141 src/toad/widgets/model_selection.py:148 src/toad/widgets/model_selection.py:209
found TypeErrors:src/toad/acp/agent_configuration.py at src/toad/acp/agent_configuration.py:61 (Item "None" of "SessionConfigOptionSelect | SessionConfigOptionBoolean | None" has no attribute "id"  [union-attr]) src/toad/acp/agent_configuration.py:83 (Argument 1 to "SelectChoices" has incompatible type "SessionConfigOptionSelect | SessionConfigOptionBoolean"; expected "SessionConfigOptionSelect"  [arg-type]) src/toad/acp/agent_configuration.py:96 (Argument 1 to "bind" of "ConfigurationSetting" has incompatible type "SessionConfigOptionSelect | SessionConfigOptionBoolean"; expected "SessionConfigOptionSelect"  [arg-type]) src/toad/acp/agent_configuration.py:133 (Argument 1 of "bind" is incompatible with supertype "ConfigurationSetting"; supertype defines the argument type as "SessionConfigOptionSelect"  [override]) src/toad/acp/agent_configuration.py:138 (Item "None" of "SessionConfigOptionSelect | SessionConfigOptionBoolean | None" has no attribute "description"  [union-attr]) src/toad/acp/agent_configuration.py:152 (Argument 1 of "selection_event" is incompatible with supertype "ConfigurationSetting"; supertype defines the argument type as "str | bool"  [override]) src/toad/acp/agent_configuration.py:218 (Item "None" of "SessionConfigOptionSelect | SessionConfigOptionBoolean | None" has no attribute "id"  [union-attr]) src/toad/acp/agent_configuration.py:269 (Item "None" of "SessionConfigOptionSelect | SessionConfigOptionBoolean | None" has no attribute "id"  [union-attr])
found TypeErrors:src/toad/forms/editors.py at src/toad/forms/editors.py:199 (Argument 1 to "decode" of "FieldCodec" has incompatible type "object"; expected "TypeForm[Never]"  [arg-type])
found TypeErrors:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:154 ("apply_native_layout" undefined in superclass  [misc]) src/toad/widgets/model_selection.py:155 ("SelectionBounds" has no attribute "styles"  [attr-defined]) src/toad/widgets/model_selection.py:156 ("SelectionBounds" has no attribute "styles"  [attr-defined]) src/toad/widgets/model_selection.py:157 ("SelectionBounds" has no attribute "styles"  [attr-defined]) src/toad/widgets/model_selection.py:158 ("SelectionBounds" has no attribute "styles"  [attr-defined]) src/toad/widgets/model_selection.py:159 ("SelectionBounds" has no attribute "styles"  [attr-defined])
found TypeErrors:src/toad/widgets/model_switcher.py at src/toad/widgets/model_switcher.py:32 (Cannot override writeable attribute with read-only property  [override]) src/toad/widgets/model_switcher.py:73 (Item "None" of "AdvertisedSetting | None" has no attribute "setting"  [union-attr]) src/toad/widgets/model_switcher.py:80 (Item "None" of "AdvertisedSetting | None" has no attribute "setting"  [union-attr]) src/toad/widgets/model_switcher.py:82 (Argument 1 to "selection_event" of "ConfigurationSetting" has incompatible type "object"; expected "str | bool"  [arg-type]) src/toad/widgets/model_switcher.py:107 ("FormView" has no attribute "represents"  [attr-defined])
found UnannotatedParameter:src/toad/acp/agent_configuration.py at src/toad/acp/agent_configuration.py:36 src/toad/acp/agent_configuration.py:40 src/toad/acp/agent_configuration.py:98 src/toad/acp/agent_configuration.py:174 src/toad/acp/agent_configuration.py:182 src/toad/acp/agent_configuration.py:190 src/toad/acp/agent_configuration.py:198 src/toad/acp/agent_configuration.py:207 src/toad/acp/agent_configuration.py:214 src/toad/acp/agent_configuration.py:226 src/toad/acp/agent_configuration.py:272
found UnannotatedParameter:src/toad/widgets/model_switcher.py at src/toad/widgets/model_switcher.py:72
introduced NoneAbsence:src/toad/acp/agent_configuration.py at lines [46]
introduced NoneAbsence:src/toad/widgets/model_switcher.py at lines [111]
Warn-only, never blocks (4)
src/toad/widgets/model_selection.py: LintFindings +3
src/toad/widgets/model_selection.py: Unformatted +1
found LintFindings:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:105 (RUF012 Mutable default value for class attribute) src/toad/widgets/model_selection.py:118 (RUF012 Mutable default value for class attribute) src/toad/widgets/model_selection.py:330 (SIM102 Use a single `if` statement instead of nested `if` statements)
found Unformatted:src/toad/widgets/model_selection.py at src/toad/widgets/model_selection.py:1 (Black would reformat this file)

@trissim
trissim marked this pull request as ready for review November 12, 2026 21:52
Copilot AI balanced review requested due to automatic review settings November 12, 2026 21:52

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 insufficient remaining quota. Try requesting a review at a lower effort level.

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 merged commit fbbe585 into main Nov 12, 2026
1 of 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