#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
#
# lane-handoff — the swap, the context clear and the handoff, under one name.
#
#   lane-handoff [why]             hand this lane off: fix the identity triple,
#                                  refresh the handoff, poll the writers, write
#                                  the PAUSED record, print the restart line
#   lane-handoff --restart [why]   the same, and then RESPAWN this lane's own
#                                  pane through the launcher with the handoff's
#                                  top block as the new session's first prompt
#                                  (`/ctx`, Amendment 17(f))
#   lane-handoff --exit [why]      the same, and then type `/exit` into this
#                                  lane's own pane (Amendment 18(d), for a
#                                  handoff another place REQUESTED)
#   lane-handoff --in-process [why]
#                                  the same, for a clear that keeps THIS PROCESS
#                                  running: the record says `kind in-process`
#                                  and the top block tells the next session that
#                                  every writer SURVIVED and to relaunch none
#   lane-handoff --late --at <UTC> [why]
#                                  the record written AFTER THE FACT for a swap
#                                  that never ran, BEFORE the relaunch
#
# lane-collision-protocol **Amendment 17**, ratified 2026-09-14T09:45:33Z,
# clause (a): *"the act Amendment 8(a) calls the swap is the HANDOFF:
# `lane-handoff` on `PATH` (placed by `openRepoTools --install`) from a shell,
# `/handoff` from inside a session; `/lane-swap` and `/swap` remain as aliases"*.
# The steps are the `handoff` skill's, which are Amendment 8(a)'s and Amendment
# 11's as they stand — THIS FILE AND THAT SKILL ARE ONE ACT IN TWO SURFACES, and
# the skill is the one a session runs, because a session can send a subagent a
# message and a shell cannot.
#
# WHAT IS NEW HERE, AND WHAT IS NOT. Nothing about the record changes but two
# sub-fields: clause (b) gives the `PAUSED` payload `agent <name>` and
# `transcript <id|none>` beside Amendment 11(c)'s `window`, `dir` and `profile`,
# so that the next session can be started by whatever agent can read the lane
# (`lane-start --agent`, clause (c)). The free text still says WHY — `clear`,
# `reset`, `switch`, `handoff to <who>`, `requested by <uuid>@<host>/<container>`
# — and nothing else changes with the why. That is the whole of clause (a):
# *"The word has been wrong, not the act."*
#
# THE FLAGS, and each is one act after the record rather than a second kind of
# record — except `--in-process`, which is the one fact about the act that
# FOLLOWS the record and which the record therefore carries:
#
#   --restart  Amendment 17(f), `/ctx`: *"a `/ctx` whose record could not be
#              written REFUSES before it kills anything (a pane is never
#              respawned over an unrecorded lane)"*. So the pane is respawned
#              ONLY after the PAUSED line is written, and a refused write is a
#              refusal of the whole act with the pane untouched.
#   --exit     Amendment 18(d): a handoff to ANOTHER PLACE ends the session,
#              because 17(f)'s respawn is for the lane that stays where it is.
#              The `why` a requester gives is `requested by <uuid>@<host>/<c>`.
#   --late     Amendment 17 adoption act 7: the swap that never ran, recorded
#              after the fact. It is written BEFORE the relaunch — see THE LATE
#              RULE below, which is the whole of why it takes `--at`.
#   --in-process
#              THE WRITERS SURVIVE THIS ONE. Measured in this lane on
#              2026-09-14: a harness `/clear` mints a new transcript id IN THE
#              SAME PROCESS, so every subagent the lane has running lives
#              through it and only its in-flight tool calls die. The record then
#              says `kind in-process` and the top block tells the next session
#              to EXPECT EVERY WRITER BELOW LIVE — an expectation and never an
#              instruction, which is Addendum 1 (j): what to DO is clause (i)'s
#              count, the same in every kind. Relaunching a writer that is still
#              live puts two of them on one worktree (k). `--restart`, `--exit`
#              and `--late` are `kind respawn`: a new process, and its writers
#              are gone. A PLAIN handoff is `kind unknown`, because the act that
#              follows it is not this command's to know.
#
# THE LATE RULE, stated here because it is the one rule of this command a
# reader cannot derive from the amendment. A lane's state is its log's LAST
# lane-kind line IN FILE ORDER (Amendment 7's rule, R14, and every reader in
# `lanes-edit.sh` implements it that way — `swapped_candidates`, `lane_row_facts`,
# `lane_payload_field`). The log is APPEND-ONLY. So a late `PAUSED` appended
# after the `RESUMED` that `lane-start` wrote at the relaunch would make a lane
# that is running read as paused, in a file nothing rewrites — the one thing the
# record must never say. Two ways out were available: teach every reader to skip
# a `PAUSED` whose `late` sub-field predates a later `RESUMED`, or refuse to
# write the line where it can no longer be the last one. This command takes the
# second, because it is the only one that keeps `binding` and every state read
# correct WITHOUT editing readers this amendment does not touch:
#
#   * `--late` REQUIRES `--at <UTC>` — the moment the old session ended. A late
#     line is dated by its own field, not by the clock of the shell writing it.
#   * it is written only where the lane's last lane-kind line is a `STARTED` or
#     `RESUMED` OLDER than that instant — the dead session's own start. That is
#     the state of a lane whose swap never ran, and it is the state that exists
#     only BEFORE the relaunch.
#   * a last line that is already a `PAUSED` (the record exists), an `ENDED` or
#     `RETIRED` (the lane is closed), or a `STARTED`/`RESUMED` at or after that
#     instant (the relaunch is already recorded) is a REFUSAL that writes
#     nothing and names the act to take instead.
#
# So the documented act is: run `lane-handoff --late --at <UTC>` FROM THE SHELL,
# then `pclaude <profile>`. Run from inside the session that has already been
# resumed, it refuses — and the honest record of the state that session now
# holds is its own next handoff.
#
# EXIT CODES, this toolset's and the family's:
#
#   0  the handoff was written (and the pane respawned or exited, where asked)
#   2  REFUSED — nothing was written, or the record was written and the act
#      that follows it was refused before touching the pane, or tmux would not
#      rename the window and the record was NOT written (the refusal names
#      what had landed before it: the handoff's top block, SWAPPING)
#   1  a read failed, which is never "nothing to report" (Amendment 7(d))
#
#   $LANES_EDIT       the register's reader/writer (default: beside this file)
#   $LANES_AGENT      this agent's name for the record (default: claude)
#   $PCLAUDE          the launcher                 (default: lclaude, else pclaude, else claude-profile)
#   $LANE_HANDOFF_NO_TMUX=1   never touch tmux (the identity fix, --exit, --restart)
#                             — and with `$TMUX` unset, this is not inside tmux,
#                             so tmux is not touched either
#
# lane-collision-protocol Amendment 17 (in force 2026-09-14T09:45:33Z),
# Amendment 18(d) and Addendum 2 (in force 2026-09-14T16:50:32Z).

set -uo pipefail

prog="${0##*/}"
SELF="${BASH_SOURCE[0]:-$0}"
selfdir="$(cd -- "$(dirname -- "$SELF")" && pwd)"

say()  { printf '%s\n' "$*"; }
note() { printf '%s: %s\n' "$prog" "$*" >&2; }
step() { printf '%s: %s\n' "$prog" "$*" >&2; }
die()  { printf '\n%s: REFUSED: %s\n' "$prog" "$1" >&2; exit "${2:-2}"; }
# Exact launch facts must not carry record delimiters, on Bash 3.2 too.
restart_fact_ok() {
  local LC_ALL=C
  case "${1-}" in *[[:cntrl:]]*) return 1 ;; esac
  return 0
}
# EVERY ARGUMENT AS ONE SHELL WORD, WITHOUT `printf %q` AND WITHOUT A PIPE —
# measured on the macOS job at `db206db` and `ac0c697`, where three cases of
# this branch's own went red and no other platform could see it. One line, two
# defects:
#
#   * `printf '%q '` RENDERS DIFFERENTLY UNDER BASH 3.2, which is what Apple
#     ships and what that job runs (`/bin/bash` 3.2.57). Bash 4.4 and later
#     give a multi-line argument back as `$'…\n…'` — one readable, runnable
#     word; 3.2 has no such form and escapes every space and every byte of
#     every multi-byte character with a backslash of its own. The one caller
#     that passes a multi-line argument is the `--no-launch` print of a launch
#     carrying the handoff's top block as its first prompt (Amendment 17(c)),
#     and it got back neither a readable line nor a runnable one.
#   * AND THE PIPE THROUGH `sed` MADE THAT FATAL RATHER THAN UGLY. Under
#     `set -o pipefail` this function's status IS the pipeline's, and BSD `sed`
#     in a UTF-8 locale (`LC_ALL=en_US.UTF-8` on that runner) refuses bytes
#     that are not a valid sequence — `RE error: illegal byte sequence` — which
#     is what 3.2's `%q` makes of the em dash every one of these documents is
#     written with. `quoted` is a BARE command in the `--no-launch` branch, so
#     `set -e` ended the command there: exit 1, and an empty stdout.
#
# So the quoting is this file's own, and it is the POSIX one every shell reads
# the same way: a word of safe characters bare, anything else in single quotes
# with its own single quotes spelled `'\''`. A newline inside single quotes IS
# a newline, so the line stays readable as well as runnable, on either bash.
quoted() {
	q_sep=""
	for q_a in "$@"; do
		case "$q_a" in
		'' | *[!A-Za-z0-9._/:=@%+,-]*)
			printf "%s'%s'" "$q_sep" "${q_a//\'/\'\\\'\'}" ;;
		*) printf '%s%s' "$q_sep" "$q_a" ;;
		esac
		q_sep=' '
	done
	return 0
}

usage() {
	cat <<'USAGE'
lane-handoff [--restart | --exit | --in-process] [--late --at <UTC>]
             [--lane <lane>] [--agent <name>] [--transcript <id|none>]
             [--writers-file <path>] [--dir <path>] [why …]

  lane-handoff [why]      hand this lane off — the act /handoff, /swap and
                          /lane-swap all name. The identity triple is fixed,
                          the handoff file gains a fresh Rule 3 top block with
                          a WRITERS section, every running writer is polled,
                          the lane's PAUSED record is written with Amendment
                          11(c)'s sub-fields plus `agent` and `transcript`,
                          and the one restart command is printed.
  --restart               /ctx: after the record, respawn THIS lane's own pane
                          through the launcher, the new session's first prompt
                          being the handoff's top block. A record that cannot
                          be written refuses before anything is killed.
  --exit                  after the record, type /exit into this lane's own
                          pane (Amendment 18(d): a handoff to another place).
  --in-process            the clear that follows keeps THIS PROCESS running (a
                          harness /clear), so every writer this lane has running
                          survives it: the record says `kind in-process` and the
                          top block tells the next session to EXPECT every
                          writer below live — an expectation, never an
                          instruction (Addendum 1 (j)). Refused with --restart,
                          --exit and --late, which each mean the process ended.
                          With none of the four the kind is `unknown`.
  --supervise             THE PANE SUPERVISOR, started by --restart's respawn
                          and not typed by a person: it claims the lane's
                          restart intent, launches the replacement as its own
                          CHILD, confirms readiness before anything is called
                          running, and STAYS IN THE PANE with the diagnostic and
                          a retry when the launch fails. Needs --lane and
                          --operation.
  --restart-status        read the lane's restart intent — its operation,
                          generation, attempt, state, handoff, digest,
                          transcripts and bounded failure reason — and print the
                          act that is open on it. Reads only. Needs --lane.
  --operation <id>        the restart operation --supervise was started for. An
                          id that is not the lane's current one is a refusal.
  --late --at <UTC>       write the record a swap never left, dated by the
                          moment the old session ended. Run it from a shell
                          BEFORE the relaunch; see --help's LATE RULE.
  --lane <lane>           the lane, where this window does not name it.
  --agent <name>          the agent for the record (default: $LANES_AGENT, else
                          claude). Letters, digits, `.`, `_`, `-`.
  --transcript <id|none>  its resumable id (default: this session's, else none)
  --writers-file <path>   lines of `<worktree><TAB><brief>` — the brief each
                          writer was given, for the WRITERS section.
  --dir <path>            the lane's checkout, where its record names none.
  why …                   the free text: clear, reset, switch, handoff to <who>,
                          requested by <uuid>@<host>/<container>.

Exit: 0 written · 2 refused · 1 a read failed.
      --supervise adds: 3 the launch failed before readiness and there was no
      terminal here to offer the retry on · 4 the same, for a launch that ran
      PAST the readiness deadline still alive and only then ended (the record
      carries INDETERMINATE and the intent is retryable either way) · 143 and
      129, a supervisor sent SIGTERM or SIGHUP, which marks the intent failed,
      kills nothing, and says whether the child was still running.
USAGE
}

# ------------------------------------------------------------------ arguments

do_restart=0; do_exit=0; do_late=0; do_in_process=0; do_supervise=0; do_status=0
late_at=""; lane=""; agent=""; transcript=""; writers_file=""; dir_flag=""
operation=""
why=""

# A FLAG WHERE A VALUE BELONGS IS REFUSED, in this command as in `park`,
# `resume` and `status` (`92eab6c`): `--lane --restart` must not hand off a lane
# called `--restart`, and `--flag=value` is the spelling that gives a `-`-led
# value back. One reader, byte-identical to theirs.
# AND ITS REFUSAL ENDS THIS COMMAND, NOT ONLY ITS OWN SUBSHELL (opensoft/
# openRepoTools#80). Every arm reads it as `x="$(flag_value …)"`, and a `die`
# inside `$( )` exits the subshell it runs in: the REFUSED line was printed and
# the run then went on with the value empty — `--lane --restart` handed off
# whatever lane the window resolved to, and `--writers-file ""` wrote a handoff
# with no briefs. So every arm ends `|| exit`, which carries the refusal's own
# status out, and this file sets no `-e` that would have done it silently.
flag_value() {   # <flag> <the next argument, if any>
	case "${2-}" in
	'') die "$1 needs a value" 2 ;;
	-*) die "$1 needs a value and '$2' is a flag. Use $1=$2 where that really is the value." 2 ;;
	esac
	printf '%s' "$2"
}

while [ $# -gt 0 ]; do
	case "$1" in
	-h | --help) usage; exit 0 ;;
	--restart) do_restart=1; shift ;;
	--exit) do_exit=1; shift ;;
	--late) do_late=1; shift ;;
	# THE PROCESS SURVIVES THIS ONE, AND THAT CHANGES WHAT THE NEXT SESSION IS
	# TOLD (measured in this lane on 2026-09-14): a harness `/clear` mints a new
	# transcript id IN THE SAME PROCESS, so every subagent this lane has running
	# lives through it and only its in-flight tool calls die. A block that then
	# says *relaunch every writer* puts a second writer on a worktree the first
	# one still holds.
	--in-process) do_in_process=1; shift ;;
	# THE OTHER HALF OF `--restart`, AND THE SAME COMMAND ON PURPOSE
	# (openRepoTools#94). `--supervise` is what tmux starts in the respawned
	# pane: it claims the restart intent `--restart` wrote, launches the
	# replacement as a CHILD, confirms readiness and stays in the pane when
	# anything goes wrong. It is a MODE and not a thirteenth installed word,
	# because Amendment 18 Addendum 2 (i-8) is explicit that *"no word is kept
	# on `PATH` for it alone"* — which is the ground on which `restart` was
	# taken off it. `--restart-status` is the read-only surface over the same
	# record.
	--supervise) do_supervise=1; shift ;;
	--restart-status) do_status=1; shift ;;
	# AN `=` WITH NOTHING AFTER IT IS A VALUE THAT WAS TYPED AND LOST, never one
	# that was not typed (opensoft/openRepoTools#80, Copilot's review of
	# workBenches#91 at `lane-handoff:242` and `:248`). Each `--flag=*` arm below
	# takes whatever follows the `=`, and every one of these values is read
	# further down as "was this given at all?": `--lane=` fell through to the
	# window's own lane and handed THAT one off, `--writers-file=` wrote the
	# WRITERS section with no brief for a writer the caller had briefed, and
	# `--dir=` took the record's directory in place of the one being named. The
	# spaced spelling has always refused an empty value through `flag_value`;
	# this is the same refusal for the other spelling, in ONE arm ahead of the
	# seven, because `case` takes the first pattern that matches. The arms below
	# keep taking a value that begins with `-`, which is what `=` is for.
	--operation= | --at= | --lane= | --agent= | --transcript= | --writers-file= | --dir=)
		die "${1%=} needs a value, and '$1' gives it an empty one. Give it one after the '=', or leave the flag out." 2 ;;
	--operation) operation="$(flag_value --operation "${2-}")" || exit; shift 2 ;;
	--operation=*) operation="${1#--operation=}"; shift ;;
	--at) late_at="$(flag_value --at "${2-}")" || exit; shift 2 ;;
	--at=*) late_at="${1#--at=}"; shift ;;
	--lane) lane="$(flag_value --lane "${2-}")" || exit; shift 2 ;;
	--lane=*) lane="${1#--lane=}"; shift ;;
	--agent) agent="$(flag_value --agent "${2-}")" || exit; shift 2 ;;
	--agent=*) agent="${1#--agent=}"; shift ;;
	--transcript) transcript="$(flag_value --transcript "${2-}")" || exit; shift 2 ;;
	--transcript=*) transcript="${1#--transcript=}"; shift ;;
	--writers-file) writers_file="$(flag_value --writers-file "${2-}")" || exit; shift 2 ;;
	--writers-file=*) writers_file="${1#--writers-file=}"; shift ;;
	--dir) dir_flag="$(flag_value --dir "${2-}")" || exit; shift 2 ;;
	--dir=*) dir_flag="${1#--dir=}"; shift ;;
	--) shift; while [ $# -gt 0 ]; do why="${why:+$why }$1"; shift; done ;;
	-*) die "unknown option '$1' — see $prog --help" 2 ;;
	*) why="${why:+$why }$1"; shift ;;
	esac
done

# THE WHY IS ONE LINE, AND IT IS REFUSED AT THE DOOR (opensoft/openRepoTools#72
# item 6, #85). It reaches FOUR places, and only the last two pass through
# `sanitize`: the handoff's top block, where a newline writes a malformed prompt
# (a `---` line among them, which is where `lane-start`'s `handoff_top_block`
# ends the first prompt it hands the next session); the handoff commit's
# subject; the object log's PAUSED line, where `write_event` refuses it, but
# only AFTER section 2 has refreshed and committed the handoff, so the act ends
# with a top block and no record behind it; and the register's file-level
# line, where `append-line` used to write it first and refuse it after. One
# test here covers all four, and it comes before the identity triple, the
# refresh and every write, so the refusal leaves nothing to undo. It is the
# rule `lane-end --reason` and `rename-lane`'s reason already keep for a free
# text that becomes one line. `sanitize` flattens a newline as well, but that
# is the second line of defence and not this one.
if [ "${why//[$'\n\r']/}" != "$why" ]; then
	die "the why is ONE line: it is written into the handoff's top block, its commit message, the object log's PAUSED line and the register's file-level line, and a newline or carriage return in it would split each of them — the last two in files nothing rewrites. Nothing was written. Put it on one line, with '; ' where the break was, and re-run." 2
fi

# ONE ACT AT A TIME AFTER THE RECORD. `--restart` respawns the pane for a lane
# that STAYS HERE and `--exit` ends the session for a lane going somewhere else
# (Amendment 18(d)); asking for both is asking the same pane to do two opposite
# things, and whichever ran second would run against a pane the first had
# already replaced.
# AND THE TWO MODES THAT ARE NOT HANDOFFS AT ALL ARE ASKED FOR ALONE
# (openRepoTools#94). `--supervise` is the pane's own root process after a
# `/ctx` and `--restart-status` is a read; neither writes a PAUSED record, and a
# caller that asked for one of them beside `--restart` is asking this command to
# hand off a lane and to be the thing that catches the handoff, in one process.
for lh_mode_a in supervise:$do_supervise status:$do_status; do
	[ "${lh_mode_a#*:}" = 1 ] || continue
	for lh_mode_b in restart:$do_restart exit:$do_exit late:$do_late in-process:$do_in_process; do
		[ "${lh_mode_b#*:}" = 1 ] || continue
		die "--${lh_mode_a%%:*} is not a handoff and --${lh_mode_b%%:*} is: the first is the pane's own process after a /ctx (or a read of what that /ctx left), and the second writes the record. Ask for one." 2
	done
done
[ "$do_supervise" = 1 ] && [ "$do_status" = 1 ] &&
	die "--supervise launches and --restart-status reads; ask for one." 2
# AND `--operation` NAMES THE ACT `--supervise` WAS STARTED FOR, so it is
# meaningless anywhere else — and worse than meaningless on `--restart`, whose
# own tail MINTS an operation: a value given there would be silently discarded,
# which is the shape of thing a person only finds out about from a record that
# does not say what they typed.
[ -n "$operation" ] && [ "$do_supervise" != 1 ] &&
	die "--operation names the restart operation a supervisor was started for, and only --supervise reads it. --restart MINTS its own operation and would discard this one silently; every other mode has none. Drop it, or run:  $prog --supervise --lane <lane> --operation $operation" 2

[ "$do_restart" = 1 ] && [ "$do_exit" = 1 ] &&
	die "--restart and --exit are two different ends for one act: --restart respawns this lane's own pane (Amendment 17(f), the lane stays here) and --exit ends the session (Amendment 18(d), the lane goes elsewhere). Pick one." 2
# AND `--late` IS NEITHER OF THEM. It is written BEFORE the relaunch by a shell
# that is not in the lane's session at all — there is no pane of this lane's to
# respawn or to type into, and the relaunch it precedes is the operator's own
# `pclaude`.
[ "$do_late" = 1 ] && { [ "$do_restart" = 1 ] || [ "$do_exit" = 1 ]; } &&
	die "--late is the record a swap never left, written from a shell BEFORE the relaunch: there is no session of this lane's to restart or exit. Write the late record first, then start the lane." 2
# AND `--late --in-process` IS A CONTRADICTION IN ITS OWN TERMS (Copilot round 4
# on openRepoTools#47). A late record is written for a session that has ALREADY
# ENDED — that is what makes it late — and `--in-process` says THIS PROCESS KEPT
# RUNNING. Taken together the kind block below would take the `in-process` arm
# first and write a record telling the next session to expect writers live that
# died with the process the record is about.
[ "$do_late" = 1 ] && [ "$do_in_process" = 1 ] &&
	die "--late and --in-process cannot both be true: a late record is written for a session that has ALREADY ENDED (that is what makes it late, and its writers went with it), while --in-process says THIS PROCESS KEPT RUNNING. A late record is \`kind respawn\`. Drop --in-process." 2

# ------------------------------------------- THE KIND OF CLEAR THIS RECORDS
#
# MEASURED IN THIS LANE ON 2026-09-14, and it is the difference between a
# handoff a session can act on and one that costs it a worktree:
#
#   in-process  a harness `/clear` — and any `/ctx` that clears IN PLACE rather
#               than respawning the pane — mints a NEW TRANSCRIPT ID IN THE SAME
#               PROCESS. Every subagent this lane has running SURVIVES it; only
#               the tool calls they had in flight die (a `Bash` killed at the
#               clear exits 137). A top block that then says *relaunch every
#               writer below* puts a SECOND writer on a worktree the first one
#               still holds, and the two of them lose each other's work.
#   respawn     the pane is respawned (`--restart`) or the session is ended
#               (`--exit`) — a NEW PROCESS either way, and every writer of the
#               old one is gone with it. A profile switch and a usage-reset
#               relaunch are the same kind by the same argument (Addendum 1
#               (h)), and each is this command with one of those two flags.
#
#   unknown     a PLAIN handoff — `/handoff` with none of the three flags —
#               after which the person may type `/clear` or may relaunch. The
#               act that follows is not this command's to know, and Addendum 1
#               (h) is explicit that such a record writes `kind unknown` rather
#               than guessing: the top block then treats it as (i) treats every
#               kind, which is to COUNT the live writers first.
#
# THE KIND SAYS WHAT TO EXPECT AND NEVER WHAT TO DO (Amendment 17 Addendum 1,
# ratified 2026-09-14T20:59:31Z, clause (j)). Clause (i) is what says what to
# do, it is the same in all three cases, and it is the WRITERS section's first
# line below.
[ "$do_in_process" = 1 ] && { [ "$do_restart" = 1 ] || [ "$do_exit" = 1 ]; } &&
	die "--in-process says THIS PROCESS KEEPS RUNNING, and --restart respawns this lane's pane while --exit ends the session: each of those replaces the process every writer of this lane is a child of. Pick one — the flag is for a clear that happens inside the session that is running." 2
if [ "$do_in_process" = 1 ]; then
	handoff_kind=in-process
	kind_headline='expect every writer below live — count them before you touch any of them'
	kind_act='THIS HANDOFF WAS WRITTEN FOR AN IN-PROCESS CLEAR: the process was not replaced, so expect every writer below live and the count to name them all.'
	kind_state='the process was not replaced, so every writer above kept running through the clear and only its in-flight tool calls died'
elif [ "$do_restart" = 1 ] || [ "$do_exit" = 1 ] || [ "$do_late" = 1 ]; then
	# `--late` IS A RESPAWN AND NEVER AN UNKNOWN: the record a swap never left
	# is written for a session that has ALREADY ended — that is why it is late —
	# so the process is gone and every writer with it, which is what the word
	# names (Addendum 1 (h): "a usage-reset relaunch").
	handoff_kind=respawn
	kind_headline='expect none of the writers below live — count them, then relaunch from where each stands'
	kind_act='THIS HANDOFF WAS WRITTEN FOR A RESPAWN: the process that ran the writers is gone, so expect the count to name none of them.'
	kind_state='a NEW PROCESS takes this lane on — the pane respawned or the session ended — so every writer of the old one is gone with it'
