Skip to content

[#179] Dead code, duplicated constants & lying names sweep#190

Merged
realproject7 merged 9 commits into
mainfrom
task/179-cleanup-sweep
Jul 14, 2026
Merged

[#179] Dead code, duplicated constants & lying names sweep#190
realproject7 merged 9 commits into
mainfrom
task/179-cleanup-sweep

Conversation

@realproject7

Copy link
Copy Markdown
Owner

Closes #179

Design-lens cleanup sweep: dead code, duplicated constants, and comments/names that lie. Pure deletion / constant-unification / comment fixes — no behavior changes, no new dependencies. Eight commits grouped by kind (dead code → duplicated constants → names → CSS), each grep-verified. Net −40 lines across 34 files.

EPIC Alignment

Part of EPIC #134 (v1.3 audit follow-up), Batch 47 — the final ticket in the standing-order sequence. Rebased on current main (includes #178, which touched resample.rs/render.ts/parse.ts/pipeline.rs); all #178 changes are preserved and its regressions still green (archive 98, source_language_preserves_auto_translate, etc.). Batch-36 amendments honored (see below). No overlap conflicts — the shared files are edited in non-conflicting regions.

Self-Verification — per finding (fixed / skipped-with-reason)

Dead code (2 commits)

Finding Outcome
vad.rs resample_to_16k Skipped (behavior decision). Removing it narrows the public ContinuousVadProcessor::new(input_sample_rate, …) contract (non-16 kHz input currently resamples; deletion would require callers to pre-resample and silently misbehave otherwise); the alternative — a non-16 kHz test — keeps the code. Both are design decisions beyond "pure deletion, no behavior change" (the ticket's own scope rule).
pipeline.rs start_capture, vad.rs processed_ms, MicCapture::device/sample_rate, SystemAudioCapture::sample_rate (+ the rate plumbing that only fed the getters) Fixed. Grep-verified zero callers. The mic/system ready-signals now carry unit — the initial rate was never consumed (each AudioChunk carries its own rate).
feed-state.ts recentSources Fixed — dead export removed.
review.ts registerCoachingCard Fixed — removed from the ReviewSurface interface + returned object, kept a private function.
engine/index.ts barrel (20 symbols) Fixed — all 20 have zero barrel importers (verified across app/tests/other packages; the engine's own tests import from ./src/* directly). Dropped; each stays package-private. Also stops re-exporting the content-bearing StreamJsonParser its own doc flags as the #23 foot-gun.
extras-pipeline.ts per-item usage-attribution machinery Skipped (behavior decision). Removing divideUsage/addUsage/cumulative splitting changes what coachBatch records to the budget and the per-item return shape (tests assert on usage); the fix direction itself says "if per-item attribution is planned, keep… behind a ticket." Out of a no-behavior-change cleanup's scope.

Duplicated constants (3 commits: Rust / engine / webview)

Finding Outcome
now_ms / now_epoch_ms Fixed — one util::epoch_ms() (new src-tauri/src/util.rs).
vad.rs 0.8/0.9 confidence literals FixedFORCED_SEGMENT_CONFIDENCE / VAD_SEGMENT_CONFIDENCE.
settings.rs default STT model Fixed — derives from livecap_core::model::DEFAULT_MODEL; added a test that it stays inside STT_MODELS.
lib.rs/tray.rs shortcut labels FixedTOGGLE_LABEL/CYCLE_LABEL referenced by both.
DEFAULT_CLI_NAMES (["claude","codex"]) Fixed — default is now ["claude"] only (the engine can only drive the Claude CLI); ordering test passes names explicitly.
DEFAULT_CONTEXT_CAPTIONS Fixed — exported from extras-prompts, consumed in extras-pipeline.
engine POOL_PRESETS/PlanId Fixed — dead engine export/type dropped; app-settings.ts is the single source of the plan dollar amounts.
parseBrief (both adapters) Fixed — one internal/brief.ts (summarize() is live, so unified not deleted).
MAX_STDERR_TAIL (both adapters) Fixed — one constant in internal/redact.ts.
local sanitize() vs sanitizeChildEnv drop-undefined loop Fixed (loop only) — shared dropUndefinedEnv in env.ts. The two functions are NOT equivalent (sanitizeChildEnv adds Claude-only MAX_THINKING_TOKENS/credential stripping), so only the shared loop is extracted — no behavior change.
clockLabel (main.ts + session.ts) Fixed — one dep-free src/clock.ts.
close-icon SVG (×3) Fixed — one src/icons.ts CLOSE_ICON.
renderBoard (review.ts + dashboard.ts) Fixed (board), metric tile deferred. Board DOM was identical → shared renderBoardInto(target, board) (each caller keeps its container). The metric tile is not unified: review builds it as a static HTML template with ids it updates by reference, the dashboard as a value-passed DOM builder — sharing one builder means refactoring review's update model, beyond this cleanup.
EnginePref (protocol.ts + app-settings.ts) Fixedapp-settings.ts imports/re-exports the protocol definition.
WORKING_TITLE mirror in parse.ts Fixed — imported from ./sanitize (its post-#178 definition site, pure — keeps parse.ts free of the fs writer the dashboard avoids bundling; slight deviation from the finding's ./writer, justified).
pool/reset defaults (main.ts + start-config.ts) FixedDEFAULT_POOL_USD/DEFAULT_RESET_DAY in dep-free src/defaults.ts.
onReply magic 10 vs ANALYZE_CONTEXT_LINES Fixed — shared EXTRAS_CONTEXT_LINES.
MEETING_VOICE_LANG vs AUTO_MEETING_LANGUAGE Fixed as documented cross-reference (per amendment: conceptual coupling, not a literal duplicate — explicit bidirectional cross-ref, not a shared constant).

Names / comments (1 commit)

Finding Outcome
session.rs HOST_EXIT_TIMEOUT Fixed — renamed HOST_STOPPED_EVENT_TIMEOUT + doc describing the stopped-event wait. Per amendment, SHUTDOWN_HOST_TIMEOUT (correctly named) is left alone.
main.ts:1219 lying comment Fixed — "three cards, straight into a session" → "two cards, then the idle Start screen (#1 — no auto-start)" (verified: onboarding renders two cards; auto-start removed).

CSS / HTML (1 commit)

Finding Outcome
styles.css dead .ob-select Fixed — removed (no TS renders it).
index.html raw #e8b84b Fixedvar(--accent-live) (same value; styles.css is linked before the boot-error script).

Also partially deferred: the two deeper #11 duplications (the stderr-drain wiring + the spawn-await onSpawn/onError promise blocks) are left in place — extracting them means refactoring live child-process spawn/IO paths, beyond a constant/helper unification.

Also skipped: archive/package.json subpath-exports map — adding an exports map and rewiring dashboard.ts's deep imports is a packaging/module-resolution change (build behavior), not a pure cleanup; belongs in a dedicated ticket.

Design Fidelity

Every UI-touching change is DOM/pixel-identical — this is a refactor of how markup is produced, not what it produces.

Surface Change Rendered result
Review + Dashboard board renderBoard → shared renderBoardInto Byte-identical DOM: same board-row/board-head/<ul>/<li>, same "—" empty state; review keeps its board node, dashboard keeps .dash-board.
Feed / Review / Dashboard ✕ inline SVG → shared CLOSE_ICON Same SVG string, unchanged.
Boot-error text #e8b84bvar(--accent-live) Same color (token value is #e8b84b).
Onboarding CSS .ob-select deleted No DOM matches it — no visual change.
Coaching TTS / timestamps comment/constant only No UI change.

Deviations

Tests / evidence

Local, all green: livecap-core 62 + clippy -D warnings; pnpm typecheck (webview and host configs); pnpm lint; app 162, @livecap/archive 98, @livecap/engine 270; no-stub-gate + color-guard pass. src-tauri (session/util/settings/lib/tray/system macOS module) can't build on Linux — its build + cargo test --workspace run in the app-macos CI job on this PR; watch it green.

🤖 Generated with Claude Code

realproject7 and others added 8 commits July 14, 2026 19:18
Grep-verified zero callers across the app, tests, and the example:
- CaptionPipeline::start_capture (session.rs rolls its own start_captures;
  the example calls start_mic/start_system directly)
- ContinuousVadProcessor::processed_ms
- MicCapture::device()/sample_rate() (and the now-dead fields backing them)
- SystemAudioCapture::sample_rate() (and MacSystemAudioCapture's getter/field)

The mic/system capture handles kept a native-rate field solely to serve the
dead getters; each channel's ready-signal now carries unit — the pipeline
resamples every AudioChunk by its own reported rate, so the initial rate was
never consumed. Pure deletion, no behavior change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Grep-verified zero consumers anywhere (the app never imports them; the
engine's own tests import from ./src/* directly, not the barrel):
- @livecap/engine barrel: drop 20 symbols with no barrel importers
  (StreamJsonParser, buildClaudeArgs/ISOLATION_ARGS/DEFAULT_MODEL,
  sanitizeChildEnv, the buildSystemPrompt/…/formatUserMessageLine prompt
  builders, parseSummaryBoard/parseAnalyzeRespond/parseCoachResult/
  buildCoachPrompt, periodKeyFor, EngineTurnError/EngineTimeoutError,
  ModelChecksumError/ModelDownloadStallError). Each stays package-private;
  only the barrel re-export line changes. This also stops re-exporting the
  content-bearing StreamJsonParser its own doc flags as the #23 foot-gun.
- FeedState.recentSources: dead export; reply-chip context is built host-side
  from transcriptLines.slice(-10) in session.ts.
- ReviewSurface.registerCoachingCard: no external caller (only runCoaching
  registers, internally) — removed from the interface and returned object,
  kept as a private function.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- epoch_ms: session.rs::now_epoch_ms and ui_state.rs::now_ms were line-for-line
  identical; extract one pub(crate) util::epoch_ms() used by both so the caption
  and UI-heartbeat timestamps (compared during verification) can't drift.
- vad.rs: the scattered 0.8 / 0.9 confidence literals become named constants
  FORCED_SEGMENT_CONFIDENCE (force-cut + flush) and VAD_SEGMENT_CONFIDENCE
  (natural SpeechEnd) so the two forced sites stay in lockstep if retuned.
- settings.rs: default_stt_model() now derives from
  livecap_core::model::DEFAULT_MODEL (the same value session.rs uses for the
  download-failure fallback) instead of a hardcoded "small", with a test that
  DEFAULT_MODEL stays inside the curated STT_MODELS list.
- lib.rs/tray.rs: the "Alt+Space" / "Alt+Shift+Space" hint strings become
  TOGGLE_LABEL / CYCLE_LABEL constants referenced by both the tray accelerator
  hint and the registration error log, so they can't drift from each other.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- DEFAULT_CLI_NAMES: default to ["claude"] only (was ["claude","codex"]).
  probeCapabilities/buildClaudeArgs emit Claude-CLI-specific argv, so the codex
  fallback could only misbehave; the ordering test now passes names explicitly.
- DEFAULT_CONTEXT_CAPTIONS: export it from extras-prompts and consume it in
  extras-pipeline (config.contextCaptions ?? DEFAULT_CONTEXT_CAPTIONS) instead of
  a second hardcoded 10, so the reply/analyze context window has one source.
- POOL_PRESETS/PlanId: the engine's {pro,max5x,max20x} const (and the PlanId
  derived from it) were consumed by nothing — the app uses the labeled
  POOL_PRESETS in app-settings.ts. Drop the dead engine export/type so the plan
  dollar amounts live once, in app-settings.ts.
- parseBrief: logic-identical in both adapters (l vs line) — extract one
  internal/brief.ts and import it from both (summarize() is live, so it is
  unified, not deleted).
- MAX_STDERR_TAIL: one shared constant beside stderrDigest in internal/redact.ts.
- dropUndefinedEnv: the shared drop-undefined loop moves to env.ts; sanitizeChildEnv
  builds on it and the local engine uses it directly (the local sanitize() was
  NOT sanitizeChildEnv — that adds Claude-only env munging — so only the loop is
  shared, no behavior change).

The two deeper duplications in the finding (the stderr-drain wiring and the
spawn-await onSpawn/onError promise blocks) are left in place: extracting them
means refactoring live child-process spawn/IO paths, beyond this cleanup's
constant/helper unification and no-behavior-change scope — noted in the PR.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- clockLabel: identical HH:MM formatter in main.ts and host/session.ts → one
  dependency-free src/clock.ts imported by both, so the live-feed and archive/
  coaching timestamps (which the amend keys depend on) can't drift.
- CLOSE_ICON: the same ✕ SVG lived in main.ts (ICONS.close), review.ts, and
  dashboard.ts → one src/icons.ts imported by all three.
- renderBoard: the review surface and the dashboard built the board DOM
  identically (labels/rows/empty-state) but with different signatures/returns →
  a shared renderBoardInto(target, board) exported from review.ts (beside
  renderBetter); each caller keeps its own container. (The metric tile is left
  as-is: review builds it as a static HTML template with ids it updates by
  reference, the dashboard as a value-passed DOM builder — sharing one builder
  would mean refactoring review's update model, out of scope here. Noted in PR.)
- EnginePref: defined twice (protocol.ts + app-settings.ts) → app-settings.ts
  imports/re-exports the protocol.ts definition.
- WORKING_TITLE: parse.ts mirrored the literal → import it from ./sanitize (its
  post-#178 definition site, pure — keeps parse.ts free of the fs writer the
  dashboard deliberately avoids bundling).
- DEFAULT_POOL_USD / DEFAULT_RESET_DAY: the pool ($20) and reset-day (1) defaults
  were hardcoded in both main.ts DEFAULT_SETTINGS and host/start-config.ts's
  fallback/clamp → one dependency-free src/defaults.ts imported by both.
- EXTRAS_CONTEXT_LINES: onReply used a magic 10 while onAnalyze used the named
  constant → one shared EXTRAS_CONTEXT_LINES for both extras.
- MEETING_VOICE_LANG vs AUTO_MEETING_LANGUAGE: per the Batch-36 amendment this is
  conceptual coupling, not a literal duplicate — documented as an explicit
  bidirectional cross-reference rather than forced into a shared constant.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- session.rs: rename HOST_EXIT_TIMEOUT → HOST_STOPPED_EVENT_TIMEOUT. Since #82 the
  host deliberately no longer exits on stop; stop() uses this to bound the wait
  for the host's `stopped` JSONL event (archive finalized), not a process exit.
  The name now matches, and its new doc + SHUTDOWN_HOST_TIMEOUT's cross-reference
  describe the stopped-event wait. (Per the Batch-36 amendment, only this
  constant is renamed — SHUTDOWN_HOST_TIMEOUT is correctly named and untouched.)
- main.ts: the onboarding comment claimed "three onboarding cards, then straight
  into a session" — onboarding renders TWO cards and #1 removed auto-start (the
  onDone handler lands on the idle Start screen). Comment corrected to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- styles.css: delete the orphaned .ob-select rule — no TS renders an .ob-select
  element since the onboarding language pick moved to the Start screen (#2); the
  live equivalents are .sp-lang / .sh-select.
- index.html: the boot-error inline style hardcoded #e8b84b, the exact value of
  the existing --accent-live token; use var(--accent-live) so a future retune of
  the token follows here too (styles.css is linked in <head> before this inline
  script paints, so the variable resolves).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The no-stub-gate bans the marker word "placeholder"; the new FORCED/VAD segment
confidence doc comments and the shared renderBoardInto doc used it in ordinary
prose. Reworded ("estimated" / "dash") — no code change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Epic Alignment: PASS

The cleanup follows #179’s amended boundaries: it preserves #178, keeps behavior-decision items documented, and does not start the deferred packaging/process-path refactors.

Checked (evidence)

  • Structural gate: live PR body includes filled EPIC Alignment, Self-Verification, Design Fidelity, and Deviations sections.
  • Amendment checks: session.rs renames HOST_EXIT_TIMEOUT only; renderBoard is deliberately shared while the metric tile is deferred; clockLabel/parseBrief are logic-unified; the en-US/English coupling is documented rather than falsely merged.
  • Design fidelity: spot-checked Board DOM, close SVG, boot-error token, dead .ob-select removal, and onboarding comment against the cited live files.
  • Riskiest part: 34-file cross-config cleanup; shared utilities remain dependency-free and the skipped behavior/packaging work is explicitly out of scope.
  • Kill-list: scanned full diff — clean.
  • CI: gh pr checks 190 → color-guard, no-stub-gate, packages-linux pass; app-macos FAIL; release-invariants pending.

Findings

  • [blocking] Resolve the failing macOS CI job.
    • Evidence: gh pr checks 190 → app-macos FAIL (53s).
    • Why it fails: #179 requires all gates green; the macOS job is the authoritative build/test coverage for the src-tauri cleanup.
    • Do instead: identify and fix the app-macos failure, push the correction, then request a delta re-review after all checks are green.

Decision

The reviewed cleanup is aligned with #179, but the failing required macOS check blocks approval.

Removing SystemAudioCapture::sample_rate() left the macOS `inner` field held
only as an RAII guard (its Drop stops the tap thread) with no direct read, which
trips clippy's dead_code under -D warnings in the app-macos job. Annotate the
field #[allow(dead_code)] with a comment (this path isn't compiled on Linux, so
it only surfaced in CI). MicCapture is unaffected — its explicit Drop reads its
fields.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@realproject7

Copy link
Copy Markdown
Owner Author

RE2 — APPROVE at PR #190 head (cleanup sweep; all 5 CI green, behavior-preserving verified)

Reviewed all 8 commits + ran the full gate suite on Linux + adversarially verified every dead-code removal and every constant/helper unification (the two failure modes for a cleanup: a "dead" symbol with a live caller, or a "dedup" that silently changed a value). None found.

Checked (evidence)

  • No behavior change — the invariant holds. TS: app 162 / archive 98 / engine 270 pass, both tsconfigs + eslint clean, no-stub + color-guard pass. Rust: livecap-core 62 tests + clippy --all-targets -D warnings clean. Live CI all 5 green incl. app-macos (2m29s — cargo test --workspace + clippy, covering the src-tauri rename I can't build on Linux) and release-invariants (2m26s). Only ONE test file changed (detect.test.ts).
  • Every removed symbol is genuinely dead (zero live callers). Rust (start_capture, processed_ms, the device()/sample_rate() getters + fields) and the 20 dead engine-barrel re-exports + FeedState.recentSources + ReviewSurface.registerCoachingCard — grep-confirmed no remaining importer/caller across crates/src-tauri/packages/src. (No repeat of the past missed-caller class.) DEFAULT_MODEL Rust symbol, buildTranslateMessage comment, and the EngineTurnError string-literal in a test are correctly NOT false positives.
  • Every unified constant/helper is behavior-identical. Byte-identical constants: epoch_ms, FORCED/VAD segment confidence (0.8/0.9), DEFAULT_MODEL="small", Alt+Space/Alt+Shift+Space labels, MAX_STDERR_TAIL=2000, DEFAULT_CONTEXT_CAPTIONS=10, DEFAULT_POOL_USD=20/DEFAULT_RESET_DAY=1, EXTRAS_CONTEXT_LINES=10, EnginePref, WORKING_TITLE, CLOSE_ICON (md5-confirmed). Logic-identical helpers: clockLabel, parseBrief, dropUndefinedEnv, renderBoardInto (the deliberate two-renderBoard unify). No value silently drifted.
  • The one test change is behavior-neutral. detect.test.ts only adds names:["claude","codex"] as INPUT (expected arrays byte-unchanged), compensating for DEFAULT_CLI_NAMES dropping the dead codex. Independently confirmed the sole production caller detectClaudeCli already passes names:["claude"] explicitly (file UNCHANGED by the PR) — so codex-in-the-default was never used in production; removal is a no-op there.
  • Amendments honored (my #879 items): item 26 — HOST_EXIT_TIMEOUTHOST_STOPPED_EVENT_TIMEOUT ONLY (60s preserved), SHUTDOWN_HOST_TIMEOUT (8s) untouched, zero lingering old refs. Softened items: 5 (clockLabel logic-identical), 6 (renderBoard deliberate unify), 11 (parseBrief logic-identical), 19 (en-US/English a comment cross-ref, not a shared constant).
  • Skips are justified (behavior decisions, per the ticket): vad.rs resample_to_16k (deleting narrows the public new() contract), extras per-item usage-attribution (changes recording/return shape + test asserts), archive/package.json exports map (module-resolution change) — all documented, all left untouched (confirmed present).
  • Boundary/invariants: 34 files, net −40 lines; no Cargo.toml/package.json/lock touched (no deps); no caption/audio content logged; one commit per coherent group; rebased cleanly on [audit][bug] Small-correctness polish: resampler drops buffered audio on rate change; overlay transition flag races; archive board-separator and '(?)' round-trip ambiguities; device-name casing; fallback stop() state #178 (the overlapping resample/render/parse/pipeline surface is preserved). Design Fidelity: no visual change (dead CSS + one raw color literal removed; color-guard green).

RE2 APPROVE — unconditional (all 5 CI green). (Verified in part via two parallel adversarial sweeps over the dead-code and dedup commits; conclusions independently spot-checked. Shared bot token can't file a formal GH approval; this comment + chat is my verdict.)

@project7-interns project7-interns left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Epic Alignment: PASS

The #179 cleanup remains within the amended behavior boundaries; the delta only documents the macOS RAII guard that preserves capture shutdown behavior.

Checked (evidence)

  • Re-review range: 2e0c2a1..edfe2ce
  • Prior CI blocker resolved: crates/livecap-core/src/audio/system.rs:29 preserves the macOS capture field as a documented Drop-driven RAII guard.
  • Riskiest part of this diff: the field is intentionally unread, but its lifetime triggers capture cleanup on Drop; the field-scoped allow documents and preserves that invariant.
  • Kill-list: scanned all new-range items — clean.
  • CI: gh pr checks 190 → app-macos, color-guard, no-stub-gate, packages-linux, and release-invariants all pass.

Findings

None.

Decision

The sole follow-up change fixes the macOS warning without changing runtime behavior. The live CI suite is green and the re-review delta is aligned with #179.

@realproject7
realproject7 merged commit 479977d into main Jul 14, 2026
5 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.

[audit][cleanup] Dead code, duplicated constants & lying names sweep (design-lens findings, itemized)

2 participants