Repository navigation
fix: harden iMessage pickup timing and binding output - #19
Merged
Merged
Conversation
…ound destination from bind The pickup scheduled reply reads and capture retries on the wall clock, so a backward clock step silently stalled replies for the size of the step. Pace them on time.monotonic(), keep wall time for record timestamps, and treat a receipt republish time ahead of now as due. conversation bind now returns a non-default destination beside conversation_id and credential, so state/imessage/binding.json can be written exactly as bind returned it; a default voice binding is unchanged.
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
Part of the overnight hardening build: smallest durable best-practice fixes, never today-only patches, never over-engineered. The final VM pass (~/dev/firstmate/data/vm-final-pass/report.md) found two small Firstmate-side defects in the courier iMessage pickup before live activation:
P2: bin/fm-courier-pickup.py schedules its reply cadence on the wall clock (around line 233
now=time.timeand lines 650-651self.next_reply = self.now() + REPLY_EVERY). After a backward clock step, no published reply is claimed or sent for the size of the step, with nothing logged (a 10-minute step delayed a reply by over 60 s; a restart sent it at once).D2: bin/fm_inbox_conversation.py
bind(around line 365) returns only conversation_id and credential, but the activation runbook (firstmate-voice docs/imessage-linq.md around lines 553-555 and docs/deploy-hermes.md around line 272) says to write state/imessage/binding.json as {conversation_id, credential, destination} exactly asbindreturned them, and the pickup refuses to start without destination.What Changed
bindoutput so iMessage bindings can be saved directly; add regression cases for clock rollback and binding output.Risk Assessment
✅ Low: The bounded fixes address both reported defects, preserve transport authorization and default voice compatibility, and include behavioral regression coverage.
Testing
Both targeted suites and isolated real-process CLI checks passed, with pre-change defects reproduced, fixture setup errors corrected, evidence retained, and disposable files removed; clock steps were process-local and delivery was validated at the courier spool boundary.
Evidence: Targeted CLI suite transcript
Source: Targeted CLI suite transcript
Evidence: Live binding, clock-step, retry and restart checks
Source: Live binding, clock-step, retry and restart checks
Evidence: Pre-change defect reproduction
Source: Pre-change defect reproduction
Evidence: Forward clock step after publication
Source: Forward clock step after publication
Evidence: Retained executable scenario driver
Source: Retained executable scenario driver
Evidence: Validation setup, oracles and evidence boundaries
Source: Validation setup, oracles and evidence boundaries
Pipeline
Updates from git push no-mistakes
✅ **Intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
✅ **Review** - passed
✅ No issues found.
✅ **Test** - passed
✅ No issues found.
TMPDIR="$PWD/.validation/tmp" PYTHONDONTWRITEBYTECODE=1 bin/fm-test-run.sh --jobs 1 tests/fm-inbox-conversation.test.sh tests/fm-courier-pickup.test.shPYTHONDONTWRITEBYTECODE=1 TMPDIR="$PWD/.validation/tmp" .validation/codex -c 'python3 "$1" "$2" "$3" "$$"; exit "$?"' fixture "$PWD/.validation/clock-bind-driver.py" "$PWD" "$PWD/.validation/manual-current-final"Executed the same scenario driver against workspace-local copies of the two changed binaries from base commit4b73a9119db78d2bbfab9e3a0ce89bed00e02103; reproduced missing destination and clock-related stalls.Executed the driver selectorreply-forwardagainst current and base binaries with the clock step applied after publication committed.Corrected initial disposable fixture ownership and policy-permission setup errors, re-ran affected checks, retained evidence, and removed.validation;git status --shortwas empty.✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.