else
	handoff_kind=unknown
	kind_headline='the count decides: this handoff cannot know whether the process survived'
	kind_act='THIS HANDOFF CANNOT KNOW WHICH KIND FOLLOWED IT: a plain handoff may be followed by a `/clear` in this process or by a relaunch, so nothing below assumes either — the count is the answer.'
	kind_state='the act that follows this record was not this command'"'"'s to know (`kind unknown`, Addendum 1 (h)) — the restart line below is one of the two, and a `/clear` typed here is the other'
fi

# ---------------------------------------------------------------- the helper
#
# Beside this command first — `--install` places both in one directory — then on
# PATH. One resolution, so a workstation with two copies never reads one and
# writes the other.
LANES_EDIT="${LANES_EDIT:-}"
if [ -z "$LANES_EDIT" ]; then
	if [ -x "$selfdir/lanes-edit.sh" ]; then LANES_EDIT="$selfdir/lanes-edit.sh"
	else LANES_EDIT="$(command -v lanes-edit.sh 2>/dev/null || printf '')"
	fi
fi
[ -n "$LANES_EDIT" ] && [ -x "$LANES_EDIT" ] || die "no register reader at ${LANES_EDIT:-lanes-edit.sh} — it is installed beside this
    command by \`openRepoTools --install\`. Run that, or set \$LANES_EDIT." 2

utc_now() { date -u +%Y-%m-%dT%H:%M:%SZ; }
UTC="$(utc_now)"

# TMUX IS THIS LANE'S ONLY FROM INSIDE IT (opensoft/openRepoTools#80 item 10,
# Copilot's review of workBenches#91 at `lane-handoff:351`). A `tmux` binary on
# PATH is not a tmux client: from an ordinary shell on a host where any tmux
# server runs — another person's, a leftover one — every `display-message`
# below answers about that server's most recent client, and the rename, the
# record's `window` and `--restart`/`--exit` would then read or act on a window
# that is not this lane's. `$TMUX` is set only inside a real client, which is
# the test `lane`'s `tmux_here` makes and the one made here.
have_tmux() {
	[ "${LANE_HANDOFF_NO_TMUX:-0}" = 1 ] && return 1
	[ -n "${TMUX:-}" ] && command -v tmux >/dev/null 2>&1
}

# THIS COMMAND'S OWN ABSOLUTE PATH, because tmux starts the supervisor and a
# respawned pane's `PATH` is whatever the person's shell profile makes of it —
# which is one of the ways a respawn comes up with a word that is not this
# estate's.
SELF_ABS="$selfdir/${SELF##*/}"

# THE HANDOFF'S DIGEST, spelled as `lanes-edit.sh` and `lane-start` spell it:
# all three compare the same number, so there is ONE implementation of it and
# not three. `none` is an ANSWER — this workstation has neither tool — and it
# means *not checked here*, never *unchanged*.
handoff_digest() {   # <file>
	[ -r "${1-}" ] || { printf 'none\n'; return 0; }
	if command -v sha256sum >/dev/null 2>&1; then
		sha256sum -- "$1" 2>/dev/null | awk '{print $1; exit}'
	elif command -v shasum >/dev/null 2>&1; then
		shasum -a 256 -- "$1" 2>/dev/null | awk '{print $1; exit}'
	else
		printf 'none\n'
	fi
}

# A PANE REF IS COMPARED COMPONENT-WISE, NEVER AS A SUFFIX OR A PREFIX. The
# three spellings are `<session>:<@id>`, `<session>:<@id>.%<pane>` and, in
# `$TMUX_PANE`, the bare `%<pane>` — and a `case` on `*"$x"` accepts `%16` for
# `%6` and a `case` on `"$x"*` accepts `@331` for `@33`. Both are the wrong
# window, and this comparison decides whether a second session of a lane gets
# started in one. Empty on either side is NOT a disagreement: a comparison that
# cannot be made is said rather than failed shut, which is what the callers do
# with it.
pane_agrees() {   # <a> <b>
	pa_a="${1-}"; pa_b="${2-}"
	[ -n "$pa_a" ] && [ -n "$pa_b" ] || return 0
	[ "$pa_a" != none ] && [ "$pa_b" != none ] || return 0
	[ "$pa_a" = "$pa_b" ] && return 0
	# A BARE `%<pane>` on either side is compared against the other's pane
	# component and against nothing else.
	case "$pa_a" in
	%*) case "$pa_b" in *.%*) [ "$pa_a" = "${pa_b##*.}" ] && return 0 ;; esac; return 1 ;;
	esac
	case "$pa_b" in
	%*) case "$pa_a" in *.%*) [ "$pa_b" = "${pa_a##*.}" ] && return 0 ;; esac; return 1 ;;
	esac
	# Otherwise both name a window; one may also name a pane, and a record that
	# names only the window agrees with an intent that names the pane inside it.
	case "$pa_a" in *.%*) pa_aw="${pa_a%.*}" ;; *) pa_aw="$pa_a" ;; esac
	case "$pa_b" in *.%*) pa_bw="${pa_b%.*}" ;; *) pa_bw="$pa_b" ;; esac
	[ "$pa_aw" = "$pa_bw" ]
}

# ---------------------------------------------------- the readiness predicate
#
# READ-ONLY, AND POSITIVE. It asks five things and every one of them must
# answer, because the failure this exists to stop is a launch that was ACCEPTED
# and never happened:
#
#   1. the child this supervisor started is still alive;
#   2. this workstation's session records name a LIVE HOLDER of the lane;
#   3. exactly ONE of them — a second is Amendment 18(h)'s collision, and a
#      restart that confirmed itself while two processes answered for one lane
#      would be the tooling making the very thing the protocol refuses;
#   4. that holder's transcript is the one `lane-start` said it was about to
#      make — and, where it said nothing, at least one that is NOT the
#      transcript the `/ctx` paused, which is the spec's *a transcript distinct
#      from the old transcript*;
#   5. it is in the pane the intent was written for, where both are knowable.
#
# IT WRITES NOTHING, AND IT NEEDS NOTHING FROM THE `SessionStart` HOOK, whose
# read-only, network-free, always-zero contract is load-bearing (`R-A8-1`,
# ratified) and is untouched by any of this.
#
# THE CHILD'S PID COMES OUT OF A FILE and not out of a variable, because the
# child is started in the FOREGROUND (below) and this predicate runs in a
# background observer that has no way to be told it otherwise. An empty file is
# *the child has not got as far as recording itself*, which is not the same as
# *the child is gone*.
#
# 0 ready · 1 not yet (the reason is on `READY_WHY`) · 2 the child is gone.
ready_check() {   # <lane> <pid file> <expected new transcript|""> <old transcript|""> <pane|"">
	rc_lane="$1"; rc_pidf="$2"; rc_new="$3"; rc_old="$4"; rc_pane="$5"
	READY_WHY=""; READY_SID=""
	rc_pid=""
	[ -r "$rc_pidf" ] && rc_pid="$(head -n 1 -- "$rc_pidf" 2>/dev/null | tr -dc '0-9')"
	if [ -z "$rc_pid" ]; then
		READY_WHY="the child has not recorded its pid yet"
		return 1
	fi
	kill -0 "$rc_pid" 2>/dev/null || { READY_WHY="the child (pid $rc_pid) is gone"; return 2; }
	rc_ps="$(ps -p "$rc_pid" -o stat= 2>/dev/null)"; rc_ps="$(printf '%s' "$rc_ps" | tr -d '[:space:]')"
	case "$rc_ps" in
	  Z*) READY_WHY="the child (pid $rc_pid) exited and is awaiting reap"; return 2 ;;
	  '') READY_WHY="the child process state could not be established"; return 1 ;;
	esac
	rc_out=""; rc_rc=0
	rc_out="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-holders "$rc_lane" 2>/dev/null)" || rc_rc=$?
	case "$rc_rc" in
	0) : ;;
	8) READY_WHY="no live session record names lane $rc_lane yet"; return 1 ;;
	*) READY_WHY="this workstation's session records could not be read (live-holder exited $rc_rc), which is NOT 'nothing is live'"; return 1 ;;
	esac
	rc_n="$(printf '%s\n' "$rc_out" | awk -F'\037' '!seen[$4]++ {n++} END {print n+0}')"
	if [ "${rc_n:-0}" != 1 ]; then
		READY_WHY="$rc_n live holders answer for lane $rc_lane and readiness needs exactly one (Amendment 18(h))"
		return 1
	fi
	# Historical records for one live PID are one process. Prefer the
	# current attempt's exact fresh UUID; another PID still blocks above.
	if [ -n "$rc_new" ] && [ "$rc_new" != none ]; then
		rc_expected="$(printf '%s\n' "$rc_out" | awk -F'\037' -v sid="$rc_new" '$1==sid {print; exit}')"
		[ -z "$rc_expected" ] || rc_out="$rc_expected"
	fi
	# lane-holders reads only trusted Claude-native interactive session records;
	# that provenance plus the Claude-only launch gate supplies agent evidence.
	rc_sid="$(printf '%s\n' "$rc_out" | awk -F'\037' '{print $1; exit}')"
	rc_tgt="$(printf '%s\n' "$rc_out" | awk -F'\037' '{print $2; exit}')"
	rc_nm="$(printf '%s\n' "$rc_out" | awk -F'\037' '{print $3; exit}')"
	READY_SID="$rc_sid"
	# THE HOLDER'S NAME IS THE LANE'S ADDRESS, and it is evidence this predicate
	# already had in its hand and did not read (Copilot round 2 on
	# openRepoTools#121). Amendment 2 makes the session NAME the lane's messaging
	# address — `ListAgents`, `SendMessage`, `@<lane>` and the statusline all read
	# it — so a replacement answering for this lane under some other name is not
	# the replacement this restart was for, whatever its transcript says.
	# Compared case-insensitively, because Amendment 15 makes one lane's two
	# spellings one lane; `none` on either side is a comparison that cannot be
	# made and is said rather than failed shut, as `pane_agrees` does.
	if [ -n "$rc_nm" ] && [ "$rc_nm" != none ]; then
		if [ "$(printf '%s' "$rc_nm" | tr '[:upper:]' '[:lower:]')" != "$(printf '%s' "$rc_lane" | tr '[:upper:]' '[:lower:]')" ]; then
			READY_WHY="the live holder is named '$rc_nm' and this lane is $rc_lane — a session answering for the lane under another name is not this restart's replacement (Amendment 2)"
			return 1
		fi
	fi
	if [ -n "$rc_new" ] && [ "$rc_new" != none ]; then
		if [ "$rc_sid" != "$rc_new" ]; then
			READY_WHY="the live holder's transcript is $rc_sid and this launch was preparing $rc_new"
			return 1
		fi
	elif [ -n "$rc_old" ] && [ "$rc_old" != none ] && [ "$rc_sid" = "$rc_old" ]; then
		READY_WHY="the live holder's transcript is $rc_sid, which is the one this /ctx paused — that is a resume and not a fresh session"
		return 1
	fi
	if ! pane_agrees "$rc_pane" "$rc_tgt"; then
		READY_WHY="the live holder is in $rc_tgt and the intent names pane $rc_pane"
		return 1
	fi
	return 0
}

# ------------------------------------------------- the observer, and the wait
#
# THE CHILD RUNS IN THE FOREGROUND AND THIS PROCESS WAITS ON IT. That order is
# not a preference: the child is an interactive terminal program, and a
# background child in a shell with no job control cannot read the terminal at
# all. So the OBSERVATION goes into the background instead — one subshell that
# polls the read-only predicate above and, the moment it answers, makes the one
# fenced write that turns this restart into a confirmed one. That is the
# design's *separate observation path*, and it is why nothing is printed over a
# running Claude's screen: the observer WRITES its verdict, and
# `--restart-status` from any other window is where it is read.
#
# EVERY TWO SECONDS AND NOT EVERY ONE: the predicate's middle question goes
# through `lanes-edit.sh live-holder`, which reads the register, and sixty of
# those in a minute is sixty git processes behind a session that is trying to
# start.
supervise_watch() {   # <lane> <operation> <generation> <pid file> <new> <old> <pane>
	sw_lane="$1"; sw_op="$2"; sw_gen="$3"; sw_pidf="$4"; sw_new="$5"; sw_old="$6"; sw_pane="$7"; sw_attempt="$8"; sw_stop="$9"
	# THE DEADLINE IS WALL CLOCK, NOT A COUNT OF SLEEPS. This loop used to add
	# 2 per turn and call that the elapsed time, which counts only the `sleep`
	# and never the work between two of them — and the work is a `live-holder`
	# read that resolves the lane, reads the published row and scans every
	# session record this workstation has. On a loaded machine that is seconds,
	# so a "60-second" deadline was sixty seconds PLUS thirty register reads,
	# and the INDETERMINATE line then reported a number that had never elapsed.
	# The design's promise is *"waits up to 60 seconds"* and a person waiting on
	# a pane is owed the number they were told.
	#
	# THE COUNTED SLEEPS ARE KEPT AS THE FLOOR, so this loop terminates on a
	# workstation whose `date` cannot answer or whose clock steps backwards:
	# the wait is the GREATER of what was slept and what the clock says, and a
	# clock that goes backwards simply leaves the counted sleeps deciding.
	sw_t0="$(date +%s 2>/dev/null | tr -dc '0-9')"
	sw_slept=0
	sw_waited=0
	while [ "$sw_waited" -lt "$SUPERVISE_READY_SECONDS" ]; do
		[ ! -e "$sw_stop" ] || return 0
		sleep 2
		[ ! -e "$sw_stop" ] || return 0
		sw_slept=$((sw_slept + 2))
		sw_waited="$sw_slept"
		sw_now="$(date +%s 2>/dev/null | tr -dc '0-9')"
		if [ -n "$sw_t0" ] && [ -n "$sw_now" ] && [ "$sw_now" -gt "$sw_t0" ]; then
			sw_el=$((sw_now - sw_t0))
			[ "$sw_el" -gt "$sw_waited" ] && sw_waited="$sw_el"
		fi
		# lane-start writes the prepared UUID after the observer has started.
		# Read the current attempt, never the preceding attempt's UUID.
		if ! ri_load "$sw_lane"; then return 5; fi
		[ "$RI_OP" = "$sw_op" ] && [ "$RI_GEN" = "$sw_gen" ] &&
		  [ "$RI_ATTEMPT" = "$sw_attempt" ] && [ "$RI_STATE" = starting ] || return 5
		sw_new="$RI_NEW"
		case "$sw_new" in ''|none) continue ;; esac
		sw_rc=0
		ready_check "$sw_lane" "$sw_pidf" "$sw_new" "$sw_old" "$sw_pane" || sw_rc=$?
		case "$sw_rc" in
		2) return 3 ;;          # the child is gone; the supervisor has its status
		0)
			# THE FINALIZER, FENCED ON THIS OPERATION AND THIS GENERATION. A
			# stale observer of a superseded operation writes nothing: exit 7
			# is the intent refusing it, and that refusal is the whole point of
			# the fence.
			[ ! -e "$sw_stop" ] || return 0
			sw_frc=0
			LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sw_lane" ready \
				--expect starting --expect-operation "$sw_op" --expect-generation "$sw_gen" --expect-attempt "$sw_attempt" \
				--new-transcript "${READY_SID:-$sw_new}" \
				--reason "readiness confirmed after ${sw_waited}s" >/dev/null 2>&1 || sw_frc=$?
			if [ "$sw_frc" != 0 ]; then
				note "lane $sw_lane came up and the restart intent could NOT be marked ready (exit $sw_frc): the session is running and the record does not say so. Read it:  $prog --restart-status --lane $sw_lane"
				return 5
			fi
			# Legacy readiness belongs only to this intent. Never advance #97's
			# diagnostic snapshot or a managed JSON generation/operation here.
			return 0 ;;
		esac
	done
	# THE DEADLINE, WITH THE CHILD STILL ALIVE — INDETERMINATE, which is a THIRD
	# answer and not a failure. Nothing is killed (Amendment 8(f): ending
	# somebody's process is not a boundary script's act), nothing is retried,
	# and the lane is NOT marked running.
	# FENCED ON THE GENERATION LIKE EVERY OTHER WRITE THIS OBSERVER MAKES. It is
	# the same argument Copilot's round 1 makes about the failure write: an
	# observer whose lane has moved on must not publish its verdict over a newer
	# generation's record, and `$sw_gen` is the generation the supervisor
	# CLAIMED rather than whatever is on disk by now.
	[ ! -e "$sw_stop" ] || return 0
	LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sw_lane" starting \
		--expect starting --expect-operation "$sw_op" --expect-generation "$sw_gen" --expect-attempt "$sw_attempt" \
		--reason "INDETERMINATE: ${sw_waited}s elapsed (deadline ${SUPERVISE_READY_SECONDS}s) with the child alive and readiness unconfirmed; ${READY_WHY:-no evidence}" >/dev/null 2>&1 || :
	return 4
}

# THE CHILD'S ARGV, out of the intent and out of nothing else — the spec's *no
# picker, attach, select, current-directory, title, or default-profile
# resolution*, and never the human-facing `lane` dispatcher, whose valid
# outcomes include attaching to something instead of launching.
#
# THE LAUNCHER FIRST, because it is what configures the ACCOUNT: `pclaude
# --lane <lane> <profile>` is the same act `lane`'s available branch makes, one
# door along, and `lane-start` is what it runs. Where this workstation has no
# launcher, or the intent records no profile to hand one, the supervisor runs
# `lane-start` itself with the fresh mode as an ARGUMENT — the narrow operation
# launch, and the only path on which `--operation` can be passed at all, since
# the launcher forwards no argument of its own.
#
# EITHER WAY THE FRESH SESSION IS THE INTENT'S TO DECIDE AND NOT THIS ARGV'S:
# `lane-start` reads the same file and goes fresh with no flag and no variable
# set. The flag and the variable are set here anyway, because a launch that
# says what it is in three places is a launch whose defect capture can be read
# — and because on the launcher path they are the only two that even reach it.
supervise_argv() {   # <lane> <operation>
	sa_lane="$1"; sa_op="$2"
	SUPERVISE_CMD=(); SUPERVISE_VIA=""
	sa_launcher="${PCLAUDE:-}"
	if [ -z "$sa_launcher" ]; then
		sa_launcher="$(command -v lclaude 2>/dev/null || command -v pclaude 2>/dev/null || command -v claude-profile 2>/dev/null || printf '')"
	fi
	if [ -n "$sa_launcher" ] && [ -n "$RI_PROFILE" ] && [ "$RI_PROFILE" != none ]; then
		SUPERVISE_CMD=("$sa_launcher" --lane "$sa_lane" "$RI_PROFILE")
		SUPERVISE_VIA="the launcher ($sa_launcher), which configures the account and runs lane-start"
		return 0
	fi
	sa_start=""
	if [ -x "$selfdir/lane-start" ]; then sa_start="$selfdir/lane-start"
	else sa_start="$(command -v lane-start 2>/dev/null || printf '')"
	fi
	[ -n "$sa_start" ] || return 1
	SUPERVISE_CMD=("$sa_start" --fresh --operation "$sa_op")
	[ -n "$RI_DIR" ] && [ "$RI_DIR" != none ] && SUPERVISE_CMD+=(--dir "$RI_DIR")
	SUPERVISE_CMD+=("$sa_lane")
	if [ -n "$sa_launcher" ]; then
		SUPERVISE_VIA="lane-start directly ($sa_start) — this lane's record names no profile, so there is nothing to tell the launcher which account to come up in"
	else
		SUPERVISE_VIA="lane-start directly ($sa_start) — there is no launcher on PATH here"
	fi
	return 0
}

# THE FAILURE SURFACE. The supervisor is STILL IN THE PANE, which is the whole
# of what this change is for, and what it offers is one line to retry and one
# to walk away with. A pane with no terminal — the suite, a `--supervise` run
# from a script — is told the same thing and gets exit 3 rather than a read
# nobody will answer.
#
# 3 = reported, no terminal · 10 = reported, ask the person.
# THE FAILURE IS FENCED ON THE GENERATION TOO, AND ON THE ONE THIS SUPERVISOR
# CLAIMED (Copilot round 1 on openRepoTools#121). The readiness finalizer has
# always carried `--expect-generation`; this write did not, so a supervisor
# whose lane had moved on could publish its old failure over a newer
# generation's record. The number has to be the one captured AT THE CLAIM and
# not the one on disk now — re-reading it would read the newer generation and
# match it, which is the stale write the fence exists to refuse.
supervise_failed() {   # <lane> <operation> <reason>
	sf_lane="$1"; sf_op="$2"; sf_why="$3"
	# A dead launcher can leave a descendant holding the lane. Only an
	# affirmative empty holder read allows a retryable failure.
	sf_hrc=0
	LANES_NO_FETCH=1 "$LANES_EDIT" lane-holders "$sf_lane" >/dev/null 2>&1 || sf_hrc=$?
	if [ "$sf_hrc" != 8 ]; then
		LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sf_lane" starting \
			--expect starting --expect-operation "$sf_op" \
			--expect-generation "$SV_CLAIMED_GEN" --expect-attempt "$SV_CLAIMED_ATTEMPT" \
			--reason "INDETERMINATE: launch ended but holder absence is unproven (read $sf_hrc); $sf_why" >/dev/null 2>&1 || :
		say "INDETERMINATE — holder absence is unproven; retry is blocked."
		say "  read it: $prog --restart-status --lane $sf_lane"
		return 4
	fi
	sf_fence=()
	[ -n "$SV_CLAIMED_GEN" ] && sf_fence=(--expect-generation "$SV_CLAIMED_GEN" --expect-attempt "$SV_CLAIMED_ATTEMPT")
	sf_wrc=0
	LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sf_lane" failed \
		--expect 'starting|pending' --expect-operation "$sf_op" \
		${sf_fence[@]+"${sf_fence[@]}"} \
		--reason "$sf_why" >/dev/null 2>&1 || sf_wrc=$?
	case "$sf_wrc" in
	  0) : ;;
	  7)
		say "SUPERSEDED — this supervisor no longer owns operation $sf_op; no retry is authorized here."
		say "  read it: $prog --restart-status --lane $sf_lane"
		return 2 ;;
	  *)
		note "the restart failure could not be recorded (exit $sf_wrc); retry remains blocked. Read it: $prog --restart-status --lane $sf_lane"
		return 1 ;;
	esac
	say ""
	say "RESTART FAILED — lane $sf_lane, operation $sf_op"
	say "  $sf_why"
	say ""
	say "  The old session is gone (this pane was respawned for the restart) and the"
	say "  handoff it wrote is intact: its top block is still the first prompt the next"
	say "  session gets, and nothing of the lane has been lost."
	say ""
	say "  retry:   $(quoted "$SELF_ABS") --supervise --lane $sf_lane --operation $sf_op"
	say "  read it: $(quoted "$SELF_ABS") --restart-status --lane $sf_lane"
	say "  retry uses this same supervised operation; ordinary lane resume is not recovery."
	say ""
	if [ "${LANE_SUPERVISOR_NO_PROMPT:-0}" = 1 ] || [ ! -t 0 ]; then
		note "there is no terminal here to offer the retry on, so this supervisor exits 3 rather than blocking on a read nobody will answer. The intent is \`failed\` and carries the reason; the three lines above are the whole of what to do next."
		return 3
	fi
	return 10
}

# THE ONE QUESTION THIS COMMAND EVER ASKS, and it asks it only where a person is
# looking at the pane. `r` retries the SAME operation; anything else leaves the
# pane to the person, with the intent `failed` and every line above still on
# screen.
supervise_prompt() {   # <lane> <operation>
	printf '%s: retry this restart? [r = retry, q = leave it] ' "$prog" >&2
	sp_ans=""
	IFS= read -r sp_ans || { printf '\n' >&2; return 3; }
	case "$sp_ans" in
	r | R | retry) return 0 ;;
	*)
		say ""
		say "left as it is. The intent stays \`failed\` and this pane is yours:"
		say "  retry:   $(quoted "$SELF_ABS") --supervise --lane $1 --operation $2"
		return 3 ;;
	esac
}

# THE SUPERVISOR PROPER. It loops only because a RETRY is the same launch made
# again under the same operation, generation, digest, directory and mode — the
# spec's idempotent retry — and never because a child that ended is relaunched
# on its own.
# THE CHILD, AS ONE WORD, so the two spellings of its launch differ only in the
# redirection that hands it this pane's stdin. It reads `sr_dir`, `sr_op`,
# `sr_pidf` and `SUPERVISE_CMD` from the run it is called inside.
supervise_child() {
	( trap - INT QUIT
	  if [ -n "$sr_dir" ] && [ "$sr_dir" != none ]; then
		cd -- "$sr_dir" || exit 127
	  fi
	  LANE_START_FRESH=1 LANE_RESTART_OPERATION="$sr_op" LANE_RESTART_ATTEMPT="$SV_CLAIMED_ATTEMPT" \
		exec sh -c 'printf "%s\n" "$$" > "$1"; shift; exec "$@"' _ "$sr_pidf" "${SUPERVISE_CMD[@]}" )
}

