diff --git a/docs/agent-handoff.md b/docs/agent-handoff.md index ba7bc82..327c2dd 100644 --- a/docs/agent-handoff.md +++ b/docs/agent-handoff.md @@ -1,7 +1,7 @@ # Agent handoff — cross-machine continuity **Last updated: 2026-07-12, on the laptop, by the editops session -(merging the auto-pairing #110 post-merge sync).** This file is the +(post-#111 merge; scripts/bite micro-PR).** This file is the bridge between development machines. If you are an agent reading this on a fresh clone: this document plus the `docs/*-framing.md` files ARE your memory. Read this fully before taking on work, seed @@ -11,22 +11,23 @@ reads it the way you just did. ## 1. Where the project stands (2026-07-12) -- `main` @ `4174f3e` (auto-pairing #110 merged), protocol **v15** +- `main` @ `f0a05c5` (editops #111 merged), protocol **v15** (`SUPPORTED=[6..15]`). -- **Editing-conveniences pack (editops) in flight: PR #111** — the - Lua parallel lane, branch `editops`. Framing - `docs/editing-conveniences-framing.md` at revision 6 (three - pre-branch rounds, one adopted post-approval hardening, and PR - round 1: full UTF-8 scalar validation, per-word capitalize with - the `_`-constituent deviation named, trim-on-save dual-channel - error reporting). goto-line, case ops, transpose, zap-to-char - (kill-chain member with an origin guard and killring's new - pending-prompt marker), line move/duplicate/join, region - sort/reverse/dedupe, delete-trailing-whitespace + opt-in - trim-on-save. killring.lua gains `kill_range` / - `break_chain([fid])` / the marker lifecycle. On the laptop this - branch lives in a git worktree at `../pmacs-editops`; fold it - back after merge. +- **Editing-conveniences pack (editops, #111) landed** — the Lua + parallel lane. Framing `docs/editing-conveniences-framing.md` at + revision 6 (three pre-branch rounds, one adopted post-approval + hardening, one PR round: full UTF-8 scalar validation, per-word + capitalize with the `_`-constituent deviation named, trim-on-save + dual-channel error reporting). Ships goto-line, case ops, + transpose, zap-to-char (kill-chain member with an origin guard + and killring's pending-prompt marker), line move/duplicate/join, + region sort/reverse/dedupe, delete-trailing-whitespace + opt-in + `pmacs.editops.trim_on_save`. New substrate other code can use: + `pmacs.killring.kill_range` / `break_chain([fid])` / + `arm_kill_prompt`+`commit_kill_prompt` (the marker lifecycle), + and the origin-guard pattern for chain-sensitive minibuffer + commands. The development worktree at `../pmacs-editops` has been + folded back. - **Auto-pairing (#110) landed — Arc 2 is COMPLETE.** Framing `docs/auto-pairing-framing.md` at revision 6 (two pre-branch rounds + three PR rounds). Shape that shipped: the nine built-in pair @@ -168,7 +169,18 @@ New wire surface ⇒ bump + both-frontends support + acceptance. - **The checkout may be shared with the user.** Check `git status` for foreign uncommitted work before any stash/checkout/branch surgery; never assume dirty files are yours. (Their uncommitted fix was nearly - orphaned once.) + orphaned once.) A clean status goes stale within minutes when two + lanes are active — for parallel work, `git worktree add` a sibling + directory off main instead of switching the shared checkout. +- **Never `git stash` in this repo.** The stash namespace is + REPO-GLOBAL — one list shared across every worktree and with the + user; a scripted push/pop can pop a human's years-old stash into + your tree (happened during #111: a failed `stash push` chained + into `stash pop`, which grabbed the user's PR-#17-era entry). For + run-tests-against-an-old-version swaps, use `scripts/bite` — a + trap-guarded one-file swap over read-only `git show`, with an + inverted verdict (exit 0 iff the tests FAIL against the old + version), making bite-verification machine-checkable. - **Stacked PRs**: retarget the child to main BEFORE merging the parent — GitHub auto-closes a PR whose base branch is deleted and cannot reopen it (#104 → re-opened as #105). diff --git a/scripts/bite b/scripts/bite new file mode 100755 index 0000000..cccd3eb --- /dev/null +++ b/scripts/bite @@ -0,0 +1,60 @@ +#!/bin/sh +# scripts/bite --- prove a fix's tests BITE: run them against an older +# version of ONE file and succeed only if they FAIL there. +# +# scripts/bite [cargo-test-args...] +# +# Example (the PR #111 round-1 shape): +# scripts/bite HEAD~1 builtin/runtime/editops.lua \ +# --test editops_acceptance -- capitalize trim_on_save_unexpected +# +# Exit status: 0 when the named tests fail against 's version of +# (the fix bites), 1 when they still pass (vacuous), 2 on +# usage/setup errors. The working-tree file is restored on every exit +# path, including interrupts. +# +# Caveat: a COMPILE error of the old tree also counts as "fails" — +# correct, but weaker evidence than a clean assertion failure; eyeball +# the output when the swapped file is Rust rather than Lua. +# +# Why this exists: bite-verification is step 4 of the working method, +# and the obvious shortcut — git stash — is a trap here. The stash +# namespace is REPO-GLOBAL: shared across every worktree and with +# humans, so a scripted push/pop can collide with (or pop!) someone +# else's stashed work. This helper never touches git state beyond a +# read-only `git show`. + +set -eu + +if [ "$#" -lt 2 ]; then + echo "usage: scripts/bite [cargo-test-args...]" >&2 + exit 2 +fi + +ref=$1 +path=$2 +shift 2 + +if [ ! -f "$path" ]; then + echo "bite: no such file: $path" >&2 + exit 2 +fi + +saved=$(mktemp "${TMPDIR:-/tmp}/bite.XXXXXX") +cp -- "$path" "$saved" +restore() { + cp -- "$saved" "$path" + rm -f -- "$saved" +} +trap restore EXIT INT TERM + +# The `./` prefix makes the pathspec cwd-relative for git-show, so the +# script works from any directory inside the repo. +git show "$ref:./$path" > "$path" + +if cargo test "$@"; then + echo "bite: VACUOUS --- tests still pass against $ref:$path" >&2 + exit 1 +fi + +echo "bite: OK --- tests fail against $ref:$path (the fix bites)"