Skip to content

fix(bin): stop a resolve-key close from re-waking its home during signal grace - #4929

Open
jasonlgong wants to merge 4 commits into
kunchenguid:mainfrom
jasonlgong:fm/fm-ship-4767-companion
Open

jasonlgong wants to merge 4 commits into
kunchenguid:mainfrom
jasonlgong:fm/fm-ship-4767-companion

Conversation

@jasonlgong

@jasonlgong jasonlgong commented Sep 19, 2026 •

Copy link
Copy Markdown

Problem

Fix

  • In bin/fm-watch.sh, after the grace period, status files are classified from the fresh rescan only.
  • Turn-end markers from the first scan are kept, so a turn-end still surfaces if its marker disappears or changes back during grace.
  • This relies on status logs being append-only, which is already the contract.
    • A status file rewritten in place at the same inode and size could hide a real signal.
    • That case is outside the contract and is documented in docs/architecture.md rather than handled here.

Tests

  • tests/fm-send-resolve-key.test.sh: test_answer_close_during_signal_grace
    • Holds the answer mid-commit while the watcher scans.
    • Checks that the close does not wake the home, and that a later worker blocked: line still does.
    • Fails on 39f4c2a, passes with this change.
  • tests/fm-watch-triage.test.sh: two cases cover a first-scan turn-end marker during grace.
    • One deletes the marker; one restores it to its reported signature.
    • Both still surface.

@kunchenguid

Copy link
Copy Markdown
Owner

Speaking as Kun's firstmate:

Tip 39d537c054d7bbdd89a884f9614c9ff166c7b8a8 — attestation MATCH. Contract-class restore (post-grace scan_signals only in bin/fm-watch.sh so a mid-grace --resolve-key seen-marker commit does not re-wake; append-only status contract documented).

Closes claim: author body explicitly says this does not fully close #4767 alone — it is the grace-window half. #4895 (fold/self-announce half) just landed as b6930db7. Keep this PR for the remaining grace path; do not treat GitHub closesReadyForPr as a full close vote.

Fork workflows approved this pass (CI 35448145592, NM 35448145611) — now in progress. MERGEABLE/UNSTABLE until green. We will re-watch after CI + no-mistakes SUCCESS. Waiting on CI, not on the author.

The signal grace-period rescan concatenated the first scan back onto the
post-grace scan, so a fm-send --resolve-key self-close whose seen-marker
commits during the grace window kept its stale first-scan entry and re-woke
this home for its own resolved line. Use only the post-grace rescan as the
authoritative pending set, and skip publishing an empty final list.

Genuine worker signals still surface: they are append-only, so the marker
never advances over foreign bytes and the rescan re-detects them. The
guarantee is append-only, not unconditional signal-losslessness: a status
file rewritten in place (same inode, same size) during grace can lose a
signal, but status logs are append-only by contract, so that edge is
out-of-contract and left as a documented limitation.

Companion to the folded-decision self-wake fix in bin/fm-wake-lib.sh; that
path is untouched here. Adds test_answer_close_during_signal_grace, which
freezes the real sender between its close append and its marker commit,
lets the real watcher capture that transient state, and asserts the grace
rescan drops the self-close while a later worker blocker still wakes.
@jasonlgong
jasonlgong force-pushed the fm/fm-ship-4767-companion branch from 39d537c to df07ae2 Compare September 23, 2026 02:54
@jasonlgong jasonlgong changed the title fix: prevent self-announced closes from re-waking the watcher fix(bin): prevent self-wakes during signal grace Sep 23, 2026
@jasonlgong jasonlgong changed the title fix(bin): prevent self-wakes during signal grace fix(bin): stop a resolve-key close from re-waking its home during signal grace Sep 23, 2026
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.

2 participants