summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-09-21 19:18:56 +0000
committerClaude <noreply@anthropic.com>2026-09-21 19:18:56 +0000
commit4c99649d4fdc77334f749c68b81c33a2fcb6d36f (patch)
tree4c9b2432f1ea1b70b625ba0ba0e93192490bcc6a /CLAUDE.md
parent42fce8b0293f78e8cf9f60a0bf2c4cd1bd010a5a (diff)
Fix a queue bug that deleted episodes, and delete dead DAO methods
Review found a data-losing bug. advance() drops the head of the queue, but play() never put the played episode there. Play something from a show list, let it finish, and advance dropped whatever was actually at the head -- a different episode, removed from the queue having never been played. The fix is an invariant rather than a special case: anything played becomes the head, so advance always drops the episode that just finished. playNow() does that, play() calls it, and the tests name the scenario. Two DAO methods had no caller -- getQueue, superseded by observeQueue, and observeUnplayed, written for a screen that was never built. Deleted. Room generates an implementation for each, so they were not free. The reachability guard now covers DAO methods too, which is the shape that bit FeeDreader: three superseded methods sat undetected until a manual audit. Interfaces need looser matching than objects, since a call's receiver varies by site and a @Transaction default method calls its siblings unqualified, so it matches both forms and errs toward "called" -- a false alarm costs more attention than a missed one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018AwnALZL6bD4VBtATDVv3B
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md24
1 files changed, 23 insertions, 1 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index e78257a..67de4bd 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -54,11 +54,23 @@ with `adb shell monkey`. Use the shared wrappers, which report from exit codes,
and a logcat capture started before launch:
```
-/workspace/devtools/bin/gradle-test /workspace/listen -- --rerun-tasks
+/workspace/devtools/bin/gradle-test /workspace/listen -- --rerun-tasks
+/workspace/devtools/bin/gradle-report /workspace/listen detekt
/workspace/devtools/bin/android-launch-check org.terst.listen \
--apk app/build/outputs/apk/debug/app-debug.apk --settle 15
+/workspace/devtools/bin/android-ui org.terst.listen dump
+/workspace/devtools/bin/publish-apk \
+ app/build/outputs/apk/debug/app-debug.apk listen-debug.apk
```
+**Never read `app/build/reports/detekt/detekt.xml` directly.** An invalid config aborts detekt
+before it analyses anything and leaves the previous run's report in place; it was read as
+current findings three times. `gradle-report` refuses a report older than the run.
+
+**Never `adb shell input tap X Y`.** A blind tap landed in FeeDreader's settings and the
+screenshot after it was reported as Listen. `android-ui` checks the foreground package first
+and taps by label.
+
See `/workspace/devtools/README.md`. These exist because grepped console text has produced wrong
claims three separate times across these repos.
@@ -130,3 +142,13 @@ intro/outro skipping. Schema fields for manual skip offsets exist but nothing re
- **Feeds are big.** A real subscription in testing produced 2753 episodes in one refresh. Any
per-episode work — a query in a loop, an O(n²) match — needs to be considered at that scale.
+
+- **The playing episode is always the head of the queue.** `advance()` drops the head, so if
+ something played from a show list isn't there, finishing it deletes a queued episode unplayed.
+ `play()` calls `playNow()` first to hold that invariant. Don't add a playback entry point that
+ skips it.
+
+- **Two reachability tests guard dead code**, one for helper objects and one for DAO methods.
+ Both exist because code was written, tested, documented and never called: `findFeedLink` (the
+ share-sheet bug) and `QueueRepository.advance` (the queue silently stopped). Adding to their
+ allowlists needs a reason, not just a name.