fix(wake-drain): surface unread status once via presentation cursor - #59
Merged
Merged
Conversation
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.
Intent
Stop fm-wake-drain from reprinting the entire unread-since-last-drain status history, including the observed 169KB-class dump to surface one new line, by selectively adapting public upstream commit db0280f/kunchenguid#2331 unread-once presentation-cursor design into this fork current unified presentation and annotation path. Reconcile it with this fork current version-5 incremental OPEN DECISIONS cursor precedent from #57/bf01a42 rather than blind cherry-picking or inventing a fork-only cap. Preserve upstream identity-level behavior for every unread note and pending-reply resolution and every unread direct-signal annotation, preserve transactional identity-bound presentation and teardown retirement, and retain the existing session-start annotation cap. Do not change OPEN DECISIONS identity or behavior from #57, watcher-arm count, successor-first coordinator, Grok idle work, VPS teardown work, or any product repository. Prove the cause against code and add behavior-level regression coverage, including migration from existing per-task decision cursors so only newly appended bytes surface, with invalid cursors failing safely. Measure a representative copied corpus before and after for a signal dump, empty warm drain, and cold drain; do not add a fork-only cold-refold optimizer unless the post-fix cold path still crosses about 15 seconds, and report numbers instead if it does. Account in the report for every relevant upstream commit after bf01a42 touching drain/classify/wake-lib and identify what the fork lacked. Deliver only through no-mistakes to a PR with CI-ready checks green; do not merge.
What Changed
status_presentation_cursorinbin/fm-classify-lib.shso wake-drain only re-emits status bytes appended since the last drain, instead of replaying the entire unread-since-last-drain history (previously a ~169KB dump to surface a single new line), while preserving unified presentation/annotation, transactional identity-bound retirement, and the session-start annotation cap.tests/fm-wake-drain-unread-status.test.sh(5 regression cases) covering once-only note/pending-reply surfacing, annotation-cap preservation, decision-cursor migration bounds, and invalid-cursor fallback; registered the suite inbin/fm-test-run.shand documented the cursor seeding indocs/architecture.md.Risk Assessment
✅ Low: The change adds a read-only migration seed that fully re-validates the reused version-5 cursor and fails safe to byte zero, leaves the OPEN DECISIONS incremental fold untouched, and is covered by end-to-end regression tests for every intent-required behavior.
Testing
Baseline: the new regression suite tests/fm-wake-drain-unread-status.test.sh runs green (5/5). Primary product evidence: an A/B run of the real fm-wake-drain.sh against an identical ~168KB unread-since-last-drain corpus shows the pre-fix classify library emits a 473,097-byte dump replaying the whole history twice to surface one line, whereas the target fix emits 297 bytes surfacing only the newly appended line with zero history replays; empty warm drain is identical (54B). Migration from an existing per-task OPEN DECISIONS cursor and invalid-cursor fail-safe are both exercised. Cold-drain timing (22.5s post-fix) crosses the intent's ~15s threshold but is pre-existing and unchanged by this fix (base 28.0s) and sits in the classify fold, not the presentation cursor — reported as informational per the intent. Overall: the intended behavior is demonstrated working end-to-end; no test failures. Worktree left clean.
Evidence: A/B signal-dump measurement (base flood vs fixed bounded output)
Evidence: Target fixed drain output (complete, 297B)
Evidence: Cold-path timing (pre-existing, unchanged by fix)
Evidence: Evidence summary
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
bash tests/fm-wake-drain-unread-status.test.sh— all 5 regression cases pass (buried notes surface once, annotation cap preserved, pending-reply resolves once, decision-cursor migration bounds first presentation, invalid cursor falls back to byte zero)A/B: ran productionbin/fm-wake-drain.shagainst an identical ~168KB corpus with base vs targetfm-classify-lib.sh; measured signal-dump bytes (BASE 473097B / 2400 replays vs TARGET 297B / 0 replays) and empty warm drain (54B both)Timing: realistic post-fix migration drain=1.13s, isolatedstatus_presentation_cursor_offsetscan on 167KB=0.23s, cold drain BASE 28.02s vs TARGET 22.54sVerified test-runner registration of the new suite inbin/fm-test-run.sh(family + line-count row)✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.