Skip to content

skills/handoff/SKILL.md:310-315: the handoff commit is a bare git commit in a spelled ~/projects/brett-wip, so it can publish other lanes' staged work and stop mid-rebase: resolve the checkout, commit by pathspec, refuse foreign staged entries #197

Closed

Description

@brettheap

Sibling check

No branch, issue or PR fixes this, and none conflicts with the fix. This was read at origin/main f87fd5a and on every remote branch at 2026-10-13T15:1xZ, from a fresh clone.

Branch Tip Against main The block Relation to this fix (measured with git merge-tree)
fix/handoff-skill-98-99-100 (#98, #99 and #100, CLAIMED by lane openRepoTools-4 at 2026-10-11T16:30:56Z-16:32:10Z; no PR) 00814c0 2 ahead, 0 behind Kept verbatim (its :331-336) Neighbour. Its hunks insert 7 lines after old :301 and make $L resolve on PATH first (#100). It merges clean, and its 16 tests pass with this fix merged
fix/handoff-skill-78-79 (#78 and #79, CLAIMED by lane openRepoTools-5 at 2026-10-11T16:38:09Z and 16:39:35Z; WIP, no PR) 2c4b7a6 1 ahead, 0 behind Kept (the branch adds a test file only) Neighbour, and a test home. It merges clean. Its bash -n check of every fenced block accepts the new block. Its 2 failures are its own RED cases, the same with and without this fix: #78's lclaude <profile> line and #79's wording
001-separate-swap-ctx-handoff (the OpenSpec change separate-swap-ctx-handoff) 3c26041 27 ahead, 28 behind Kept verbatim in its "Unmanaged legacy compatibility" section (its :365-368) No new conflict. Its 11 conflicting files against main are the same 11 with this fix, and SKILL.md auto-merges
feat/supervised-context-restart f13d329 30 ahead, 13 behind Kept verbatim SKILL.md auto-merges. Its existing conflicts (lane-start and lanes-edit.sh) are unchanged

What happens

Step 2 of the skill ends in its only handoff commit (skills/handoff/SKILL.md:310-315 at f87fd5a). A session runs it after every publication (:215):

cd ~/projects/brett-wip
git add "$handoff"
git commit -m "handoff(<lane>@<ws>): PAUSED, <one-line state>" -m "Lane: <lane>"
git pull --rebase && git push

The text around it says what it should do, and the block does not do it:

  • :307-308 say "Commit with an explicit pathspec", but the commit has none.
  • :317 says "On a rebase conflict: abort, leave the tree clean, report it", but the block has no abort.

The installed copy is this text: ~/.claude/skills/handoff/SKILL.md, read in lane opsXfactory-2's environment on Eagle, has the same sha256 prefix, ec9fadbf.

1. The bare commit publishes other lanes' staged work. A bare git commit commits the whole index, whatever the git add before it named.

  • The protocol forbids it. Amendment 4(d), the handoff rule, requires "explicit pathspecs — never git add -A, never a bare git commit". Amendment 5(c) bans "a bare git commit" too (lane-collision-protocol-amendment-5.md:63-64).
  • The order makes it worse. By committing everything staged, the commit leaves the index equal to HEAD, so the following git pull --rebase starts where it would otherwise have refused, and then git push publishes.
  • Measured by reviewer R7b in a plain-git 2.43.0 sandbox. The checkout was in the state the shared checkout held from 2026-10-11T20:07Z (DIAGNOSIS-C §2.3): main moved by a linked worktree's checkout -B, so the index stayed at the old tree, as a staged reversal. It also held one stranded stamp built on that stale tree. Only the block's four commands ran, with only the cd target changed:
== bare (as shipped), origin's next change on ANOTHER file:
   before: staged=1 [handoffs/h2.md ] ahead=1 behind=1     origin h2: peer handoff v2 (P1)   origin row4: | row4 | P1 |
   commit rc=0 carried: [handoffs/h1.md handoffs/h2.md ] still staged=0
   pull --rebase rc=0 ; push rc=0
   after: origin log: handoff(L1@ws): PAUSED, sim|LANES(stamp) on stale tree|P2|P1|seed|
   origin h2 after: peer handoff v1   origin row4: | row4 | a |   origin row2: | row2 | STAMP |
== bare (as shipped), origin's next change on the SAME file:
   commit rc=0 carried: [handoffs/h1.md handoffs/h2.md ] still staged=0
   CONFLICT (content): Merge conflict in handoffs/h2.md
   pull --rebase rc=1 … push not run (&&)      [the checkout is left mid-rebase: the block has no abort]
== pathspec (-- "$handoff"):
   commit rc=0 carried: [handoffs/h1.md ] still staged=1
   pull --rebase rc=128: error: cannot pull with rebase: Your index contains uncommitted changes.
   push not run (&&) ; after: ahead=2 ; origin unchanged
== guard (git diff --cached --quiet before the add):
   GUARD: index differs from HEAD in 1 path(s); refusing before the commit ; origin unchanged
  • Origin's next change on another file: the shipped block published the peer's staged reversal (h2 went back to v1, undoing the peer's P1). It also published the stranded stale-base stamp, which reverted P1's row4.
  • Origin's next change on the same file: the checkout was left mid-rebase.
  • A pathspec alone turned the publish into one more stranded commit. Only a refusal on the staged index wrote nothing.

2. The spelled path is not the checkout the lane writes.

  • The lane tools resolve the checkout.
    • lanes-edit.sh writes in $LANES_REPO, which defaults to workspace.yaml's path: only when unset (lanes-edit.sh:1029-1032).
    • lane-handoff finds the handoff under $LANES_REPO first, then lanes-edit.sh workspace-root (lane-handoff:2021-2025). It commits in that file's own top level, with -- "$hs_rel" (:2126-2130), and aborts a failed pull (:2136).
  • Lane windows now export the lane's own clone. Measured in lane opsXfactory-2's session on Eagle, 2026-10-13: LANES_REPO=/home/brett/projects/brett-wip-ops2, LANES_DIR=…/brett-wip-ops2/lanes and LANES_FILE=…/brett-wip-ops2/lanes/LANES.md. So this skill's own step-4 writes ("$L" log, append-line and set-row-state) go to the lane's clone, while its step-2 commit cds to the shared checkout.
  • The publication target is never named. Step 2's publish-handoff writes to $handoff_file (:209), which no block in the skill defines. That variable, $prepared_file and $prior_sha256 appear only on that line, so which checkout the file is published in is left to the session.
  • Measured in a second plain-git 2.43.0 sandbox (writer WI-H, 2026-10-13; the script and its output are at the end). LANES_REPO named the lane's clone, where the handoff was written, and ~/projects/brett-wip was a second clone:
    • The shared checkout carrying a peer's staged reversal (case 3). The shipped block made a commit in the shared checkout, subject handoff(<lane>@<ws>): PAUSED, …, holding 1 file: the peer's reverted h2. It pushed that commit to origin. The lane's own handoff stayed uncommitted in its own clone ( M handoffs/h1.md).
    • The shared checkout clean and current (case 3b; that is its state as read at 2026-10-13T15:07Z, 0 staged, 0 ahead and 0 behind its last fetch). The block printed "nothing to commit", "Already up to date" and "Everything up-to-date", and its last line exited 0. Origin's h1 was still v1, and the lane's handoff stayed uncommitted in its clone. Amendment 4(d)'s reason for committing at once applies: "a write left uncommitted is captured by the next lane's commit and its attribution is lost".

The ruling

Brett Heap, by multi-choice in lane opsXfactory-2's terminal, recorded on opensoft/OpsxFactory#207. Verbatim:

  • R7 (comment 6132554846, 2026-10-12T21:02:33Z): "Fail-closed first (Recommended)".
  • D4 (comment 6147284908, 2026-10-13T14:00:26Z): "Own issue, landed first (Recommended)": "the /handoff skill's bare git commit (no pathspec), which can publish other lanes' staged work, gets its own issue. It is filed with the main issue and lands first."
  • The same record names the governance: "The /handoff fix and D2's narrow guard implement existing Amendments 5(c)/(d) and 7(f), so they go as an issue and a PR."

R7's main fail-closed issue, for lanes-edit.sh, lane-start's stamps and lane-handoff, is filed alongside this one by the same lane. This one lands first.

The fix

Three changes to skills/handoff/SKILL.md alone, in step 2's commit paragraph and block (:307-317). They need neither D1 nor D2:

  1. Resolve the checkout; never spell it.

    • Use $LANES_REPO first, then "$L" workspace-root, which is lane-handoff's order. Take the first one that holds $handoff.
    • Name step 2's publication target $handoff_file as that same file, so the file published is the file committed.
  2. Commit by the handoff's own path: git -C "$hc_root" add -- "$handoff", then commit … -- "$handoff".

  3. Refuse before the git add in either of two cases:

    • the index holds a staged entry other than $handoff, read with git diff --cached --name-only;
    • a rebase, merge, cherry-pick or revert is in progress, found with rev-parse --absolute-git-dir, not --git-path (R7a measured that --git-path answers relative to the -C directory).

    A refusal prints what was not done and names the staged paths. The swap goes on (R-A11-11): the handoff file is written, and the commit is not.

As well as those three, the block now:

  • pulls and pushes origin "${LANES_BRANCH:-main}", as lane-handoff does;
  • runs git rebase --abort when the pull or push fails, and says "NOT PUSHED" with a look-first command, which is the paragraph's own :317 and Amendment 4(d)'s "the writer ABORTS, leaves the checkout clean and reports".

The proposed block, exactly as the sandbox ran it:

# THE CHECKOUT IS RESOLVED, NEVER SPELLED: `$LANES_REPO` first, then the
# helper's own `workspace-root`, the order `lane-handoff` uses. Lane windows
# export `LANES_REPO` to the lane's own clone, and step 4's writes go there.
hc_root=""; hc_why=""; hc_staged=""
for hc_base in "${LANES_REPO:-}" "$("$L" workspace-root 2>/dev/null)"; do
  if [ -n "$hc_base" ] && [ -f "$hc_base/$handoff" ]; then hc_root="$hc_base"; break; fi
done
if [ -z "$hc_root" ]; then
  hc_why="$handoff is under neither \$LANES_REPO nor the workspace root"
else
  hc_git="$(git -C "$hc_root" rev-parse --absolute-git-dir)"
  for hc_op in rebase-merge rebase-apply MERGE_HEAD CHERRY_PICK_HEAD REVERT_HEAD; do
    [ ! -e "$hc_git/$hc_op" ] || hc_why="$hc_root has an operation in progress ($hc_op)"
  done
  # A STAGED ENTRY THIS HANDOFF DID NOT MAKE, read BEFORE the add: a bare
  # commit would publish it, and with a pathspec the pull would refuse on it.
  hc_staged="$(git -C "$hc_root" diff --cached --name-only | grep -vxF -- "$handoff")"
  [ -z "$hc_staged" ] || hc_why="${hc_why:+$hc_why; }the index of $hc_root holds $(printf '%s\n' "$hc_staged" | wc -l | tr -d ' ') staged path(s) this handoff did not make"
fi
if [ -n "$hc_why" ]; then
  printf 'HANDOFF NOT COMMITTED: %s. The file is written; nothing was committed or pushed. Never commit staged entries you did not make.\n' "$hc_why"
  [ -z "$hc_staged" ] || printf '%s\n' "$hc_staged" | head -n 20 | sed 's/^/  staged: /'
elif ! { git -C "$hc_root" add -- "$handoff" &&
         git -C "$hc_root" commit -m "handoff(<lane>@<ws>): PAUSED, <one-line state>" -m "Lane: <lane>" -- "$handoff"; }; then
  printf 'HANDOFF NOT COMMITTED: git refused the add or the commit in %s (its words are above).\n' "$hc_root"
elif git -C "$hc_root" pull --rebase origin "${LANES_BRANCH:-main}" &&
     git -C "$hc_root" push origin "${LANES_BRANCH:-main}"; then
  echo "handoff pushed from $hc_root"
else
  git -C "$hc_root" rebase --abort 2>/dev/null || :
  printf 'HANDOFF NOT PUSHED: it is a local commit in %s, any rebase is aborted, and git said why above. Never force; look first:\n  git -C %s fetch origin && git -C %s cherry -v origin/%s HEAD\n' \
    "$hc_root" "$hc_root" "$hc_root" "${LANES_BRANCH:-main}"
fi

What it measured as (the same sandbox, and the block run under both bash and zsh with the same outcomes):

Case Shipped block Proposed block
1-2. Regime 2: a foreign staged entry; origin's next change on another file Published the peer's reversal; origin h2 = v1 HANDOFF NOT COMMITTED: … holds 1 staged path(s) this handoff did not make, then staged: handoffs/h2.md. HEAD and origin unchanged, and h1 still written
3-4. LANES_REPO = the lane's clone, with the shared checkout in regime 2 A commit in the shared checkout holding only the peer's reversal, pushed; the lane's handoff left uncommitted Committed and pushed from the lane's clone: origin h1 = v2 and h2 = v2 (the peer's work kept). The shared checkout was untouched: same HEAD, same staged entry
3b. LANES_REPO = the lane's clone, with the shared checkout clean Exit 0; nothing committed; origin h1 = v1 (case 4's path) committed and pushed from the lane's clone
5. Origin's next change on the same file (a real conflict) Left the checkout mid-rebase HANDOFF NOT PUSHED …; rebase aborted, mid-rebase=no, 1 ahead. In the checkout the shipped block had left mid-rebase: HANDOFF NOT COMMITTED: … operation in progress (rebase-merge)
6. This handoff already staged by an earlier attempt (not run) Committed and pushed: the handoff's own path is exempt

Diff against main (+48/-7 in skills/handoff/SKILL.md). Trial merges on a local scratch branch, never pushed:

  • clean with fix/handoff-skill-98-99-100 and fix/handoff-skill-78-79;
  • with both merged, tests/test_handoff_skill_98_99_100.py gives 16 passed, and tests/test_skill_shell_blocks.py keeps only its own 2 RED cases.
The diff
diff --git a/skills/handoff/SKILL.md b/skills/handoff/SKILL.md
index ea21bf9..2771bd7 100644
--- a/skills/handoff/SKILL.md
+++ b/skills/handoff/SKILL.md
@@ -304,17 +304,58 @@ block the stamps land in the middle of.
 in a container with no `LANES_WORKSTATION`, that step 4's register and object-log writes were therefore NOT
 made, and that the row still reads as it did — so the next session knows the register is behind its own
 handoff rather than believing the lane never paused. This commit is in the LANE'S OWN repository and is not
-one of the writes that stop. Commit with an explicit pathspec
-and the Rule 5 `Lane:` trailer, then pull-rebase and push:
+one of the writes that stop.
+
+**COMMIT IN THE CHECKOUT THE HANDOFF WAS PUBLISHED IN, BY ITS OWN PATH, AND NOTHING ELSE** (Amendment 4(d):
+*"with explicit pathspecs — never `git add -A`, never a bare `git commit`"*; Amendment 5(c) and (d)). The
+checkout is RESOLVED, never spelled: `$LANES_REPO` first, then the helper's own `workspace-root`, which is the
+order `lane-handoff` uses — a lane window exports `LANES_REPO` to the lane's own clone, and step 4's writes go
+there. Step 2's publication target `$handoff_file` is the same file (`$LANES_REPO/$handoff` where that exists,
+else the workspace root's), so the file published is the file committed. A STAGED ENTRY THIS HANDOFF DID NOT
+MAKE IS A REFUSAL, read before the `git add`: a bare commit would publish it, and with a pathspec the pull would
+refuse on it. So is a rebase, merge, cherry-pick or revert in progress. Then the Rule 5 `Lane:` trailer,
+pull-rebase and push:
 
 ```sh
-cd ~/projects/brett-wip
-git add "$handoff"
-git commit -m "handoff(<lane>@<ws>): PAUSED, <one-line state>" -m "Lane: <lane>"
-git pull --rebase && git push
+# THE CHECKOUT IS RESOLVED, NEVER SPELLED: `$LANES_REPO` first, then the
+# helper's own `workspace-root`, the order `lane-handoff` uses. Lane windows
+# export `LANES_REPO` to the lane's own clone, and step 4's writes go there.
+hc_root=""; hc_why=""; hc_staged=""
+for hc_base in "${LANES_REPO:-}" "$("$L" workspace-root 2>/dev/null)"; do
+  if [ -n "$hc_base" ] && [ -f "$hc_base/$handoff" ]; then hc_root="$hc_base"; break; fi
+done
+if [ -z "$hc_root" ]; then
+  hc_why="$handoff is under neither \$LANES_REPO nor the workspace root"
+else
+  hc_git="$(git -C "$hc_root" rev-parse --absolute-git-dir)"
+  for hc_op in rebase-merge rebase-apply MERGE_HEAD CHERRY_PICK_HEAD REVERT_HEAD; do
+    [ ! -e "$hc_git/$hc_op" ] || hc_why="$hc_root has an operation in progress ($hc_op)"
+  done
+  # A STAGED ENTRY THIS HANDOFF DID NOT MAKE, read BEFORE the add: a bare
+  # commit would publish it, and with a pathspec the pull would refuse on it.
+  hc_staged="$(git -C "$hc_root" diff --cached --name-only | grep -vxF -- "$handoff")"
+  [ -z "$hc_staged" ] || hc_why="${hc_why:+$hc_why; }the index of $hc_root holds $(printf '%s\n' "$hc_staged" | wc -l | tr -d ' ') staged path(s) this handoff did not make"
+fi
+if [ -n "$hc_why" ]; then
+  printf 'HANDOFF NOT COMMITTED: %s. The file is written; nothing was committed or pushed. Never commit staged entries you did not make.\n' "$hc_why"
+  [ -z "$hc_staged" ] || printf '%s\n' "$hc_staged" | head -n 20 | sed 's/^/  staged: /'
+elif ! { git -C "$hc_root" add -- "$handoff" &&
+         git -C "$hc_root" commit -m "handoff(<lane>@<ws>): PAUSED, <one-line state>" -m "Lane: <lane>" -- "$handoff"; }; then
+  printf 'HANDOFF NOT COMMITTED: git refused the add or the commit in %s (its words are above).\n' "$hc_root"
+elif git -C "$hc_root" pull --rebase origin "${LANES_BRANCH:-main}" &&
+     git -C "$hc_root" push origin "${LANES_BRANCH:-main}"; then
+  echo "handoff pushed from $hc_root"
+else
+  git -C "$hc_root" rebase --abort 2>/dev/null || :
+  printf 'HANDOFF NOT PUSHED: it is a local commit in %s, any rebase is aborted, and git said why above. Never force; look first:\n  git -C %s fetch origin && git -C %s cherry -v origin/%s HEAD\n' \
+    "$hc_root" "$hc_root" "$hc_root" "${LANES_BRANCH:-main}"
+fi
 ```
 
-On a rebase conflict: abort, leave the tree clean, report it, and never force.
+A refusal, a conflict or a rejected push does not stop the swap (`R-A11-11`, *a swap is never left
+unwritten*): the handoff file is written, the block prints what it did NOT do, and the report carries that
+line. On a rebase conflict the block aborts and leaves the tree clean. Never force, and never commit staged
+entries you did not make.
 
 ## 3. Subagents and worktrees — the one question, and the sweep that fills WRITERS
 

Not in this issue (R7's main issue, by D1 and D2)

The rulings scope these to R7's main fail-closed issue, filed alongside this one:

Tests

Home: a new pytest module, tests/test_handoff_skill_commit_block.py, run by tests/run.sh -k handoff_skill_commit_block (seconds). CI's tests job is the suite of record (AGENTS.md:246-254).

  • Pattern: that of tests/test_handoff_skill_98_99_100.py on fix/handoff-skill-98-99-100:
    • the fenced block is extracted by a marker it alone carries (for example hc_root=""; hc_why="");
    • it runs under bash against a stub lanes-edit.sh on PATH that answers workspace-root;
    • the environment is an explicit dict, and every path is under tmp_path.
  • Real git: a bare origin and two clones (the "shared" one at $HOME/projects/brett-wip, and the lane's own), with maintenance.auto=false and gc.auto=0 in the fixture config.
  • No inherited LANES_* variable, ever. This block READS LANES_REPO, and a lane window's value points at that lane's real clone. The shell suite's unset lists also miss LANES_DIR, LANES_NO_GIT and LANES_NO_FETCH (R7b F8, tests/test_lane_helpers.sh:127 and tests/test_lane_helpers_suite.py:168). The main issue fixes those lists.

RED cases. Each fails against main's block and passes with the fix:

  1. A foreign staged entry (regime 2), with origin's next change on another file.
    • Expected: no commit, HEAD and origin unchanged, the staged path named, and the handoff file still written.
    • On main: origin's peer file is reverted.
  2. LANES_REPO = the lane's clone, holding the edited handoff, with $HOME/projects/brett-wip holding a foreign staged entry.
    • Expected: commit and push from the lane's clone, and the other clone unchanged.
    • On main: a commit of only the foreign entry is pushed, and the lane's handoff is left uncommitted.
  3. LANES_REPO = the lane's clone, with the other clone clean.
    • Expected: the handoff is pushed.
    • On main: exit 0, and origin's handoff unchanged.
  4. A same-file conflict.
    • Expected: no rebase directory afterwards, 1 commit ahead, and "NOT PUSHED" printed.
    • On main: left mid-rebase.
  5. A checkout mid-rebase.
    • Expected: a refusal naming the operation, and no commit.
  6. Static checks:
    • the skill text no longer contains ~/projects/brett-wip;
    • the commit line carries -- "$handoff";
    • the block parses under bash -n (fix/handoff-skill-78-79's checker covers this once it lands).

Keepers:

  • clean and current: pushed;
  • the handoff already staged: pushed;
  • the shell suite's assertions on the skill text, which do not pin this block (tests/test_lane_helpers.sh:5452-5582 and :10206-10231, and tests/test_repo_hygiene.py:363).

Governance

An issue and a PR. No OpenSpec change and no amendment.

Coordination

The sandbox script (plain git 2.43.0, a hermetic HOME, a stub lanes-edit.sh; it reads shipped-block.txt, which is lines 310-315 of the skill at f87fd5a, and proposed-block.sh, which is the block above)
#!/usr/bin/env bash
# WI-H sandbox: the /handoff skill's commit block, shipped vs proposed.
# Plain git, hermetic HOME, local bare origin. Nothing outside $SB is touched.
set -u
SIM="$(cd "$(dirname "$0")" && pwd)"
SB="$SIM/sb"
[ ! -e "$SB" ] || { echo "sandbox $SB exists; remove it first" >&2; exit 1; }
mkdir -p "$SB/home/projects" "$SB/bin"
export HOME="$SB/home" GIT_CONFIG_NOSYSTEM=1 LC_ALL=C TZ=UTC
unset LANES_REPO LANES_DIR LANES_FILE LANES_BRANCH LANES_WORKSPACE_ROOT GIT_DIR GIT_WORK_TREE
cat > "$HOME/.gitconfig" <<'EOF'
[user]
	name = sim
	email = sim@example.invalid
[init]
	defaultBranch = main
[maintenance]
	auto = false
[gc]
	auto = 0
[advice]
	detachedHead = false
EOF
# The stub helper: only `workspace-root` is read by the block.
cat > "$SB/bin/lanes-edit.sh" <<'EOF'
#!/usr/bin/env bash
case "$1" in workspace-root) printf '%s\n' "$HOME/projects/brett-wip" ;; *) exit 2 ;; esac
EOF
chmod +x "$SB/bin/lanes-edit.sh"
L="$SB/bin/lanes-edit.sh"
handoff=handoffs/h1.md          # this lane's handoff (the row's cell; repo-relative)
SHIPPED="$(sed -n '2,5p' "$SIM/shipped-block.txt")"
PROPOSED="$(cat "$SIM/proposed-block.sh")"

q() { git -C "$1" "${@:2}" 2>&1; }
new_origin() {      # $1 = name; seed: h1 (this lane), h2 (a peer's), LANES.md rows
  local o="$SB/$1.git" s="$SB/$1-seed"
  git init -q --bare "$o"; git init -q "$s"
  mkdir -p "$s/handoffs" "$s/lanes"
  printf 'h1 v1\n' > "$s/handoffs/h1.md"; printf 'h2 v1\n' > "$s/handoffs/h2.md"
  printf '| row1 | a |\n| row2 | a |\n| row3 | a |\n| row4 | a |\n' > "$s/lanes/LANES.md"
  q "$s" add -A >/dev/null; q "$s" commit -q -m seed >/dev/null
  q "$s" remote add origin "$o"; q "$s" push -q origin main >/dev/null
}
peer_commit() {     # $1 origin name, $2 file, $3 content, $4 msg
  local p="$SB/$1-peer"; [ -d "$p" ] || git clone -q "$SB/$1.git" "$p"
  q "$p" pull -q --rebase origin main >/dev/null; printf '%s\n' "$3" > "$p/$2"
  q "$p" commit -q -m "$4" -- "$2" >/dev/null; q "$p" push -q origin main >/dev/null
}
origin_file() { git --git-dir="$SB/$1.git" show "main:$2" 2>&1; }
origin_log() { git --git-dir="$SB/$1.git" log --format=%s main | tr '\n' '|'; }
state() {           # $1 checkout
  local g; g="$(git -C "$1" rev-parse --absolute-git-dir)"
  q "$1" fetch -q origin >/dev/null
  printf '   %s: staged=%s unstaged=%s ahead=%s behind=%s mid-rebase=%s\n' "$1" \
    "$(git -C "$1" diff --cached --name-only | tr '\n' ' ')" "$(git -C "$1" diff --name-only | tr '\n' ' ')" \
    "$(git -C "$1" rev-list --count origin/main..HEAD)" "$(git -C "$1" rev-list --count HEAD..origin/main)" \
    "$( { [ -e "$g/rebase-merge" ] || [ -e "$g/rebase-apply" ]; } && echo yes || echo no)"
}
regime2() {         # $1 origin name, $2 checkout: a peer's v2 of h2 lands on origin, then
                    # main moves to it WITHOUT the index (a linked worktree's checkout -B):
                    # the index still holds h2 v1, i.e. a STAGED reversal of the peer's work
  peer_commit "$1" handoffs/h2.md 'h2 v2 (peer P1)' 'P1: peer handoff v2'
  q "$2" fetch -q origin >/dev/null
  q "$2" update-ref refs/heads/main origin/main >/dev/null
}
run_block() {       # $1 label, $2 block text; cwd is $HOME
  echo "-- $1"; ( cd "$HOME" && L="$L" handoff="$handoff" bash -c "$2" ) 2>&1 | sed 's/^/   | /'
}

echo "== bash -n: shipped block"; bash -n <(printf '%s\n' "$SHIPPED") && echo "   parses"
echo "== bash -n: proposed block"; bash -n "$SIM/proposed-block.sh" && echo "   parses"

echo; echo "== CASE 1. Regime 2 in the checkout the literal path names, origin's next change on ANOTHER file"
new_origin c1; W="$HOME/projects/brett-wip"; git clone -q "$SB/c1.git" "$W"
regime2 c1 "$W"; peer_commit c1 lanes/LANES.md "$(printf '| row1 | a |\n| row2 | a |\n| row3 | a |\n| row4 | P2 |')" 'P2: peer row4'
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"
state "$W"
run_block "SHIPPED block" "$SHIPPED"
state "$W"
echo "   origin log: $(origin_log c1)"; echo "   origin h2: $(origin_file c1 handoffs/h2.md)   (the peer's P1 said: h2 v2 (peer P1))"

echo; echo "== CASE 2. The same checkout state, PROPOSED block"
rm -rf "$W"; new_origin c2; git clone -q "$SB/c2.git" "$W"
regime2 c2 "$W"; peer_commit c2 lanes/LANES.md "$(printf '| row1 | a |\n| row2 | a |\n| row3 | a |\n| row4 | P2 |')" 'P2: peer row4'
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"
h_before="$(git -C "$W" rev-parse HEAD)"; o_before="$(git --git-dir="$SB/c2.git" rev-parse main)"
state "$W"
run_block "PROPOSED block" "$PROPOSED"
state "$W"
echo "   HEAD unchanged: $([ "$(git -C "$W" rev-parse HEAD)" = "$h_before" ] && echo yes || echo NO)   origin unchanged: $([ "$(git --git-dir="$SB/c2.git" rev-parse main)" = "$o_before" ] && echo yes || echo NO)   h1 still written: $(cat "$W/$handoff")"

echo; echo "== CASE 3. LANES_REPO names the lane's own clone, where the handoff was written; the literal path is the shared checkout"
rm -rf "$W"; new_origin c3; git clone -q "$SB/c3.git" "$W"; P="$HOME/projects/brett-wip-own"; git clone -q "$SB/c3.git" "$P"
regime2 c3 "$W"; q "$P" pull -q --rebase origin main >/dev/null
printf 'h1 v2 (this lane PAUSED)\n' > "$P/$handoff"
w_before="$(git -C "$W" rev-parse HEAD)"
state "$W"; state "$P"
echo "-- SHIPPED block (LANES_REPO=$P)"; ( cd "$HOME" && LANES_REPO="$P" L="$L" handoff="$handoff" bash -c "$SHIPPED" ) 2>&1 | sed 's/^/   | /'
state "$W"; state "$P"
echo "   own clone's handoff: $(git -C "$P" status --short -- "$handoff")  (uncommitted where it was written)"
echo "   origin log: $(origin_log c3)"; echo "   origin h2: $(origin_file c3 handoffs/h2.md)"

echo; echo "== CASE 3b. As 3, but the shared checkout CLEAN and current (its state as read at 2026-10-13T15:07Z)"
rm -rf "$W" "$P"; new_origin c3b; git clone -q "$SB/c3b.git" "$W"; git clone -q "$SB/c3b.git" "$P"
peer_commit c3b handoffs/h2.md 'h2 v2 (peer P1)' 'P1: peer handoff v2'
q "$W" pull -q --rebase origin main >/dev/null; q "$P" pull -q --rebase origin main >/dev/null
printf 'h1 v2 (this lane PAUSED)\n' > "$P/$handoff"
state "$W"; state "$P"
echo "-- SHIPPED block (LANES_REPO=$P)"; ( cd "$HOME" && LANES_REPO="$P" L="$L" handoff="$handoff" bash -c "$SHIPPED"; echo "   (exit of the block's last line: $?)" ) 2>&1 | sed 's/^/   | /'
state "$P"
echo "   own clone's handoff: $(git -C "$P" status --short -- "$handoff")   origin h1: $(origin_file c3b handoffs/h1.md)"

echo; echo "== CASE 4. The same layout from scratch, PROPOSED block (LANES_REPO=own clone)"
rm -rf "$W" "$P"; new_origin c4; git clone -q "$SB/c4.git" "$W"; git clone -q "$SB/c4.git" "$P"
regime2 c4 "$W"; q "$P" pull -q --rebase origin main >/dev/null
printf 'h1 v2 (this lane PAUSED)\n' > "$P/$handoff"
w_head="$(git -C "$W" rev-parse HEAD)"; w_idx="$(git -C "$W" diff --cached --name-only | tr '\n' ' ')"
echo "-- PROPOSED block (LANES_REPO=$P)"; ( cd "$HOME" && LANES_REPO="$P" L="$L" handoff="$handoff" bash -c "$PROPOSED" ) 2>&1 | sed 's/^/   | /'
state "$P"
echo "   origin log: $(origin_log c4)"; echo "   origin h1: $(origin_file c4 handoffs/h1.md)   origin h2: $(origin_file c4 handoffs/h2.md)"
echo "   shared checkout untouched: HEAD $([ "$(git -C "$W" rev-parse HEAD)" = "$w_head" ] && echo same || echo MOVED), staged still [$(git -C "$W" diff --cached --name-only | tr '\n' ' ')] (was [$w_idx])"

echo; echo "== CASE 5. Clean checkout, origin's next change on the SAME file (a real conflict)"
rm -rf "$W"; new_origin c5; git clone -q "$SB/c5.git" "$W"
peer_commit c5 handoffs/h1.md 'h1 v2 (someone else)' 'P3: conflicting h1'
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"
run_block "SHIPPED block" "$SHIPPED"
state "$W"
echo "   (the shipped block leaves that checkout mid-rebase; the PROPOSED block run next in the SAME checkout:)"
printf 'h1 v3 (this lane, again)\n' > "$W/$handoff" 2>/dev/null
run_block "PROPOSED block, in the checkout the shipped one left" "$PROPOSED"
rm -rf "$W"; new_origin c5b; git clone -q "$SB/c5b.git" "$W"
peer_commit c5b handoffs/h1.md 'h1 v2 (someone else)' 'P3: conflicting h1'
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"
run_block "PROPOSED block, fresh checkout, same conflict" "$PROPOSED"
state "$W"

echo; echo "== CASE 6. Own handoff already staged by an earlier attempt (it is exempt)"
rm -rf "$W"; new_origin c6; git clone -q "$SB/c6.git" "$W"
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"; q "$W" add -- "$handoff" >/dev/null
state "$W"
run_block "PROPOSED block" "$PROPOSED"
state "$W"; echo "   origin h1: $(origin_file c6 handoffs/h1.md)"

echo; echo "== CASE 7. Clean, 1 ahead (a stranded stale-base commit that reverts a peer's row), 1 behind: NOT this issue's (D1)"
rm -rf "$W"; new_origin c7; git clone -q "$SB/c7.git" "$W"
peer_commit c7 lanes/LANES.md "$(printf '| row1 | a |\n| row2 | a |\n| row3 | a |\n| row4 | P4 |')" 'P4: peer row4'
q "$W" fetch -q origin >/dev/null
# main moves to P4 WITHOUT the index or the file (regime 2's move), and a stamp is then
# committed BY PATHSPEC on the stale file: row2 stamped, row4 still 'a', so its diff
# against its new parent reverts P4's row4. The checkout is then clean and 1 ahead.
q "$W" update-ref refs/heads/main origin/main >/dev/null
printf '| row1 | a |\n| row2 | STAMP |\n| row3 | a |\n| row4 | a |\n' > "$W/lanes/LANES.md"; q "$W" commit -q -m 'LANES(stamp) on stale tree' -- lanes/LANES.md >/dev/null
echo "   the stranded commit's own diff: $(git -C "$W" show --format= -U0 HEAD -- lanes/LANES.md | grep -E '^[-+]\|' | tr '\n' ' ')"
peer_commit c7 handoffs/h2.md 'h2 v2 (peer P5)' 'P5: peer h2'
printf 'h1 v2 (this lane PAUSED)\n' > "$W/$handoff"
state "$W"
run_block "PROPOSED block" "$PROPOSED"
state "$W"
echo "   origin log: $(origin_log c7)"; echo "   origin LANES.md row4: $(origin_file c7 lanes/LANES.md | grep row4)"
echo; echo "== done"
Its output (sandbox path shortened to <SB>; git's rebase hints dropped)
== bash -n: shipped block
   parses
== bash -n: proposed block
   parses

== CASE 1. Regime 2 in the checkout the literal path names, origin's next change on ANOTHER file
   <SB>/home/projects/brett-wip: staged=handoffs/h2.md  unstaged=handoffs/h1.md  ahead=0 behind=1 mid-rebase=no
-- SHIPPED block
   | [main aff6649] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  2 files changed, 2 insertions(+), 2 deletions(-)
   | Rebasing (1/1)Successfully rebased and updated refs/heads/main.
   | To <SB>/c1.git
   |    99178af..f861811  main -> main
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   origin log: handoff(<lane>@<ws>): PAUSED, <one-line state>|P2: peer row4|P1: peer handoff v2|seed|
   origin h2: h2 v1   (the peer's P1 said: h2 v2 (peer P1))

== CASE 2. The same checkout state, PROPOSED block
   <SB>/home/projects/brett-wip: staged=handoffs/h2.md  unstaged=handoffs/h1.md  ahead=0 behind=1 mid-rebase=no
-- PROPOSED block
   | HANDOFF NOT COMMITTED: the index of <SB>/home/projects/brett-wip holds 1 staged path(s) this handoff did not make. The file is written; nothing was committed or pushed. Never commit staged entries you did not make.
   |   staged: handoffs/h2.md
   <SB>/home/projects/brett-wip: staged=handoffs/h2.md  unstaged=handoffs/h1.md  ahead=0 behind=1 mid-rebase=no
   HEAD unchanged: yes   origin unchanged: yes   h1 still written: h1 v2 (this lane PAUSED)

== CASE 3. LANES_REPO names the lane's own clone, where the handoff was written; the literal path is the shared checkout
   <SB>/home/projects/brett-wip: staged=handoffs/h2.md  unstaged= ahead=0 behind=0 mid-rebase=no
   <SB>/home/projects/brett-wip-own: staged= unstaged=handoffs/h1.md  ahead=0 behind=0 mid-rebase=no
-- SHIPPED block (LANES_REPO=<SB>/home/projects/brett-wip-own)
   | [main 4bc83b8] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | Current branch main is up to date.
   | To <SB>/c3.git
   |    3220242..4bc83b8  main -> main
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   <SB>/home/projects/brett-wip-own: staged= unstaged=handoffs/h1.md  ahead=0 behind=1 mid-rebase=no
   own clone's handoff:  M handoffs/h1.md  (uncommitted where it was written)
   origin log: handoff(<lane>@<ws>): PAUSED, <one-line state>|P1: peer handoff v2|seed|
   origin h2: h2 v1

== CASE 3b. As 3, but the shared checkout CLEAN and current (its state as read at 2026-10-13T15:07Z)
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   <SB>/home/projects/brett-wip-own: staged= unstaged=handoffs/h1.md  ahead=0 behind=0 mid-rebase=no
-- SHIPPED block (LANES_REPO=<SB>/home/projects/brett-wip-own)
   | On branch main
   | Your branch is up to date with 'origin/main'.
   | 
   | nothing to commit, working tree clean
   | Already up to date.
   | Everything up-to-date
   |    (exit of the block's last line: 0)
   <SB>/home/projects/brett-wip-own: staged= unstaged=handoffs/h1.md  ahead=0 behind=0 mid-rebase=no
   own clone's handoff:  M handoffs/h1.md   origin h1: h1 v1

== CASE 4. The same layout from scratch, PROPOSED block (LANES_REPO=own clone)
-- PROPOSED block (LANES_REPO=<SB>/home/projects/brett-wip-own)
   | [main 8486460] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | From <SB>/c4
   |  * branch            main       -> FETCH_HEAD
   | Current branch main is up to date.
   | To <SB>/c4.git
   |    54512d1..8486460  main -> main
   | handoff pushed from <SB>/home/projects/brett-wip-own
   <SB>/home/projects/brett-wip-own: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   origin log: handoff(<lane>@<ws>): PAUSED, <one-line state>|P1: peer handoff v2|seed|
   origin h1: h1 v2 (this lane PAUSED)   origin h2: h2 v2 (peer P1)
   shared checkout untouched: HEAD same, staged still [handoffs/h2.md ] (was [handoffs/h2.md ])

== CASE 5. Clean checkout, origin's next change on the SAME file (a real conflict)
-- SHIPPED block
   | [main 4587a83] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | From <SB>/c5
   |    ece2976..c93540c  main       -> origin/main
   | Rebasing (1/1)Auto-merging handoffs/h1.md
   | CONFLICT (content): Merge conflict in handoffs/h1.md
   | error: could not apply 4587a83... handoff(<lane>@<ws>): PAUSED, <one-line state>
   | Could not apply 4587a83... handoff(<lane>@<ws>): PAUSED, <one-line state>
   <SB>/home/projects/brett-wip: staged=handoffs/h1.md  unstaged=handoffs/h1.md handoffs/h1.md  ahead=0 behind=0 mid-rebase=yes
   (the shipped block leaves that checkout mid-rebase; the PROPOSED block run next in the SAME checkout:)
-- PROPOSED block, in the checkout the shipped one left
   | HANDOFF NOT COMMITTED: <SB>/home/projects/brett-wip has an operation in progress (rebase-merge). The file is written; nothing was committed or pushed. Never commit staged entries you did not make.
-- PROPOSED block, fresh checkout, same conflict
   | [main 1a6c66f] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | From <SB>/c5b
   |  * branch            main       -> FETCH_HEAD
   |    ece2976..02a9055  main       -> origin/main
   | Rebasing (1/1)Auto-merging handoffs/h1.md
   | CONFLICT (content): Merge conflict in handoffs/h1.md
   | error: could not apply 1a6c66f... handoff(<lane>@<ws>): PAUSED, <one-line state>
   | Could not apply 1a6c66f... handoff(<lane>@<ws>): PAUSED, <one-line state>
   | HANDOFF NOT PUSHED: it is a local commit in <SB>/home/projects/brett-wip, any rebase is aborted, and git said why above. Never force; look first:
   |   git -C <SB>/home/projects/brett-wip fetch origin && git -C <SB>/home/projects/brett-wip cherry -v origin/main HEAD
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=1 behind=1 mid-rebase=no

== CASE 6. Own handoff already staged by an earlier attempt (it is exempt)
   <SB>/home/projects/brett-wip: staged=handoffs/h1.md  unstaged= ahead=0 behind=0 mid-rebase=no
-- PROPOSED block
   | [main 8eecb92] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | From <SB>/c6
   |  * branch            main       -> FETCH_HEAD
   | Current branch main is up to date.
   | To <SB>/c6.git
   |    2f71a71..8eecb92  main -> main
   | handoff pushed from <SB>/home/projects/brett-wip
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   origin h1: h1 v2 (this lane PAUSED)

== CASE 7. Clean, 1 ahead (a stranded stale-base commit that reverts a peer's row), 1 behind: NOT this issue's (D1)
   the stranded commit's own diff: -| row2 | a | +| row2 | STAMP | -| row4 | P4 | +| row4 | a | 
   <SB>/home/projects/brett-wip: staged= unstaged=handoffs/h1.md  ahead=1 behind=1 mid-rebase=no
-- PROPOSED block
   | [main 0bdabd9] handoff(<lane>@<ws>): PAUSED, <one-line state>
   |  1 file changed, 1 insertion(+), 1 deletion(-)
   | From <SB>/c7
   |  * branch            main       -> FETCH_HEAD
   | Rebasing (1/2)Rebasing (2/2)Successfully rebased and updated refs/heads/main.
   | To <SB>/c7.git
   |    103e921..ea38b81  main -> main
   | handoff pushed from <SB>/home/projects/brett-wip
   <SB>/home/projects/brett-wip: staged= unstaged= ahead=0 behind=0 mid-rebase=no
   origin log: handoff(<lane>@<ws>): PAUSED, <one-line state>|LANES(stamp) on stale tree|P5: peer h2|P4: peer row4|seed|
   origin LANES.md row4: | row4 | a |

== done

Lane: opsXfactory-2

Activity

  1. brettheap commented on Oct 13, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane opsXfactory-2, session 855b0f1e-41e2-4241-83a7-48d38d70d4b5@Eagle, 2026-10-13T15:22:52Z, for #197

    Logged in lanes/log/opsXfactory-2.md at 8bf6aed07fa10a640b59a6c1d650b10740dd7cec.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoTools#197:
       none
    2. `gh pr list --repo opensoft/openRepoTools --state all --search "#197"`, kept where the row or its body names `#197`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoTools` branches naming `197` as a whole token:
       none
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions