diff --git a/campaign/board.md b/campaign/board.md index 4874b8a..f4dc766 100644 --- a/campaign/board.md +++ b/campaign/board.md @@ -343,3 +343,4 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`). | adopting a clone: do not diagnose from ARP | meta | verified | high | 100% | 2026-09-08 | Lane L2, ~15 minutes, and **the obvious diagnosis was wrong**. No IPv4 in any ARP table, no guest agent, and a 40 s tap capture caught ONE packet - which looks exactly like a clone whose inherited static IP was disabled for a duplicate-address conflict. It was none of that: sendkey into an elevated cmd plus a screendump of `ipconfig /all` showed a healthy DHCP lease on 192.168.10.143 obtained half an hour earlier. **THE GUEST WAS SIMPLY IDLE. Take a screendump first.** Four things the clone needed: shim.cfg was a previous lane's hooks=trace; C:\SOTS\launch-b.cmd does not exist though sotsb.xml invokes it; **lobby slot 2 defaults to Computer and a /join client cannot take an AI slot**; hostname/SID duplicate VM140 (harmless for SSH-by-IP). ALSO: with 10 initial colonies and 0 initial technologies **neither player starts with a single ship**, so random encounters at 100% never fire - you must build warships first | | LAB HAZARDS from L2 | meta | verified | high | 100% | 2026-09-08 | (1) **`pgrep -f "tap141i0"` matches QEMU's OWN command line** (`ifname=tap141i0`), so stopping a tcpdump SIGTERMed the VM. Use `pgrep -x tcpdump`. The guest came back clean (fsutil not dirty, same IP). (2) Driving the starmap needs **REAL MOUSE MOTION** - SetCursorPos alone does not move the game's cursor - plus wheel zoom; L2's driver is in verify/harness/l2-ui/. (3) From lane L4: **`move X Y` then `click X Y`** - a bare click is delivered at the PREVIOUS cursor position about half the time, which reads as "the click did nothing" then "the next click did the previous thing" | | FOURTH cross-lane commit sweep - now with plain git commit | meta | verified | high | 100% | 2026-09-08 | Lane L1's board commit swallowed all 22 of lane L2's staged files. Content intact and verified in HEAD; L2 correctly did NOT rewrite history with other lanes live. **This is the fourth instance of the hazard addresses.d/README documents, and it now happens with plain `git commit` too, not just addresses.json** - because a lane stages by path but another lane's commit picks up whatever is in the index. The index is shared per-repo; staging by path does not protect against someone else's commit. Needs a real fix, not another rule | +| STRUCTURAL FIX for the commit-sweep hazard (rule 25) | meta | verified | high | 100% | 2026-09-08 | Four instances in one session, the last with plain `git commit` and NO `-A` anywhere - **every lane had staged by path exactly as instructed and it still happened**, because `git add ` puts a file in THE REPO'S ONE INDEX and the next commit takes all of it. Staging by path was never the protection. **THE FIX IS A FORM OF THE COMMAND**: `git commit -m "msg" -- path/one path/two` commits only those paths and leaves the rest of the index untouched - verified in a scratch repo (two files staged, pathspec commit took one, the other stayed staged). Lanes now commit with a pathspec, always. Deeper fix if it recurs: a per-lane CLONE of sots-re, mirroring the per-lane worktree of sots-engine - which is precisely why sots-engine has never had this problem | diff --git a/guides/method-rules.md b/guides/method-rules.md index e3106d9..fb06dc8 100644 --- a/guides/method-rules.md +++ b/guides/method-rules.md @@ -307,3 +307,27 @@ like nondeterminism in the engine). So: **a fresh build directory per measurement**, or `rm -rf` the build tree before building. And when a merged result does not reproduce a lane's own number, suspect the build before suspecting the lane. + +## 25. Commit with a pathspec — the index is shared, staging by path is not enough + +Four times in one session, a lane's `git commit` swallowed another lane's staged files in the shared +`sots-re` clone. The last one was plain `git commit -m ...` with no `-A` anywhere: **every lane had +staged by path exactly as instructed, and it still happened**, because `git add ` puts a file +in *the repo's one index* and the next `git commit` takes everything in it. + +The fix is a form of the command, not more discipline: + +```sh +git commit -m "message" -- path/one path/two # commits ONLY those paths +``` + +With a pathspec, git commits the named paths from the working tree and **leaves the rest of the +index untouched** — verified: with two files staged, `git commit -- a.txt` committed only `a.txt` +and left `b.txt` staged. That is exactly the isolation lanes need, and it costs nothing. + +So: **lanes commit with a pathspec, always.** `git add` by path stays good hygiene for reviewing a +diff, but it is not the protection — the pathspec on `commit` is. + +The deeper fix, if this recurs: give each lane its own clone of `sots-re`, the way each already gets +its own `git worktree` of `sots-engine` (which is why that repo has never had this problem). Rule 21 +covers the worktree side; this is its counterpart for the shared evidence repo.