Skip to content

feat(inbox-sweep): --state makes repeated sweeps idempotent - #124

Merged
hyperpolymath merged 1 commit into
mainfrom
feat/inbox-sweep-state
Oct 1, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
feat/inbox-sweep-state

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Follow-up to #123.

Why

GET /notifications?all=true also lists threads that are already done, and the REST notification object has no done field. I measured this live on hyperpolymath/HOL:

Without memory, every hourly run would therefore re-clear the same ~640 threads: about 1300 REST writes against a 5000/h budget that other sessions share.

What

--state <path> stores {thread id: updated_at}:

  • An entry is recorded only after both DELETEs return 204. The file is written atomically (temp file + rename).
  • A thread whose updated_at is unchanged is skipped before any GraphQL read or REST write.
  • New activity, which GitHub uses to bring a done thread back to the inbox, makes it eligible again.
  • Entries for threads that are no longer listed are pruned, so the file stays bounded.
  • A missing file means empty state. A corrupt file exits 2: an empty state would silently re-clear everything.

Evidence

  • just quality: exit 0, 310 passed, 0 failed.
  • New tests: a second sweep using the saved state performs zero writes; a bumped updated_at is re-cleared; stale entries are pruned; the state file round-trips and a corrupt one is refused.
  • Mutant: replacing the skip predicate with false fails 2 of the new tests.

🤖 Generated with Claude Code

https://claude.ai/code/session_0196aKTfvS6vPQVp2LPoXbjP

`GET /notifications?all=true` also lists threads already marked done,
and REST exposes no done state. Measured live on hyperpolymath/HOL:
after a successful unsubscribe + mark-done, all five threads stayed
in the listing unchanged, while the web inbox showed only the one
open PR. Without memory, every hourly run would re-clear the same
~640 threads (~1300 REST writes against a shared 5000 budget).

`--state <path>` records (thread id, updated_at) once both DELETEs
returned 204, and is written atomically (temp file + rename). A thread
whose updated_at is unchanged is skipped before any read or write.
A thread with new activity, which GitHub returns to the inbox, is
decided again. Entries for threads that are no longer listed are
dropped. A missing file means empty state; a corrupt file is an
error, because a silently empty state would re-clear everything.

Tests: a second sweep using the saved state writes nothing; a bumped
updated_at is re-cleared; stale entries are pruned; the state file
round-trips and a corrupt one is refused. Mutant check: disabling the
skip fails 2 of these tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0196aKTfvS6vPQVp2LPoXbjP
@hyperpolymath
hyperpolymath enabled auto-merge (squash) October 1, 2026 14:49
@coderabbitai

coderabbitai Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 04f29c49-8b73-49ba-a651-94eb80a31fe7

📥 Commits

Reviewing files that changed from the base of the PR and between 2f9434b and 0c39aa6.

📒 Files selected for processing (1)
  • crates/squabble-cli/src/inbox.rs
 _______________________________________
< Goodbye, code review procrastination. >
 ---------------------------------------
  \
   \   (\__/)
       (•ㅅ•)
       /   づ
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath merged commit f620076 into main Oct 1, 2026
50 of 51 checks passed
@hyperpolymath
hyperpolymath deleted the feat/inbox-sweep-state branch October 1, 2026 14:50
hyperpolymath added a commit that referenced this pull request Oct 1, 2026
Resolve crates/squabble-cli/src/main.rs as a union: main added
`board`/`inbox-sweep` (exit 6, #123/#124) where this branch added
`verify-satisfied` (exit 5, #119). Both modules, dispatch arms, usage
lines and exit-code docs are kept; codes listed in numeric order.

cargo fmt --check, clippy -D warnings and cargo test --workspace (279) pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
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.

1 participant