refactor(channels): delete the two dead outbound-upload surfaces - #7542
Conversation
Design Review (Fable 5) — ✅ PASSDesign-level review of Design-Verdict: PASS Pure dead-code removal, verified dead: no remaining callers of either deleted symbol, no transport interface break, and spec references point at the surviving client-level verbs. [DESIGN-REVIEWED] 7386cd9 |
GPT 5.6 Review — ✅ no blocking findingsGPT 5.6 completed its review of This comment is updated in place on each push. Review detailsNo findings. False positive or not applicable? A repository writer can comment: |
Opus 4.8 Review — ✅ no blocking findingsReviewed Verdict parsed from the review's SHA-scoped output markers for commit False positive or not applicable? A repository writer can comment: |
First Principles Review (Fable 5) — ✅ PASSPremise-level review of All claims verified. Both deletions are clean: First-Principles-Verdict: PASS Pure subtraction of two zero-consumer surfaces, with every riding item forced by the deletion itself — this is the change this lane exists to ask for. What this change shipsIntent: delete two upload seams that shipped for transports that never landed, so readers stop trusting a documented path no message takes. This is a SUBTRACTION (a fix by deletion), not an addition.
The description's zero-caller claims, the spec's silence on both symbols, and the client-verb survivals were each verified by grep, not taken from the PR text. Nothing to subtract from a subtraction. [FIRST-PRINCIPLES-REVIEWED] 7386cd9 |
|
Disposition for the two red shards on Evidence that it is main-owned:
Tracked on main as #7549. Not folding a fix for it into this PR: it is someone else's file and the correct clearance is either raising Everything else on this head is green: 51 checks pass, all five review lanes clean with zero findings (Design PASS, GPT 5.6 no findings, Opus 4.8 no findings, First Principles PASS, UX success). |
`messaging/split.py::open_fence_at_end` and `DiscordTransport.send_message_with_files` were shipped in PR #4832 as surfaces the O3 Telegram / O4b Slack transports were expected to consume. Neither gained a consumer: `open_fence_at_end` has zero callers at all, and the transport verb's only callers were its own two tests -- the renderer uploads through the client verb (`renderer.py::_land_sealed` -> `DiscordClient.send_message_with_files`) and `file_send` routes through `send_document`, which `upload_destination.py` names explicitly. Pure subtraction, no replacement code: - split.py: the function and its `__all__` entry. Its `_advance` / `_lines` helpers stay -- `iter_fence_spans` and `iter_fence_lines` drive them. - discord/transport.py: the verb and its over-cap drop branch, plus the imports that branch was the last user of (`Sequence`, `DISCORD_MAX_FILES_PER_MESSAGE`, `logging` and the module logger). - The two cross-references that would have dangled now name live symbols: Discord's `send_document` docstring points at the client verb it is the name-preserving counterpart of, and Telegram's points at Discord's `send_document`. - test/test_discord_outbound_files.py: `TestTransportVerb`, the deleted verb's only callers. - test/test_file_send_channel.py: two mock transports no longer declare a verb the real class cannot have. `spec_set=["send_document"]` is now the guard the removed `assert_not_called` used to be -- an upload path reaching for any other verb raises instead of being audited after the fact -- and the verb-less Discord transport is modelled with `send_message`. Closes #4919
65882c3 to
7386cd9
Compare
bolichen97
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: refactor (5 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: code-move/dead-code removal only — deletes the two unused outbound-upload surfaces (DiscordTransport.send_message_with_files and messaging/split.open_fence_at_end), no behaviour change on live paths.
iamwhatever
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: refactor (5 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: deletes two surfaces verified dead by repo-wide search (DiscordTransport.send_message_with_files and messaging.split.open_fence_at_end, the latter exported in all with no caller anywhere); the live Discord upload path calls DiscordClient.send_message_with_files directly and the per-message file cap stays enforced as the renderer's extraction budget, so no behaviour change, and the messaging spec's reference is to the client method that remains.
bolichen97
left a comment
There was a problem hiding this comment.
Tier 1 auto-approve: refactor (5 files). Criteria: no conflict, no requested changes, security path denylist clean, design-doc gate clean, SAST annotations clean, security checklist all-NO, AI reviewers green. Category: deletes two surfaces with no remaining callers, verified against the PR head -- DiscordTransport.send_message_with_files (the renderer calls DiscordClient.send_message_with_files directly and never went through the wrapper) and messaging/split.open_fence_at_end (zero references repo-wide). No limit is lost with the wrapper: the 10-attachment ceiling it re-checked is enforced upstream at extraction (renderer passes max_files=DISCORD_MAX_FILES_PER_MESSAGE), and DISCORD_MAX_FILES_PER_MESSAGE is still imported and used there.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Upstream kirodotdev#7542 (3a5824d) converted dashboard/handlers/memory.py's two pip-stderr log sites to `redact_log_via_context` (via _redact_pip_stderr), so the module no longer reads a baseline redactor anywhere and the census entry only holds slack: on the merge ref, test_the_census_holds_no_slack fails with `dashboard/handlers/memory.py: 0 sites, census says 2`. Drop the entry per the census's emptied-module rule. No source change.
Problem / Motivation
Two outbound-upload surfaces shipped in #4832 as the seams the O3 Telegram / O4b Slack transports were expected to consume. Neither gained a consumer, and both are dead on
maintoday:messaging/split.py::open_fence_at_end-- zero callers anywhere, and zero tests. Its only other appearance is its own__all__entry.DiscordTransport.send_message_with_files-- zero production callers. The renderer uploads through the client verb (renderer.py::_land_sealed->DiscordClient.send_message_with_files), and thefile_sendpath resolvessend_documentby name (dashboard/upload_destination.py:284), never the extraction verb. The transport verb's only callers were its own two tests.Why it matters
Dead code that looks like a designed extension point is worse than dead code that looks dead. A reader arriving at
DiscordTransport.send_message_with_filesfinds a documented "transport-level upload verb" with a ceiling policy and a warning branch, and reasonably concludes the upload path goes through it -- it does not. The same goes for a publicopen_fence_at_endin a module whose spec enumerates its exports: it advertises a fence-state accessor no caller has ever needed, and its two tests (for the transport verb) buy confidence in a path no user reaches.It also costs maintenance directly. The transport verb carried an over-cap drop branch whose reasoning had to be kept true against the client's real ceilings, and it kept a module logger alive for one warning that never fires in production.
What changed (motivation -> approach -> change)
Task 1 and task 2 of #4919 both asked "give it a consumer or delete it". No consumer landed, and both surfaces stay reachable in git history if a future one wants them back, so deletion is the answer. Pure subtraction -- no replacement code, no behaviour change on any live path:
messaging/split.py: the function and its__all__entry. Its_advance/_lineshelpers stay, becauseiter_fence_spansanditer_fence_linesdrive them.discord/transport.py: the verb and its over-cap drop branch, plus the three imports that branch was the last user of (Sequence,DISCORD_MAX_FILES_PER_MESSAGE,logging) and the now-unused module logger.send_document-- the verbfile_sendactually calls -- is untouched.send_documentpoints at the client verb it is the name-preserving counterpart of, and Telegram'ssend_documentpoints at Discord'ssend_documentrather than at the deleted one.MessagingTransportdeclares no upload verb, so nothing is left abstract by the removal.Task 3 of #4919 (have
split_markdown_safedeclare its context-degrading tier so the Discord renderer can drop its syntheticprobe) is NOT a deletion and does not belong in this PR. It is carried forward as #7540, which also records that the third half of that task -- hoisting the restricted-session upload gate into a channel-neutral helper -- has already landed asmessaging/upload_gate.py::uploads_restricted.Tests
No new tests: a deletion's proof is that nothing needed the thing.
test_discord_outbound_files.py::TestTransportVerb(2 tests) -- the deleted verb's only callers.test_file_send_channel.pyno longer declare a verb the real class cannot have. In the delivering casespec_set=["send_document"]now IS the guard the removedassert_not_calledused to be, and a stricter one: an upload path reaching for any other verb raises on the mock instead of being audited after the fact. The verb-less-Discord-transport case is modelled withsend_message, which keeps its actual pin (adiscordlink whose transport lackssend_documentis a skip, not a crash -- distinct from the neighbouringteamscase, which never reaches the verb lookup at all).Targeted runs, all green:
test_messaging_split.py,test_discord_outbound_files.py,test_file_send_channel.py(252 passed), and the adjacent transport consumerstest_discord.py,test_capability_ledger.py,test_channel_registry.py,test_channel_transport_outbound_authz.py(320 passed). flake8 / isort / black clean on all five touched files;scripts/check_black_formatting.pypasses in scope.Manual verification
N/A -- unit coverage sufficient. Nothing on a live path changes: the two deleted symbols have no production callers, verified by grep across
src/,test/anddocs/for both names, with every surviving hit belonging to the client verb of the same name.Related Issues
Closes #4919
Refs #7540
Pattern harvest
Rule candidate:
lintPattern: a module-level
defexported in__all__with no reference anywhere insrc/ortest/.open_fence_at_endsurvived a year because__all__membership reads as intent and no gate distinguishes "public API" from "public and unused" -- a vulture-style unused-symbol pass oversrc/kiro_crew/**, behind a shrinking baseline like the black and per-file-coverage gates, would have flagged it the day its consumer failed to land. The Discord half is weaker as a rule candidate (the method is reachable in principle through duck-typed transport dispatch, so a naive callers-count check would false-positive across the channel layer) and its real tell was different: a verb whose only callers are its own tests. That one is a review-prompt line rather than a lint.