Ponytail-audit: ~4.8k lines / 5 deps removable (one finding is ~3.9k of it) #376
harshitsinghbhandari
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
A repo-wide ponytail-audit hunting only for over-engineering and complexity (correctness/security/perf were explicitly out of scope). Run across ~87k LOC with 8 parallel scoped passes. Findings ranked biggest cut first.
TL;DR: ~4,800 lines and 5 deps are removable, but ~3,900 of those lines are one finding: the 23 agent adapters are near-identical copy-paste. Everything else is rounding error by comparison.
Tier 1 — The big cut: agent-adapter duplication (~3,900 lines)
The 23 adapters in
backend/internal/adapters/agent/*reimplement the same logic per-adapter.yagni:6hooks.gofiles (claudecode, qwen, codex, droid, agy, goose) reimplement the same settings-JSON hook engine (readXSettings/writeXSettings/groupXHooksByEvent/isXManagedHook/parseXHookType/addXHook/matchersEqual+ matcher/spec structs). Hoist one generichookjsonhelper; adapters keep only their hook list + paths. ~1,500 lines.shrink:23 copies ofResolveXBinary(identical PATH lookup + windows.cmd/.exeblock +/usr/local/bin,/opt/homebrew/bincandidates) → onehookutil.ResolveBinary(ctx, name, extra...). ~1,100 lines.shrink:16 byte-identicalnormalizePermissionMode+ ~17 near-identicalappendPermissionFlags→ package-levelnormalizePermissionMode+ClaudeStylePermissionFlags(cmd, mode). ~300 lines.shrink:23 copies ofbinaryMu sync.Mutex/resolvedBinary+ per-adapter cache method → one embeddablebinaryCache.Get(ctx, resolveFn). ~250 lines.shrink:~10DeriveActivityStatefuncs are the same string-switch →activitydispatch.DeriveStandardEvent. ~250 lines.shrink:~22 no-opGetConfigSpec+ 23 identicalGetPromptDeliveryStrategy→ embeddabledefaultAgentbase. ~200 lines.shrink:~15 identicalSessionInfo-from-metadata methods → onehookutil.SessionInfoFromMetadata. ~200 lines.shrink:23 identicalfileExists(os.Stat+!IsDir) → onehookutil.FileExists. ~90 lines.stdlib:qwenatomicWriteFile+ claudecode temp+rename duplicate existinghookutil.AtomicWriteFile. ~50 lines.Tier 2 — Dead legacy paths (~410 lines)
delete:legacyObservelump inscm/github/provider.go:98-656(Observe,restPull,fetchGraphQL,parsePRURL, +9 more) — no non-test caller; live path isobserver_provider.go. ~155 lines.delete:whole fileinternal/ports/pr_observations.go:1-55(PRObserver,PRObservation,ErrSCMPRNotFound) — zero users; live path isSCMObservation.delete:frontend/.../ui/sidebar.tsx— 8 never-imported shadcn parts (SidebarRail, SidebarInset, SidebarMenuBadge…). ~120 lines.delete:landing/components/LandingDifferentiators.tsx— zero importers. ~58 lines.delete:app/docs/404/page.tsx— unreachable; Next routes to existingnot-found.tsx.Tier 3 — Speculative single-impl abstractions (yagni)
yagni:adapters/registry.go:1-83top-levelRegistry— no production registrant; agent/reviewer registries are separate. Delete.yagni:reviewerpackage = registry+resolver+interface over exactly one product (claudecode). Collapse to directclaudecode.New()or a 3-line map.yagni:service/prActionManagerinterface +ActionServicestub — interface seam over a stub that fabricates success. Collapse or delete until the SCM merge path exists.yagni:scm/github/auth.goFallbackTokenSource+tokenInvalidatorfan-out — prod wires a single source.yagni:httpd/controllers/dto.go:44-94ProjectOrDegradedcustom marshaler — the comment admits the real guard is upstream;omitempty+ nil-check does it.yagni:ports.AgentMessenger/runtimeMessageSendersingle-method ports over the one concrete*zellij.Runtime.Tier 4 — Frontend dead exports/variants (~230 lines)
delete:types/workspace.tsexports referenced only by their own tests (mergedPRCount,primaryPR,workerStatusPulses,sessionNeedsAttention,workerStatusLabel,attentionZoneLabel/Order) + their tests. ~50 lines.delete:unusedWorkspaceSummaryfields (type/diff/accentColor),displayStatus,ChangedFile.delete:WorkbenchTabstate inui-store.ts(comment says selection moved to URL).delete:unused Badge variants (neutral/accent/success/warning/error) + Buttonsecondary/icon-sm.Tier 5 — Deps removable (frontend)
native:4 deps@radix-ui/react-{dialog,slot,tabs,tooltip}→ already-present umbrellaradix-uire-exports all four. -4 deps.yagni:bareplaywrightalongside@playwright/test(borderline). -1 dep.Tier 6 — Small stdlib/shrink one-liners
stdlib:cli/doctor.go:509-554hand-rolledcompareDottedVersion→golang.org/x/mod/semver.Compare(already in module graph).shrink:cliconfirm prompts (confirm/confirmProjectRemoval/confirmSessionCleanup) → onepromptLinehelper.shrink:cli/client.gopatchJSON/putJSON/deleteJSONone-line wrappers → inlinehttp.Method*.stdlib:httpd/logger.gologgerOrDefault→cmp.Or(log, slog.Default()).shrink:service/project/service.go:431isGitRepotail is dead →return strings.EqualFold(top, path).delete:unused gen queryDeletePRReviewThreads,cdc.SubscriberCount(),terminal/attachment.isExited(),RemovedStorageDirfield.cli,session_manager,daemon,lifecycle,zellij.Net
net: ~-4,800 lines, -5 deps possible.
The single highest-leverage move by far is a shared
hookutil/defaultAgentbase for the 23 agent adapters (~80% of the total). I'd scope that as its own focused PR (introducehookutil+defaultAgent, migrate adapters in batches) rather than folding it into other cleanup.Explicitly NOT flagged (genuinely lean)
The apispec code-first generator + drift test, the SCM observer diff/persistence machinery, the CDC poller, terminal attach loop,
gen/sqlc output,src/api/schema.ts(generated), thesrc/shared/*testability splits, and the//go:buildplatform forks. These earn their keep.Beta Was this translation helpful? Give feedback.
All reactions