Skip to content

self-proof: a live owner pid without its instance marker is undetermined, never proved (#1187) - #1191

Merged
fujibee merged 1 commit into
integration/terminal-driver-v1from
fix/1187-proof-requires-marker
Sep 13, 2026
Merged

self-proof: a live owner pid without its instance marker is undetermined, never proved (#1187)#1191
fujibee merged 1 commit into
integration/terminal-driver-v1from
fix/1187-proof-requires-marker

Conversation

@fujibee

@fujibee fujibee commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Fixes #1187.

What was measured

The flaky test pins that an owner whose process is gone comes back undetermined. Run against the suite's own fixture:

owner pid marker ancestry verdict
alive stranger (sleep) none two edges, not reaching the root undetermined invocation_ancestry_truncated
alive stranger none complete, containing it, pane process in it proved
the test shell itself none complete proved

So the classifier judged liveness once (kill -0 plus the marker) before the walk, never re-checked it, and read an absent marker as alive: with a complete ancestry it then proved a pid that nothing tied to the session. The two CI reds were the same mechanism seen from the red side — a reaped pid handed to a new process on a loaded macOS runner made the reason change from owner_not_alive, and the exact-match assertion failed. That those runs landed on undetermined was an accident of a fixture whose fake ancestry stopped short of the root, not a property of the classifier.

Why it matters before release

The self-write path (#1157) writes a seat's identity cells on the strength of proved. A pid reused after a session ended, with the session's marker cleaned up, is rare — and it is exactly the shape that fails silently: a proved that was never established, handed to a caller that writes into someone else's pane.

The change

After liveness says alive, the proof asks for the instance marker itself: absent → undetermined owner_marker_absent; unreadable → undetermined owner_liveness_unknown. The lock's default (an absent marker is alive) stays as it is — it is the conservative side there, where nothing contradicts a live pid and reclaiming would be the harm. The two contexts do not share the default, and the comment at the call site says why, for the next person who wants to unify them.

Tests

  • New control: alive, unmarked, complete ancestry → undetermined owner_marker_absent. Red before this change (it returned proved); removing the marker requirement reddens it alone (and the whole-suite shell-state harness, which reruns the file).
  • The fixture's live owner gets its instance marker in setup, as a live session has.
  • The flaky test checks its own precondition: if the reaped pid is found alive again before the read, it skips by name instead of measuring a stranger.

Suite 45/45 including the nested shell-state reruns; the static checkers at their baselines; shellcheck unchanged on the file.

…ned, never proved (#1187)

The proof judged the owner alive with agmsg_instance_alive, which reads an
absent instance marker as alive: the conservative side for the lock it
serves, where nothing contradicts a live pid. Here the same default sat on
the dangerous side. A pid reused by a stranger after the session ended, with
the marker gone, walked as the owner and, with a complete ancestry, proved
into whatever pane the stranger sat in. Measured on 2026-09-13 with the
suite's own fixture: alive, unmarked, complete ancestry returned proved. The
two CI reds behind #1187 were the same mechanism seen from the other side:
a reaped pid handed to a new process on a loaded macOS runner made the
verdict's reason change, and the exact-match assertion went red; that it
landed on undetermined there was an accident of a fixture whose ancestry did
not reach the root, not a property of the classifier.

The proof now asks for the marker itself after liveness and does not share
the lock's default: absent -> undetermined owner_marker_absent; unreadable ->
undetermined owner_liveness_unknown. The fixture's live owner gets its marker
in setup, the flaky test skips by name when its reaped pid is found reused
before the read, and a control pins alive+unmarked+complete -> undetermined
(red before this change).
@fujibee
fujibee merged commit 532a60f into integration/terminal-driver-v1 Sep 13, 2026
27 checks passed
@fujibee
fujibee deleted the fix/1187-proof-requires-marker branch September 13, 2026 09:24
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