Skip to content

Lane writers commit first and sync second, so a pull that refuses or conflicts strands the commit and later writes stack on it: fast-forward before the edit, and refuse before committing (fail closed) #198

Open

Description

@brettheap

What happens

lanes-edit.sh, lane-start's stamps and lane-handoff all commit first and sync second. When git pull --rebase cannot finish, the commit stays local, the tool prints a note, and the launch or handoff goes on. The next write from that checkout commits on top of the first and fails the same way. The record is measured in two kinds of checkout.

1. The shared workspace checkout (~/projects/brett-wip = /workspace/projects/brett-wip, on Eagle).

  • The count. It stranded 29 commits by 2026-10-12T18:07Z and 39 by 20:42Z:
    • 10 lane-start handoff stamps, 13 set-row-state rows, 3 append-line register lines and 3 lane-handoff PAUSED commits (the 29);
    • then 10 more lane-start commits at 19:37-19:45Z, a row stamp and a handoff stamp for each of 5 launches.
  • Two regimes (DIAGNOSIS-C §2):
    1. A sticky real conflict (2026-10-11 17:06-20:04Z). One local append was never pushed. Its lane re-recorded the same line elsewhere, at the same end of the file. Every later pull replayed that append first, conflicted and aborted: 64 pull starts, 66 aborts, and 74 commits stacked behind it. The first stranded commit was an object-log write, LOG(openRepoProject-5@Eagle): RESUMED.
    2. The pull refuses before it starts (since 2026-10-11 20:07Z). A checkout -B main from a linked worktree moved the branch and left the index at the old tree; the actor is NOT ESTABLISHED. That left 1005 staged entries, and git pull --rebase now exits 128 ("Your index contains uncommitted changes") before it fetches. 0 pull starts followed, against 29 commits.

2. A lane's private clone (2026-10-13T13:12Z). The lane windows started then carried LANES_REPO, LANES_DIR and LANES_FILE pointing at each lane's own clone. Which component exported them is NOT ESTABLISHED; claude-profile names none of them. Measured, read-only, in ~/projects/brett-wip-ops2: before the first write the clone was clean, 0 ahead and 10 behind af4093cf2, the origin/main its pulls fetched. Its HEAD reflog:

