diff --git a/.claude/commands/handy.md b/.claude/commands/handy.md index e8f69d2e..04658947 100644 --- a/.claude/commands/handy.md +++ b/.claude/commands/handy.md @@ -19,13 +19,13 @@ Produces two things: the handoff files this repo requires, and a the topic was. That description is what a future session reads to decide whether to open the file at all. -3. **Update `docs/HANDOFF.md` in place** — the state line if it moved, any - affected Open threads, and one line in Recent sessions. Never paste the - session into that file; it is an index. +3. **Do not edit `docs/HANDOFF.md`.** The new file in `docs/plans/handoffs/` + is the record. Parallel PRs that stamp State or Recent conflict on merge + (#142, #143, #145, #148). -4. **Run `pnpm handoff:check`.** It enforces the shape and a 900-line cap on - `docs/HANDOFF.md`. Over the cap, prune a *resolved* thread down to its - outcome — git holds the detail. +4. **Run `pnpm handoff:check`.** It checks handoff-file frontmatter and a + 900-line cap on `docs/HANDOFF.md`. Over the cap, prune a *resolved* + thread in a dedicated index edit — not as part of a product PR. 5. **Emit the copy-paste block** (below). This is part of the deliverable, not an extra; a handoff without it is incomplete. diff --git a/.cursor/rules/continual-learning.mdc b/.cursor/rules/continual-learning.mdc index 9ce624c6..ba3ca77e 100644 --- a/.cursor/rules/continual-learning.mdc +++ b/.cursor/rules/continual-learning.mdc @@ -14,5 +14,5 @@ When running `continual-learning` or `agents-memory-updater` in this repo: 3. Touch **only** `## Learned User Preferences` and `## Learned Workspace Facts`. Never edit process rules, product rules, or the Continual-learning guard block itself. 4. A new bullet must be all of: durable next month, Rhizome Agent–specific, recurring or explicitly “always remember,” and actionable. One topic. ~2 short lines max. ≤12 bullets per section. 5. **Refuse:** SHAs, clocks, burn windows, usage meters, billing/subscriptions, secrets, ENV, one-offs, today’s chore list, docked answers that belong in HANDOFF/BOARD, Cursor/xAI account chatter, mega-paragraphs. -6. Session / ship / issue / native status → `docs/HANDOFF.md`, `docs/BOARD.md`, `docs/NEXT.md`, `docs/plans/handoffs/` — not Learned. +6. Session / ship / issue / native status → a new file in `docs/plans/handoffs/`, plus `docs/BOARD.md` / `docs/NEXT.md` when those indexes change. Do not append a line to `docs/HANDOFF.md`. Not Learned. 7. Still refresh the incremental transcript index (mtimes + delete missing paths) even when AGENTS.md is unchanged. diff --git a/.cursor/skills/rhizome-ship/SKILL.md b/.cursor/skills/rhizome-ship/SKILL.md index c0d66c9e..b03f3c22 100644 --- a/.cursor/skills/rhizome-ship/SKILL.md +++ b/.cursor/skills/rhizome-ship/SKILL.md @@ -95,8 +95,9 @@ Only when the user will **use** `/Applications/Rhizome Agent.app`. 3. Package into `/Applications/Rhizome Agent.app` using this repo’s documented Tauri build path (`pnpm tauri build` / the ship docs in `AGENTS.md`). Vite / `pnpm tauri dev` is **not** this verb. -4. Stamp `docs/HANDOFF.md` State and `docs/BOARD.md` with the new - commit + install time. Keep three SHAs: origin, local, app. +4. Add a ship note under `docs/plans/handoffs/` and stamp `docs/BOARD.md` + with the new commit + install time. Keep three SHAs: origin, local, app. + Do not append a line to `docs/HANDOFF.md`. **Done when:** the installed app’s commit/mtime matches the intended HEAD, leftovers are gone, and living docs name the new app SHA. diff --git a/AGENTS.md b/AGENTS.md index d21fd303..2078b3ad 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -65,7 +65,7 @@ ls docs/plans/handoffs | grep -v archive | tail -1 # the latest handoff ``` - Open that one, and any older one whose `description:` frontmatter sounds relevant — that field exists so you can skip the rest. **Write your own session as a new file there** (`YYYY-MM-DD-HHMM--.md`, frontmatter with `session`, `model`, `description`), and update `HANDOFF.md` in place rather than pasting into it. `pnpm handoff:check` enforces the shape and runs in pre-commit. + Open that one, and any older one whose `description:` frontmatter sounds relevant — that field exists so you can skip the rest. **Write your own session as a new file there** (`YYYY-MM-DD-HHMM--.md`, frontmatter with `session`, `model`, `description`). Do **not** edit `HANDOFF.md` for a PR — that is how #142, #143, #145, and #148 conflicted. `pnpm handoff:check` enforces the per-file frontmatter and a 900-line cap on the index, and runs in pre-commit. Restructured 2026-08-21: the file had reached 2156 lines of stacked sessions, and because each session inserted next to whichever heading it was reading, the newest handoff had drifted to third place — "read the latest handoff" pointed at the wrong one. Read it directly; the wiki's search-first rule does not apply to repo docs. - Check `docs/plans/handoffs/` for the latest session file (newest by filename) — dated detail behind the handoff summary. The old `*-session-status.md` dumps are gone. @@ -176,7 +176,7 @@ **Why:** git's `author` field is `Atticus` on every commit in this repo regardless of who or what wrote it, so it carries no provenance. Without the trailer, the only record of which model did what is `HANDOFF.md`'s prose — written by the agents about themselves. This repo runs several models by design (see `docs/CROSS-MODEL-HANDOFF.md`), and self-reported claims here have a track record of not surviving verification. One trailer turns "who wrote this?" into `git log --pretty='%h %s %(trailers:key=Co-Authored-By,valueonly)'` instead of a document you have to trust. Commits before 2026-07-31 are mostly unsigned; the 2026-07-27 session was Hermes and the 2026-07-31 sessions were Claude Opus 5. Don't retro-stamp them — history is pushed or about to be. -- **If you write the words "pre-existing" (or "not introduced by this session" / "unrelated to this change" / "was never..."), open or update a `C`-number in `HANDOFF.md`'s Open threads, in the same commit.** A note buried in a session-status doc is not tracked — it is only findable by a session that happens to reopen that exact file. Don't split the difference with a one-line mention elsewhere in the doc; the C-number entry is the whole fix, because it's the one place a fresh session is guaranteed to look. +- **If you write the words "pre-existing" (or "not introduced by this session" / "unrelated to this change" / "was never..."), open or update a `C`-number in your `docs/plans/handoffs/` file, in the same commit.** Do not append that C-number to `HANDOFF.md` Open threads from a PR. A note buried only in chat is not tracked. The handoff file is what a fresh session reads after the index. **Why:** the same finding gets rediscovered by session after session and fixed by none, because "pre-existing" reads as a reason to stop looking @@ -184,9 +184,9 @@ `wiki/`-prefix mismatch was logged that way three separate times, and `pnpm l10n:validate`'s locale gap three more; both are tracked now as C17 and C18. A note buried in a session-status doc is not tracked — it is findable - only by a session that happens to reopen that exact file. The C-number entry - is the whole fix, because it is the one place a fresh session is guaranteed - to look. + only by a session that happens to reopen that exact file. The C-number in + the handoff file is the whole fix. Do not also stamp `HANDOFF.md` from the + same PR. **On the evidence:** those incidents happened in Rhizome Desktop before this repo existed — the sweep is dated 2026-08-02 and the files it cites @@ -435,7 +435,7 @@ ADRs live in `docs/adr/`. Create in the same commit as the code. Never edit exis After any Tauri command, new component/hook, data model change, or new integration: update `docs/ARCHITECTURE.md`, `docs/ABSTRACTIONS.md`, and/or `docs/GETTING-STARTED.md` in the same commit. -**Origin tags on living docs.** This repo is several models and at least two harnesses (Claude Code subscription, Cursor). The chat that wrote a paragraph is not in `rg`. When you add a section to `HANDOFF.md`, `NEXT.md`, or a design note other agents will treat as current, put one visible line under the heading: +**Origin tags on living docs.** This repo is several models and at least two harnesses (Claude Code subscription, Cursor). The chat that wrote a paragraph is not in `rg`. When you add a section to `NEXT.md` or a design note other agents will treat as current, put one visible line under the heading. Do not add an Origin line to `HANDOFF.md` from a PR: ``` **Origin:** · · @@ -587,8 +587,9 @@ not a session log, not billing notes, not a second HANDOFF. 5. **Never store:** SHAs, clocks, burn windows, usage %, invoices, secrets, ENV, one-off chores, “what we did today,” docked answers that belong in BOARD/HANDOFF, or Cursor/xAI subscription chatter. -6. Session / ship / native-check / issue status → `docs/HANDOFF.md`, - `docs/BOARD.md`, `docs/NEXT.md`, `docs/plans/handoffs/`. +6. Session / ship / native-check / issue status → a new file in + `docs/plans/handoffs/`, plus `docs/BOARD.md` / `docs/NEXT.md` when + those indexes change. Do not append a line to `docs/HANDOFF.md`. 7. Long product chrome → living docs or an ADR, not Learned. 8. If the only candidate is stale, transient, or already in Section 1, leave Learned empty and refresh the transcript index only. diff --git a/docs/CROSS-MODEL-HANDOFF.md b/docs/CROSS-MODEL-HANDOFF.md index d258c0b2..87e986b9 100644 --- a/docs/CROSS-MODEL-HANDOFF.md +++ b/docs/CROSS-MODEL-HANDOFF.md @@ -9,7 +9,8 @@ re-verify rather than trust this doc blindly. If something here goes stale, fix the doc, don't just work around it silently. For general project state, read `docs/HANDOFF.md` first — this file is -narrower: traps and landmines, not status. +narrower: traps and landmines, not status. Per-PR notes go in +`docs/plans/handoffs/`. Do not append a line to `HANDOFF.md`. --- diff --git a/docs/GETTING-STARTED.md b/docs/GETTING-STARTED.md index 612273bb..d9e373ca 100644 --- a/docs/GETTING-STARTED.md +++ b/docs/GETTING-STARTED.md @@ -490,6 +490,9 @@ That browser harness is a deterministic desktop command bridge, not real native Verified against source 2026-09-14. Longer landmine list: [`CROSS-MODEL-HANDOFF.md`](CROSS-MODEL-HANDOFF.md). +- **Do not append a line to `docs/HANDOFF.md` from a PR.** Add a file under + `docs/plans/handoffs/` instead. Parallel PRs that stamp State or Recent + conflict on merge (#142, #143, #145, #148). - **One Rhizome at a time.** Debug bundle and `/Applications/Rhizome Agent.app` share `ai.rhizome.agent`. Launching a second copy silently forwards to the first. Quit the installed app before `pnpm tauri dev`. diff --git a/docs/HANDOFF.md b/docs/HANDOFF.md index c2fa468c..09356fc9 100644 --- a/docs/HANDOFF.md +++ b/docs/HANDOFF.md @@ -1,6 +1,10 @@ # Handoff — read this first **What is true right now.** Not a history log: per-session records live in `docs/plans/handoffs/`, one file each, newest by filename. + +**New PRs must not edit this file.** Add a file under `docs/plans/handoffs/` +instead (`YYYY-MM-DD-HHMM--.md`). A State or Recent line here +is why #142, #143, #145, and #148 conflicted on merge. ```bash ls docs/plans/handoffs | grep -v archive | tail -1 # the latest handoff ``` @@ -21,8 +25,10 @@ commits: abc1234..def5678 --- ``` -Then update this file **in place**: the state line below, Open threads, and one -line in Recent sessions. Do not paste your session into this file. +Do **not** then edit this file. Do not add a State Origin line, a Recent +sessions line, or an Open-threads C-number as part of a PR. The new file +is the record. `pnpm handoff:check` still keeps this file under 900 lines +and forbids `## Session handoff` sections here. **Why it works this way.** This file was 2156 lines of stacked sessions, always loaded in full, mostly restating commit messages and `docs/plans/*-session-status.md` diff --git a/docs/YOU-SHOULD-KNOW.md b/docs/YOU-SHOULD-KNOW.md index 44e90e66..3fc43fe4 100644 --- a/docs/YOU-SHOULD-KNOW.md +++ b/docs/YOU-SHOULD-KNOW.md @@ -317,9 +317,8 @@ Vault twins exist as notes, not code. - Living docs are palimpsests. `NEXT.md` was Claude `b8dc8fb`, then Grok `2b5daba` inserted composition. Read **Origin:** lines. `rg` cannot attribute a section. -- Session handoffs: one new file in `docs/plans/handoffs/`, one line - in `HANDOFF.md` Recent sessions. Do not paste the session into - `HANDOFF.md`. +- Session handoffs: one new file in `docs/plans/handoffs/`. Do not add a + line to `HANDOFF.md` Recent sessions or State. - After a named handoff task, pick next work from `NEXT.md`. Do not invent a Prime verb because the surface is nearby. diff --git a/docs/plans/handoffs/2026-10-11-0755-cursor-grok-4-6-handoff-per-pr-files.md b/docs/plans/handoffs/2026-10-11-0755-cursor-grok-4-6-handoff-per-pr-files.md new file mode 100644 index 00000000..85c21bf5 --- /dev/null +++ b/docs/plans/handoffs/2026-10-11-0755-cursor-grok-4-6-handoff-per-pr-files.md @@ -0,0 +1,33 @@ +--- +session: 2026-10-11T07:55Z +model: Cursor Grok 4.6 +description: >- + Per-PR notes go in docs/plans/handoffs/ only. HANDOFF.md stays an index + and no longer takes a State or Recent line from each PR. +commits: HEAD +--- + +**Origin:** Cursor Grok 4.6 · 2026-10-11 · stop HANDOFF.md merge conflicts + +## What landed + +Every PR was appending a State Origin line and a Recent sessions line +near the bottom of `docs/HANDOFF.md`. Whichever PR merged second always +conflicted (#142, #143, #145, #148). + +New PRs add one file under `docs/plans/handoffs/` named +`YYYY-MM-DD-HHMM--.md`. They do not edit `HANDOFF.md`. +The index keeps its existing body and now says so at the top. + +Agent instructions in `AGENTS.md`, `.claude/commands/handy.md`, +`.cursor/skills/rhizome-ship/SKILL.md`, `.cursor/rules/continual-learning.mdc`, +`docs/CROSS-MODEL-HANDOFF.md`, `docs/GETTING-STARTED.md`, +`docs/YOU-SHOULD-KNOW.md`, and `docs/plans/rhizome-ship-skill.md` now +point at the per-PR file. `pnpm handoff:check` still caps the index at +900 lines, forbids inline `## Session handoff` sections, requires +frontmatter, and now also requires the top pointer. + +## Not in this change + +No product code. No State or Recent line on `HANDOFF.md` (this file is +the record). knispo merges. diff --git a/docs/plans/rhizome-ship-skill.md b/docs/plans/rhizome-ship-skill.md index 481a7b90..e6f59496 100644 --- a/docs/plans/rhizome-ship-skill.md +++ b/docs/plans/rhizome-ship-skill.md @@ -33,7 +33,7 @@ Atticus ships this private repo himself. Agents already know `git commit` / `git |---|---|---| | **commit** | Stage intended files. Commit with a why-message. Run repo hooks. | Push. Rebuild. `--no-verify`. Amend unless the usual amend rules hold. | | **push** | `git push` to `tuckcode/rhizome-agent` after pre-push passes. | Skip hooks. Force-push main. Add remotes. Buy CI. | -| **rebuild** | Quit the installed app if needed, then package into `/Applications/Rhizome Agent.app`. Delete leftover `.app` copies. Stamp HANDOFF/BOARD with commit + time. | Rebuild “while we’re here.” Vite/`pnpm tauri:dev` is not this verb. | +| **rebuild** | Quit the installed app if needed, then package into `/Applications/Rhizome Agent.app`. Delete leftover `.app` copies. Stamp BOARD and add a `docs/plans/handoffs/` file with commit + time. Do not edit `HANDOFF.md`. | Rebuild “while we’re here.” Vite/`pnpm tauri:dev` is not this verb. | Commit, push, and rebuild stay **three jobs**. Rebuild only when he will use the packaged app. @@ -69,7 +69,7 @@ Each verb’s completion criterion: 1. **commit** — `git status` clean for the intended files; `git log -1` is the new commit. 2. **push** — `git status` shows in sync with `origin/main` (or ahead only if push was not requested). -3. **rebuild** — `/Applications/Rhizome Agent.app` mtime/commit matches HEAD; HANDOFF State line updated. +3. **rebuild** — `/Applications/Rhizome Agent.app` mtime/commit matches HEAD; BOARD updated; ship note in `docs/plans/handoffs/`. --- diff --git a/scripts/check-handoff-shape.mjs b/scripts/check-handoff-shape.mjs index 5657920c..2c502f94 100644 --- a/scripts/check-handoff-shape.mjs +++ b/scripts/check-handoff-shape.mjs @@ -2,11 +2,11 @@ /** * Keeps `docs/HANDOFF.md` an index rather than an archive. * - * The file grew to 2156 lines of stacked session sections, always loaded in - * full, and the newest one drifted to third place because sessions inserted - * next to whichever heading they were reading. A prose convention did not stop - * that — three sessions in a row wrote the rule down and the file kept - * growing. This does. + * Per-PR notes belong in `docs/plans/handoffs/` (one new file each). A PR + * must not append a State, Recent, or Open-threads line to HANDOFF.md — + * that is how parallel PRs conflicted on merge. This check still forbids + * inline `## Session handoff` sections, caps the index at 900 lines, and + * requires frontmatter on each handoff file. */ import { readFileSync, readdirSync } from 'node:fs' @@ -17,6 +17,13 @@ const MAX_LINES = 900 const problems = [] const handoff = readFileSync(HANDOFF, 'utf8') +if (!handoff.includes('New PRs must not edit this file')) { + problems.push( + `${HANDOFF} is missing the per-PR pointer.`, + ` New PRs add a file under ${HANDOFF_DIR}/; they must not append a line here.`, + ) +} + const sessionSections = handoff.match(/^## Session handoff/gm) ?? [] if (sessionSections.length > 0) { problems.push( @@ -58,4 +65,6 @@ if (problems.length > 0) { process.exit(1) } -console.log(`Handoff shape OK — ${lines} lines, no session sections inline.`) +console.log( + `Handoff shape OK — ${lines} lines, no session sections inline, per-PR files in ${HANDOFF_DIR}/.`, +)