Skip to content

gut(mattermost): remove dead model-picker UI — CLI agents own model selection (#2449)#2451

Merged
alexey-pelykh merged 1 commit intomainfrom
gut/mattermost-model-picker-2449
Apr 21, 2026
Merged

gut(mattermost): remove dead model-picker UI — CLI agents own model selection (#2449)#2451
alexey-pelykh merged 1 commit intomainfrom
gut/mattermost-model-picker-2449

Conversation

@alexey-pelykh
Copy link
Copy Markdown

Summary

Closes #2449 (Mattermost model-picker gut). Also closes #2415 — the "fresh product rationale" it required for gutting is provided here by the Middleware Boundary Principle, matching bullet 1 of its "Alternative: Gut" path (see the superseded-by comment on #2415).

Parallel to Discord gut #2414 / PR #2450 (merged 2026-04-21). Same rationale, same shape, smaller scope — Mattermost's picker was a 515-LoC UI + ~120-LoC handler wiring inside extensions/mattermost/ vs. Discord's 2.3k LoC pattern inside src/discord/monitor/.

Per Middleware Boundary Principle (product/strategy.md), model selection is owned by CLI runtimes (Claude, Gemini, Codex, OpenCode). RemoteClaw does not route model choice through its infrastructure.

Changes

Delete (515 LoC):

  • extensions/mattermost/src/mattermost/model-picker.ts (360)
  • extensions/mattermost/src/mattermost/model-picker.test.ts (155)

Modify extensions/mattermost/src/mattermost/slash-http.ts (−15 LoC):

  • Remove 5 imports from deleted ./model-picker.js (only resolveMattermostModelPickerEntry was actually called; the other 4 were dead imports)
  • Remove the 8-line picker-entry branch at slash-http.ts:388-395/model and /models now fall through to normal slash-command handling

Modify extensions/mattermost/src/mattermost/monitor.ts (−121 LoC):

  • Remove parseMattermostModelPickerContext + 4 now-orphan imports (authorizeMattermostCommandInvocation, buildButtonProps, updateMattermostPost, MattermostInteractionResponse) whose only live callers were the deleted handlers
  • Remove handleInteraction: handleModelPickerInteraction wiring
  • Remove buildModelPickerProps, updateModelPickerPost, handleModelPickerInteraction (lines 760-874)

Stale picker buttons

Old Mattermost posts with model-picker buttons will no longer have a handler wired. The interaction handler gracefully no-ops when handleInteraction is undefined — verified at extensions/mattermost/src/mattermost/interactions.ts:558 where if (params.handleInteraction) guards the call. No throw, default ack path.

Non-scope

Verification

  • pnpm check: 0 warnings / 0 errors (format ✓, tsgo ✓, lint ✓, no-random-messaging ✓, no-remoteclaw-ai ✓)
  • pnpm test: 7010 passed / 3 skipped / 0 failed — matches PR gut(discord): remove dead model-picker UI — CLI agents own model selection (#2414) #2450 baseline at c6d8440
  • node scripts/check-no-zombie-imports.mjs: exit 0
  • node scripts/check-throwing-stub-callers.mjs: 0 violations
  • node scripts/check-stub-debt.mjs: baseline 133 unchanged
  • node scripts/check-obsolescence-audit.mjs: exit 0
  • Grep verification: grep -rn "ModelPicker\|model-picker\|modelPicker" extensions/mattermost/ --include="*.ts" returns zero matches
  • LIVE smoke: not required (touches extensions/mattermost/, not src/middleware/)

Related

Test plan

  • pnpm check green
  • pnpm test green (7010/3/0)
  • zombie-import / throwing-stub / stub-debt / obsolescence gates green
  • Mattermost non-picker slash-command flow intact (non-model commands fall through)
  • Mattermost interaction handler graceful when handleInteraction unset
  • CI green on all gates

🤖 Generated with Claude Code

…election (#2449)

The Mattermost model-picker UI was dead-but-compile-linked after the #2337
provider cascade — /model and /models slash commands routed to a picker
whose data source had been gutted, so the handler only returned "No models
available." while keeping ~520 LoC of picker UI wiring alive at compile time.

Per Middleware Boundary Principle (product/strategy.md), model selection is
owned by CLI runtimes (Claude, Gemini, Codex, OpenCode). RemoteClaw does
not route model choice through its infrastructure. Parallel to Discord gut
in #2450 (merged 2026-04-21), which applied the same rationale.

Changes:
- Delete extensions/mattermost/src/mattermost/model-picker{,.test}.ts (515 LoC)
- Remove picker-entry branch + 5 picker imports from slash-http.ts
- Remove picker handler wiring, 3 helper functions, and 4 now-orphan imports
  (parseMattermostModelPickerContext, authorizeMattermostCommandInvocation,
   buildButtonProps, updateMattermostPost, MattermostInteractionResponse)
  from monitor.ts
- Stale picker buttons on old Mattermost posts fall through to default
  interaction handling — verified graceful no-op at interactions.ts:558
  where handleInteraction is guarded

Closes #2449 (Mattermost gut). Also closes #2415 (superseded — the "fresh
product rationale" it called for is provided here by the Middleware Boundary
Principle, matching bullet 1 of its "Alternative: Gut" path).

pnpm check: 0 warnings / 0 errors
pnpm test: 7010 passed / 3 skipped / 0 failed (matches #2450 baseline at c6d8440)
zombie-import / throwing-stub / stub-debt / obsolescence gates: all exit 0

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@alexey-pelykh alexey-pelykh enabled auto-merge (squash) April 21, 2026 12:35
@alexey-pelykh alexey-pelykh merged commit 32fb155 into main Apr 21, 2026
15 checks passed
@alexey-pelykh alexey-pelykh deleted the gut/mattermost-model-picker-2449 branch April 21, 2026 12:41
alexey-pelykh added a commit that referenced this pull request Apr 21, 2026
…tion per MBP (#2455)

Delete src/agents/model-selection.ts (170 LOC) per Middleware Boundary
Principle. Model selection is owned by CLI runtimes (Claude, Gemini, Codex,
OpenCode); middleware only reads the configured default from cfg.agents.defaults.

Live config-reading utilities relocated to src/agents/provider-utils.ts
(their natural home alongside existing provider normalization + model ref
parsing helpers):
- buildModelAliasIndex
- resolveConfiguredModelRef
- resolveDefaultModelForAgent
- ModelAliasIndex type

Dead stubs eliminated (zero production callers):
- resolveModelRefFromString (only the test-mock consumed it)
- resolveThinkingDefault (always returned undefined; caller block in chat.ts
  was unreachable — removed)
- getModelRefStatus (always returned undefined)
- inferUniqueProviderFromConfiguredModels (always returned undefined; caller
  block in session-utils.ts was unreachable — removed)
- splitTrailingAuthProfile (internal helper; only served resolveModelRefFromString)

14 callers migrated (issue listed 13 + 1 phantom; this PR additionally covered
provider-capabilities.ts, transcript-policy.ts, and get-reply.test-mocks.ts
which were missed by the issue's path-qualified grep):
- Category A (re-export redirects): agent-runner, directive-handling.model-picker,
  session-store, defaults, gateway-cli-backend.live.test, provider-capabilities,
  transcript-policy
- Category B (type relocation): directive-handling
- Category C (live-function callers): status.summary, sticker-cache, session-utils,
  chat (imports dropped + dead thinkingLevel fallback removed)
- Category D (test mocks): agent.test (with modelSelectionModule →
  providerUtilsModule rename), run.test-harness (mock retarget + stale mock
  helpers removed), get-reply.test-mocks (dead vi.mock block removed)

Zombie-import gate updated:
- scripts/check-no-zombie-imports.mjs: removed "agents/model-selection" from
  fallbackDeadModulePatterns + explanatory block
- scripts/data/zombie-import-allowlist.json: -12 entries
- .zombie-import-allowlist-baseline: 23 → 11

Baselines self-healed:
- .fork-boundary-mock-baseline: 133 → 132 (direct: removed vi.mock in
  get-reply.test-mocks.ts)
- .obsolescence-baseline: 134 → 49 (this PR: -1; pre-existing unbaselined
  improvements: -84 — verified via stash-based pre-change gate run)

Sibling precedents: #2414 (Discord model-picker gut), #2449/#2451 (Mattermost
model-picker gut). Surfaced during #2454 H3 restoration; closes #2355 debt.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
alexey-pelykh added a commit that referenced this pull request Apr 21, 2026
…tion per MBP (#2455) (#2456)

Delete src/agents/model-selection.ts (170 LOC) per Middleware Boundary
Principle. Model selection is owned by CLI runtimes (Claude, Gemini, Codex,
OpenCode); middleware only reads the configured default from cfg.agents.defaults.

Live config-reading utilities relocated to src/agents/provider-utils.ts
(their natural home alongside existing provider normalization + model ref
parsing helpers):
- buildModelAliasIndex
- resolveConfiguredModelRef
- resolveDefaultModelForAgent
- ModelAliasIndex type

Dead stubs eliminated (zero production callers):
- resolveModelRefFromString (only the test-mock consumed it)
- resolveThinkingDefault (always returned undefined; caller block in chat.ts
  was unreachable — removed)
- getModelRefStatus (always returned undefined)
- inferUniqueProviderFromConfiguredModels (always returned undefined; caller
  block in session-utils.ts was unreachable — removed)
- splitTrailingAuthProfile (internal helper; only served resolveModelRefFromString)

14 callers migrated (issue listed 13 + 1 phantom; this PR additionally covered
provider-capabilities.ts, transcript-policy.ts, and get-reply.test-mocks.ts
which were missed by the issue's path-qualified grep):
- Category A (re-export redirects): agent-runner, directive-handling.model-picker,
  session-store, defaults, gateway-cli-backend.live.test, provider-capabilities,
  transcript-policy
- Category B (type relocation): directive-handling
- Category C (live-function callers): status.summary, sticker-cache, session-utils,
  chat (imports dropped + dead thinkingLevel fallback removed)
- Category D (test mocks): agent.test (with modelSelectionModule →
  providerUtilsModule rename), run.test-harness (mock retarget + stale mock
  helpers removed), get-reply.test-mocks (dead vi.mock block removed)

Zombie-import gate updated:
- scripts/check-no-zombie-imports.mjs: removed "agents/model-selection" from
  fallbackDeadModulePatterns + explanatory block
- scripts/data/zombie-import-allowlist.json: -12 entries
- .zombie-import-allowlist-baseline: 23 → 11

Baselines self-healed:
- .fork-boundary-mock-baseline: 133 → 132 (direct: removed vi.mock in
  get-reply.test-mocks.ts)
- .obsolescence-baseline: 134 → 49 (this PR: -1; pre-existing unbaselined
  improvements: -84 — verified via stash-based pre-change gate run)

Sibling precedents: #2414 (Discord model-picker gut), #2449/#2451 (Mattermost
model-picker gut). Surfaced during #2454 H3 restoration; closes #2355 debt.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant