feat(memory-sync): escalate when the queue outlives its threshold - #76
Merged
Conversation
added 2 commits
August 5, 2026 20:04
A permanently wrong remote (bad remoteUrl, renamed repo path, host without git-upload-pack) queued cleanly with exit 0 on every tick, forever — indistinguishable from a laptop offline. The tick now checks the oldest queued snapshot's already-persisted manifest createdAt after every enqueue and throws RemoteQueueEscalationError (exit 6) once it exceeds queueEscalationThresholdMs (default 24h, i.e. 96 missed ticks at the shipped 15-minute launchd/systemd intervals). Below threshold nothing changes: local commit, queued push, exit 0. The error class deliberately does not extend RemoteUnavailableError so the existing queueing discrimination cannot swallow it. Config key wired end-to-end (file, env, config get/set) after the reachabilityTimeoutMs pattern. Pins from the same review: the deliberate crash-loud fetch boundary in prepareWorkingCopy (stub git failing on fetch, non-zero exit, mutation-verified) and the precheck-bypass path (unsupported-scheme remote failing at lookupRemoteHead still queues cleanly). Docs: README queue-escalation section, machine-setup bullet, both plist template headers incl. the KeepAlive respawn analysis. Task: 11424b5e
Canonical exit-code table gains code 6. Config wiring is now pinned by tests that only pass if the override actually reaches checkQueueEscalation (2h backdate: under the 24h default, over the 1h override), plus an invalid-env exit-3 case. Clock-skew guard: an implausible age (>30x threshold) skips escalation with a diagnostic note instead of turning a healthy machine crash-loud after an NTP correction; wall-clock dependency documented. Scheduled runs catch the escalation, continue remaining ticks, report full JSON, and exit 6 at the end (single runs unchanged). Null disables escalation end-to-end, mirroring reachabilityCheckCommand's convention. README states the systemd burst arithmetic honestly with reset-failed recovery and a raised StartLimit pairing; machine-setup's no-op claim carves out the post-threshold case. Escalation message trimmed to the actionable core, queue count via direct dir listing, corrupt-manifest one-way bias documented and pinned (surviving older manifest still escalates), and the git-failure catch path has its own escalation test. Task: 11424b5e
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.
Task 11424b5e: a permanently wrong remote (bad remoteUrl, renamed repo path, host without git-upload-pack) queued cleanly with exit 0 on every tick, forever — indistinguishable from a laptop offline; the system looked healthy and never synced.
What changed
queueEscalationThresholdMs(default 24h = 96 missed ticks at the shipped 15-minute launchd/systemd intervals, cited against the actual plist/unit files). Above threshold the tick throws RemoteQueueEscalationError (exit 6, added to the canonical architecture.md table); below threshold nothing changes (byte-for-byte offline parity measured by the reviewer against master: identical stdout/stderr/exit/queue layout over 3 offline ticks).nulldisables escalation (mirroring reachabilityCheckCommand's convention). Wiring is pinned by tests that only pass if the override reaches the check (2h backdate: under the default, over the override) — mutation-verified red when the key is unwired.run --schedule) catch the escalation, continue remaining ticks, report full JSON, and exit 6 at the end; single runs exit 6 immediately (unchanged).systemctl reset-failedrecovery; macOS ThrottleInterval divergence), machine-setup's "clean no-op" claim carved out for the post-threshold case, both plist template headers incl. KeepAlive respawn analysis (edge-triggered, no tight loop — verified against chokidar ignoreInitial).Verification