Go cleanup: dead code, pattern fixes, dedup, CI#7
Merged
Conversation
added 6 commits
June 9, 2026 18:42
Verified unreachable from all cmd/ entry points (GOOS=linux to keep the carbonyl runner's build-tagged callers visible): - tui/components: BrailleCanvas widget (never wired up), FlipAnimation + RenderFlipEdge (DealAnimation/Pulse/CoinShower remain in use) - tui/theme: BlendHex and its hex-math helpers - imaging/graphics: kitty/iterm2/sixel encoders and Encode/EncodeWithFallback (protocol Detect stays - transport still records the detected protocol) - doors/roulette: Payout (superseded by GrossReturn, which the coordinator uses); test pins GrossReturn cases only now - doors/roulette/multiplayer: Registry ctx/cancel/Stop - main runs the coordinator on the signal context directly, so the registry-owned lifecycle was vestigial; NewRegistry loses its ctx param - auth: NoopRateLimiter, DefaultRateLimitParams, unused dummyAlgo field, dead pgx.ErrNoRows placeholder in classifyInsertError - transport: unused Server.ListenAndServe (main serves via the netlimit-wrapped listener) - web: requireQueries, requestExt type, OAuthProviders.Has - tui/screens: unused chatTypingStyle - security/audit: unused stubRecorder test helper
- web: renderProfile now takes the status code and owns the full header sequence (Content-Type before WriteHeader). Three handlers previously called WriteHeader before renderProfile, which made the later Content-Type set a silent no-op, serving error re-renders without a charset. All call sites across profile/boards/chat/weather/avatar handlers updated; boards' new-topic re-render had the same bug. - tui: Root.fetchStatusTempCmd uses sess.CtxWithTimeout instead of context.Background so the status-bar weather fetch cancels on SSH disconnect, per the session package's own convention. - auth: VerifyDummy evaluates verifyPHC directly instead of recursing through Verify, whose unknown-format branch calls VerifyDummy - a dummyHash without the PHC prefix would have recursed forever. - staticcheck style nits: drop arg-less fmt.Sprintf in chat helpText (S1039), use copy() for the palette16 prefix in ansiconvert (S1001), reword finance resolver error strings to not end in ':' (ST1005).
…eens - providers/httpjson (new): the one GET-and-decode helper shared by the JSON providers. Owns request-with-context, header set, 200 check (non-200 yields a typed *StatusError carrying a body snippet), and decode. Callers keep their provider-prefixed errors by wrapping, and special-case upstream statuses via errors.As (CoinGecko/Yahoo 429 messages preserved). Converts ~10 hand-rolled copies across hackernews, lobsters, coingecko, yahoo, frankfurter, open-meteo, nws, and geocoding. - finance/news: replace the hand-rolled rssCacheEntry mutex cache with ttlcache.Cache[string, []Headline] (same TTL, adds singleflight; stale- on-error behavior preserved via ttlcache.StaleOnError). - web/cookies.go (new): secureCookie/expiredCookie constructors centralize the Path/HttpOnly/SameSite/Secure attribute set used by all five cookie sites (session mint+clear, oauth state, flash). - web/handlers_oauth: extract sealTokenFields, the serialization step the near-identical insert/upsert token writes shared. - tui/screens/chat: extract seedChannelLog for the log-init sequence the bootstrap/refan/local-switch handlers each repeated; the PFP-before- AppendAll ordering constraint now lives in one place. - tui/screens: fold truncateArea/truncateRow into format.go - truncateRunes is the rune-aware variant, byte-based truncateRow was truncate with a worse n<=1 edge (could split a rune); unify handToStrings/handStrings into one slice-based helper in format.go.
- .github/workflows/ci.yml: build, vet, test, gofmt, staticcheck, and deadcode on every push/PR. Linux runner is load-bearing - the carbonyl runner is //go:build linux, so any other GOOS false-positives its helpers as dead. deadcode always exits 0, so the step fails on output (allowing the test-covered NoopRecorder noop). No LFS checkout; the Carbonyl bundle is only needed by deploy.yml's docker build. - .gitattributes: force LF for *.go / go.mod / go.sum so Windows checkouts under autocrlf stop making gofmt -l flag every file. All 273 .go files already store LF in the index, so this only affects fresh checkouts - no renormalization commit needed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Codebase-wide Go cleanup from a
deadcode/staticcheck/manual sweep. Net −539 lines across 52 files. Four commits, ordered by risk:1. Dead code deletion (
c9bd201, −599 lines)Everything verified unreachable from all
cmd/entry points withGOOS=linux deadcode(Linux tags matter — on Windows the carbonyl runner's callers are invisible and false-positive):tui/components: BrailleCanvas widget (never wired up), FlipAnimation +RenderFlipEdge(Deal/Pulse/CoinShower remain in use)tui/theme:BlendHex+ hex-math helpersimaging/graphics: kitty/sixel/iterm2 encoders andEncode/EncodeWithFallback.Detect/Protocolstay (tested, plumbed through transport) — but note the detected protocol is currently a write-only session field; nothing reads it.doors/roulette:Payout(superseded byGrossReturn, which the coordinator uses)doors/roulette/multiplayer: the Registry'sctx/cancel/Stopmachinery. Its doc comment prescribed aStop()-after-Persistshutdown ordering it could never deliver (the internal context derived from main's signal context, andreg.ctxwas unexported so main couldn't follow the prescribed pattern anyway). Removed; theRuncontext the caller passes is the real lifecycle, and the refund hook covers in-flight bets.auth:NoopRateLimiter(zero refs, even tests),DefaultRateLimitParams, unuseddummyAlgofield, dead_ = pgx.ErrNoRowsplaceholdertransport: unusedServer.ListenAndServe(main serves via the netlimit-wrapped listener)web:requireQueries, therequestExttype,OAuthProviders.HaschatTypingStyle, the unusedstubRecordertest helper2. Pattern fixes (
b45e430)renderProfileheader ordering: handlers calledw.WriteHeader()beforerenderProfile, whose laterContent-Typeset was a silent no-op — error re-renders shipped without a charset.renderProfilenow takes the status and owns the full Content-Type → WriteHeader → execute sequence; all call sites across profile/boards/chat/weather/avatar updated (boards' new-topic re-render had the same bug).Root.fetchStatusTempCmdusedcontext.Background(); nowsess.CtxWithTimeout(5s)so the status-bar weather fetch cancels on SSH disconnect.VerifyDummyrecursion footgun: it round-tripped throughVerify, whose unknown-format branch callsVerifyDummy— a dummy hash that ever lost its PHC prefix would recurse forever. Now callsverifyPHCdirectly.3. Duplication consolidation (
a2aa852)providers/httpjson: one GET-and-decode helper replacing ~10 hand-rolled copies (hackernews, lobsters, coingecko ×2, yahoo, frankfurter, open-meteo, nws, geocoding). Non-200 yields a typed*StatusErrorwith a body snippet; providers keep their error prefixes by wrapping and preserve their 429 special-cases viaerrors.As.finance/news: hand-rolledrssCacheEntrymutex cache →ttlcache.Cache(same TTL + stale-on-error, gains singleflight).web/cookies.go:secureCookie/expiredCookiecentralize the Path/HttpOnly/SameSite/Secure attribute set used by all five cookie sites.web/handlers_oauth: extractedsealTokenFieldsfrom the near-identical insert/upsert token writes.tui/screens/chat: extractedseedChannelLogfrom the bootstrap/refan/local-switch handlers; the PFP-before-AppendAll ordering constraint now lives in one place, and the local-switch nil-reactions guard is preserved via an explicit flag.tui/screens:truncateArea/truncateRowfolded into format.go (truncateRunesis the rune-aware variant; byte-basedtruncateRowwastruncatewith a worse n≤1 edge that could split a rune);handToStrings/handStringsunified.4. CI + line endings (
3add895).github/workflows/ci.yml: build/vet/test/gofmt/staticcheck/deadcode on every push + PR. Linux runner is load-bearing (carbonyl build tags). No LFS checkout — the bundle is only needed by deploy.yml's docker build..gitattributes:*.go text eol=lfso Windows checkouts stop makinggofmt -lflag every file. All 273 .go files already store LF in the index, so no renormalization churn.Deliberately not changed
ReadTimeout/WriteTimeout:/ws/bbsis a long-lived hijacked connection and the deadline interaction needs investigation first; Cloudflare fronts the HTTP surface meanwhile.audit.NoopRecorder: test-covered nil-object of the Recorder interface (unlike the truly orphanedNoopRateLimiter).Verification
go build,go vet, fullgo test ./...,GOOS=linux go build, andGOOS=linux staticcheck ./...all clean at every commit boundary.