supervise_run() {   # <lane> <operation>
	sr_lane="$1"; sr_op="$2"
	# THIS PANE'S OWN STDIN, SAVED, so the background child below can be given
	# it back. Where fd 0 cannot be duplicated the child is started without it,
	# which is what a foreground child would have had anyway on such a shell.
	SV_STDIN_SAVED=0
	# Scope stderr suppression to the descriptor save. A bare exec also
	# redirects this shell's stderr permanently, hiding the retry prompt.
	if { exec 9<&0; } 2>/dev/null; then SV_STDIN_SAVED=1; fi
	sr_pidf="$(mktemp "${TMPDIR:-/tmp}/lane-supervisor.XXXXXX" 2>/dev/null || printf '')"
	[ -n "$sr_pidf" ] || die "no temporary file could be made to record the launch's pid, and without it this supervisor cannot tell a child that died from one that is starting. Nothing was started." 2
	SV_PIDFILE="$sr_pidf"
	while : ; do
		# ---- the claim: `pending`/`failed` -> `starting`, fenced on the
		# operation AND the generation. It is INSIDE the loop because a retry
		# is a second claim of the same operation and must take the fence
		# again: between the failure and the `r` a person may have started the
		# lane by hand, and the retry must lose that race rather than win it.
		ri_load "$sr_lane" || die "the restart intent could not be read. Nothing was started." 2
		case "$RI_STATE" in
		pending) sr_att=(--attempt=1); sr_claim_attempt=1 ;;
		failed)  sr_att=(--bump-attempt); sr_claim_attempt=$((RI_ATTEMPT + 1)) ;;
		*) die "lane $sr_lane's restart intent is '${RI_STATE:-none}' and this supervisor can only launch from \`pending\` or \`failed\`. Nothing was started. Read it:  $prog --restart-status --lane $sr_lane" 2 ;;
		esac
		LANES_NO_FETCH=1 "$LANES_EDIT" legacy-restart-check "$sr_lane" ||
			die "managed ownership blocks this legacy retry. Nothing was started." 2
		sr_claim_gen="$RI_GEN"
		SV_CLAIMED_GEN=""; SV_CLAIMED_ATTEMPT=""; SV_CHILD_LAUNCH_STARTED=0
		SV_DEFERRED_SIGNAL=""; SV_DEFERRED_STATUS=""
		SV_CLAIMING=1
		sr_crc=0
		LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sr_lane" starting \
			--expect "$RI_STATE" --expect-operation "$sr_op" --expect-generation "${RI_GEN:-0}" --expect-attempt "$RI_ATTEMPT" \
			"${sr_att[@]}" --new-transcript none --reason "supervisor claimed the operation" >/dev/null 2>&1 || sr_crc=$?
		# The writer is the authority for a successful CAS; publish its exact
		# requested identity before replaying a signal deferred during the claim.
		if [ "$sr_crc" = 0 ]; then
			SV_CLAIMED_GEN="$sr_claim_gen"; SV_CLAIMED_ATTEMPT="$sr_claim_attempt"
		fi
		SV_CLAIMING=0
		[ -z "$SV_DEFERRED_SIGNAL" ] || sv_signal "$SV_DEFERRED_SIGNAL" "$SV_DEFERRED_STATUS"
		case "$sr_crc" in
		0) : ;;
		7) die "lane $sr_lane's restart intent moved between reading it and claiming it: another act owns operation $sr_op now. Nothing was started. Read it:  $prog --restart-status --lane $sr_lane" 2 ;;
		*) die "lane $sr_lane's restart intent could not be claimed (\`set-restart-intent\` exited $sr_crc), and this supervisor will not launch without a fenced hold on operation $sr_op. Nothing was started." 2 ;;
		esac
		ri_load "$sr_lane" || die "the claimed intent could not be read back. Nothing was started." 2
		[ "$RI_OP" = "$sr_op" ] && [ "$RI_GEN" = "$sr_claim_gen" ] && [ "$RI_ATTEMPT" = "$sr_claim_attempt" ] && [ "$RI_STATE" = starting ] ||
			die "another operation replaced the supervisor claim. Nothing was started." 2
		# THE GENERATION THIS SUPERVISOR HOLDS, taken once, here, where the claim
		# has just succeeded and the record is this act's. Every later write of
		# this operation is fenced on THIS number rather than on whatever the file
		# says at the time, which is what makes a superseded supervisor's write
		# refuse instead of landing.
		SV_CLAIMED_GEN="${RI_GEN:-0}"
		SV_CLAIMED_ATTEMPT="$RI_ATTEMPT"
		case "$SV_CLAIMED_GEN" in '' | *[!0-9]*) SV_CLAIMED_GEN=0 ;; esac

		# Repeat this check for every claimed attempt, including an interactive
		# retry: a holder may have appeared while the previous failure waited.
		sr_hrc=0
		LANES_NO_FETCH=1 "$LANES_EDIT" lane-holders "$sr_lane" >/dev/null 2>&1 || sr_hrc=$?
		if [ "$sr_hrc" != 8 ]; then
			LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$sr_lane" starting \
				--expect starting --expect-operation "$sr_op" --expect-generation "$SV_CLAIMED_GEN" --expect-attempt "$SV_CLAIMED_ATTEMPT" \
				--reason "INDETERMINATE: holder absence is unproven before attempt launch (read $sr_hrc)" >/dev/null 2>&1 || :
			say "INDETERMINATE — holder absence is unproven; no child was launched and retry is blocked."
			return 4
		fi

		if ! supervise_argv "$sr_lane" "$sr_op"; then
			supervise_failed "$sr_lane" "$sr_op" "there is no launcher and no lane-start on PATH here, so nothing could be started"
			sr_fs=$?
			[ "$sr_fs" = 10 ] || return "$sr_fs"
			supervise_prompt "$sr_lane" "$sr_op" || return $?
			continue
		fi
		sr_dir="$RI_DIR"
		if [ ! -d "$sr_dir" ] || [ ! -r "$sr_dir" ] || [ ! -x "$sr_dir" ]; then
			supervise_failed "$sr_lane" "$sr_op" "the intent's checkout $sr_dir does not exist here, so the launch was not made"
			sr_fs=$?
			[ "$sr_fs" = 10 ] || return "$sr_fs"
			supervise_prompt "$sr_lane" "$sr_op" || return $?
			continue
		fi
		say "lane $sr_lane — restarting (operation $sr_op, attempt ${RI_ATTEMPT:-1})"
		say "  through $SUPERVISE_VIA"
		say "  first prompt: the top block of ${RI_HANDOFF:-the handoff this lane names}"
		say "  this supervisor stays in the pane: whatever the launch does, it will say so here."
		say ""
		: > "$sr_pidf"
		SV_WATCH_DIR="$(mktemp -d "${TMPDIR:-/tmp}/lane-observer.XXXXXX" 2>/dev/null)" ||
			die "no private observer directory could be created. Nothing was started." 2
		supervise_watch "$sr_lane" "$sr_op" "$SV_CLAIMED_GEN" "$sr_pidf" "$RI_NEW" "$RI_OLD" "$RI_PANE" "$RI_ATTEMPT" "$SV_WATCH_DIR/stop" &
		sr_watch=$!
		# PUBLISHED, so the signal handler can stop it: it is a background job of
		# this shell and a signal to this shell is not a signal to it.
		SV_WATCH_PID="$sr_watch"
		sr_status=0
		# THE CHILD RUNS IN THE BACKGROUND AND THIS PROCESS `wait`s ON IT, and
		# that is not a preference either: **bash defers a trap until the
		# foreground command it is running returns**. Measured — a `TERM` sent
		# to a shell running `sleep 20` in the foreground does not reach its
		# `TERM` trap for the whole twenty seconds, and the same shell with the
		# sleep backgrounded and `wait`ed runs the trap in the same second. A
		# supervisor whose child is an interactive Claude runs for hours, so a
		# foreground child means the signal handling above would never fire when
		# it is needed, which is the whole of Copilot round 1's finding.
		#
		# TWO THINGS A BACKGROUND JOB LOSES, AND BOTH ARE PUT BACK, because the
		# child here is an interactive terminal program and neither loss is
		# survivable for one:
		#
		#   * ITS STDIN. With job control off — which is every non-interactive
		#     bash — an asynchronous command's stdin is redirected from
		#     `/dev/null`. Measured. So fd 9 holds this pane's own stdin, saved
		#     before the loop, and the child is started with `<&9`.
		#   * ITS `INT` AND `QUIT`. Bash sets both to SIG_IGN for an
		#     asynchronous command, and SIG_IGN SURVIVES `exec` — so Claude
		#     would come up with Ctrl-C dead, in the pane a person just cleared
		#     the context of. Measured: `SigIgn 0000000000000006` on the child
		#     without the reset, `0000000000000000` with it. `trap - INT QUIT`
		#     in the subshell restores the disposition this shell was entered
		#     with, which is the default, and it does so even though this shell
		#     has since set `trap '' INT` for itself.
		#
		# THE PID IS WRITTEN BY THE PROCESS THAT BECOMES THE CHILD, and `sh -c`
		# is how, on bash 3.2 as well as on a modern one: `$$` inside it is
		# that shell's pid, and the `exec` on the next word makes that pid the
		# launch's own. `$BASHPID` would be the one-liner and macOS ships bash
		# 3.2, which does not have it.
		# `9<&-` CLOSES THE SAVED COPY IN THE CHILD once it has become its
		# stdin: the pane's descriptor is this process's bookkeeping and is no
		# part of the environment an interactive Claude should be handed.
		SV_CHILD_LAUNCH_STARTED=1  # conservative before the fork/pid-file boundary
		if [ "$SV_STDIN_SAVED" = 1 ]; then
			supervise_child <&9 9<&- &
		else
			supervise_child &
		fi
		sr_child=$!
		wait "$sr_child" || sr_status=$?
		sv_stop_watch
		# WHAT THE RECORD SAYS NOW IS WHAT DECIDES, and never this process's
		# memory of what it started: the observer is the only thing that ever
		# had positive evidence, and it wrote that evidence down.
		ri_load "$sr_lane" >/dev/null 2>&1 || :
		if [ "$RI_STATE" = ready ] && [ "$RI_OP" = "$sr_op" ] && [ "$RI_GEN" = "$SV_CLAIMED_GEN" ] && [ "$RI_ATTEMPT" = "$SV_CLAIMED_ATTEMPT" ]; then
			say ""
			say "lane $sr_lane: the replacement session was CONFIRMED (operation $sr_op, transcript ${RI_NEW:-unrecorded}) and has now exited."
			say "  A session that exited on purpose is not relaunched here — that is \`lane $sr_lane\`."
			return 0
		fi
		# AND WHETHER IT WENT THROUGH `INDETERMINATE` IS PART OF THE ANSWER
		# (Copilot round 1 on openRepoTools#121). The usage block promises
		# `4 indeterminate`, and no path returned it: the observer's `return 4`
		# is read by nothing, because the observer runs in the background and
		# this process decides from the RECORD. So the record decides that too.
		#
		# THE `failed` TRANSITION STAYS, and it is the half Copilot asked to
		# remove. `INDETERMINATE` is the answer for a child that is ALIVE at the
		# deadline — the supervisor keeps waiting, kills nothing and marks
		# nothing — and this branch is reached only once that child has EXITED.
		# A launch that ended having never been confirmed is a failed launch by
		# every reading, and it is retryable; leaving the intent `starting`
		# there would wedge the lane in the one state neither a retry nor the
		# next `/ctx` can move, which is the defect the signal handling above
		# exists to close. What was owed was the DISTINCTION, and it is the
		# exit status and the reason, not a different transition.
		sr_why="the launch ended with status $sr_status before readiness was confirmed"
		sr_end=3
		case "$RI_REASON" in
		INDETERMINATE:*)
			sr_why="the launch was INDETERMINATE — it ran past the readiness deadline still alive, then ended with status $sr_status; $RI_REASON"
			sr_end=4 ;;
		esac
		supervise_failed "$sr_lane" "$sr_op" "$sr_why"
		sr_fs=$?
		# `10` IS "ASK THE PERSON" AND EVERY OTHER VALUE IS THE STATUS TO LEAVE
		# WITH — except that an indeterminate end reports 4 rather than the 3
		# `supervise_failed` returns for "reported, no terminal here".
		if [ "$sr_fs" != 10 ]; then
			[ "$sr_fs" = 3 ] && return "$sr_end"
			return "$sr_fs"
		fi
		supervise_prompt "$sr_lane" "$sr_op" || return $?
	done
}

# ============ THE PANE SUPERVISOR AND THE RESTART STATUS (openRepoTools#94)
#
# WHY A PROCESS STAYS IN THE PANE. `/ctx` respawned its own pane and treated
# tmux ACCEPTING the command as proof a session had started. Tmux accepting a
# command says nothing about whether the child resolved a profile, executed
# Claude, stayed alive, or consumed the handoff it was supposed to. On
# 2026-09-15 the preservation side completed, the old process was killed, and
# what came back was not the act the record says — with nothing in the pane to
# notice, because the thing tmux started was the launch itself and a launch
# that ends takes the pane with it.
#
# THE PROTOCOL ALREADY ASKS FOR THIS IN SO MANY WORDS. Amendment 11's own
# invariant is **"No path the launcher opened exits the pane"** (clause (b),
# with its width, closed under `R-A11-16`); `/ctx` opened a path that did. The
# supervisor is that invariant kept for the one act that had no one keeping it:
# it is the pane's root process, it launches the real thing as a CHILD, and
# whatever the child does the pane still has a process in it that can say what
# happened and offer the retry.
#
# AND IT IS NOT A NEW WORD ON `PATH` (Amendment 18 Addendum 2 (i-8): *"no word
# is kept on `PATH` for it alone"*, which is the ground on which `restart` was
# removed from the installed set). It is a MODE of the command that already
# owns the `/ctx` transaction, invoked by absolute path — tmux must not depend
# on the respawned pane's `PATH` — and a person still has exactly one word,
# `lane`.
#
# WHAT IT NEVER DOES: it never kills the child (Amendment 8(f): ending
# somebody's process is not a boundary script's act), it never relaunches a
# child that exited AFTER readiness, it never runs a picker, it never
# rediscovers a launch choice from the current directory, the window title or a
# rotating default, and it never marks a lane running on anything but positive
# evidence.
#
# SUPERVISOR EXIT CODES, and they are contract:
#   0  the child became ready and has since exited normally, or the operator
#      ended the supervisor after a reported outcome
#   2  REFUSED before launching anything — a stale operation, a mismatched
#      pane, an intent that is not this lane's, an ambiguous live holder
#   3  the launch FAILED before readiness and there was no terminal here to
#      offer the retry on (the intent is `failed` and carries the reason)
#   4  the launch was INDETERMINATE: the child is alive and readiness could not
#      be confirmed inside the deadline. Nothing was killed and nothing was
#      marked running

# HOW LONG READINESS IS WAITED FOR. Sixty seconds is the design's number and a
# slow workstation's transcript can take a few of them; the seam is for the
# suite, which must not spend a minute proving a timeout.
SUPERVISE_READY_SECONDS="${LANE_SUPERVISOR_READY_SECONDS:-60}"
case "$SUPERVISE_READY_SECONDS" in '' | *[!0-9]*) SUPERVISE_READY_SECONDS=60 ;; esac

# ONE FIELD OF THE LANE'S RESTART INTENT. Empty where there is none, which
# every caller below tests for rather than guessing at.
ri_field() {   # <lane> <key>
	LANES_NO_FETCH=1 "$LANES_EDIT" restart-intent "$1" 2>/dev/null \
		| awk -F'\t' -v k="$2" '$1 == k { print $2; exit }'
}

# THE WHOLE INTENT ONCE, into `RI_*`. 0 where there is one, 8 where there is
# not, 1 where the read FAILED — which is never the same as "there is none"
# (Amendment 7(d)).
ri_load() {   # <lane>
	RI_STATE=""; RI_OP=""; RI_GEN=""; RI_MODE=""; RI_AGENT=""; RI_PROFILE=""
	RI_DIR=""; RI_PANE=""; RI_WINDOW=""; RI_HANDOFF=""; RI_DIGEST=""; RI_PREPARED_DIGEST=""
	RI_OLD=""; RI_NEW=""; RI_ATTEMPT=""; RI_REASON=""; RI_FILE=""
	ril_out=""; ril_rc=0
	ril_out="$(LANES_NO_FETCH=1 "$LANES_EDIT" restart-intent "$1" 2>/dev/null)" || ril_rc=$?
	case "$ril_rc" in
	0) : ;;
	8) return 8 ;;
	*) return 1 ;;
	esac
	RI_STATE="$(printf '%s\n' "$ril_out"   | awk -F'\t' '$1 == "state" { print $2; exit }')"
	RI_OP="$(printf '%s\n' "$ril_out"      | awk -F'\t' '$1 == "operation" { print $2; exit }')"
	RI_GEN="$(printf '%s\n' "$ril_out"     | awk -F'\t' '$1 == "generation" { print $2; exit }')"
	RI_MODE="$(printf '%s\n' "$ril_out"    | awk -F'\t' '$1 == "mode" { print $2; exit }')"
	RI_AGENT="$(printf '%s\n' "$ril_out"   | awk -F'\t' '$1 == "agent" { print $2; exit }')"
	RI_PROFILE="$(printf '%s\n' "$ril_out" | awk -F'\t' '$1 == "profile" { print $2; exit }')"
	RI_DIR="$(printf '%s\n' "$ril_out"     | awk -F'\t' '$1 == "dir" { print $2; exit }')"
	RI_PANE="$(printf '%s\n' "$ril_out"    | awk -F'\t' '$1 == "pane" { print $2; exit }')"
	RI_WINDOW="$(printf '%s\n' "$ril_out"  | awk -F'\t' '$1 == "window" { print $2; exit }')"
	RI_HANDOFF="$(printf '%s\n' "$ril_out" | awk -F'\t' '$1 == "handoff" { print $2; exit }')"
	RI_DIGEST="$(printf '%s\n' "$ril_out"  | awk -F'\t' '$1 == "digest" { print $2; exit }')"
	RI_PREPARED_DIGEST="$(printf '%s\n' "$ril_out" | awk -F'\t' '$1 == "prepared_digest" {print $2; exit}')"
	RI_OLD="$(printf '%s\n' "$ril_out"     | awk -F'\t' '$1 == "old_transcript" { print $2; exit }')"
	RI_NEW="$(printf '%s\n' "$ril_out"     | awk -F'\t' '$1 == "new_transcript" { print $2; exit }')"
	RI_ATTEMPT="$(printf '%s\n' "$ril_out" | awk -F'\t' '$1 == "attempt" { print $2; exit }')"
	RI_REASON="$(printf '%s\n' "$ril_out"  | awk -F'\t' '$1 == "reason" { print $2; exit }')"
	RI_FILE="$(printf '%s\n' "$ril_out"    | awk -F'\t' '$1 == "file" { print $2; exit }')"
	return 0
}

# THE STATUS SURFACE — read-only, and the whole of what an operator needs to
# tell a preservation failure, a tmux refusal, a launcher failure, an immediate
# child exit, an indeterminate readiness and a confirmed run apart.
if [ "$do_status" = 1 ]; then
	[ -n "$lane" ] || die "--restart-status needs the lane: $prog --restart-status --lane <lane>" 2
	rst_rc=0
	ri_load "$lane" || rst_rc=$?
	case "$rst_rc" in
	8) say "lane $lane has no restart intent: no /ctx is in flight for it."; exit 0 ;;
	1) die "lane $lane's restart intent could not be read (\`$LANES_EDIT restart-intent $lane\` failed). That is NOT 'there is none' — a read that failed is never an answer (Amendment 7(d))." 1 ;;
	esac
	say "lane        $lane"
	say "intent      $RI_STATE (attempt ${RI_ATTEMPT:-0})"
	say "operation   ${RI_OP:-none}   generation ${RI_GEN:-0}"
	say "mode        ${RI_MODE:-none}"
	say "agent       ${RI_AGENT:-none}   profile ${RI_PROFILE:-none}"
	say "dir         ${RI_DIR:-none}"
	say "pane        ${RI_PANE:-none}   window ${RI_WINDOW:-none}"
	say "handoff     ${RI_HANDOFF:-none}"
	say "digest      ${RI_DIGEST:-none}   prepared ${RI_PREPARED_DIGEST:-none}"
	say "transcript  old ${RI_OLD:-none} → new ${RI_NEW:-none}"
	say "reason      ${RI_REASON:-none}"
	say "file        ${RI_FILE:-none}"
	say "authority   legacy restart intent only"
	say "lifecycle   separate diagnostics; never used to decide restart readiness"
	case "$RI_STATE" in
	preparing) say "PREPARING: old pane was not respawned; inspect preservation and reconcile this exact reservation before a new /ctx." ;;
	failed)
          say ""
          if [ "$RI_MODE" = preservation-only ] && [ "$RI_ATTEMPT" = 0 ] && [ "$RI_NEW" = none ]; then
            say "PREPARATION FAILED: the old pane was not respawned; no supervised launch was attempted."
            say "When every holder is confirmed absent, ordinary resume is available: lane $lane"
            say "From the original live session, a new /ctx may retry preservation."
          else
            say "RETRY:   $(quoted "$SELF_ABS") --supervise --lane $lane --operation ${RI_OP:-<id>}"
          fi ;;

	pending)  say ""; say "NOT YET CLAIMED: no supervisor has taken this operation. The pane it was written for may never have been respawned." ;;
	starting) say ""; say "IN FLIGHT: this attempt is reserved; a child may still be alive. Do not start a second one — read the pane it is in (${RI_PANE:-pane not recorded})." ;;
	ready)    say ""; say "DONE: this restart was confirmed. It authorises no further launch; an ordinary \`lane $lane\` resumes the lane." ;;
	esac
	exit 0
fi

# THE PANE IS HELD OPEN ON EVERY NON-ZERO EXIT OF THIS MODE, refusals
# included. Amendment 11's invariant is *"No path the launcher opened exits the
# pane"*, and a supervisor that refused before launching and then returned would
# leave tmux printing `[exited]` over the one message that says why — which is
# the shape of the defect this whole mode exists to close, reached through its
# own front door. Where there is no terminal there is nobody to hold it for, and
# the status is simply returned.
SV_PIDFILE=""
SV_SIGNALLED=0
SV_WATCH_PID=""
SV_WATCH_DIR=""
SV_CLAIMING=0
SV_DEFERRED_SIGNAL=""; SV_DEFERRED_STATUS=""
SV_CHILD_LAUNCH_STARTED=0
# Never signal a saved PID: an observer can finish hours before its child.
# Cancellation uses a private marker; wait addresses our owned shell job.
sv_stop_watch() {
	if [ -n "$SV_WATCH_DIR" ]; then
		: > "$SV_WATCH_DIR/stop"
		# A signal can arrive after the fork but before PID publication. $!
		# identifies that owned shell job; before the fork it is absent or a
		# previously waited owned job. Waiting never signals a recycled PID.
		sv_wait_pid="${SV_WATCH_PID:-${!:-}}"
		[ -z "$sv_wait_pid" ] || wait "$sv_wait_pid" 2>/dev/null || :
		SV_WATCH_PID=""
		rm -f -- "$SV_WATCH_DIR/stop" 2>/dev/null
		rmdir -- "$SV_WATCH_DIR" 2>/dev/null || :
		SV_WATCH_DIR=""
	fi
}

# Empty until this supervisor has successfully claimed a specific attempt.
SV_CLAIMED_GEN=""
SV_CLAIMED_ATTEMPT=""
sv_on_exit() {
	sv_hs=$?
	sv_stop_watch
	[ -z "$SV_PIDFILE" ] || rm -f -- "$SV_PIDFILE" 2>/dev/null
	[ "$sv_hs" = 0 ] && return 0
	# A SUPERVISOR SOMEBODY SIGNALLED AWAY IS NOT ONE ANYBODY IS WAITING TO
	# READ. Holding the pane open for an Enter after a `tmux kill-pane` is a
	# pane that will not close.
	[ "$SV_SIGNALLED" = 1 ] && return 0
	[ "${LANE_SUPERVISOR_NO_PROMPT:-0}" = 1 ] && return 0
	[ -t 0 ] || return 0
	printf '\n%s: this pane is held open so the lines above can be read (exit %s). Press Enter to close it. ' "$prog" "$sv_hs" >&2
	IFS= read -r sv_ignored || :
	return 0
}

