Skip to content

fix(watcher): make Linux PID identity clock-drift stable#900

Open
omnimaycha wants to merge 1 commit into
kunchenguid:mainfrom
omnimaycha:fm/firstmate-pid-identity-drift-v2
Open

fix(watcher): make Linux PID identity clock-drift stable#900
omnimaycha wants to merge 1 commit into
kunchenguid:mainfrom
omnimaycha:fm/firstmate-pid-identity-drift-v2

Conversation

@omnimaycha

Copy link
Copy Markdown

Intent

Prevent a live, healthy Firstmate watcher from being rejected by process-identity checks when WSL2 or another Linux host adjusts its wall-clock or boot-time reference.

Background

On WSL2, ps lstart changed for the same live PID after NTP synchronization or suspend.
Observed identities shifted from 07:09:22 when recorded to 07:09:27 on a live read, and a later watcher shifted from 07:11:22 to 07:11:33.
The drift recurred after watcher restarts, causing the turn-end guard and continuity gate to treat a healthy watcher as mismatched.

What Changed

  • Use Linux /proc/<pid>/stat field 22 (starttime, in clock ticks since boot) together with the full /proc/<pid>/cmdline bytes.
  • Split the stat record after its final ) so process names containing spaces or parentheses parse correctly.
  • Fail closed on Linux when the required /proc identity data is unavailable instead of falling back to drift-prone ps lstart.
  • Keep the locale-pinned ps lstart plus command fallback for non-Linux hosts such as macOS.
  • Return failure for omitted, invalid, zero, or missing PIDs.

Compatibility and migration

Existing consumers compare the identity as an opaque string and require no format-specific changes.
A legacy lstart identity mismatches once without producing a false healthy result.
The supported watcher restart arm replaces that lock with a fresh watcher and writes the stable Linux identity.

Regression coverage

  • Repeated identity reads remain stable across simulated boot-time changes.
  • PID reuse changes the identity.
  • Invalid and missing PIDs fail.
  • Linux never consults ps when /proc data is missing.
  • A process name containing a closing parenthesis parses from the final delimiter.
  • A live watcher lock remains matched while simulated ps lstart output shifts by 11 seconds.
  • A real watcher with a legacy identity is rejected safely and repaired by fm-watch-arm.sh --restart.

Validation

  • bin/fm-test-run.sh --changed --base origin/main: 10 watcher/wake/lock scripts passed with 0 failures.
  • tests/fm-watcher-lock.test.sh: passed on WSL2, including the live lock and legacy migration cases.
  • bin/fm-lint.sh: passed with the repository-pinned ShellCheck 0.11.0 across the canonical script set.
  • No-mistakes automated review, targeted test, documentation, and lint validation completed successfully before its upstream push failed because this contributor has read-only access.

Risk assessment

Low.
The behavior change is limited to Linux process-identity collection and strengthens fail-closed handling.
The non-Linux fallback and opaque consumer contract remain intact.

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