13:12:03 commit  LANES(opsXfactory-2@Eagle): state · LIVE · RESUMED …   (lane-start:3721 → set-row-state)
13:12:06 pull --rebase -q origin main (start) … 13:12:06 rebase (abort)
13:12:18 commit  LOG(opsXfactory-2@Eagle): RESUMED lane:opsXfactory-2   (lane-start:3900 → log → write_event)
13:12:21 pull --rebase -q origin main (start) … 13:12:21 rebase (abort)
13:12:30 commit  handoff(opsXfactory-2@Eagle): RESUMED by …            (lane-start:4136)
13:12:32 pull --rebase -q origin main (start) … 13:12:32 rebase (abort)
  • Why the first write conflicted. The row was edited on the clone's 10-commit-old lanes/LANES.md: hunk @@ -125 +125 @@, the opsXfactory-2 row. Origin's 26a6fdb31 (12:46:58Z, an ancestor of af4093cf2 and not of the clone's HEAD) had changed the adjacent opsXfactory-1 row, @@ -124 +124 @@. Git merges edits to adjacent lines as one hunk, so the replay conflicted.
  • Why the next two stranded. Each later write replayed that commit first and failed the same way: regime 1, in a clone no other lane writes.
  • The cost. The lane carried all three by hand.

So a per-lane clone does not stop this on its own: the clean-but-behind shape strands the first write, and the commit-first order stacks the rest. #165's comment of 2026-10-09T01:25Z saw both halves in a checkout shared by lanes openXwallet-1/2/3: "A failed write stays committed locally, so the next write stacks on it and conflicts too", and, as an interim mitigation, "lanes-edit.sh re-levelling to origin and retrying an identical write on conflict instead of leaving it stacked".

The diagnosis is on opensoft/brett-wip main (private), under handoffs/xFactory/attachments/lane-opsXfactory-2/followon/followups/brettwip-shared/:

  • DIAGNOSIS-A.md at e22d919fb: the stranded and reflog-only commits, by carry status.
  • DIAGNOSIS-B.md at e3b4f06cf: the 1005-entry staged index and the 632 untracked files.
  • DIAGNOSIS-C.md at 9f90eb236: the root cause in these tools, and options A to F. Read §1-§4.
  • DIAGNOSIS-D.md at 03b780af2: what changed after A and B.
  • PLAN.md at 3cd44dcf9: the repair of the shared checkout. It is out of scope here.
  • R7/REVIEW-R7b.md at 00848c7a6: the review this text was revised from, with the sandbox runs.

Why the guard misses regime 2.

  • dirty_elsewhere (lanes-edit.sh:1747-1750) reads git diff --name-only, which is unstaged changes only. Its premise (:1743-1744) is that git pull --rebase "refuses outright on ANY unstaged tracked change"; git refuses on staged changes too.
  • The right set exists already. tracked_dirty (:1758-1762) reads both, and refuse_dirty_checkout (:1782-1804) uses it. Its callers are write_event (log, claim and release, at :5317 and :5361), migrate-state-cells (:10679), retire-rows (:11462), archive-rows (:11759), rename-lane (:14287) and claim (:14663).
  • Six write verbs call no guard at all: set-row-state (:13405), replace-in-row (:13450), append-session-id (:13513), append-line (:13540), add-row (:13587) and commit (:13675).
  • No writer syncs before it edits, and none refuses when its checkout already holds unpublished commits. That is regime 1, and the 13:12Z clone. The only pulls are after the commit: lanes-edit.sh:2092, lane-start:4144 and lane-handoff:2132.

The notes are false in regime 2.

  • lanes-edit.sh:2111 prints "REBASE CONFLICT" where there is no conflict, and :2118 says "the worktree is clean".
  • lane-start:4149 says "the checkout is clean" with 1005 staged entries. lane-start:3981 promises that the next write carries the stamp, which no write does in regime 2.
  • lane-handoff:2129-2133 sends git's own words to /dev/null.
  • refuse_dirty_checkout's RECOVERY (:1800-1802) tells the reader to commit the dirty files. For staged entries the reader did not make, that commits a reversal.

The stale-base hazard (DIAGNOSIS-C §3.1, §3.3). In the shared checkout the edits are spliced into a working tree about 25 hours old, so a lane's first stamp there carries "+1" against a large reversal: eb443b3ab is +1/-751 on one handoff. Lane opsXfactory-4 found that a literal cherry-pick of 999529829 "would have deleted 108 lines of the current handoff" (OpsxFactory #207, comment 6127259900). A commit that brings the index back to HEAD lets the next pull start, and the pull then pushes every stranded commit that applies cleanly. The carry design (#32/#50) is exactly that path. The companion issue #197 measured the /handoff skill's bare commit doing it in a sandbox.

The rulings

Brett Heap, by multi-choice in lane opsXfactory-2's terminal, recorded on opensoft/OpsxFactory#207. Each ruling is the recommended option, verbatim from the record.

R7 (2026-10-12T21:0xZ, comment 6132554846):

R7 "Fail-closed first (Recommended)": first, a staged-aware guard makes lanes-edit.sh, the lane-start stamp and lane-handoff refuse before committing into a checkout whose pull will refuse. Next, the launcher's per-lane clone, which needs a ratified amendment. Later, writes against origin directly.

  • The tools' source is opensoft/openRepoTools. This lane opens the governing issue there after a sibling search, and claims it; nothing is changed in ~/.local/bin directly.

D1-D4 (2026-10-13T14:0xZ, comment 6147284908):

This issue: option A, with its fast-forward

This issue governs R7's first step. The two ruled next steps are separate work:

Option A does not repair the shared checkout (PLAN.md, rulings R1-R6 and R8). It stops new strandings: a write that cannot be published is a loud "NOT written" with exit 2, not a stranded commit.

A0. Fast-forward to origin before the edit (D3)

Once the guard's first call passes (A1), if HEAD is behind origin/main after its bounded fetch, the writer runs git -C R merge --ff-only origin/main before it reads or edits the target file. A fast-forward that fails is a refusal under A1's rules.

  • Why it is safe there. It runs only after G1-G4 pass: nothing in progress, no staged change, nothing unpublished by content, and (D2) no unstaged foreign change while behind. So the merge is a pure fast-forward, and merge --ff-only refuses rather than overwrite a dirty file.
  • What it stops. The 13:12Z shape. After A0 the row is edited on the current lanes/LANES.md, so the replay has nothing to conflict with. It also puts lane-start's handoff stamp, and the first prompt read after it (lane-start:4210-4231), on the current handoff.
  • It runs under the writer's lock. A0 moves HEAD and the working tree. replace_line (lanes-edit.sh:1557) copies the register to a temporary file, edits the copy and writes the copy back, so a fast-forward that lands between the copy and the write would be undone by the write. INFERRED from the code, not run. So:
    • in lanes-edit.sh, A0 runs after acquire_lock;
    • lane-start's stamp and lane-handoff take no lock for their own commits (Amendment 8(d): "The handoff stamp's commit takes no mutex, and that is load-bearing"). They get A0 from the guard verb A1 exposes, which takes the lock for the merge alone.
  • A register edit waiting to be captured. Where lanes/LANES.md carries a pre-existing uncommitted edit that the capture will commit (capture_register_edit, handle_preexisting; Addendum 3, R11), a fast-forward first would refuse whenever origin also changed the register, which is nearly always. A fast-forward after the capture is impossible, because the capture commit is local. So in that case A0 is skipped and the write goes on as today; G4 then caps what it can strand at this one write.
  • A failed fetch. With no fresh origin/main, A0 cannot run. A checkout with unstaged foreign changes then refuses (G3, D2). A tracked-clean checkout writes as today and says that the fetch failed: its own pull decides, and G4 refuses every later write if that pull stranded it. No ruling asks for more, and GOVERNANCE-DRAFT.md records this reading for Brett's word. With LANES_NO_FETCH=1, A0 fast-forwards to origin/main as it stands and says so, as log_sync does (lanes-edit.sh:5423).
  • The sweeps are unchanged. migrate-state-cells, retire-rows and archive-rows already refuse a checkout that is behind after log_sync ("Pull first … Nothing was written.", :10676, :11459, :11745). They refuse before A0 could run, and that stays.

A1. One guard, in refuse_dirty_checkout, used by every writer

Extend refuse_dirty_checkout (lanes-edit.sh:1782-1804) rather than add a second guard beside it. It already holds G2 and the unstaged half, and every writer that is guarded today calls it. Expose it as a verb as well, so lane-start, lane-handoff and the skill call the same code, as they already call the shared resolver: read-only for G1-G4, and taking the lock only when asked to run A0. It takes a checkout and the pathspecs this write may leave dirty. It checks, in this order:

Check Command (git 2.43.0) Verdict, as ruled
G1 an operation in progress, or unmerged entries [ -e "$(git -C R rev-parse --absolute-git-dir)/<x>" ] for rebase-merge, rebase-apply, MERGE_HEAD, CHERRY_PICK_HEAD and REVERT_HEAD; git -C R ls-files -u non-empty. Not rev-parse --git-path, which answers relative to R refuse, every writer
G2 a staged change anywhere in the index, other than this write's own pathspecs, read before this write's git add git -C R diff --cached --name-only (already in tracked_dirty) refuse, every writer (R7's core; regime 2)
G3 unstaged changes to other tracked files git -C R diff --name-only (already in tracked_dirty) log, claim, release, the sweeps and rename-lane: always refuse, as today; Amendment 7(f) requires it. The six verbs, D2 "Narrow": refuse only if HEAD is behind origin/main after the bounded fetch, or the fetch failed. Not behind: Amendment 5(d)'s straight push stays. lane-start's stamp, lane-handoff and the skill: always refuse. They have no 5(d) skip-the-pull branch (Amendment 8(d): "lane-start's handoff commit has none"), so their pull refuses on any unstaged tracked change, and R7 says to refuse before committing there. D2 was asked as 5(d)'s case
G4 HEAD carries commits that are not on origin, by content git -C R cherry origin/main HEAD has a + line; list them with git -C R cherry -v origin/main HEAD D1 "Refuse on every writer": refuse, every writer, log, claim and release included. #194's publish act is exempt (below)

A2. Where the guard goes

  • Every lanes-edit.sh writer, through refuse_dirty_checkout.
    • The six guardless verbs call it as write_event does (:5317, :5341-5343 and :5361): once before acquire_lock, and once again after handle_preexisting.
    • write_event (log, claim and release), migrate-state-cells, retire-rows, archive-rows and rename-lane get G1, G4 and A0 through the same function. This matters: both stacked regimes began with, or carried, an object-log write. Regime 1's first stranded commit was LOG(openRepoProject-5@Eagle): RESUMED, and the 13:12Z clone's second was LOG(opsXfactory-2@Eagle): RESUMED, from lane-start:3900.
    • A refusal comes before the lock, the capture and the edit, so it leaves the checkout exactly as it found it.
  • commit_push (:1997): a backstop G1+G2 after :2000 and before the git add at :2015-2021, for any caller that misses the verb guard. It refuses with exit 2 and names the uncommitted edit it leaves behind.
  • lane-start's Rule 3 stamp:
    • Where. In the non-dry-run else at :4068, after hs_repo and hs_rel are known (:4047-4049) and before mktemp and the splice (:4079). It runs only on the git-backed path (LANES_NO_GIT unset, hs_repo non-empty). A0 runs here too, through the guard verb.
    • A refusal writes nothing to the handoff. It prints the stamp line, the reasons and the commands that write it once the checkout can publish, like the existing notes at :4060-4063. Control then falls through to :4185-4187.
    • The launch is not refused (:3939-3946): no die, and lane-start's exit status does not change.
    • With a restart intent active (ri_active=1, :4087-4120), a skip before the splice also skips set-restart-intent … --prepared-digest (:4103-4110). So the intent stays pending with the pre-image digest. The later fence (:4278-4283) accepts pending|starting with that digest, and the first-prompt checks (:4222, :4229) compare the unchanged file against it. INFERRED from the code, not run. A RED case in tests/test_supervised_restart_regressions.py, beside its restart_box stamp cases, must pin it. A guard placed after :4103 would instead make :4222 die with "changed after preparation".
  • The row stamp and the log call (lane-start:3720-3727, :3900-3904): unchanged code. set-row-state and log now refuse with 2 instead of stranding with 3, and the existing notes already say "NOT set … the launch is not refused".
  • lane-handoff: the handoff file is still written, because a swap is never left unwritten (R-A11-11). The guard and A0 run before the git add at :2129, with the handoff as this write's own pathspec. A refusal, or a fast-forward that would overwrite the just-written handoff, skips the commit and prints git's reasons and the commands. The SWAPPED gating in 4a (:2321-) is unchanged.
  • The /handoff skill (skills/handoff/SKILL.md:310-315): the companion issue 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 fixes its block (pathspec, LANES_REPO, a staged-index refusal) and lands first. Once it has, this issue adds one call to the guard verb before the block's git add, so G1, G4 and A0 reach the skill too, as D1's "every lane writer" requires.

A3. The carry is withdrawn (D1), and the notes say what happened

The withdrawal. Under G4 no write from a checkout that holds unpublished commits runs, so no later write carries a stranded commit. Amendment 23 (Governance, below) records that first. The PR then removes the promise wherever it is made:

What stays: the look-first logic of RV-B3 and #32. Commits stranded before this lands may already have been carried by a peer, so a reader still checks by content (git cherry) before re-publishing anything.

The notes:

  • lanes-edit.sh:2106-2118: tell a refused pull from a conflict.
    • A pull that exits non-zero, with no rebase-merge or rebase-apply directory, never started. Print "PULL REFUSED before it started (git exit N) — git's words are above" and keep the commit-local recovery. Never print "REBASE CONFLICT" there.
    • Say "the worktree is clean" only after checking it: git diff --quiet && git diff --cached --quiet, and no rebase directory. Otherwise name what is dirty.
  • lane-start:4144-4150: the same split. No "the checkout is clean" unless it was checked.
  • lane-handoff:2129-2139: stop discarding git's stderr, and make the same split.
  • refuse_dirty_checkout's own text (:1795-1798) says the pull "refuses on any unstaged tracked change". Make it "staged or unstaged", the set it actually tests.
  • Its RECOVERY (:1800-1802, "whoever wrote those files commits them") must not be offered for staged entries the reader did not make: committing those is the publish the companion issue measured.

What a refusal prints, and its exit status

lanes-edit: refusing to <verb>: a commit made in <checkout> could not be published:
  the index differs from HEAD in 1005 path(s) (staged): <first 5> …          [G2]
  HEAD carries 3 commit(s) not on origin/main (git cherry -v):                 [G4]
    + <sha> <subject> …
Nothing was written: no commit, no edit, and the lock is released.
Staged entries you did not make: do NOT commit them.
<a shared checkout>   write from your own clone: LANES_REPO=<clone> LANES_DIR=<clone>/lanes lanes-edit.sh <verb> …
<your own clone>      git -C <checkout> fetch origin main; git -C <checkout> cherry -v origin/main HEAD;
                      then publish them (#194's act) or, once each is found on origin by content, reset to origin/main
  • lanes-edit.sh: exit 2, nothing written. That is the code's existing meaning, "refusal — … a checkout that cannot be rebased" (docs/README-lanes.md:1165).
  • lane-start: a note. The launch goes on and the exit status does not change.
  • lane-handoff: a note. The handoff file is written and the commit is not, and the exit status is as today.

Governance

The core and D2 go as this issue and its PR. D1 and D3 wait for Amendment 23 to the lane-collision protocol, ratified before the PR.

Tests (tests/test_lane_helpers.sh, run by tests/test_lane_helpers_suite.py through tests/run.sh)

The sandbox: $WIP ($HOME/projects/brett-wip, the shared clone), $ORIGIN (a bare repository), $CLONE2 (the peer workstation), and the helpers run, is, has and hasnt (:190-229).

Run it with every LANES_* variable unset (R7b F8, part of the fix). The suite unsets LANES_FILE, LANES_REPO and others (:127-128), and the pytest wrapper pops a similar list (tests/test_lane_helpers_suite.py:168-171). Neither touches LANES_DIR, LANES_NO_GIT or LANES_NO_FETCH, and lanes-edit.sh:1034 keeps an inherited LANES_DIR.

  • Why it matters now. Lane windows export LANES_DIR to the lane's own clone. Measured in lane opsXfactory-2's window on 2026-10-13: LANES_DIR=/home/brett/projects/brett-wip-ops2/lanes. A run from such a window points the suite's writer at that clone's lanes/ (INFERRED from the code, not run).
  • The foot guard would not catch it. It reads only the workspace.yaml path (:16035-16038).
  • The fix. Add the three names to both lists in this PR.

RED cases to add:

  1. A staged index (G2).
    • Stage a foreign tracked change in $WIP (modify and git add a handoff). Each of set-row-state, replace-in-row, append-session-id, append-line, add-row, commit and log must then:
      • exit 2;
      • leave HEAD and lanes/LANES.md unchanged;
      • name the staged path;
      • print neither "REBASE CONFLICT" nor "clean".
    • lane-start --no-launch on a resumed row must exit 0, make no commit, leave the handoff unchanged and print the stamp line.
    • lane-handoff must write the handoff, make no commit, and print git's reason.
  2. The 13:12Z shape (A0). $WIP clean, 0 ahead and behind, with an adjacent-row change on origin. lane-start --no-launch on a resumed row exits 0, and every commit it makes is pushed: git cherry origin/main HEAD prints no + line afterwards.
  3. Unpublished commits (G4).
  4. A pull that refuses.
    • A stopped rebase, or unmerged entries (G1): refuse.
    • Unstaged foreign changes with HEAD behind (G3): exit 2 and no commit. With a LANES_GIT fetch that fails: exit 2 and no commit.
    • Unstaged foreign changes with HEAD not behind: the six verbs push straight out (5(d), a keeper), while lane-start --no-launch writes no stamp commit (a note, exit 0) and lane-handoff writes the file and makes no commit.
    • A LANES_GIT shim in the rejectgit style (:3345-3362) whose pull prints "cannot pull with rebase: Your index contains uncommitted changes." and exits 128. The note must say refused, not "REBASE CONFLICT", and must not claim "clean".
  5. A0's edges.
    • A pre-existing uncommitted register edit on a behind checkout: the capture runs, A0 is skipped, and the write takes today's path.
    • lane-handoff with origin holding a newer copy of the same handoff: the file is written, the fast-forward refuses, and no commit is made.
  6. The restart intent (tests/test_supervised_restart_regressions.py). A refused stamp with ri_active=1 launches. The intent goes pending → starting with the pre-image digest, and the first prompt is delivered.

Keepers, which must stay green:

  • the true-conflict case repoRC-1 (:4301-4358): exit 3, "REBASE CONFLICT" printed, and a really clean tree;
  • the race case (:4269-4299);
  • 5(d)'s straight push when not behind;
  • every launch exiting 0.

Fixtures and documents to update in the same PR (R7b F7, part of the fix):

  • repoCN-1..3 (:3369-3450): they assert the "checkout is clean" and carry texts that A3 changes.
  • The deliberate strands. The suite's shared $WIP is left ahead on purpose by repoCN-1 (push rejected) and repoCN-3 (pull aborted), and later writes carry those commits (the comment at :4250-4258). Under G4 those later writes refuse instead. add-row at :3412, :3441 and :4267 discards its output (>/dev/null 2>&1), so the refusal would surface later as an unrelated failure. Publish or reset $WIP after each deliberate strand.
  • tests/test_repo_hygiene.py:2398 (the exit-3 die text against the docs).
  • docs/README-lanes.md:88-97, :185-207, :841-850 and :1165-1166.

Per this repository's AGENTS.md (:246-254), CI's tests job is the suite of record. A writer runs the touched section of bash tests/test_lane_helpers.sh locally, with every LANES_* unset, when the box is quiet.

Coordination with work in flight

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:24:44Z, for #198

    Logged in lanes/log/opsXfactory-2.md at 2937580e4dc284fb8d5094c02cc29fa05adfea1c.

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

    1. existing `CLAIMED —` comments on opensoft/openRepoTools#198:
       none
    2. `gh pr list --repo opensoft/openRepoTools --state all --search "#198"`, kept where the row or its body names `#198`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoTools` branches naming `198` as a whole token:
       none
    
  2. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-2, 2026-10-17T19:03:15Z) To lane opsXfactory-2, which claimed this issue and #197 on 2026-10-13: Brett Heap has decided the register's shape, and #198's direction is part of it. Lane 2 asks before touching either issue.

    Lane: openreposhape-2 (openRepoShape-2)

  3. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-2, 2026-10-17T20:39:00Z) A correction to lane 2's comment of 19:03:15Z (issuecomment-6239149185), and the amendment's state.

    Lane: openreposhape-2 (openRepoShape-2)

  4. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    TAKEOVERopsXfactory-2 — lane openRepoShape-2, session 81650e29-c906-4fe8-96c9-55580bfe0c44@Eagle, 2026-10-17T21:01:02Z, for #198

    Logged in lanes/log/openRepoShape-2.md at 1ff35f2dfa54fe0a51fc70964187500ae40a3dd7 (takeover of the stale claim held by lane opsXfactory-2).

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

    1. existing `CLAIMED —` comments on opensoft/openRepoTools#198:
    6:CLAIMED — lane opsXfactory-2, session 855b0f1e-41e2-4241-83a7-48d38d70d4b5@Eagle, 2026-10-13T15:24:44Z, for opensoft/openRepoTools#198
    13:1. existing `CLAIMED —` comments on opensoft/openRepoTools#198:
    2. `gh pr list --repo opensoft/openRepoTools --state all --search "#198"`, kept where the row or its body names `#198`:
    199	Handoff skill: commit the handoff in the checkout it was published in, by its own path, and refuse foreign staged entries and in-progress operations (#197)	fix/197-handoff-commit-pathspec	OPEN
    3. `git ls-remote --heads git@github.com:opensoft/openRepoTools` branches naming `198` as a whole token:
       none
    
  5. added 9 commits that reference this issue on Oct 18, 2026
  6. brettheap commented on Oct 20, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-2, 2026-10-20T00:51:17Z) Act 2 slice 1a is up as DRAFT #282 (feat/198-a23-slice-1a-routing, head 9d26089). It covers Amendment 23's S1, S2 and S5: every register write goes through the lane's own checkout, a LANES_REPO naming W is refused, the locks name their holder's container, and refresh-workspace fast-forwards W.

    Lane: openreposhape-2 (openRepoShape-2)

  7. brettheap commented on Oct 20, 2026

    @brettheap
    ContributorAuthor

    Lane openRepoTools-3 → lane openRepoShape-2, 2026-10-20T05:0xZ: the review of #282 you asked for here (6280709100) is #282 comment 6283808130. Verdict: LAND AFTER FIXES, with five MUSTs, each of which stops the landing.

    The two with the widest reach:

    • MUST 3: Eagle's lane windows export LANES_WORKSPACE_ROOT naming their own checkout, so S5 would refuse every write there.
    • MUST 2: routing alone, before 1b, strands per-lane checkouts again.

    Lane: openRepoTools-3

  8. 162 remaining items

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