# Cancellation writes only an owned attempt. A live or unknown child keeps
# starting and blocks retry; an unclaimed pending intent remains unchanged.
sv_signal() {   # <signal name> <exit status>
	# Bash may deliver a deferred signal as the CAS returns, before the caller
	# records its successful claim. Finish publication before reconciliation.
	if [ "$SV_CLAIMING" = 1 ]; then
		SV_DEFERRED_SIGNAL="$1"; SV_DEFERRED_STATUS="$2"
		return 0
	fi
	SV_SIGNALLED=1
	# THE OBSERVER GOES FIRST, AND IS REAPED (Copilot round 2 on
	# openRepoTools#121). It is a background job of this shell and a signal to
	# this process is not a signal to it: left running it keeps polling after its
	# supervisor is gone, and the two verdicts then race. Neither can overwrite
	# the other — both writes are fenced and the loser is refused — but the
	# LOSER STILL SPEAKS, and a supervisor printing *the restart intent is
	# `failed`* about an operation the observer had just confirmed `ready` is a
	# line nobody can act on. So it is stopped, reaped, and the record is read
	# back AFTER the write below rather than assumed.
	# A SIGNAL BEFORE THIS PROCESS KNOWS WHICH OPERATION IT IS SUPERVISING has no
	# record to write and says so: the traps are installed at the top of the mode,
	# ahead of the arguments being checked, because a supervisor that could be
	# signalled between those two lines and leave nothing behind is the same gap
	# one instruction wide.
	sv_stop_watch
	if [ -z "$lane" ] || [ -z "$operation" ]; then
		say ""
		say "$prog: SIG$1 before this supervisor had a lane and an operation to supervise — nothing was claimed, nothing was started and nothing is left behind."
		exit "$2"
	fi
	# A preflight signal has no claimed generation/attempt to reconcile.
	if [ -z "$SV_CLAIMED_GEN" ]; then
		say "$prog: SIG$1 before the restart claim; the intent was left unchanged."
		exit "$2"
	fi
	sv_sg_child=""; sv_sg_alive="child termination could not be established"; sv_sg_state=starting
	if [ -n "$SV_PIDFILE" ] && [ -r "$SV_PIDFILE" ]; then
		sv_sg_child="$(head -n 1 -- "$SV_PIDFILE" 2>/dev/null | tr -dc '0-9')"
	fi
	if [ -n "$sv_sg_child" ]; then
		if kill -0 "$sv_sg_child" 2>/dev/null; then
			sv_sg_alive="the launch (pid $sv_sg_child) was STILL RUNNING and was not killed"
		else
			sv_sg_alive="the launch (pid $sv_sg_child) had already ended"
			sv_sg_hrc=0
			LANES_NO_FETCH=1 "$LANES_EDIT" lane-holders "$lane" >/dev/null 2>&1 || sv_sg_hrc=$?
			[ "$sv_sg_hrc" != 8 ] || sv_sg_state=failed
		fi
	fi
	if [ "$SV_CHILD_LAUNCH_STARTED" = 0 ]; then
		sv_sg_alive="no child was launched"
		sv_sg_hrc=0
		LANES_NO_FETCH=1 "$LANES_EDIT" lane-holders "$lane" >/dev/null 2>&1 || sv_sg_hrc=$?
		[ "$sv_sg_hrc" != 8 ] || sv_sg_state=failed
	fi
	sv_sg_fence=()
	[ -n "$SV_CLAIMED_GEN" ] && sv_sg_fence=(--expect-generation "$SV_CLAIMED_GEN" --expect-attempt "$SV_CLAIMED_ATTEMPT")
	sv_sg_reason="supervisor received SIG$1 before readiness; $sv_sg_alive"
	[ "$sv_sg_state" != starting ] || sv_sg_reason="INDETERMINATE: $sv_sg_reason"
	LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$lane" "$sv_sg_state" \
		--expect 'pending|starting' --expect-operation "$operation" \
		${sv_sg_fence[@]+"${sv_sg_fence[@]}"} \
		--reason "$sv_sg_reason" \
		>/dev/null 2>&1 || :
	ri_load "$lane" >/dev/null 2>&1 || :
	say ""
	say "$prog: SIG$1 — this supervisor is leaving operation $operation on lane $lane."
	say "  $sv_sg_alive."
	if [ "${RI_STATE:-}" = ready ]; then
		# THE OBSERVER GOT THERE FIRST, and its evidence is better than this
		# handler's: the replacement was confirmed before the signal arrived, and
		# the `failed` write above was refused by the fence for exactly that
		# reason. Saying `failed` here would be this process reporting its own
		# intention over the record's fact.
		say "  The replacement was CONFIRMED before this signal arrived (transcript ${RI_NEW:-unrecorded}), so the intent is \`ready\` and this restart is DONE."
		say "    read it: $(quoted "$SELF_ABS") --restart-status --lane $lane"
	else
		say "  The restart intent is \`${RI_STATE:-starting}\`; no child was killed."
		say "    read it: $(quoted "$SELF_ABS") --restart-status --lane $lane"
		if [ "${RI_STATE:-}" = failed ]; then
			say "    retry:   $(quoted "$SELF_ABS") --supervise --lane $lane --operation $operation"
		else
			say "  Retry remains blocked until the child is confirmed gone and the attempt is reconciled."
		fi
	fi
	exit "$2"
}

if [ "$do_supervise" = 1 ]; then
	trap sv_on_exit EXIT
	# `INT` IS THE CHILD'S AND NOT THIS PROCESS'S. Ctrl-C reaches the whole
	# foreground process group, and a supervisor that exited on it would tear
	# the pane down under a Claude that was merely interrupted — so this process
	# ignores it and the child's own subshell puts it back to default before the
	# exec, which is the one thing that keeps Ctrl-C working in that pane.
	trap '' INT
	trap 'sv_signal TERM 143' TERM
	trap 'sv_signal HUP 129' HUP
	[ -n "$lane" ] || die "--supervise needs the lane: $prog --supervise --lane <lane> --operation <id>" 2
	[ -n "$operation" ] || die "--supervise needs the operation it was started for: $prog --supervise --lane $lane --operation <id>. A supervisor that took whatever intent it found would be a supervisor that launches a lane for an act somebody else is in the middle of." 2

	LANES_NO_FETCH=1 "$LANES_EDIT" legacy-restart-check "$lane" ||
		die "legacy supervisor refuses managed or unknown ownership. Nothing was started." 2

	# ---- the operation this supervisor was started for, and no other
	sv_rc=0
	ri_load "$lane" || sv_rc=$?
	case "$sv_rc" in
	8) die "lane $lane has no restart intent, so there is nothing for operation $operation to launch. Nothing was started. A /ctx whose intent could not be written should have refused before it killed anything — read the lane:  $prog --restart-status --lane $lane" 2 ;;
	1) die "lane $lane's restart intent could not be read (\`$LANES_EDIT restart-intent $lane\` failed). That is NOT 'there is none', and this supervisor will not launch a session for an operation it could not verify (Amendment 7(d)). Nothing was started." 1 ;;
	esac
	[ "$RI_OP" = "$operation" ] ||
		die "operation $operation is not lane $lane's current restart operation, which is ${RI_OP:-none} (intent ${RI_STATE:-none}, generation ${RI_GEN:-0}). A stale supervisor never launches against a newer operation: nothing was started. Read it:  $prog --restart-status --lane $lane" 2
	case "$RI_STATE" in
	pending | failed) : ;;
	starting) die "lane $lane's restart operation $operation is already \`starting\` — a supervisor holds it, in ${RI_PANE:-a pane this record does not name}. A second one would launch a second session of one lane, which is the collision this whole protocol is about (Amendment 18(h)). Nothing was started." 2 ;;
	ready)    die "lane $lane's restart operation $operation is already \`ready\`: that restart was confirmed and this record authorises no further launch. Nothing was started. To open the lane:  lane $lane" 2 ;;
	*)        die "lane $lane's restart intent is in state '${RI_STATE:-none}', which this supervisor does not know how to launch from. Nothing was started." 2 ;;
	esac
	[ "$RI_MODE" = fresh-from-handoff ] ||
		die "lane $lane's restart intent names launch mode '${RI_MODE:-none}' and this supervisor makes only 'fresh-from-handoff' launches. Nothing was started." 2

	# ---- the pane: this supervisor is IN the pane the intent was written for
	#
	# A SUPERVISOR IN THE WRONG PANE WOULD PUT A SECOND SESSION OF THIS LANE
	# SOMEWHERE THE LANE IS NOT. The intent records the pane `/ctx` respawned;
	# `$TMUX_PANE` is where this process actually is. They are compared where
	# both are knowable, and a comparison that CANNOT be made is said rather than
	# assumed — this runs under a fake tmux in the suite and under none at all
	# where a person invoked it by hand.
	sv_pane_here="${TMUX_PANE:-}"
    [ -n "$RI_PANE" ] && [ "$RI_PANE" != none ] && [ -n "$sv_pane_here" ] ||
      die "the restart pane binding cannot be verified: recorded ${RI_PANE:-none}, current ${sv_pane_here:-none}. Nothing was started." 2
	pane_agrees "$RI_PANE" "$sv_pane_here" ||
		die "lane $lane's restart intent was written for pane $RI_PANE and this supervisor is in $sv_pane_here. Nothing was started: a launch here would put this lane's session in a pane the lane's own record does not name, and that record is what every other reader goes by." 2

	# ---- the agent: the intent's, and the lane's own record, must still agree
	#
	# DESIGN DECISION 15 SAYS AGENT, PROFILE AND DIRECTORY ARE FENCED *EARLIER* —
	# *"where a conflict refuses the launch before it is made, rather than
	# re-checked after"* — and for the agent that was not true of any line
	# (Copilot round 2 on openRepoTools#121). The intent records it and nothing
	# read it back. So it is read back here, which is the place the decision
	# names: before anything is claimed or started.
	#
	# IT IS THE CANONICAL AGENT AND NOT THE CHILD'S. What a live process IS
	# cannot be read from this estate's records — `live-holder` answers a
	# transcript, a pane, a name, a pid and a verdict, and no agent word — so
	# what is compared is the lane's own recorded agent against the one this
	# restart was written for. A lane whose agent changed under a restart is a
	# restart whose contract changed under it, and launching the intent's agent
	# into it would make the record and the process disagree.
	sv_ag=""; sv_agrc=0
	sv_ag="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-agent "$lane" 2>/dev/null)" || sv_agrc=$?
	case "$sv_agrc" in
	0)
		if [ -n "$RI_AGENT" ] && [ "$RI_AGENT" != none ] && [ -n "$sv_ag" ] && [ "$sv_ag" != "$RI_AGENT" ]; then
			die "lane $lane's restart intent was written for agent '$RI_AGENT' and the lane's own record now names '$sv_ag'. Nothing was started: the agent decides which launcher this lane is resumed by and what its first prompt even means, so a restart made for one agent into a lane recorded as another is a session neither record describes. Read it:  $prog --restart-status --lane $lane" 2
		fi ;;
	# 8 IS A LANE WHOSE RECORD NAMES NO AGENT and 2 A HELPER WITH NO WORD FOR
	# ONE; both are answers, and a comparison that cannot be made is not a
	# disagreement.
	8 | 2) : ;;
	*) die "lane $lane's recorded agent could not be read (lane-agent exited $sv_agrc). Nothing was started: unknown agent identity cannot authorize a restart." 1 ;;
	esac

	[ "$RI_AGENT" = claude ] || die "this legacy supervisor supports only the recorded Claude agent. Nothing was started." 2
	case "$RI_DIR" in /*) : ;; *) die "the supervised restart needs an absolute checkout. Nothing was started." 2 ;; esac
	[ -d "$RI_DIR" ] && [ -r "$RI_DIR" ] && [ -x "$RI_DIR" ] ||
		die "the supervised restart checkout is missing or unusable. Nothing was started." 2
	[ -n "$RI_HANDOFF" ] && [ "$RI_HANDOFF" != none ] && [ -s "$RI_HANDOFF" ] &&
	  [ -n "$RI_DIGEST" ] && [ "$RI_DIGEST" != none ] ||
	  die "the supervised restart has no complete handoff checksum. Nothing was started." 2
	# ---- the handoff's digest: the first prompt is that file, and only that file
	if [ -n "$RI_HANDOFF" ] && [ "$RI_HANDOFF" != none ] && [ -n "$RI_DIGEST" ] && [ "$RI_DIGEST" != none ]; then
		sv_now="$(handoff_digest "$RI_HANDOFF")"
		[ "$sv_now" = "$RI_DIGEST" ] || [ "$sv_now" = "${RI_PREPARED_DIGEST:-none}" ] ||
			die "lane $lane's handoff has changed since operation $operation was written: the intent records $RI_DIGEST for $RI_HANDOFF and it now digests $sv_now. The top block of that file is the new session's FIRST PROMPT, so launching now would deliver a block this /ctx did not write. Nothing was started. Take the handoff again:  $prog --restart" 2
	fi

	# ---- a live holder makes this ambiguous, and ambiguity refuses
	#
	# `live-holder` answers who is running this lane NOW. A supervisor that
	# launched behind one would be Amendment 18(h)'s second binding, made by the
	# tooling itself. A read that FAILED is not "nobody is": it refuses too,
	# because this is the one moment a second process gets created.
	sv_hold=""; sv_hrc=0
	sv_hold="$(LANES_NO_FETCH=1 "$LANES_EDIT" live-holder "$lane" 2>/dev/null)" || sv_hrc=$?
	case "$sv_hrc" in
	0) [ -z "$sv_hold" ] ||
		die "lane $lane already has a live holder, so this supervisor will not start a second session of it (Amendment 18(h)):
$sv_hold
Nothing was started. If that process is a leftover of an earlier attempt, retire it first — \`lane-end $lane --retire <pid>\` — then retry:  $prog --supervise --lane $lane --operation $operation" 2 ;;
	8 | 2) : ;;
	*) die "lane $lane's live holders could not be read (\`$LANES_EDIT live-holder $lane\` exited $sv_hrc), so whether this lane is already running is UNKNOWN from here — and a read that failed is never an answer (Amendment 7(d)). This supervisor will not create a second process on a lane that may be live. Nothing was started." 1 ;;
	esac

	supervise_run "$lane" "$operation"
	exit $?
fi


# EVERY READ OF THE REGISTER GOES THROUGH ONE FENCE, and Amendment 7(d) is the
# whole of it: `0` an answer, `8` NO ANSWER and `2` a helper predating the read
# — both of those fall to the next rung — and ANYTHING ELSE is a read that
# FAILED, which is neither. A register that could not be read is not "this
# window is not a lane", and the steps below would then write a PAUSED record,
# a stamp and a restart command for a lane this window is not.
#
# IT SETS A VARIABLE RATHER THAN PRINTING ITS ANSWER, and that is load-bearing:
# a refusal inside `$( )` kills only the substitution's subshell, and this
# command would carry on with an empty answer.
#
# AND `2` IS TWO ANSWERS (Amendment 15; Copilot round 2 on openRepoTools#47).
# It is what a helper predating a subcommand spends on an unknown one — the
# rung this fence falls through for, and every workstation until adoption
# reaches it — and it is ALSO `canon_lane`'s refusal of a register holding two
# rows that differ only by case, which every read through `check_lane_name` now
# carries. Falling through THAT is binding this window to whichever lane the
# next rung happens to answer with, and then renaming the window, writing a
# PAUSED record and respawning a pane for it. So the refusal is asked for BY
# ITS OWN WORDS — no old helper emits them from an unknown subcommand, which is
# how `lane-start:755-767`, `lane-end` and `restart` tell the two apart — and
# relayed, with the fall-through for a genuinely old helper left as it was.
sread() {   # sread <var> "<what the failure is NOT>" <verb> [args…]
	sr_var="$1"; sr_not="$2"; shift 2
	sr_out=""; sr_rc=0
	sr_out="$(LANES_NO_FETCH=1 "$LANES_EDIT" "$@" 2>/dev/null)" || sr_rc=$?
	case "$sr_rc" in
	0) : ;;
	2)
		sr_why="$(LANES_NO_FETCH=1 "$LANES_EDIT" "$@" 2>&1 >/dev/null || :)"
		case "$sr_why" in
		*"Amendment 15(d)"*)
			die "the register holds two rows for this lane that differ only by case, so no read of it is unambiguous and this command will not pick one (Amendment 15(d)). Nothing was written and nothing was renamed. The helper's own words:
$sr_why" 2 ;;
		esac
		sr_out="" ;;
	8) sr_out="" ;;
	*) die "\`$LANES_EDIT $1\` failed (exit $sr_rc). That is NOT $sr_not — a read that failed is never an answer (Amendment 7(d)), and this command will not bind a lane, write a PAUSED record or print a restart command on one. Run it by hand to see what it says." 1 ;;
	esac
	eval "$sr_var=\$sr_out"
}

# ---------------- the crash-consistent lifecycle (opensoft/openRepoTools#91)
#
# A LANE IS `RUNNING`, `SWAPPING`, `SWAPPED` OR `CLOSED`, and this command owns
# the two-phase transition in the middle of that: `SWAPPING` BEFORE any
# preservation work begins, `SWAPPED` only after every mandatory write has
# landed. What that buys is the one thing the `PAUSED` record alone could never
# say — WHERE a session that ran out of tokens stopped. `RUNNING` with no live
# holder is an ungraceful stop: nothing was polled, nothing was refreshed,
# nothing was recorded. `SWAPPING` with no live holder is an INTERRUPTED SWAP:
# some of those writes may have landed and some may not, and every worktree
# below is preserved until a person has read them.
#
# THE LIFECYCLE NEVER REFUSES THE SWAP. `R-A11-11` is that a swap is never left
# unwritten, and it binds this command: a control root that cannot be derived,
# a fence another act moved, a snapshot that cannot be written — each of them
# costs the LIFECYCLE and never the record. The handoff carries on and says
# what it could not keep, exactly as it does for a dropped sub-field.
lc_on=""; lc_gen=""; lc_op=""; lc_state=""; lc_inventory_missed=""

lifecycle_begin() {
	lc_on=""; lc_gen=""; lc_op=""; lc_state=""
	lcb_now=""; lcb_raw=""; lcb_rc=0
	# READ WHOLE, THEN PARSE (opensoft/openRepoTools#280). This read was
	# `lane-state | awk '… { print $2; exit }'` under `pipefail`, and that `awk`
	# exits at the line it wants: a `lane-state` that wrote once more after it
	# — its builtin `printf` hands a multi-line snapshot to the pipe in pieces —
	# died of SIGPIPE, the substitution's status was 141, and the `case` below
	# took that for a read that FAILED: "could not be read", no fence, no
	# inventory and no RUNNING -> SWAPPING -> SWAPPED, on timing alone (CI run
	# 39322387035). The reader had stopped listening; the read had not failed.
	# So the status below is `lane-state`'s own, from a command nothing can end
	# early, and the state is parsed out of what it printed afterwards.
	lcb_raw="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-state "$lane" 2>/dev/null)" || lcb_rc=$?
	case "$lcb_rc" in
	0 | 8) : ;;
	*)
		note "the lane lifecycle could not be read (\`$LANES_EDIT lane-state $lane\` exited $lcb_rc), so this handoff records no RUNNING -> SWAPPING -> SWAPPED transition. The swap itself goes on (\`R-A11-11\`) and the PAUSED record below is unaffected."
		return 0 ;;
	esac
	lcb_now="$(printf '%s\n' "$lcb_raw" | awk -F"\t" '$1 == "state" { print $2; exit }')"
	[ -n "$lcb_now" ] || lcb_now=none
	# AN INTERRUPTED SWAP IS TAKEN OVER, NOT COMPETED WITH. A lane still
	# reading `SWAPPING` when a new handoff starts is one whose previous
	# operation never finished; this one supersedes it with a NEW generation,
	# which is precisely what refuses the old finalizer if it ever wakes up.
	# The old operation id is named rather than lost.
	if [ "$lcb_now" = SWAPPING ]; then
		# Read whole, then parsed, for the reason given above (#280); its status
		# was never read, and the operation is only named in the note below.
		lcb_old_raw="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-state "$lane" 2>/dev/null)"
		lcb_old="$(printf '%s\n' "$lcb_old_raw" | awk -F"\t" '$1 == "operation" { print $2; exit }')"
		note "lane $lane is still recorded SWAPPING from operation ${lcb_old:-unknown}, which never finished: this handoff SUPERSEDES it with a new generation, and that is what refuses the old finalizer if it ever returns. Nothing of that operation is undone here."
	fi
	lcb_out=""; lcb_src=0
	lcb_out="$(LANES_NO_FETCH=1 "$LANES_EDIT" set-lane-state "$lane" SWAPPING \
		--expect "$lcb_now" --owner "${uuid:-none}" --agent "$agent" \
		--profile "${profile_name:-none}" --kind "$handoff_kind" 2>/dev/null)" || lcb_src=$?
	case "$lcb_src" in
	0)
		lc_gen="$(printf '%s\n' "$lcb_out" | awk -F"\t" '$1 == "generation" { print $2; exit }')"
		lc_op="$(printf '%s\n' "$lcb_out" | awk -F"\t" '$1 == "operation" { print $2; exit }')"
		# THE FENCE THIS RUN WILL FINISH WITH, READ BACK BEFORE IT IS TRUSTED.
		# Every later call carries both — the finalizer as `--expect-generation`
		# and `--expect-operation`, each tree sidecar as the operation that
		# recorded it — and an empty one there is a flag with no value, which
		# the writer refuses. Better to record no transition at all than to
		# record trees against an operation nobody can match.
		if [ -z "$lc_gen" ] || [ -z "$lc_op" ]; then
			note "the lane was taken to SWAPPING and the helper named no generation or no operation back, so this handoff records no fence and takes no inventory. Read the state by hand: $LANES_EDIT lane-state $lane"
		else
			lc_on=1
			lc_state=SWAPPING
			step "lifecycle: $lcb_now -> SWAPPING (generation $lc_gen, operation $lc_op)"
		fi ;;
	7)
		note "the lane lifecycle moved between reading it and taking it (it was $lcb_now and is not now), so this handoff records no transition and its worktree inventory carries no operation. Another process is acting on lane $lane: read it with \`$LANES_EDIT lane-reconcile $lane\` before relaunching anything. The swap itself goes on (\`R-A11-11\`)." ;;
	1)
		note "lane $lane has no lifecycle control root (its record names no directory, and \$PROJECTS_ROOT is not a directory here), so this handoff records no RUNNING -> SWAPPING -> SWAPPED transition and crash recovery for it stays incomplete. The swap itself goes on." ;;
	*)
		note "the lane lifecycle could not be taken to SWAPPING (\`set-lane-state\` exited $lcb_src). The swap goes on and records no transition." ;;
	esac
	return 0
}

# `SWAPPED` IS THE COMMIT POINT AND IT IS FENCED ON THIS OPERATION. A handoff
# whose record, row and handoff file did not all land leaves the lane
# `SWAPPING` and SAYS WHICH STEP IS UNFINISHED — because those three are
# exactly what a resumed session needs to have found, and a lane called
# `SWAPPED` on two of them is a lane whose recovery would skip the third.
lifecycle_finish() {   # <what is unfinished, empty when nothing is>
	[ -n "$lc_on" ] || return 0
	if [ -n "${1-}" ]; then
		lc_state=SWAPPING
		note "the lane stays SWAPPING (generation $lc_gen, operation $lc_op): $1. A later session reads that as an INTERRUPTED SWAP and preserves every worktree, which is the honest record of what this act left."
		return 0
	fi
	lcf_rc=0
	LANES_NO_FETCH=1 "$LANES_EDIT" set-lane-state "$lane" SWAPPED \
		--expect SWAPPING --expect-generation "$lc_gen" --expect-operation "$lc_op" \
		--owner "${uuid:-none}" --agent "$agent" --profile "${profile_name:-none}" \
		--kind "$handoff_kind" >/dev/null 2>&1 || lcf_rc=$?
	case "$lcf_rc" in
	0) lc_state=SWAPPED; step "lifecycle: SWAPPING -> SWAPPED (generation $lc_gen, operation $lc_op)" ;;
	7)
		lc_state=superseded
		note "this handoff is NOT the act that finishes lane $lane: the lifecycle fence moved under it (another handoff, or a resume that took the lane) and a stale finalizer must never overwrite a newer owner. The PAUSED record, the row and the handoff file are all written; only the SWAPPED transition was refused." ;;
	*)
		lc_state=SWAPPING
		note "the lane could not be recorded SWAPPED (\`set-lane-state\` exited $lcf_rc), so it stays SWAPPING and a later session reads it as an interrupted swap." ;;
	esac
	return 0
}

# ------------------------------------------------- 1. the identity triple
#
# THE WORKSTATION COMES FROM CONFIGURATION, NEVER FROM `hostname` (Amendment 11,
# ratified decision 8(d)): the helper's own `workstation` read is the one
# implementation, and its second tab-separated field says which rung answered.
ws_pair=""; ws_rc=0
ws_pair="$("$LANES_EDIT" workstation 2>/dev/null)" || ws_rc=$?
ws="${ws_pair%%	*}"
ws_src="${ws_pair##*	}"
# AND IT NEVER WRITES A PLACEHOLDER (`R-A11-14`). Inside a container with no
# `LANES_WORKSTATION` the register and object-log writes STOP — they are filed
# under the workstation, and a record filed under a container id is a record no
# restart of any workstation will ever find — while the SWAP ITSELF GOES ON
# (A11 Addendum 4 ruling 11, `R-A11-11`: *a swap is never left unwritten*). The
# handoff file is refreshed, it NAMES the gap, and the restart line is printed
# with `--lane`, because the row is not flipped either.
ws_missing=""
if [ "$ws_rc" != 0 ] && [ "$ws_rc" != 8 ] && [ -z "$ws" ]; then
	ws_missing=1
	note "NO WORKSTATION READ: \`$LANES_EDIT workstation\` exited $ws_rc and named none. Exit 2 is a lanes-edit.sh predating Amendment 11 (\`R-A11-8\`); anything else is a read that failed. Either way no record is filed under no workstation (\`R-A11-14\`): the register and object-log writes below are NOT made. The handoff is still refreshed and NAMES this gap, and the restart line is still printed, with --lane."
elif [ "$ws_src" = container-unset ] || [ -z "$ws" ]; then
	ws_missing=1
	note "NO WORKSTATION: this is a container and \$LANES_WORKSTATION is not set. The register and object-log writes below are NOT made — both logs are append-only and a record filed under a container id is unfindable (\`R-A11-14\`). The handoff is refreshed and NAMES the gap, and the restart line is printed with --lane. The launcher exports the value into every session and container it starts; to close it now: export LANES_WORKSTATION=<this host name> and re-run."
fi

# THE WINDOW, its `<@id>`, and the lane — the launcher's own order, with
# Amendment 11 clause (b)'s zero-question step in the middle, so this command
# and the launcher never disagree about which lane this window is.
# THREE TMUX SPELLINGS OF ONE WINDOW, AND NEITHER IS DERIVED FROM ANOTHER
# (Amendment 11 clause (c), as `lane-start:975-984` states it): the record's
# `window` sub-field is `<session>:<index> <@id>`, two space-separated refs, and
# the HARNESS's own `tmux` field — which `window-session` matches a session
# record on, and which is where the PANE comes from — is `<session>:<@id>`.
# Reading one for the other is how a record names a window nothing can resolve.
# AND EACH IS CHECKED AS A WHOLE STRING (opensoft/openRepoTools#80 item 3,
# Copilot's review of workBenches#91 at `lane-handoff:434`). `*:[0-9]*` and
# `@[0-9]*` were prefix globs, so `session:1junk` and `@123junk` passed —
# from tmux and from the launcher's environment alike — and went into the
# append-only `window` sub-field, where `window-lane` can never resolve them.
# The launcher and `lane-start` hold the same two values to `^.+:[0-9]+$` and
# `^@[0-9]+$`; these are those two rules, spelled in `case` as `lane-start`
# spells its own id check. The ref: a session part that is not empty, then
# digits and nothing else after the LAST `:`.
window_ref_ok() {   # <session>:<index>
	case "${1##*:}" in '' | *[!0-9]*) return 1 ;; esac
	case "$1" in ?*:*) return 0 ;; esac
	return 1
}
window_id_ok() {   # @<id>
	case "$1" in @ | @*[!0-9]*) return 1 ;; @*) return 0 ;; esac
	return 1
}
win=""; wid=""; window_name=""; win_harness=""
if have_tmux; then
	win="$(tmux display-message -p '#S:#I' 2>/dev/null || :)"
	window_ref_ok "$win" || win=""
	wid="$(tmux display-message -p '#{window_id}' 2>/dev/null || :)"
	window_id_ok "$wid" || wid=""
	window_name="$(tmux display-message -p '#W' 2>/dev/null || :)"
	win_harness="$(tmux display-message -p '#{session_name}:#{window_id}' 2>/dev/null || :)"
fi
[ -n "$win" ] || win="${WORKBENCHES_CLAUDE_WINDOW_REF:-}"
window_ref_ok "$win" || win=""
[ -n "$wid" ] || wid="${WORKBENCHES_CLAUDE_WINDOW_ID:-}"
window_id_ok "$wid" || wid=""
window_ref="${win}${wid:+ $wid}"

if [ -z "$lane" ] && [ -n "$window_name" ]; then
	sread row_probe "'this window is not a lane'" register-row "$window_name"
	[ -n "$row_probe" ] && lane="$window_name"
fi
if [ -z "$lane" ]; then
	wl_ref="${wid:-$win}"
	if [ -n "$wl_ref" ] && [ -n "$ws" ]; then
		sread candidate "'no lane is bound to this window'" window-lane "$ws" "$wl_ref"
		case "$candidate" in
		[A-Za-z0-9_]*) lane="$candidate" ;;
		esac
	fi
fi
if [ -z "$lane" ] && [ -n "$ws" ]; then
	# The swap record, read exactly as the launcher reads it: the tab is the
	# contract. A row that printed before a failed read, or one with no tab, is
	# not a record row — `cut -f 1` would hand back the whole line, lane-shaped
	# and wrong.
	sread rows "'this workstation has no swap record'" swapped "$ws"
	first="$(printf '%s\n' "$rows" | head -n 1)"
	case "$first" in
	*"	"*)
		candidate="${first%%	*}"
		case "$candidate" in
		[A-Za-z0-9_]*) lane="$candidate" ;;
		esac ;;
	esac
fi
if [ -z "$lane" ]; then
	case "$window_name" in
	*-[0-9]*) die "nothing binds this window: it is named '$window_name', the register has no row for that name, no record of this workstation names this window, and this workstation has no swap record to fall back to. Bind it first, then hand off:
    lane-start --no-launch ${window_name%-*} ${window_name##*-}" 2 ;;
	*) die "nothing binds this window${window_name:+ (it is named '$window_name', which is not a lane name)}, so there is no lane to hand off. Bind it first — the repository and the position are the operator's to name:
    lane-start --no-launch <repo> <n>
    or name the lane here: $prog --lane <lane>" 2 ;;
	esac
fi
# ONE NAME UNDER ANY CASE, AND BEFORE ANYTHING IS RENAMED OR WRITTEN
# (Amendment 15; Copilot round 2 on openRepoTools#47). Every rung above answers
# with a spelling of its own — the tmux window's name, a record's lane field,
# the swap row's first cell — and `--lane` answers with whatever was typed,
# validated by nothing until the record write far below. The REGISTER ROW's
# spelling is the canonical one, and it is what the window rename, the top
# block, the payload, the object log's lane field and the restart line must all
# carry; so it is taken ONCE, here, through the resolver `lane-start`,
# `lane-end`, `lanes` and `restart` share. It is also where an AMBIGUOUS
# register is refused (15(d), through the fence above) and where a `--lane`
# that is not a lane NAME at all is refused — both before the rename, so that a
# refusal leaves the window exactly as it found it.
#
# WHAT IT IS NOT IS A CHECK THAT THE LANE HAS A ROW (Copilot round 4 on
# openRepoTools#47). `canon_lane` answers with the TYPED spelling where no row
# matches, deliberately — `lane-start` uses the same resolver for a lane it is
# about to create — so a well-formed `--lane` this register has never carried
# reaches the writes below and is named there, by the row read that cannot find
# a handoff and by the row flip that finds no state cell to replace.
sread lane_canon "'this lane has no row'" canon-lane "$lane"
if [ -n "$lane_canon" ] && [ "$lane_canon" != "$lane" ]; then
	step "lane $lane → $lane_canon (Amendment 15: the register row's spelling is canonical)"
	lane="$lane_canon"
fi
case "$lane" in
*[!A-Za-z0-9._-]* | .* | -* | '')
	die "'$lane' is not a lane name (letters, digits, . _ -, not opening with . or -). Nothing was renamed and nothing was written: a name the register cannot hold is one every write below would refuse anyway, and the window would already have been renamed to it." 2 ;;
esac
step "lane=$lane${window_ref:+ window=$window_ref} workstation=${ws:-<none>}"

# THE SEAM (ruling 2026-10-04): A MANAGED-OWNED LANE IS NOT THIS COMMAND'S.
# `lanes-edit.sh managed-projection` answers 0 with the owner where the lane's
# register row carries the managed ledger's marker, 8 for a legacy lane, and 1
# where ownership could not be established. ANY other status — a helper that
# predates the verb included — is UNKNOWN as well, and refused the same way:
# a fence that opens because its read failed is no fence (Amendment 7(d)).
seam_refuse() {   # <lane> <the act>
	sr_out=""; sr_rc=0
	sr_out="$("$LANES_EDIT" managed-projection "$1" 2>/dev/null)" || sr_rc=$?
	case "$sr_rc" in
	0) die "lane $1 is owned by the managed ledger (owner ${sr_out:-unnamed}), and $2 is a legacy lane act, refused here, before the window is renamed and before a byte is written: no PAUSED, no row, no handoff file, no lifecycle transition, no inventory, and no restart. Brett Heap's ruling of 2026-10-04: \"managed ledger owns enrolled lanes; #97 owns legacy\". Act on this lane through the managed ledger." 2 ;;
	8) : ;;
	*) die "whether the managed ledger owns lane $1 is UNKNOWN (\`$LANES_EDIT managed-projection $1\` exited $sr_rc): its register row carries managed-owner vocabulary that does not parse, or the read failed. An ownership nobody could establish is never read as legacy (Amendment 7(d)), so $2 is refused here, before the window is renamed and before a byte is written: no PAUSED, no row, no handoff file, no lifecycle transition, no inventory, and no restart. Read it: $LANES_EDIT managed-projection $1" 1 ;;
	esac
}
# Here, once the lane's canonical name is known and before ANYTHING is done
# with it: every mode of this command — the handoff, `--late`, `--restart`,
# `--exit` — is behind this line, so `SWAPPING` and `SWAPPED` never run for a
# managed lane.
seam_refuse "$lane" "a handoff"

# A plain preservation writer cannot modify an in-flight restart's input.
# This read precedes window, row and log writes; publication checks it again
# under the helper mutex, together with the prior handoff checksum.
if [ "$do_restart" != 1 ]; then
  lh_irrc=0
  lh_intent="$(LANES_NO_FETCH=1 "$LANES_EDIT" restart-intent "$lane")" || lh_irrc=$?
  case "$lh_irrc" in
    0)
      lh_istate="$(printf '%s\n' "$lh_intent" | awk -F'\t' '$1=="state" {print $2; exit}')"
      case "$lh_istate" in
        ready|failed) : ;;
        *) die "a restart owns this lane, or its intent is malformed; preservation refused before window, handoff, row or log writes. Read it: $prog --restart-status --lane $lane" 2 ;;
      esac ;;
    8) : ;;
    *) die "the legacy restart intent cannot be read; preservation refused before any writes." 2 ;;
  esac
fi
if [ "$do_restart" = 1 ]; then
  LANES_NO_FETCH=1 "$LANES_EDIT" legacy-restart-check "$lane" ||
    die "legacy /ctx restart refused at the managed-lane boundary. Nothing was written or respawned." 2
fi
if [ "$do_restart" = 1 ]; then
  ri_gen=0; ri_prc=0
  ri_prior="$(LANES_NO_FETCH=1 "$LANES_EDIT" restart-intent "$lane")" || ri_prc=$?
  case "$ri_prc" in
    0) ri_gen="$(printf '%s\n' "$ri_prior" | awk -F'\t' '$1 == "generation" {print $2; exit}')" ;;
    8) : ;;
    *) die "the prior legacy intent cannot be read. Nothing was written or respawned." 2 ;;
  esac
  case "$ri_gen" in ''|*[!0-9]*) die "the legacy generation is malformed. Nothing was written." 2 ;; esac
  ri_prev_gen="$ri_gen"; ri_gen=$((ri_gen + 1))
  operation="ctx-$(date -u +%Y%m%dT%H%M%SZ)-$$-${RANDOM:-0}"
  restart_prepare_cleanup() {
    LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$lane" failed \
      --expect preparing --expect-operation "$operation" --expect-generation "$ri_gen" \
      --expect-attempt 0 --reason 'preservation stopped before pending; old pane was not respawned' >/dev/null 2>&1 || :
  }
  LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$lane" preparing \
    --expect 'none|ready|failed' --expect-generation "$ri_prev_gen" \
    --operation "$operation" --generation "$ri_gen" --mode preservation-only \
    --reason 'reserved before preservation writes' >/dev/null ||
      die "another restart owns this lane, or its reservation could not be written; an ordinary context clear never supersedes an operation in flight. No handoff, row, log or window was changed. Read it: $prog --restart-status --lane $lane" 2
  trap restart_prepare_cleanup EXIT
  trap 'exit 130' INT
  trap 'exit 143' TERM
fi
step "lane=$lane${window_ref:+ window=$window_ref} workstation=${ws:-<none>}"

# THE LIVE RECORD OF THIS WINDOW — the session's uuid, the PANE `--exit` and
# `--restart` type into, and the name `/rename` may be owed. `window-session`
# is the one implementation of this read (Amendment 11 clause (h)).
sess_uuid=""; pane=""; sess_name=""; sess_profile=""
if [ -n "$win_harness" ]; then
	ws_ref="$win_harness"
	if [ -n "$ws_ref" ]; then
		sread wsess "'no live session is in this window'" window-session "$ws_ref"
		if [ -n "$wsess" ]; then
			# `<sid><US><tmux><US><name><US><pid><US><profile>`, the record's own fields.
			sess_uuid="$(printf '%s' "$wsess" | awk -F'\037' '{print $1}')"
			pane="$(printf '%s' "$wsess" | awk -F'\037' '{print $2}')"
			sess_name="$(printf '%s' "$wsess" | awk -F'\037' '{print $3}')"
			sess_profile="$(printf '%s' "$wsess" | awk -F'\037' '{print $5}')"
		fi
	fi
fi
# THE SHELL'S OWN SESSION BEATS THE RECORD. The harness exports
# `CLAUDE_CODE_SESSION_ID` into every shell a session runs, and a session naming
# itself is the one fact no record can be more current than.
[ -n "${CLAUDE_CODE_SESSION_ID:-}" ] && sess_uuid="$CLAUDE_CODE_SESSION_ID"
if [ -n "$sess_name" ] && [ "$sess_name" != "$lane" ] && [ "$sess_name" != none ]; then
	note "the session in this window is named '$sess_name', not '$lane' — the session name is the lane's messaging address (Amendment 2) and no API renames a running one from outside it. In the session, type:  /rename $lane"
fi

# The uuid the record's `session` field carries. `write_event` refuses anything
# that is not a transcript uuid — including the literal `unknown` — so the id is
# taken from the shell, then from the row, and a lane with neither is named
# rather than written wrong (Amendment 11 clause (e)).
uuid="$sess_uuid"
if [ -z "$uuid" ]; then
	sread row_uuid "'this lane has no recorded session'" last-session "$lane"
	uuid="$row_uuid"
fi

# ---------------------------------------------- Amendment 17(b): the agent
#
# A MANIFEST KEY — letters, digits, `.`, `_`, `-` — and the shape check is also
# how this sub-field gets SPEC rev 6 §5's `; ` rule without a token of its own:
# the pattern admits neither a `;` nor a space. The writer refuses a bad one
# too (`lanes-edit.sh`'s `pause_subfields_check`); this is the caller-side half,
# so the refusal names the flag rather than the grammar.
[ -n "$agent" ] || agent="${LANES_AGENT:-claude}"
case "$agent" in
*[!A-Za-z0-9._-]* | '') die "--agent takes a manifest key — letters, digits, '.', '_', '-' — and '$agent' is not one. The record's \`agent\` sub-field is what \`lane-start --agent\` reads back to know which launcher to use (Amendment 17(b))." 2 ;;
esac
# `transcript <id|none>`: the agent's own resumable id where it has one. For
# `claude` that is this lane's transcript uuid; an agent with none writes
# `none`, which is an answer and not a gap.
#
# IT IS THE RESOLVED `$uuid` AND NOT `$sess_uuid` (Copilot round 1 on
# openRepoTools#47). Run from a shell with no `CLAUDE_CODE_SESSION_ID` and no
# live record for this window — `lane-handoff --lane <lane>` from a bare
# terminal, which is the `--late` case and every scripted one — `$sess_uuid` is
# empty while `$uuid` has already fallen back to the ROW's recorded session,
# which is the id `lane-start` resumes this lane by. Writing `transcript none`
# there records *this agent has no resumable id* about a conversation whose id
# the same line carries in its `session` field.
if [ -z "$transcript" ]; then
	if [ "$agent" = claude ] && [ -n "$uuid" ]; then transcript="$uuid"
	else transcript=none
	fi
fi
case "$transcript" in
*[!A-Za-z0-9._-]* | '') die "--transcript takes the agent's own resumable id, or the word 'none' — '$transcript' is neither (Amendment 17(b))." 2 ;;
esac

# --------------------------------------------- the lane's checkout and profile
#
# `dir` IS THE LANE'S CHECKOUT AND NEVER A WORKTREE (`R-A11-11`, Evidence 3):
# restarting into a worktree loses the repository's CLAUDE.md and the lane's
# memory. Three sources, every one of them a RECORD rather than a derivation —
# and a read that FAILED takes no substitute, because a swap typed in one
# checkout for a lane that lives in another would otherwise record this
# session's directory as that lane's, in a log nothing rewrites.
dir="$dir_flag"; dir_read_failed=""
if [ -z "$dir" ]; then
	dir_rc=0
	dir="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-dir "$lane" 2>/dev/null)" || dir_rc=$?
	case "$dir_rc" in
	0) : ;;
	8 | 2) dir="" ;;
	*) dir=""; dir_read_failed="\`$LANES_EDIT lane-dir $lane\` failed (exit $dir_rc)" ;;
	esac
	if [ -z "$dir" ] && [ -z "$dir_read_failed" ]; then
		dir="${WORKBENCHES_CLAUDE_LANE_DIR:-}"
		if [ -z "$dir" ] && [ -n "${CLAUDE_CODE_SESSION_ID:-}" ] && [ -n "${CLAUDE_CONFIG_DIR:-}" ] && command -v jq >/dev/null 2>&1; then
			dir="$(jq -r --arg id "$CLAUDE_CODE_SESSION_ID" \
				'select((.sessionId // "") == $id) | .cwd // empty' \
				"$CLAUDE_CONFIG_DIR"/sessions/*.json 2>/dev/null | head -n 1)"
		fi
	fi
fi
# AN ABSOLUTE PATH OR NOTHING AT ALL: a relative one has no meaning without the
# writer's cwd, which no reader of this log has.
case "$dir" in /*) : ;; *) dir="" ;; esac
[ -n "$dir" ] || note "NO dir sub-field: ${dir_read_failed:-neither the lane log, the launcher nor this session record names the lane checkout}, so the record is written without one (Amendment 11 clause (c))."

profile_name="${CLAUDE_PROFILE_NAME:-$sess_profile}"
case "$profile_name" in
*[!A-Za-z0-9._-]* | '') profile_name="" ;;
esac

# A restart must have a supported, exact checkout before preservation or kill.
# Ordinary handoffs may still record a missing directory as diagnostics.
if [ "$do_restart" = 1 ]; then
  [ "$agent" = claude ] || die "this legacy restart supports only Claude. Nothing was respawned." 2
  [ -n "$dir" ] && [ -d "$dir" ] && [ -r "$dir" ] && [ -x "$dir" ] ||
    die "a supervised restart requires an existing absolute checkout directory. Nothing was respawned." 2
  for restart_fact in "$dir" "${pane:-${TMUX_PANE:-}}" "$window_ref"; do
    restart_fact_ok "$restart_fact" || die "restart launch facts cannot contain control characters. Nothing was respawned." 2
  done
fi

# THE WINDOW IS NOT RENAMED HERE ANY MORE: the refusals between here and the
# record must leave it as they found it, two of them say so in as many words,
# and now they do. The rename is section 3a below, after the last of them
# (opensoft/openRepoTools#80).

# ---------------------------- the LATE record's preconditions, read FIRST
#
# BEFORE THE POLL AND BEFORE THE REFRESH, because a refusal must leave the lane
# exactly as it found it — the handoff file included. Everything this block
# needs is the lane's own published log, and the rule it enforces is THE LATE
# RULE at the head of this file: a late `PAUSED` is written only where it can
# still be the lane's LAST lane-kind line in file order.
if [ "$do_late" = 1 ]; then
	[ -n "$late_at" ] || die "--late needs --at <UTC>: a late record is dated by the moment the OLD SESSION ENDED and not by the clock of the shell writing it, and that instant is also what decides whether the line can still be the lane's last one. Pass --at 2026-09-14T12:02:27Z (the time of the last thing that session did)." 2
	case "$late_at" in
	[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]Z) : ;;
	*) die "--at takes a UTC instant spelled as the log spells it, YYYY-MM-DDTHH:MM:SSZ — '$late_at' is not one." 2 ;;
	esac
	if [ -n "$ws_missing" ]; then
		die "the late record cannot be filed under a workstation this command could not read (\`R-A11-14\`), and a late PAUSED is the one line that has no second chance: nothing was written. Export LANES_WORKSTATION and re-run." 2
	fi
	# THE LANE'S LAST LANE-KIND LINE, read from the published log exactly as
	# every state reader reads it: FILE ORDER decides which is last.
	last_line=""; ll_rc=0
	last_line="$("$LANES_EDIT" lane-last "$lane" 2>/dev/null)" || ll_rc=$?
	case "$ll_rc" in
	0) : ;;
	8) last_line="" ;;
	*) die "\`$LANES_EDIT lane-last $lane\` failed (exit $ll_rc). That is NOT 'this lane has no lane-kind line', and a late PAUSED written on an answer nobody got could pause a lane that is running (Amendment 7(d))." 1 ;;
	esac
	last_verb="$(printf '%s' "$last_line" | awk -F'\t' '{print $1}')"
	last_utc="$(printf '%s' "$last_line" | awk -F'\t' '{print $2}')"
	case "$last_verb" in
	'')
		die "lane $lane has no STARTED or RESUMED in its object log, so there is no binding for a late PAUSED to close. A lane that never started is not a lane that failed to swap." 2 ;;
	PAUSED)
		die "lane $lane's last lane-kind line is already a PAUSED (at $last_utc): the record this act writes is already there, and a second one records nothing. If that PAUSED is wrong, the log is append-only and no later line corrects it — say so in the handoff instead." 2 ;;
	ENDED | RETIRED)
		die "lane $lane's last lane-kind line is $last_verb (at $last_utc): the lane is closed, and a PAUSED after it would reopen a lane nobody is in." 2 ;;
	esac
	if ! [ "$last_utc" '<' "$late_at" ]; then
		die "lane $lane's last lane-kind line is $last_verb at $last_utc, which is AT OR AFTER the $late_at this late record claims: the relaunch is already recorded, and this log is APPEND-ONLY, so a PAUSED appended now would be the lane's last line and would make a lane that is RUNNING read as paused. Nothing was written.
    The act, in order: run \`$prog --late --at <when the old session ended>\` from a SHELL, and only then start the lane (\`pclaude <profile>\`).
    Where the relaunch has already happened — which is this case — the honest record of the state that session now holds is its own next \`$prog\`." 2
	fi
fi

# ----------------- 2a. RUNNING -> SWAPPING, before any preservation work
#
# FIRST OF THE ACTS THAT CHANGE ANYTHING, and deliberately ahead of the poll,
# the refresh and the record: a session that dies from here on leaves the lane
# reading `SWAPPING`, which is the word for *the handoff began and did not
# finish*. Taken any later, the window in which token exhaustion is
# indistinguishable from an ungraceful stop is exactly the window in which the
# writers are being polled — the longest part of the act.
#
# IT IS BELOW THE `--late` PRECONDITIONS ON PURPOSE. Those refuse and write
# nothing at all, and a refusal must leave the lane exactly as it found it.
lifecycle_begin

# ------------------------------------------------ 3. poll the running writers
#
# Amendment 17(f): the top block *"LISTS EVERY WRITER THE LANE HAS RUNNING (its
# worktree, its branch, its brief, what it had committed)"*, and the next
# session *"RELAUNCHES EVERY WRITER IT LISTS from where each stood"*. A shell
# cannot message a subagent — that is the skill's step 3, and the one question
# this act ever asks belongs there — so what a shell CAN do is read every
# worktree the lane has and report it exactly: `git status --short` and
# `git log @{u}..`, per worktree, printed here and summarised into the section.
#
# TWO PLACES, because the estate uses both: `<checkout>/.claude/worktrees/<name>`
# for a writer working inside the lane's own repository, and
# `<projects>/.lane-worktrees/<lane>/<name>` for the ones a lane keeps beside it.
# AND A THIRD WHERE THE CHECKOUT IS AN ASSEMBLY (T018, below): the paired
# feature trees `<assembly>/worktrees/<feature>/{spec,code}`.
#
# THE SNAPSHOT FILE IS A PRECONDITION, NOT A CONVENIENCE (Copilot round 1 on
# openRepoTools#47). With no temporary file the count below still rises and
# every line written to it goes nowhere: the block would then say *WRITERS: 3
# found* and list none, and a `/ctx` on that block relaunches nothing while
# telling the next session there were three. A section that cannot be filled is
# refused here, before the handoff is touched and before the record is written,
# which is the one point at which nothing has happened yet.
writers_tmp="$(mktemp "${TMPDIR:-/tmp}/lane-handoff-writers.XXXXXX" 2>/dev/null || printf '')"
[ -n "$writers_tmp" ] ||
	die "could not create a temporary file under ${TMPDIR:-/tmp} to snapshot this lane's writers into, and the WRITERS section is what the next session counts against \`ListAgents\` (Amendment 17 Addendum 1 (i)). Nothing was written, nothing was renamed and no pane was touched. Free some space, or set TMPDIR to somewhere writable, and re-run." 2
cleanup() { [ -n "${writers_tmp:-}" ] && rm -f -- "$writers_tmp"; return 0; }
trap 'cleanup; if [ "$do_restart" = 1 ]; then restart_prepare_cleanup; fi' EXIT
trap 'exit 130' INT
trap 'exit 143' TERM

brief_for() {   # <worktree path>
	[ -n "$writers_file" ] && [ -r "$writers_file" ] || return 1
	awk -F'\t' -v p="$1" '$1 == p { sub(/^[^\t]*\t/, ""); print; exit }' "$writers_file"
}

writer_count=0
pw_withheld_count=0
# A TREE WITH A `.git` OF ITS OWN THAT GIT CANNOT READ, IN AN ASSEMBLY (T018,
# S2 of the review of bf2a220), is NAMED, never passed over. A leg whose
# module directory (`<assembly>/.git/modules/<leg>`) is damaged takes every
# worktree of its repository with it: the trees `lane-worktrees add --checkout
# <assembly>/<leg>` made, and the paired trees this lane's inventory names.
# Passed over, they vanished from the WRITERS section and from its count while
# the lane went SWAPPED, as if the poll had looked everywhere it looks. So such
# a tree is listed and counted as a writer whose state nobody could read, it is
# NOT recorded (a guessed reading would replace the one its record names), and
# the lane stays SWAPPING for it. Only `poll_writer` calls this, and only where
# the checkout is an assembly: a checkout with no `project.yaml` naming a leg
# passes over such a tree as it always did, which its golden holds.
unreadable_writer() {   # <tree>
	uw_d="$1"
	uw_err="$(git -C "$uw_d" rev-parse --git-dir 2>&1 >/dev/null </dev/null \
		| awk 'NF { sub(/^[ \t]+/, ""); sub(/[ \t]+$/, ""); print; exit }')"
	uw_err="${uw_err:-no answer}"
	uw_brief="$(brief_for "$uw_d" || printf '')"
	writer_count=$((writer_count + 1))
	pw_withheld_count=$((pw_withheld_count + 1))
	say ""
	say "WRITER $uw_d — UNREADABLE: it has a .git of its own and git could not read it: $uw_err"
	say "  nothing is assumed about its branch, its commits or its edits, and it is NOT recorded"
	printf -- '- `%s` (NOT recorded) — UNREADABLE: it has a .git of its own and git could not read it (%s), so nothing is assumed about its branch, its commits or its edits. A read that failed is never a clean tree (Amendment 7(d)) — read it by hand (`git -C %s status`) before relaunching a writer onto it; brief: %s\n' \
		"$uw_d" "$uw_err" "$uw_d" "${uw_brief:-(fill in: the brief this writer was given)}" >> "$writers_tmp"
	if [ -n "$lc_on" ]; then
		lc_inventory_missed="${lc_inventory_missed:+$lc_inventory_missed }$uw_d"
		note "the worktree inventory entry for $uw_d was NOT written: it has a .git of its own and git could not read it ($uw_err), so neither what it holds nor which checkout it is recorded under is known, and a guessed reading would replace the one its record names now. This handoff's WRITERS section names it, the lane stays SWAPPING for it, and \`$LANES_EDIT lane-reconcile $lane\` says what the inventory holds."
	else
		note "the tree $uw_d has a .git of its own and git could not read it ($uw_err), so nothing is assumed about it, and this handoff's WRITERS section names it. Read it by hand (git -C $uw_d status) before relaunching a writer onto it."
	fi
	return 0
}
poll_writer() {   # <path>
	pw_d="$1"
	[ -d "$pw_d" ] || return 0
	if ! git -C "$pw_d" rev-parse --git-dir >/dev/null 2>&1; then
		[ -n "$legs_state" ] || return 0
		{ [ -e "$pw_d/.git" ] || [ -L "$pw_d/.git" ]; } || return 0
		unreadable_writer "$pw_d"
		return 0
	fi
	# THE OBSERVATION IS THE HELPER'S, AND THIS COMMAND MAKES NONE OF ITS OWN
	# (Copilot round 5 on openRepoTools#97). `lanes-edit.sh lane-tree-now` is the
	# one implementation of *what git says about this tree right now* — the same
	# function `lane-reconcile` recomputes with — so the WRITERS section a person
	# reads and the sidecar a recovery reads are ONE reading, with one error
	# handling behind them. The five fields it answers with are the five the
	# record carries: branch, full head, upstream, dirty and unpushed.
	#
	# `%h` IS NOT AMONG THEM, and that is the point of the full head: an
	# abbreviation lengthens as a repository grows and is ambiguous across
	# repositories, while the upstream is what tells `0 unpushed` from *this
	# branch tracks nothing at all*.
	#
	# AND A READING NOBODY COULD MAKE IS SAID, NOT INVENTED. Where the helper
	# refuses — git failing inside a checkout, or a lanes-edit.sh predating this
	# read, which answers 2 for a subcommand it has never heard of — every field
	# is `?`, no sidecar is filed, and the section says so. A `none` here and a
	# `0` there is exactly the clean-looking record this round removed.
	pw_obs=""; pw_orc=0
	pw_obs="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-tree-now "$pw_d" 2>/dev/null)" || pw_orc=$?
	pw_branch='?'; pw_head=unknown; pw_up='?'; pw_dirty='?'; pw_ahead='?'
	if [ "$pw_orc" = 0 ]; then
		pw_branch="$(printf '%s' "$pw_obs" | awk -F'\037' '{print $1}')"
		pw_head="$(printf '%s' "$pw_obs" | awk -F'\037' '{print $2}')"
		pw_up="$(printf '%s' "$pw_obs" | awk -F'\037' '{print $3}')"
		pw_dirty="$(printf '%s' "$pw_obs" | awk -F'\037' '{print $4}')"
		pw_ahead="$(printf '%s' "$pw_obs" | awk -F'\037' '{print $5}')"
	else
		note "the observation of $pw_d could not be made (\`$LANES_EDIT lane-tree-now\` exited $pw_orc), so this writer is listed with what could not be read rather than with a clean-looking reading of it, and no inventory entry is filed for it. The lines below are still printed from this checkout, and the swap goes on (\`R-A11-11\`)."
	fi
	# The LISTING, which is prose and not the record: the actual lines a person
	# reads under the counts above. `|| :` and not a failure, for the reason the
	# note above gives — this is what is left to show when the reading refused.
	pw_last="$(git -C "$pw_d" log -1 --format='%h %s' 2>/dev/null || :)"
	pw_status="$(git -C "$pw_d" status --short 2>/dev/null || :)"
	pw_unpushed="$(git -C "$pw_d" log '@{u}..' --oneline 2>/dev/null || :)"
	pw_brief="$(brief_for "$pw_d" || printf '')"
	writer_count=$((writer_count + 1))
	say ""
	say "WRITER $pw_d — branch $pw_branch, last commit ${pw_last:-<none>}"
	say "  git status --short: ${pw_dirty} dirty"
	[ -n "$pw_status" ] && printf '%s\n' "$pw_status" | sed 's/^/    /'
	say "  git log @{u}..: ${pw_ahead} unpushed"
	[ -n "$pw_unpushed" ] && printf '%s\n' "$pw_unpushed" | sed 's/^/    /'
	# WHERE IT IS RECORDED, decided before its line is written (below), so that a
	# tree this handoff withholds says so in its own line — `(NOT recorded)` —
	# rather than reading exactly as a recorded one (N1 of the review of
	# bf2a220). A checkout with no `project.yaml` naming a leg withholds nothing,
	# and its line is the one it always was.
	pw_co=""; pw_withheld=""
	if [ -n "$lc_on" ] && [ "$pw_orc" = 0 ]; then
		pw_co="${dir:-unknown}"
		[ -z "$legs_state" ] || pw_co="$(writer_checkout "$pw_d")"
		[ -n "$pw_co" ] || pw_withheld=" (NOT recorded)"
	fi
	printf -- '- `%s`%s — branch `%s`, last commit `%s`, %s dirty, %s unpushed; brief: %s\n' \
		"$pw_d" "$pw_withheld" "$pw_branch" "${pw_last:-<none>}" "$pw_dirty" "$pw_ahead" \
		"${pw_brief:-(fill in: the brief this writer was given)}" >> "$writers_tmp"
	# AND THE SAME OBSERVATION, MACHINE-READABLE, BESIDE THE LANE AND NOT INSIDE
	# IT (openRepoTools#91). The WRITERS section above is what a person and the
	# next session read; this is what `lane-reconcile` recomputes against after
	# a crash, when there may be no session to read anything. It carries THIS
	# handoff's generation and operation, so a tree recorded by a superseded
	# operation is visible as one. It never fails the poll and never fails the
	# swap: a lane with no control root simply keeps no inventory yet.
	#
	# THE CHECKOUT IT IS RECORDED UNDER IS THE LANE'S `dir`, EXCEPT IN AN
	# ASSEMBLY (T018): there a tree of a leg's repository is recorded under its
	# LEG, the checkout `lane-worktrees add --checkout <assembly>/code` recorded
	# and every reader of the inventory enumerates (`writer_checkout`, below).
	# Where no checkout can be vouched for — the assembly's legs could not be
	# read, or one of them is unreadable, and the tree is not of the lane's own
	# repository nor of a leg git could read — NOTHING is filed: a guessed
	# checkout would replace the one `add` recorded, so the tree is named and
	# the lane stays SWAPPING for it, as for a refused write.
	if [ -n "$lc_on" ] && [ "$pw_orc" = 0 ]; then
		if [ -n "$pw_withheld" ]; then
			pw_withheld_count=$((pw_withheld_count + 1))
			lc_inventory_missed="${lc_inventory_missed:+$lc_inventory_missed }$pw_d"
			if [ "$legs_state" = known ]; then
				pw_cant="the assembly has $legs_unreadable_count unreadable leg(s), each named by an UNREADABLE LEG line in the top block, so whether this tree is of such a leg's repository"
			else
				pw_cant="$dir/project.yaml could not be read, so whether this tree is of one of the assembly's legs"
			fi
			note "the worktree inventory entry for $pw_d was NOT written: $pw_cant — and so which checkout it is recorded under — is not known, and a guessed one would replace the checkout its record names now. This handoff's WRITERS section still names the tree, the lane stays SWAPPING for it, and \`$LANES_EDIT lane-reconcile $lane\` says what the inventory holds."
			return 0
		fi
		LANES_NO_FETCH=1 "$LANES_EDIT" set-lane-tree "$lane" "$pw_d" \
			--checkout "$pw_co" --branch "$pw_branch" --head "$pw_head" \
			--upstream "$pw_up" --dirty "$pw_dirty" --unpushed "$pw_ahead" \
			--writer "${uuid:-none}" --generation "$lc_gen" --operation "$lc_op" \
			>/dev/null 2>&1 || {
			# AND THE SWAP IS NOT COMPLETE WITHOUT IT (Copilot on 64dfd97, PR
			# #97): an inventory missing a polled writer is not the record a
			# recovery reads as a finished swap, so the tree is named here and
			# `lifecycle_finish` leaves the lane SWAPPING for it.
			lc_inventory_missed="${lc_inventory_missed:+$lc_inventory_missed }$pw_d"
			note "the worktree inventory entry for $pw_d could not be written — the helper refused it, and a refusal of 7 there is this handoff's own fence: the lane's generation or operation moved while this poll was being taken, so a superseded reading was not filed over the current one. This handoff's WRITERS section still names the tree, the lane stays SWAPPING for it, and \`$LANES_EDIT lane-reconcile $lane\` says what the inventory holds."
		}
	fi
	return 0
}

# ------------------------------------------------ 3b. A TRIAD'S LEGS (T018)
#
# opensoft/openRepoTools#186, plan task T018. THE LANE'S CHECKOUT IS AN
# ASSEMBLY when its own `project.yaml` declares a leg other than itself — the
# standard's rule, read by `lanes-edit.sh project-legs`, the one reader every
# lane tool asks, never a second grammar here. Its legs (`spec/`, `code/`) are
# submodules, and a feature's trees are worktrees of the LEGS' repositories, so
# two things follow, and neither touches a checkout with no `project.yaml`,
# which is asked nothing and polled and recorded exactly as before:
#
#   * THE PAIRED ROOT IS POLLED BY THE SWEEP'S RULE — `<assembly>/worktrees/
#     <feature>` and `<feature>/<each declared leg's path>`, the standard's
#     three-leg feature trees. The paired root is per feature and NOT per
#     lane: every lane the assembly homes keeps its feature trees there. So a
#     tree there is polled and recorded as THIS lane's writer only where one
#     of three things holds: this lane's inventory already names it; its
#     HEAD's own last `Lane:` trailer is this lane's on a commit origin's
#     default branch lacks (`lane-worktrees`' `own_trailers` and
#     `head_lane_trailer`, the rule its sweep claims the same root by); or
#     the writers file names it, because a writer with nothing committed yet
#     has no trailer to be found by. Every other checkout there is ANOTHER
#     LANE'S OR NOBODY'S: one informational line in the top block, outside
#     WRITERS, never counted and never recorded. A handoff that recorded them
#     all made other lanes' feature trees this lane's inventory, so its
#     `lane-end` refused on their work, its `sweep --yes` could act on it, and
#     the next session was told to relaunch writers into them (the pre-PR
#     review of T018, M1, option (a)). Only a directory with a `.git` of its
#     own is a checkout there: anything else under it is the assembly's own
#     working tree, where git answers too.
#   * A TREE IS RECORDED UNDER THE CHECKOUT IT BELONGS TO. A tree of a leg's
#     repository — `lane-worktrees add --checkout <assembly>/code` makes one
#     under the lane's own root, and every paired tree is one — was re-recorded
#     here with the ASSEMBLY as its checkout, and the leg `add` had recorded
#     was lost at the first handoff. Its repository's common git directory,
#     which a leg shares with every worktree of it, names its leg now.
#
# A MANIFEST THAT COULD NOT BE READ IS SAID, AND THE SWAP GOES ON
# (`R-A11-11`): the paired root is then NOT polled, the top block's WRITERS
# section says so, no tree is recorded under a checkout nobody could establish,
# and the lane stays SWAPPING — a poll that could not look everywhere is not
# the record a recovery reads as a finished swap. SO IS A PAIRED ROOT, A
# FEATURE DIRECTORY OR A LEG'S DIRECTORY UNDER IT THAT COULD NOT BE LISTED, and
# an inventory that could not be read (`paired_unread`): each is a place a
# tree of this lane's may stand unseen, exactly as `lane-reconcile` says
# `indeterminate` and the sweep refuses for the same directories.
legs_state=""; legs_unread=""; leg_rows=""; leg_commons=""; dir_common=""; dir_phys=""
paired_unread=""; paired_others=""; paired_other_count=0; paired_inv=""
tab="$(printf '\t')"
# THE PHYSICAL PATH OF A CHECKOUT'S COMMON GIT DIRECTORY, or nothing: a leg
# and every worktree of its repository share one (`<assembly>/.git/modules/
# <leg>`), and git spells it relative where it is the checkout's own `.git`.
common_dir_of() {   # <path>
	cdo_c="$(git -C "$1" rev-parse --git-common-dir 2>/dev/null)" || return 0
	[ -n "$cdo_c" ] || return 0
	case "$cdo_c" in /*) : ;; *) cdo_c="$1/$cdo_c" ;; esac
	( CDPATH=''; cd -P -- "$cdo_c" 2>/dev/null && pwd -P ) || :
	return 0
}
physical_of() {   # <path>
	( CDPATH=''; cd -P -- "$1" 2>/dev/null && pwd -P ) || :
	return 0
}
if [ -n "$dir" ] && { [ -e "$dir/project.yaml" ] || [ -L "$dir/project.yaml" ]; }; then
	legs_rc=0
	leg_rows="$(LANES_NO_FETCH=1 "$LANES_EDIT" project-legs "$dir" 2>/dev/null)" || legs_rc=$?
	case "$legs_rc" in
	0) [ -z "$leg_rows" ] || legs_state=known ;;
	8) leg_rows="" ;;
	*)
		leg_rows=""; legs_state=unread
		legs_unread="the legs of the assembly $dir could not be read (its project.yaml is there, and \`$LANES_EDIT project-legs $dir\` exited $legs_rc)"
		dir_common="$(common_dir_of "$dir")"
		note "$legs_unread — which is never 'no legs' (Amendment 7(d)). So the assembly's paired feature trees under $dir/worktrees were NOT polled, and a tree that is not of $dir's own repository is NOT recorded: read them by hand before a writer is relaunched there. The handoff goes on (\`R-A11-11\`), and where it records a lifecycle the lane stays SWAPPING for it." ;;
	esac
fi
# EACH LEG THAT IS CHECKED OUT HERE, BY ITS COMMON GIT DIRECTORY. A leg that is
# NOT — a submodule never initialized, or deinitialized — is an empty
# directory of the assembly's, where git answers the ASSEMBLY: its common
# directory would then be the assembly's own, and every tree of the assembly
# would be recorded under that leg. So a leg counts only where git's own
# toplevel there is the leg itself.
#
# A LEG WITH A `.git` OF ITS OWN THAT GIT CANNOT READ is no absent leg: it is a
# read that failed, never an absent or a clean one (Amendment 7(d)). Passed
# over, it was a leg this handoff said nothing of while the sweep counted it,
# and every tree of its repository was re-recorded under the assembly, over
# the leg `add` had recorded. So it is the sweep's rule (`probe_leg`: git's
# toplevel there is not the leg, and a `.git` stands in it), the sweep's word
# and `lane-reconcile`'s: `unreadable`, one `- UNREADABLE LEG` line a leg in the
# top block's WRITERS section and a note on stderr, and COUNTED
# (`legs_unreadable_count`). The lifecycle is NOT left SWAPPING for the leg
# itself, as the reconciliation's verdict is not `indeterminate` for it: the
# poll looked everywhere it looks. A tree this handoff then cannot place is
# another matter (`writer_checkout`): it is named, not recorded, and the lane
# stays SWAPPING for it, as for any tree no checkout can be vouched for.
#
# SO IS A LEG DIRECTORY THIS ACCOUNT CANNOT SEARCH (#255, openRepoShape-2's
# SHOULD on #246): whether a `.git` stands in it cannot be tested, and the
# `.git` test fails there exactly as for a leg that is not checked out, so
# the leg was passed over IN SILENCE while an unpushed commit of this lane's
# could be in it. It takes the same path, in the same words as the sweep's
# `probe_leg` and `lane-reconcile`. A leg directory that is not there at all
# is still passed over (`-d`), as a leg that is not checked out.
legs_unreadable=""; legs_unreadable_count=0
if [ "$legs_state" = known ]; then
	while IFS="$tab" read -r lg_repo lg_decl lg_abs; do
		[ -n "$lg_abs" ] && [ -d "$lg_abs" ] || continue
		lg_top="$(git -C "$lg_abs" rev-parse --show-toplevel 2>/dev/null </dev/null || :)"
		if [ -z "$lg_top" ] || [ "$(physical_of "$lg_top")" != "$(physical_of "$lg_abs")" ]; then
			if [ -e "$lg_abs/.git" ] || [ -L "$lg_abs/.git" ]; then
				lg_what="it has a .git of its own and git could not read it"
			elif [ ! -x "$lg_abs" ]; then
				lg_what="its directory cannot be searched, so whether it has a .git of its own could not be tested, and git could not read it"
			else
				continue
			fi
			if [ -n "$lg_top" ]; then
				lg_err="git answers $lg_top there"
			else
				lg_err="$(git -C "$lg_abs" rev-parse --show-toplevel 2>&1 >/dev/null </dev/null \
					| awk 'NF { sub(/^[ \t]+/, ""); sub(/[ \t]+$/, ""); print; exit }')"
				lg_err="${lg_err:-no answer}"
			fi
			lg_why="the $lg_decl leg of $dir/project.yaml${lg_repo:+ ($lg_repo)}: git could not be read through it ($lg_what: $lg_err)"
			legs_unreadable_count=$((legs_unreadable_count + 1))
			# `<leg> TAB <why>`, one a line: the top block writes each leg's line
			# once the poll has said whether any tree was withheld (N1), and
			# `writer_checkout` asks whether a record names one of these legs.
			legs_unreadable="$legs_unreadable$lg_abs$tab$lg_why
"
			# WHAT IS STILL VOUCHED FOR, AND WHAT COULD BE A LEG'S (`writer_checkout`).
			[ -n "$dir_common" ] || dir_common="$(common_dir_of "$dir" </dev/null)"
			[ -n "$dir_phys" ] || dir_phys="$(physical_of "$dir" </dev/null)"
			note "the leg $lg_abs is unreadable: $lg_why — a read that failed is never a clean leg (Amendment 7(d)), so nothing is assumed about it or about which tree is of its repository, and the top block's WRITERS section names it. Read it by hand (git -C $lg_abs status) before relaunching a writer onto a tree of its repository."
			continue
		fi
		lg_c="$(common_dir_of "$lg_abs" </dev/null)"
		[ -n "$lg_c" ] || continue
		leg_commons="$leg_commons$lg_c$tab$lg_abs
"
	done <<LEG_ROWS
$leg_rows
LEG_ROWS
fi
# A PLACE THE POLL COULD NOT LOOK, said where it is found and kept for the top
# block's `- NOT POLLED` line and the lifecycle.
paired_note_unread() {   # <why>
	paired_unread="${paired_unread:+$paired_unread; }$1"
	note "$1 — a read that failed is never an empty one (Amendment 7(d)). So a tree of this lane's there may be missing from the WRITERS section: read it by hand before a writer is relaunched there. The handoff goes on (\`R-A11-11\`), and where it records a lifecycle the lane stays SWAPPING for it."
}
# THIS LANE'S INVENTORY, READ ONCE, where the checkout is an assembly whose legs
# were read: which paired trees are already this lane's, and the checkout each
# recorded tree was filed under (`writer_checkout`). `<path> TAB <checkout>`, one
# a line. A checkout with no `project.yaml` never asks it.
#
# A ROW IS A RECORD ONLY WHERE IT IS A WHOLE SCHEMA-1 ONE (#255): its schema,
# `lane-trees`' thirteenth field, is `1` - the schema `lane-worktrees` reads too
# (`_discover`). Every other row keeps no field but its id, its path where the
# file named one, and its schema (`<none>`, an unknown one, `<unreadable>`, and
# #252's `<malformed>`), so it is no record of whose a tree is: read as one, it
# made the paired tree it names this lane's writer on the strength of a record
# nobody could read, and the poll then tried to file a record of its own for
# that tree - over a malformed one, which went SWAPPED in silence, or against
# one of another schema, which `set-lane-tree` refuses and this handoff then
# reported as a refused write. So such a row is NAMED, by its id, its schema and
# any path it keeps, and the lane stays SWAPPING for it, exactly as for an
# inventory that could not be read at all; it never reaches `paired_inv`.
if [ "$legs_state" = known ]; then
	pi_out=""; pi_rc=0
	pi_out="$(LANES_NO_FETCH=1 "$LANES_EDIT" lane-trees "$lane" 2>/dev/null </dev/null)" || pi_rc=$?
	case "$pi_rc" in
	0)
		paired_inv="$(printf '%s\n' "$pi_out" | awk -F'\037' 'NF >= 2 && $2 != "" && $13 == "1" { print $2 "\t" $10 }')"
		pi_bad="$(printf '%s\n' "$pi_out" | awk -F'\037' 'NF >= 2 && ($2 == "" || $13 != "1") {
			printf "%s%s (schema %s%s)", (n++ ? ", " : ""), $1, ($13 == "" ? "<none>" : $13), ($2 == "" ? "" : ", path " $2) }')"
		[ -z "$pi_bad" ] ||
			paired_note_unread "this lane's worktree inventory holds record(s) that could not be read ($pi_bad), so a paired tree only they name could not be told from another lane's" ;;
	8) : ;;
	*) paired_note_unread "this lane's worktree inventory could not be read (\`$LANES_EDIT lane-trees $lane\` exited $pi_rc), so a paired tree only it names could not be told from another lane's" ;;
	esac
fi
# THE CHECKOUT THIS LANE'S INVENTORY RECORDS FOR A TREE, under either spelling
# of the tree's path, or nothing.
inventory_checkout() {   # <tree>
	[ -n "$paired_inv" ] || return 1
	ic_r="$(physical_of "$1")"
	IC_P="$1" IC_R="$ic_r" awk -F'\t' '
		$1 == ENVIRON["IC_P"] || (ENVIRON["IC_R"] != "" && $1 == ENVIRON["IC_R"]) { print $2; f = 1; exit }
		END { exit f ? 0 : 1 }' <<IC_ROWS
$paired_inv
IC_ROWS
}
# THE CHECKOUT A POLLED TREE IS RECORDED UNDER, in an assembly: the leg whose
# repository it is a worktree of; else the checkout this lane's inventory
# already records for it, where that is a checkout of the tree's own
# repository — a dependency nested in a leg (`add --checkout
# <assembly>/code/upstream/<dep>`) is no declared leg, and re-recording its
# tree under the assembly would lose the checkout `add` recorded; else the
# lane's own `dir`, as always. Where the legs could not be read, only a tree
# of `dir`'s own repository can be vouched for, and anything else answers
# NOTHING (the caller files nothing).
#
# AND WHERE A LEG IS UNREADABLE (`legs_unreadable_count`), NOTHING IS ANSWERED
# FOR A TREE THAT COULD BE OF THAT LEG'S REPOSITORY, whose common directory
# nobody could read: the lane's `dir` would then replace the leg `add`
# recorded. Such a tree is one whose common git directory nobody could read;
# or one whose common git directory lies physically inside the assembly, or
# inside the assembly's own git directory, without being the assembly's own
# (`<assembly>/.git/modules/<leg>`, a leg's own `.git`, or a linked worktree's
# `modules/` under the common directory); or one this lane's inventory records
# under an unreadable leg, or under a checkout inside one. A tree of ANY OTHER
# repository (a worktree of an unrelated repository in the lane's own root)
# is of no leg, so it keeps the lane's `dir`, exactly as where every leg reads
# (S1 of the review of bf2a220): withheld, it left the lane SWAPPING on every
# handoff and its record going stale for as long as the leg stayed broken.
recorded_under_unreadable_leg() {   # <checkout a record names>
	ru_p="$(physical_of "$1")"
	while IFS="$tab" read -r ru_abs ru_why; do
		[ -n "$ru_abs" ] || continue
		case "$1/" in "$ru_abs"/*) return 0 ;; esac
		ru_lp="$(physical_of "$ru_abs" </dev/null)"
		if [ -n "$ru_p" ] && [ -n "$ru_lp" ]; then
			case "$ru_p/" in "$ru_lp"/*) return 0 ;; esac
		fi
	done <<RU_ROWS
$legs_unreadable
RU_ROWS
	return 1
}
writer_checkout() {   # <tree>
	wc_c="$(common_dir_of "$1")"
	if [ -n "$wc_c" ] && [ -n "$leg_commons" ]; then
		while IFS="$tab" read -r wc_l wc_p; do
			if [ -n "$wc_l" ] && [ "$wc_l" = "$wc_c" ]; then printf '%s' "$wc_p"; return 0; fi
		done <<WC_ROWS
$leg_commons
WC_ROWS
	fi
	if [ "$legs_state" = known ]; then
		wc_rec="$(inventory_checkout "$1" </dev/null || :)"
		if [ -n "$wc_c" ] && [ -n "$wc_rec" ] && [ -d "$wc_rec" ] &&
		   [ "$(common_dir_of "$wc_rec" </dev/null)" = "$wc_c" ]; then
			printf '%s' "$wc_rec"; return 0
		fi
		if [ "$legs_unreadable_count" -gt 0 ]; then
			if [ -n "$wc_c" ] && [ -n "$dir_common" ] && [ "$wc_c" = "$dir_common" ]; then
				printf '%s' "$dir"; return 0
			fi
			[ -n "$wc_c" ] && [ -n "$dir_phys" ] || return 0
			case "$wc_c/" in "$dir_phys"/*) return 0 ;; esac
			if [ -n "$dir_common" ]; then
				case "$wc_c/" in "$dir_common"/*) return 0 ;; esac
			fi
			if [ -n "$wc_rec" ] && recorded_under_unreadable_leg "$wc_rec" </dev/null; then return 0; fi
		fi
		printf '%s' "${dir:-unknown}"; return 0
	fi
	if [ -n "$wc_c" ] && [ -n "$dir_common" ] && [ "$wc_c" = "$dir_common" ]; then printf '%s' "$dir"; fi
	return 0
}

# WHOSE A PAIRED TREE IS (M1 (a) of the T018 pre-PR review). Three answers make
# it this lane's, cheapest first; anything else is another lane's or nobody's.
#
# THE WRITERS FILE, read exactly as `brief_for` reads it: a line whose first
# field is the tree.
writers_name() {   # <tree>
	[ -n "$writers_file" ] && [ -r "$writers_file" ] || return 1
	awk -F'\t' -v p="$1" '$1 == p { f = 1; exit } END { exit f ? 0 : 1 }' "$writers_file"
}
# EVERY `Lane:` TRAILER of the messages on stdin, one a line, as
# `lane-worktrees` reads them (`^Lane:\s*(\S+)\s*$`, multi-line).
lane_trailers() {
	awk '/^Lane:[[:space:]]*[^[:space:]]+[[:space:]]*$/ {
		v = $0; sub(/^Lane:[[:space:]]*/, "", v); sub(/[[:space:]]+$/, "", v); print v }'
}
# THE SWEEP'S OWN CLAIM ON THE PAIRED ROOT (`lane-worktrees`' `_lane_claims`,
# with `own_trailers` and `head_lane_trailer`): HEAD's own last `Lane:`
# trailer is this lane's, and this lane's trailer is among the commits HEAD has
# that origin's default branch lacks — `origin/HEAD`, else `origin/main`; with
# neither there is no base to tell them by, and no claim. Compared without
# case, as the sweep compares. A standalone CLONE is never claimed by its
# trailer, as the sweep never adopts one.
head_trailer_is_lane() {   # <tree>
	[ -d "$1/.git" ] && return 1
	ht_base="$(git -C "$1" symbolic-ref -q refs/remotes/origin/HEAD 2>/dev/null || :)"
	if [ -z "$ht_base" ] && git -C "$1" rev-parse -q --verify refs/remotes/origin/main >/dev/null 2>&1; then
		ht_base=refs/remotes/origin/main
	fi
	[ -n "$ht_base" ] || return 1
	ht_want="$(printf '%s' "$lane" | tr '[:upper:]' '[:lower:]')"
	ht_head="$(git -C "$1" log -1 --format=%B HEAD 2>/dev/null | lane_trailers | tail -n 1 | tr '[:upper:]' '[:lower:]')"
	[ -n "$ht_head" ] && [ "$ht_head" = "$ht_want" ] || return 1
	git -C "$1" log --format=%B "$ht_base..HEAD" 2>/dev/null | lane_trailers | tr '[:upper:]' '[:lower:]' |
		HT_W="$ht_want" awk '$0 == ENVIRON["HT_W"] { f = 1 } END { exit f ? 0 : 1 }'
}
# ONE CHECKOUT OF THE PAIRED ROOT: polled and recorded as this lane's writer,
# or named once as not this lane's — its branch, its last commit and its HEAD's
# own trailer, which is what a person needs to find its lane — and never
# counted, recorded or offered for a relaunch.
paired_tree() {   # <tree>
	if inventory_checkout "$1" >/dev/null || writers_name "$1" || head_trailer_is_lane "$1"; then
		poll_writer "$1"
		return 0
	fi
	pt_branch="$(git -C "$1" symbolic-ref -q --short HEAD 2>/dev/null)"; pt_brc=$?
	case "$pt_brc" in 0) : ;; 1) pt_branch='(detached)' ;; *) pt_branch='?' ;; esac
	pt_last="$(git -C "$1" log -1 --format='%h %s' 2>/dev/null || :)"
	pt_trailer="$(git -C "$1" log -1 --format=%B HEAD 2>/dev/null | lane_trailers | tail -n 1)"
	pt_shown=none
	[ -z "$pt_trailer" ] || pt_shown="\`$pt_trailer\`"
	paired_other_count=$((paired_other_count + 1))
	say ""
	say "PAIRED ROOT, not this lane's: $1 — branch $pt_branch, last commit ${pt_last:-<none>}"
	say "  HEAD's own Lane: trailer ${pt_trailer:-none}; neither lane $lane's inventory nor its writers file names it, so it is not polled, counted or recorded for $lane"
	paired_others="$paired_others$(printf -- '- PAIRED ROOT, not this lane'"'"'s: `%s` — branch `%s`, last commit `%s`, HEAD'"'"'s own `Lane:` trailer %s' \
		"$1" "$pt_branch" "${pt_last:-<none>}" "$pt_shown")
"
	return 0
}

: > "$writers_tmp"
if [ -n "$dir" ]; then
	for w in "$dir"/.claude/worktrees/*; do poll_writer "$w"; done
	parent="${dir%/*}"
	for w in "$parent"/.lane-worktrees/"$lane"/*; do poll_writer "$w"; done
	# THE PAIRED ROOT, where the checkout is an assembly whose legs were read.
	# `</dev/null` on every poll inside the loop: its rows are the loop's
	# stdin, and nothing the poll runs may take them. A directory there that
	# cannot be listed is said, as `lane-reconcile` says it (`indeterminate`)
	# and the sweep refuses on it — never passed over as an empty one.
	if [ "$legs_state" = known ]; then
		pr_root="$dir/worktrees"
		if [ -d "$pr_root" ] && { [ ! -r "$pr_root" ] || [ ! -x "$pr_root" ]; }; then
			paired_note_unread "the assembly's paired root $pr_root could not be listed"
		else
			for wf in "$pr_root"/*; do
				[ -d "$wf" ] && [ ! -L "$wf" ] || continue
				if [ ! -r "$wf" ] || [ ! -x "$wf" ]; then
					paired_note_unread "the assembly's feature directory $wf could not be listed"
					continue
				fi
				if [ -e "$wf/.git" ] || [ -L "$wf/.git" ]; then paired_tree "$wf" </dev/null; fi
				while IFS="$tab" read -r lg_repo lg_decl lg_abs; do
					case "$lg_decl" in ''|/*) continue ;; esac
					wl="$wf/${lg_decl#./}"
					[ -d "$wl" ] && [ ! -L "$wl" ] || continue
					if [ ! -x "$wl" ]; then
						paired_note_unread "the assembly's paired tree directory $wl could not be searched" </dev/null
						continue
					fi
					if [ -e "$wl/.git" ] || [ -L "$wl/.git" ]; then paired_tree "$wl" </dev/null; fi
				done <<LEG_ROWS
$leg_rows
LEG_ROWS
			done
		fi
	fi
fi
step "writers polled: $writer_count under ${dir:-<no recorded checkout>}"
[ "$legs_unreadable_count" = 0 ] ||
	step "legs: $legs_unreadable_count of the assembly's legs under $dir unreadable — named in the top block's WRITERS section, never a clean leg"
[ "$paired_other_count" = 0 ] ||
	step "paired root: $paired_other_count tree(s) under $dir/worktrees are not lane $lane's — listed in the top block, never counted or recorded"

# ------------------------------------------------------ 2. refresh the handoff
#
# The handoff path is the row's SIXTH column: awk field 7, because `$1` is the
# empty string before the leading pipe — `lanes-edit.sh`'s own `row_cell` /
# `handoff_of_lane` convention. NEVER count back from `NF`: a lane's row carries
# every state line to the RIGHT of the handoff column, so `$(NF-2)` lands on the
# empty string and the commit below would `git add ""` — silently, in the one
# step Amendment 6(e) exists for.
sread row "'this lane has no row'" register-row "$lane"
row_line="$(printf '%s\n' "$row" | grep '^|' | tail -n 1)"
handoff_cell="$(printf '%s' "$row_line" | awk -F'|' '{print $7}' | awk '{$1=$1};1')"

handoff_file=""
if [ -n "$handoff_cell" ]; then
	case "$handoff_cell" in
	'~/'*) [ -f "$HOME/${handoff_cell#'~/'}" ] && handoff_file="$HOME/${handoff_cell#'~/'}" ;;
	/*) [ -f "$handoff_cell" ] && handoff_file="$handoff_cell" ;;
	*)
		# THE WORKSPACE REPOSITORY, THROUGH THE HELPER'S OWN RESOLVER and never
		# through a second reading of `workspace.yaml` — Amendment 9(a) is
		# explicit that a second way to find one thing is a second answer.
		hs_root="$("$LANES_EDIT" workspace-root 2>/dev/null || :)"
		for hs_base in "${LANES_REPO:-}" "$hs_root"; do
			[ -n "$hs_base" ] || continue
			if [ -f "$hs_base/$handoff_cell" ]; then handoff_file="$hs_base/$handoff_cell"; break; fi
		done ;;
	esac
fi

# THE FRESH RULE 3 TOP BLOCK. It is PREPENDED and the file is never rewritten:
# a handoff is the one document in this protocol whose whole purpose is to be
# read by a later session, and the act that deleted two lanes' rows on
# 2026-09-08 was a file written whole out of what somebody remembered of it.
# Everything that was in the file stays below the marker, as history.
#
# LINE 1 AND THE BLANK AFTER IT ARE STRUCTURAL: `lane-start` splices its Rule 3
# stamp at *"the line immediately after the first blank line that follows line
# 1"*, so a top block that does not open that way is a block the RESUMED stamps
# land in the middle of.
top_block() {
	printf 'Lane: %s (%s, session %s) — single-use resume prompt: stamp RESUMED-by before acting (lane-collision-protocol rule 3)\n' \
		"$lane" "${profile_name:-profile unknown}" "${uuid:-unknown}"
	printf '\n'
	printf '## RESUME PROMPT — PAUSED %s (%s), agent %s, transcript %s, kind %s — %s\n\n' \
		"$UTC" "${why:-handoff}" "$agent" "$transcript" "$handoff_kind" "$kind_headline"
	printf '**FIRST ACTS, in order.** (1) You are lane `%s`%s%s. Stamp this block RESUMED before anything else (Rule 3, single use) — `lane-start --no-launch <repo> <n>` in this window writes it. (2) Read AGENTS.md, then this block. (3) COUNT THE LIVE WRITERS before relaunching anything — the WRITERS section below is a list to COUNT, not a list to relaunch (Amendment 17 Addendum 1 (i)). ONE WORKTREE, ONE WRITER (k): a worktree is one writer'"'"'s for as long as that writer is live, a relaunch onto a live writer'"'"'s worktree is the writers'"'"' form of Amendment 18(h)'"'"'s second binding, and where you find one made you retire the newer before either commits. %s Older sections below are history.\n\n' \
		"$lane" "${window_ref:+ in tmux window \`$window_ref\`}" "${dir:+, checkout \`$dir\`}" "$kind_act"
	printf '**STATE at %s.** Handed off by `%s` on %s: %s. Agent `%s`, transcript `%s`. Kind `%s`: %s.%s\n\n' \
		"$UTC" "$prog" "${ws:-<no workstation>}" "${why:-no why given}" "$agent" "$transcript" \
		"$handoff_kind" "$kind_state" \
		"${ws_missing:+ THE REGISTER AND OBJECT-LOG WRITES WERE NOT MADE: this session ran with no configured workstation, so the row still reads as it did and the register is BEHIND this file (\`R-A11-14\`). The next session binds with \`lane-start --no-launch\`.}"
	printf '**WRITERS at %s** (%s found under `%s`) — FIRST count the live writers: `ListAgents` in Claude, the agent'"'"'s equivalent elsewhere. A writer still live OWNS its worktree: do not relaunch it; one message telling it that its in-flight call died and who the coordinator now is, is enough. Relaunch only a writer that is NOT live, from where it stands — `git status` and `git log @{u}..` in its worktree, then its brief. WHERE THE COUNT AND THIS LIST DISAGREE, THE COUNT WINS: this list is what the paused session expected, the count is what is true.\n\n' \
		"$UTC" "$writer_count" "${dir:-<no recorded checkout>}"
	if [ "$writer_count" = 0 ]; then
		printf -- '- none running at the handoff. A writer this lane starts later is listed by the next refresh.\n'
	else
		cat -- "$writers_tmp"
	fi
	# T018: A POLL THAT COULD NOT LOOK EVERYWHERE SAYS SO HERE, where the next
	# session reads it — never only on a stderr nobody kept.
	if [ -n "$legs_unread" ]; then
		printf -- '- NOT POLLED: %s, so the assembly'"'"'s paired feature trees under `%s/worktrees` are not in this list. Read them by hand before relaunching a writer there.\n' \
			"$legs_unread" "$dir"
	fi
	if [ -n "$paired_unread" ]; then
		printf -- '- NOT POLLED: %s, so a tree of this lane'"'"'s under `%s/worktrees` may be missing from this list. Read it by hand before relaunching a writer there.\n' \
			"$paired_unread" "$dir"
	fi
	# AND A LEG GIT COULD NOT READ, one line a leg, in the sweep's words. Its
	# last clause says what the poll then withheld, and only that (N1 of the
	# review of bf2a220): the trees it could not place are each marked
	# `(NOT recorded)` above, and where there are none the line says so.
	if [ -n "$legs_unreadable" ]; then
		if [ "$pw_withheld_count" -gt 0 ]; then
			tb_placed="the $pw_withheld_count tree(s) this handoff could not place are named above, each marked (NOT recorded)"
		else
			tb_placed="every tree this handoff polled could still be placed, so none is withheld for it"
		fi
		while IFS="$tab" read -r tb_abs tb_why; do
			[ -n "$tb_abs" ] || continue
			printf -- '- UNREADABLE LEG: `%s` is unreadable, %s. So NOTHING is assumed about it — not its own state, nor which tree is of its repository: %s. A read that failed is never a clean leg (Amendment 7(d)) — read it by hand (`git -C %s status`) before relaunching a writer onto a tree of its repository.\n' \
				"$tb_abs" "$tb_why" "$tb_placed" "$tb_abs"
		done <<TB_ROWS
$legs_unreadable
TB_ROWS
	fi
	printf '\n'
	# T018, M1 (a): THE PAIRED ROOT'S OTHER TREES, OUTSIDE WRITERS. They are
	# other lanes' feature trees, or nobody's: named so the next session knows
	# they are there and whose to ask, never counted above, never recorded, and
	# never a writer to relaunch. Nothing is printed where there are none, so
	# a checkout with no `project.yaml` gets the block it always got.
	if [ -n "$paired_others" ]; then
		printf '**PAIRED ROOT at %s: %s tree(s) under `%s/worktrees` that are NOT this lane'"'"'s.** None is in this lane'"'"'s inventory, carries its `Lane:` trailer on a commit origin'"'"'s default branch lacks, or is named by its writers file, so none is counted above or recorded. Each is another lane'"'"'s feature tree, or nobody'"'"'s: NEVER relaunch a writer into one of them.\n\n' \
			"$UTC" "$paired_other_count" "$dir"
		printf '%s\n' "$paired_others"
	fi
}

handoff_written=0
if [ -z "$handoff_file" ]; then
	note "the row names no handoff this command could find${handoff_cell:+ ('$handoff_cell')}, so the top block was NOT written. The record below is still written; put this block at the head of the lane's handoff by hand:"
	top_block >&2
else
	hs_tmpd="$(mktemp -d 2>/dev/null || printf '')"
	if [ -z "$hs_tmpd" ]; then
		note "could not create a temporary directory, so the handoff was not refreshed: $handoff_file"
	else
		hs_prior_digest="$(handoff_digest "$handoff_file")"
		{ top_block
		  printf -- '---\n\n'
		  cat -- "$handoff_file"
		} > "$hs_tmpd/out"
		# PROVED BEFORE IT LANDS: taking the new block back out again must give
		# the original file byte for byte. That is also what catches a file whose
		# last line has no newline.
		hs_added="$(( $(grep -c '' "$hs_tmpd/out") - $(grep -c '' "$handoff_file") ))"
		if tail -n +$((hs_added + 1)) -- "$hs_tmpd/out" | cmp -s - "$handoff_file"; then
			# THE FLAG FOLLOWS THE WRITE AND NEVER THE INTENTION (Copilot round 1 on
			# openRepoTools#47). A handoff file that is read-only, or on a filesystem
			# that is full, fails HERE — and `handoff_written=1` set regardless is
			# what lets `--restart` pass its gate and respawn the pane over a STALE
			# top block, which is the one document the new session is started with.
			hs_publish_args=(publish-handoff "$lane" "$handoff_file" "$hs_tmpd/out" --expect-digest "$hs_prior_digest")
			if [ "$do_restart" = 1 ]; then
				# Bind preservation publication to this operation before replacing
				# any canonical bytes; the helper verifies file identity under lock.
				LANES_NO_FETCH=1 "$LANES_EDIT" set-restart-intent "$lane" preparing \
				  --expect preparing --expect-operation "$operation" --expect-generation "$ri_gen" --expect-attempt 0 \
				  --handoff "$handoff_file" --digest "$hs_prior_digest" >/dev/null ||
				  { rm -rf -- "$hs_tmpd"; die "the preservation handoff could not be bound to this restart. Nothing was published or respawned." 2; }
				hs_publish_args+=(--operation "$operation" --generation "$ri_gen" --attempt 0 --state preparing --transcript none)
			fi
			if hs_published="$(LANES_NO_FETCH=1 "$LANES_EDIT" "${hs_publish_args[@]}")"; then
				handoff_file="$hs_published"
				handoff_written=1
				step "handoff refreshed: $handoff_file (+$hs_added lines at the head)"
			else
				note "the refreshed top block could NOT be written to $handoff_file (the error above is the shell's own), so that file still carries the block it had. It is printed below; put it at the head of that file by hand:"
				top_block >&2
			fi
		else
			note "the splice of the new top block into $handoff_file did not prove out (the old file must survive it byte for byte), so NOTHING was written to it."
			top_block >&2
		fi
		rm -rf -- "$hs_tmpd"
	fi
fi

# The commit is in the LANE'S OWN workspace repository and is not one of the
# writes a missing workstation stops (A11 Addendum 4 ruling 11): it is where the
# gap is NAMED. One commit, an explicit pathspec and the Rule 5 trailer.
if [ "$handoff_written" = 1 ] && [ "${LANES_NO_GIT:-0}" != 1 ]; then
	# THE PARENT IS RESOLVED WITH `cd -P`, NOT `readlink -f` (Copilot round 3 on
	# openRepoTools#47, the same rule as `lane-start`'s `real_of`). Where
	# `readlink -f` is not in the userland the fallback hands the path back
	# UNRESOLVED, so `hs_repo` — which git answers with a PHYSICAL path — and
	# `hs_rel`, derived from the symlinked spelling, disagree: `git add` then
	# refuses a pathspec that "leaves the repository", and the handoff this act
	# has just written is left uncommitted. A handoff is reached through the
	# estate's `handoffs` symlink on every workstation that has one.
	hs_dirreal="$( CDPATH=''; cd -P -- "$(dirname -- "$handoff_file")" 2>/dev/null && pwd -P )" ||
		hs_dirreal="$(dirname -- "$handoff_file")"
	hs_real="$hs_dirreal/$(basename -- "$handoff_file")"
	hs_repo="$(git -C "$(dirname -- "$hs_real")" rev-parse --show-toplevel 2>/dev/null || :)"
	if [ -n "$hs_repo" ]; then
		hs_rel="${hs_real#"$hs_repo"/}"
		if git -C "$hs_repo" add -- "$hs_rel" >/dev/null 2>&1 &&
		   git -C "$hs_repo" commit -q -m "handoff($lane@${ws:-unknown}): PAUSED, ${why:-handoff}" -m "Lane: $lane" -- "$hs_rel" >/dev/null 2>&1; then
			step "handoff commit: handoff($lane@${ws:-unknown}): PAUSED"
			if git -C "$hs_repo" pull --rebase -q origin "${LANES_BRANCH:-main}" >/dev/null 2>&1 &&
			   git -C "$hs_repo" push -q origin "${LANES_BRANCH:-main}" >/dev/null 2>&1; then
				step "handoff pushed to origin/${LANES_BRANCH:-main}"
			else
				git -C "$hs_repo" rebase --abort >/dev/null 2>&1 || :
				note "the handoff is committed here and was NOT pushed (a conflict, or no reachable origin). Never force; look first, then push:
    git -C $hs_repo fetch origin ${LANES_BRANCH:-main} && git -C $hs_repo log --oneline origin/${LANES_BRANCH:-main} -3
    git -C $hs_repo pull --rebase origin ${LANES_BRANCH:-main} && git -C $hs_repo push origin ${LANES_BRANCH:-main}"
			fi
		else
			note "the handoff is written and NOT committed — an uncommitted write is captured by the next lane's commit and its attribution is lost (Amendment 4(d)). Commit it yourself:
    git -C $hs_repo commit -m \"handoff($lane@${ws:-unknown}): PAUSED\" -m \"Lane: $lane\" -- $hs_rel"
		fi
	fi
fi

# ------------------------- 3a. the window takes the lane's name, and only now
#
# THE OTHER TWO NAMES MADE TO MATCH IT, mechanically. The window is renamed
# here; the SESSION's name is the lane's messaging address (Amendment 2) and
# there is no API to rename a running session from outside it, so where the
# live record's name is not the lane the act is PRINTED, beside the read of
# that record above — it is the operator's `/rename`, and it is not a question.
#
# AFTER THE LAST REFUSAL AND BEFORE THE FIRST RECORD (opensoft/openRepoTools#80
# items 2 and 11, Copilot's review of workBenches#91 at `lane-handoff:519`). The
# rename used to run before the `--late` preconditions, the writers' snapshot
# file, the row read and the `--restart` binding — every one of them a refusal,
# two of them saying that nothing was renamed — so a refused handoff left the
# window carrying the name of a lane it had not handed off. And its failure was
# swallowed: the `&&` gated only the message, and the PAUSED record, the row and
# the restart line went on as if the window were the lane's, which is how the
# next handoff from that window binds the wrong lane. `lane-start` holds this
# same rename fatal, and so does this command now: a rename tmux refuses is a
# refusal, made before the PAUSED record, the LANES.md line and the row, and
# before any pane is touched. What HAS landed by then is said, because the act
# that follows is a re-run and a person deciding on one needs to know.
if have_tmux && [ -n "$window_name" ] && [ "$window_name" != "$lane" ]; then
	rn_err=""
	if ! rn_err="$(tmux rename-window "$lane" 2>&1 >/dev/null)"; then
		rn_landed=""
		[ "$handoff_written" = 1 ] &&
			rn_landed=" The handoff's new top block IS written, and a re-run puts a newer one above it."
		[ -n "$lc_on" ] &&
			rn_landed="$rn_landed The lane reads SWAPPING until a handoff finishes, and the next one supersedes this one."
		die "tmux would not rename this window '$window_name' → '$lane'${rn_err:+ (tmux: $rn_err)}, and the window IS the lane (Amendment 8(b)): a record written beside a window that still carries another name is how the next handoff from it binds the wrong lane. So the PAUSED record, the LANES.md line and the row were NOT written, and no pane was touched.$rn_landed Rename the window, then run the same command again:
    tmux rename-window $lane" 2
	fi
	step "window renamed '$window_name' → '$lane' (Amendment 8(b): the window IS the lane)"
fi

# ------------------------------------------------------- 4. the swap record
#
# THE FREE TEXT IS SANITIZED ONCE: Amendment 7(b)/R26 refuses any payload or
# free text containing ` — ` (exit 2), because that separator is what divides a
# line's fields from its free text.
#
# AND A LINE BREAK IS SPELLED `; ` TOO (opensoft/openRepoTools#85), whatever
# its spelling — CRLF, a lone CR, a lone LF — so that one break is one `; `.
# Both writers this text reaches refuse a newline before they write
# (`write_event` for the log, `append-line` for the register), and a why that
# carries one is refused at the door, right after the arguments are read, so
# nothing that reaches here today carries one. This is the second line of
# defence, in the shape #85 asks of the caller: where a break does arrive, the
# act still happens, on one line. `sed` cannot do it, because `sed` reads a
# line at a time and hands the break back.
sanitize() {
	sz="${1//$'\r\n'/; }"
	sz="${sz//$'\r'/; }"
	sz="${sz//$'\n'/; }"
	printf '%s' "$sz" | sed 's/ — /; /g'
}
# THE FREE TEXT NAMES THE KIND AFTER ITS WHY (Amendment 17 Addendum 1 (h), in
# force 2026-09-14T20:59:31Z): `clear in-process`, `clear respawn`, `switch
# respawn`, `reset respawn` — the why the caller gave, then the word for what
# happened to the PROCESS. A handoff that cannot know which will follow writes
# `kind unknown`, which is the addendum's own spelling of it. The payload
# carries the same fact as a sub-field (`; kind <k>`) for the readers that
# parse the line; this is for the person who reads it.
kind_word="$handoff_kind"
[ "$handoff_kind" = unknown ] && kind_word="kind unknown"
why_text="$(sanitize "${why:-handoff}") $kind_word"

# THE PAYLOAD. It opens `swap; ` because that is what `swapped` matches on — the
# record the launcher restarts from — and the sub-fields after it are Amendment
# 11(c)'s three plus Amendment 17(b)'s two. A value carrying `, `, ` — `, `; ` or
# `"` is DROPPED (the sub-field, not the line) and what was dropped is PRINTED:
# `R-A11-11` binds this writer — *a swap is never left unwritten* — so an
# offending sub-field costs its own information and never the record.
payload="swap"
refused=""
# THE SAME FENCE FOR ALL FOUR SEPARATORS (Copilot round 3 on openRepoTools#47).
# `window` is two space-separated refs in ONE sub-field, so a `; ` inside it
# would be read back as the END of the sub-field and the rest as another one:
# every reader of this line would then recover a window ref that is not the
# lane's. The comment above already said both were dropped; now they are.
case "$window_ref" in *', '* | *' — '* | *'; '* | *'"'*) refused="$refused window=$window_ref"; window_ref="" ;; esac
case "$dir" in *', '* | *' — '* | *'; '* | *'"'*) refused="$refused dir=$dir"; dir="" ;; esac
dir_field="$dir"
case "$dir_field" in *' '*) dir_field="\"$dir_field\"" ;; esac
[ -z "$window_ref" ] || payload="$payload; window $window_ref"
[ -z "$dir_field" ] || payload="$payload; dir $dir_field"
[ -z "$profile_name" ] || payload="$payload; profile $profile_name"
[ -z "$ws" ] || payload="$payload; workstation $ws"
# AMENDMENT 17(b) — THE TWO SUB-FIELDS THAT MAKE THE LANE RESUMABLE BY ANY
# AGENT. They go LAST, after Amendment 11(c)'s, because every reader written
# before this amendment stops at the sub-field it knows and a reader that finds
# none says so (Amendment 7(i)'s cutover rule).
payload="$payload; agent $agent; transcript $transcript"
# AND THE KIND OF CLEAR, AFTER THEM, ON THE SAME ARGUMENT: a reader written
# before this field stops at the sub-field it knows. It is in the record and not
# only in the handoff because the record is what a launcher and a later reader
# have — `in-process` says the writers of that session were still running when
# the line was written, which is the one fact that decides whether relaunching
# them is right.
payload="$payload; kind $handoff_kind"
[ -z "$refused" ] || note "DROPPED sub-field (not appended, and the line is still written):$refused"

# A lane-aware launcher is required for restarts. An explicit lane keeps the
# pclaude fallback safe across both old and new launcher installations.
lane_profile_word="pclaude --lane $lane"
command -v lclaude >/dev/null 2>&1 && lane_profile_word=lclaude

# ------------------------------------------------------------ the LATE branch
if [ "$do_late" = 1 ]; then
	late_payload="$payload; late $late_at"
	late_why="$(sanitize "${why:-late; usage limit hit before the swap at $late_at}") $kind_word"
	if LANES_LANE="$lane" LANES_SESSION="$uuid" "$LANES_EDIT" log PAUSED "lane:$lane" \
		'→' "$late_payload" "$late_why" --utc "$late_at"; then
		step "late PAUSED written, dated $late_at (before the relaunch, which is the only place it can go)"
		# THE LATE RECORD'S MANDATORY SET IS TWO AND NOT THREE: the row is not
		# flipped by this branch at all (it exits below), so requiring it would
		# leave every late record reading as an interrupted swap for ever.
		lc_unfinished=""
		[ "$handoff_written" = 1 ] || lc_unfinished="the handoff file was not refreshed"
		[ -z "$lc_inventory_missed" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the worktree inventory was not recorded for $lc_inventory_missed"
		[ -z "$legs_unread" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the assembly's legs could not be read, so its paired feature trees were not polled"
		[ -z "$paired_unread" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }a directory of the assembly's paired root, or this lane's inventory, could not be read, so a paired tree of this lane's may not have been polled"
		lifecycle_finish "$lc_unfinished"
	else
		lifecycle_finish "the late PAUSED record was refused by the helper"
		die "the late PAUSED was NOT written (the helper refused it — its own message is above). Nothing else was done." 2
	fi
	say ""
	say "LATE RECORD WRITTEN for lane $lane, dated $late_at. Now start the lane:"
	say "  $lane_profile_word ${profile_name:-<profile>}"
	if [ -n "$lc_on" ]; then
		say "  lifecycle: $lc_state (generation $lc_gen, operation $lc_op) — lanes-edit.sh lane-reconcile $lane"
	fi
	exit 0
fi

# --- BEGIN shared one-line cut (lane-collision-protocol Amendment 13(a)) ---
# BYTE-IDENTICAL IN `lane-start`, `lane-end` AND `lane-handoff`, the three
# commands that write a row's state cell — the same trade the four lane helpers
# already make for their workspace resolver, and for the same reason: a drifted
# copy is TWO ANSWERS to one question, and "what may this line contain, and
# where may it be cut" is one question.
#
# FOUR THINGS THE CELL'S LINE MAY NOT CARRY, and `set-row-state` REFUSES all
# four — which would cost the row its stamp or its closing write, so they are
# fixed here rather than met there:
#
#   ` · `  the phrase's own separator. A second one reads back as a fourth part
#          of `<STATE> · <UTC> · <one line>`; it is spelled `; `.
#   `|`    a cell boundary in a Markdown table row. A launch command or a
#          directory may legitimately hold one — `claude --flag 'a|b'`, a path
#          with a pipe in it — and the row is where it would forge a column
#          (Copilot round 1 on openRepoTools#82). It is spelled `¦`, the broken
#          bar, which is not a separator anywhere here; the object log's own
#          line keeps the character itself.
#   CR/LF  a row is ONE LINE of a table, so a newline in this text would split
#          it in two and every row after it would be read as a lane. Spelled
#          `; ` for the same reason the separator is (Copilot round 2).
#   >240   ratified decision O1's cap. Cut at 230 with the last partial WORD
#          dropped, which is what makes the cut safe: `${s:0:n}` counts BYTES
#          wherever the locale is not a UTF-8 one, and a byte offset can land
#          inside the very characters above. 230 and not 240, so the ` ...`
#          marker fits inside the cap however the two count.
cut_to_line() {   # <line> — the row's one line, safe to hand to set-row-state
  ctl="${1//$'\r'/ }"
  ctl="${ctl//$'\n'/; }"
  ctl="${ctl// · /; }"
  ctl="${ctl//|/¦}"
  [ "${#ctl}" -gt 230 ] || { printf '%s' "$ctl"; return 0; }
  ctl="${ctl:0:230}"
  case "$ctl" in *' '*) ctl="${ctl% *}" ;; esac
  printf '%s ...' "$ctl"
}
# --- END shared one-line cut ---

# ------------------------------------------------- (a) the object-log PAUSED
record_written=0
row_write_refused=""
if [ -n "$ws_missing" ]; then
	note "NOT WRITTEN: the PAUSED line, the LANES.md line and the row's state cell all stop where there is no configured workstation (clause (k) rule (d), \`R-A11-14\`). The handoff refreshed above names the gap, and the restart line below carries --lane, because a restart cannot resolve this lane from a row that was never set."
	row_write_refused=1
else
	if LANES_LANE="$lane" LANES_SESSION="$uuid" "$LANES_EDIT" log PAUSED "lane:$lane" \
		'→' "$payload" "$why_text"; then
		record_written=1
		step "object log: PAUSED lane:$lane → $payload"
	else
		note "the PAUSED line was NOT written — the helper's own refusal is above. Write it before anything else:"
		note "  LANES_LANE=$lane LANES_SESSION=$uuid $LANES_EDIT log PAUSED lane:$lane '→' \"$payload\" \"$why_text\""
	fi
	# (b) the LANES.md file-level line, the shape every prior PAUSED/RESUMED
	# used. It is written whether or not (a) could be (`R-A11-11`: a swap is
	# never left unwritten) — EXCEPT where there is no transcript uuid to name,
	# which is the one thing that must never be written into either file. The
	# literal `unknown` is in this estate's append-only log four times already
	# and no later line corrects any of them (Amendment 11 clause (e)); a
	# register line naming it would be the fifth, one file along.
	if [ -n "$uuid" ]; then
		"$LANES_EDIT" append-line "PAUSED — lane $lane, session $uuid@$ws, $UTC, $why_text; handoff refreshed" >/dev/null 2>&1 ||
			note "the LANES.md file-level PAUSED line was not appended (the register may be busy or behind); the object-log line above is the record readers take."
	else
		note "no transcript uuid is knowable for this lane, so neither the object log's PAUSED nor the register's file-level line was written — a record naming 'unknown' in that field is a record no restart can read (Amendment 11 clause (e)). The handoff file above is refreshed and is the whole of what this act left behind. Bind the session first:  lane-start --no-launch <repo> <n>"
	fi
	# (c) the row: ONE WRITE, which sets the whole cell (Amendment 13(a)).
	#
	# It used to be TWO, and both of them were guesses at a cell that was a
	# history: `replace-in-row` flipping the leading state word — derived by
	# grepping the row for `| WORD ·` or `| WORD |`, since the anchor had to
	# occur exactly once or the write was refused — and then an
	# `append-row-status` putting `PAUSED — <payload>` at the END of the same
	# cell, so the row said PAUSED twice, in two places, with a day of narrative
	# between them. The cell is now one phrase that `set-row-state` REPLACES, so
	# a swap writes it once and there is no anchor to guess at: a row whose cell
	# opens with anything at all, or with nothing, takes the same write.
	#
	# The payload carries the record's sub-fields (`swap; window …; dir …;
	# profile …; agent …; transcript …`), which is exactly the line a person
	# reading the row wants; a ` · ` inside it would read back as a fourth part
	# of the phrase, and 240 characters is the cap (ratified decision O1) — the
	# object-log line written above carries the full payload either way.
	hs_line="$(cut_to_line "$payload")"
	LANES_LANE="$lane" "$LANES_EDIT" set-row-state "$lane" "PAUSED · $hs_line" >/dev/null 2>&1 || row_write_refused=1
	[ -z "$row_write_refused" ] || note "the row's state cell was NOT set to PAUSED (the write was refused — run it by hand to see what it says: lanes-edit.sh set-row-state $lane \"PAUSED · $hs_line\"). The restart line below carries --lane for that reason."
fi

# ------------------------- 4a. SWAPPING -> SWAPPED, the operation's commit point
#
# THE THREE WRITES THAT MUST HAVE LANDED, and they are the same three
# `--restart` and `--exit` already gate on: the lane's `PAUSED` record (what
# every launcher and every later reader takes its state from), the row (what
# every OTHER lane reads) and the handoff file (whose top block is literally
# the next session's first prompt). A lane called `SWAPPED` on two of those is
# a lane whose recovery would skip the third, so the transition is made only on
# all three and the state otherwise STAYS `SWAPPING` — which a later session
# reads as an interrupted swap and answers by preserving every worktree.
#
# THE SWAP IS STILL REPORTED AND STILL RESTARTABLE (`R-A11-11`, *a swap is
# never left unwritten*): this changes what the lane's lifecycle SAYS, never
# whether the act completes.
lc_unfinished=""
[ "$record_written" = 1 ] || lc_unfinished="the lane's PAUSED record did not land"
[ -z "$row_write_refused" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the row's state cell was not flipped"
[ "$handoff_written" = 1 ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the handoff file was not refreshed"
[ -z "$lc_inventory_missed" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the worktree inventory was not recorded for $lc_inventory_missed"
[ -z "$legs_unread" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }the assembly's legs could not be read, so its paired feature trees were not polled"
[ -z "$paired_unread" ] || lc_unfinished="${lc_unfinished:+$lc_unfinished; }a directory of the assembly's paired root, or this lane's inventory, could not be read, so a paired tree of this lane's may not have been polled"
lifecycle_finish "$lc_unfinished"

# ------------------------------------------- 5. the restart line — one command
if [ -n "$row_write_refused" ]; then
	if [ "$lane_profile_word" = lclaude ]; then
		restart_cmd="lclaude --lane $lane ${profile_name:-<profile>}"
	else
		restart_cmd="$lane_profile_word ${profile_name:-<profile>}"
	fi
	restart_note=" (the row was not flipped, so the lane must be named explicitly)"
else
	restart_cmd="$lane_profile_word ${profile_name:-<profile>}"
	restart_note=""
fi
say ""
say "READY — restart with: $restart_cmd$restart_note"
say "  record: PAUSED lane:$lane → $payload"
say "  agent $agent, transcript $transcript (lane-start --agent $agent resumes it)"
if [ -n "$lc_on" ]; then
	say "  lifecycle: $lc_state (generation $lc_gen, operation $lc_op) — lanes-edit.sh lane-reconcile $lane"
	say "  inventory: $writer_count worktree(s) recorded — lanes-edit.sh lane-trees $lane"
fi

# -------------------------------------------- Amendment 17(f) / 18(d): the end
#
# THE RECORD COMES FIRST, ALWAYS. *"a `/ctx` whose record could not be written
# REFUSES before it kills anything (a pane is never respawned over an unrecorded
# lane)"* — so both branches below test `record_written` before they touch tmux,
# and a lane whose PAUSED line did not land keeps its pane and its session.
if [ "$do_restart" = 1 ] || [ "$do_exit" = 1 ]; then
	[ "$record_written" = 1 ] ||
		die "the lane's PAUSED record was NOT written, so this pane is left exactly as it is: a pane is never respawned over an unrecorded lane, and a session is never ended without one (Amendment 17(f)). Fix the write above and re-run." 2
	# AND THE RECORD IS THREE WRITES, NOT ONE (Copilot rounds 1 and 2 on
	# openRepoTools#47). The object-log line above is the first of them; the
	# ROW is what every other lane and every launcher reads this lane's state
	# from, and the HANDOFF is the document the new session is started with —
	# its top block is literally the respawn's first prompt (`lane-start`'s
	# 5a). A pane respawned over an unflipped row leaves the register saying
	# RUNNING about a session that no longer exists, and a pane respawned over
	# a STALE top block hands the new session the last handoff's instructions:
	# the writers of another act, the why of another act. Neither is a state
	# this command may create and then kill the only process that could fix it,
	# so both are gates, and each names the act that clears it.
	[ -z "$row_write_refused" ] ||
		die "the lane's PAUSED line is written and the ROW WAS NOT FLIPPED (the note above says why), so this pane is left exactly as it is: respawning it would leave the register reading RUNNING for a session that has just been replaced, and every other lane reads the row. Flip it and re-run, or restart by hand:  $restart_cmd" 2
	[ "$handoff_written" = 1 ] ||
		die "the lane's PAUSED line is written and the HANDOFF WAS NOT REFRESHED (the note above says why), so this pane is left exactly as it is: the top block of that file is what the new session is started with, and respawning now would hand it the block of a handoff this act has replaced. Put the block printed above at the head of the handoff, then re-run — or restart by hand once you have:  $restart_cmd" 2
	have_tmux ||
		die "the record is written, and there is no tmux here to ${do_restart:+respawn}${do_exit:+end} this pane with. Do it by hand — the record is the part that mattered." 2
	# THE PANE, from the LIVE RECORD's own `tmux` field — `<session>:<@id>.%<pane>`
	# — because that is the pane the session is really in; the window ref is the
	# fallback for a record that carries none, and tmux resolves it to that
	# window's active pane.
	target="${pane:-${TMUX_PANE:-}}"
	[ -n "$target" ] || target="${wid:-$win}"
	[ -n "$target" ] ||
		die "the record is written, and no pane of this lane's could be resolved (no live record names one, \$TMUX_PANE is unset and this window has no ref). Nothing was killed." 2
fi

if [ "$do_exit" = 1 ]; then
	# AMENDMENT 18(d): the session ENDS, because a handoff to another place is a
	# handoff and not a restart. `/exit` is typed into the lane's own pane —
	# Amendment 12's M1, the one mechanism there is — so the session ends at its
	# next prompt with nothing of the person's lost.
	if tmux send-keys -t "$target" '/exit' Enter 2>/dev/null; then
		say "  /exit typed into $target (Amendment 18(d): the session ends where the handoff was requested from elsewhere)"
	else
		die "the record is written and `/exit` could NOT be typed into $target. Type it in the lane's own pane yourself." 2
	fi
	exit 0
fi

if [ "$do_restart" = 1 ]; then
	# AMENDMENT 17(f) — THE RESPAWN, THROUGH THE LAUNCHER, WITH THE TOP BLOCK AS
	# THE NEW SESSION'S FIRST PROMPT. `respawn-pane -k` replaces the pane's
	# process, so the act survives the death of the session that started it: the
	# session running this command is killed BY the command it just wrote the
	# record for.
	#
	# WHAT THE RESPAWN LINE USED TO BE, AND WHY IT IS NOT THAT ANY MORE.
	# Amendment 18 Addendum 2 (i-8) names two doors for this act: *"relaunches
	# the lane's own pane with `lane <name>` (its parked branch is exactly
	# Amendment 11(i)'s act), or through the launcher directly"*. This command
	# respawned with the first of them, and openRepoTools#94 is what that cost:
	# `lane` is a HUMAN DISPATCHER whose valid outcomes include attaching to an
	# existing session without launching anything, and the fresh-session
	# requirement it was asked to carry was an environment variable that the
	# launcher's own `tmux new-session` dropped on the way through.
	#
	# BOTH DOORS ARE KEPT, ONE LEVEL DOWN. What tmux starts now is this
	# command's `--supervise` mode, and what the SUPERVISOR starts is (i-8)'s
	# second door — `pclaude --lane <lane> <profile>`, the launcher directly —
	# falling to `lane-start` itself where this workstation has no launcher or
	# the lane's record names no profile. The ground of (i-8) is honoured
	# exactly: *"no word is kept on `PATH` for it alone"*, and none is — the
	# supervisor is a mode of a command that is already installed, and a person
	# still has one word, `lane`.
	#
	# THE DEVIATION IS WRITTEN DOWN rather than taken quietly: it is decisions
	# 10 and 11 of `openspec/changes/add-supervised-context-restart/design.md`
	# — 10 for the supervisor being a MODE of this command rather than the new
	# installed word decision 5 proposed, 11 for neither of (i-8)'s two doors
	# being taken at THIS level — and the protocol text that would ratify it is
	# task 7.4's, unwritten as this lands.

	# ---- THE PRE-KILL COMMIT POINT: THE RESTART INTENT (openRepoTools#94)
	#
	# THE FRESH SESSION IS WRITTEN DOWN BEFORE ANYTHING IS KILLED, and that is
	# the whole of this change. `LANE_START_FRESH=1` in the respawn's command
	# string was the seam and it was measured NOT ARRIVING: `claude-profile`
	# re-created the child through `tmux new-session` in that incident. The current
	# launcher keeps an existing TMUX pane; an out-of-pane tmux launch hands a command
	# the SERVER's environment and not the client's — the launcher's own code
	# says so, which is why it threads six values into the command string
	# explicitly and why a seventh nobody thought to thread simply vanished.
	# The pane came back resuming the transcript this act had just paused.
	#
	# SO THE REQUIREMENT BECOMES A FILE. The intent is written under the lane's
	# own control root, carries the lane, generation, operation, old
	# transcript, agent, profile, checkout, pane, handoff path and DIGEST and
	# the launch mode, and `lane-start` reads it back whatever the environment
	# did. It is the one channel that crosses a boundary another repository
	# owns.
	#
	# AND IT IS A GATE, LIKE THE THREE ABOVE IT. Amendment 17(f) is an order —
	# *a `/ctx` whose record could not be written REFUSES before it kills
	# anything* — and after this change the intent IS part of that record: a
	# pane respawned with no intent is a pane whose supervisor has nothing to
	# launch from, which is the same unrecorded restart one step along. It
	# therefore refuses here, with the old process still alive, rather than
	# after it is dead.
	#
	# Complete the reservation made before preservation writes.
	ri_args=(set-restart-intent "$lane" pending
		--expect preparing --expect-operation "$operation" --expect-generation "$ri_gen" --expect-attempt 0
		--operation "$operation" --generation "$ri_gen"
		--mode fresh-from-handoff
		--agent "$agent" --pane "$target"
		--old-transcript "${transcript:-none}"
		--profile "${profile_name:-none}" --window "${window_ref:-none}"
		--dir "$dir" --handoff "$handoff_file")
	ri_wrc=0
	LANES_NO_FETCH=1 "$LANES_EDIT" "${ri_args[@]}" >/dev/null 2>&1 || ri_wrc=$?
	case "$ri_wrc" in
	0) : ;;
	7) die "lane $lane already has a restart in flight (its intent is \`pending\` or \`starting\`), so this /ctx did NOT replace the pane: an ordinary context clear never supersedes an operation somebody else is in the middle of. The record above IS written. Read what is open:  $prog --restart-status --lane $lane" 2 ;;
	*) die "the lane's PAUSED record, row and handoff are all written and the RESTART INTENT could not be (\`set-restart-intent\` exited $ri_wrc), so this pane is left exactly as it is. The intent is what tells the new session it is a FRESH one primed by the handoff's top block, and a pane respawned without it comes up resuming the transcript this act just paused — which is openRepoTools#94, measured. Restart by hand once it can be written:  $restart_cmd" 2 ;;
	esac
	# READ BACK BEFORE THE KILL, because a write that reported success and a
	# record a second process can read are not the same fact, and the process
	# that could fix the difference is the one about to die.
	ri_load "$lane" || die "the pending restart intent could not be read back. Nothing was respawned." 2
	[ "$RI_STATE" = pending ] && [ "$RI_OP" = "$operation" ] && [ "$RI_GEN" = "$ri_gen" ] &&
	  [ "$RI_ATTEMPT" = 0 ] && [ "$RI_MODE" = fresh-from-handoff ] && [ "$RI_AGENT" = claude ] &&
	  [ "$RI_PROFILE" = "${profile_name:-none}" ] && [ "$RI_DIR" = "$dir" ] && [ -d "$RI_DIR" ] &&
	  [ "$RI_PANE" = "$target" ] && [ "$RI_WINDOW" = "${window_ref:-none}" ] &&
	  [ "$RI_OLD" = "${transcript:-none}" ] && [ "$RI_NEW" = none ] &&
	  [ "$RI_HANDOFF" = "$handoff_file" ] && [ -s "$RI_HANDOFF" ] &&
	  [ "$RI_DIGEST" != none ] && [ -n "$RI_DIGEST" ] && [ "$(handoff_digest "$RI_HANDOFF")" = "$RI_DIGEST" ] ||
		die "the pending restart launch facts could not be verified before replacing the pane. Nothing was respawned; read the intent: $prog --restart-status --lane $lane" 2
	say "  restart intent $operation written (generation $ri_gen, mode fresh-from-handoff)"

	# ---- THE RESPAWN, INTO A SUPERVISOR AND NOT INTO THE LAUNCH ITSELF
	#
	# WHAT TMUX STARTS IS A PROCESS THAT STAYS. The old line respawned the pane
	# with the launch, so a launch that failed took the pane with it and left
	# an empty dead window where a person's lane had been — against Amendment
	# 11's own invariant, *"No path the launcher opened exits the pane"*. The
	# supervisor is that invariant kept for the one act that had nobody
	# keeping it: it claims the intent, runs the launch as its CHILD, confirms
	# readiness, and on any failure stays in the pane with the diagnostic and
	# the retry.
	#
	# BY ABSOLUTE PATH, because a respawned pane's `PATH` is whatever the
	# person's shell profile makes of it, and a respawn is the one act no later
	# refusal can undo. It is checked for existence HERE, while this process is
	# still alive to say so.
	[ -x "$SELF_ABS" ] ||
		die "the record and the restart intent are written and this command cannot find itself at $SELF_ABS to hand the pane to, so nothing was respawned: tmux starts the supervisor by absolute path because a respawned pane's PATH is not this one's. Restart by hand:  $restart_cmd" 2
	# AND THE ENVIRONMENT THE SUPERVISOR NEEDS IS WRITTEN INTO THE COMMAND
	# STRING, for exactly the reason #94 exists: the workstation name is what
	# every register write from the new session is filed under (`R-A11-14`),
	# and tmux would otherwise hand the pane whatever the SERVER has.
	launch_line="$(quoted "$SELF_ABS" --supervise --lane "$lane" --operation "$operation")"
	[ -n "$ws" ] && launch_line="LANES_WORKSTATION=$(quoted "$ws") $launch_line"
	[ -z "${LANES_LANE_STATE_ROOT:-}" ] || launch_line="LANES_LANE_STATE_ROOT=$(quoted "$LANES_LANE_STATE_ROOT") $launch_line"
	[ -z "${AGENT_PROTOCOL_ROOT:-}" ] || launch_line="AGENT_PROTOCOL_ROOT=$(quoted "$AGENT_PROTOCOL_ROOT") $launch_line"
	[ -z "${LANES_HOST:-}" ] || launch_line="LANES_HOST=$(quoted "$LANES_HOST") $launch_line"
	[ -z "${LANES_OS:-}" ] || launch_line="LANES_OS=$(quoted "$LANES_OS") $launch_line"
	[ -z "${LANES_CONTAINER:-}" ] || launch_line="LANES_CONTAINER=$(quoted "$LANES_CONTAINER") $launch_line"
	say "  respawning $target: $launch_line"
	if tmux respawn-pane -k -t "$target" "$launch_line" 2>/dev/null; then
		say "  respawned into the supervisor — it launches the fresh session, confirms it came up, and stays in this pane if it did not"
	else
		die "the record and the restart intent are written and \`tmux respawn-pane -k -t $target\` was refused, so this pane is exactly as it was and the lane's restart intent is \`pending\` for operation $operation. Nothing was killed. Start it yourself:  $restart_cmd
    or hand this pane to the supervisor once tmux will take it:
      $launch_line" 2
	fi
	exit 0
fi

exit 0
