Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .claude/commands/handy.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion .cursor/rules/continual-learning.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
5 changes: 3 additions & 2 deletions .cursor/skills/rhizome-ship/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
17 changes: 9 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -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-<model>-<topic>.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-<model>-<topic>.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.
Expand Down Expand Up @@ -176,17 +176,17 @@
**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
rather than a reason to make it someone's problem. The Ask-tab/Library-panel
`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
Expand Down Expand Up @@ -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:** <model> · <date> · <commit or session id>
Expand Down Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion docs/CROSS-MODEL-HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

---

Expand Down
3 changes: 3 additions & 0 deletions docs/GETTING-STARTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
10 changes: 8 additions & 2 deletions docs/HANDOFF.md
Original file line number Diff line number Diff line change
@@ -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-<agent>-<topic>.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
```
Expand All @@ -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`
Expand Down
5 changes: 2 additions & 3 deletions docs/YOU-SHOULD-KNOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
Original file line number Diff line number Diff line change
@@ -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-<agent>-<topic>.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.
4 changes: 2 additions & 2 deletions docs/plans/rhizome-ship-skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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/`.

---

Expand Down
21 changes: 15 additions & 6 deletions scripts/check-handoff-shape.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand All @@ -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.`,
)
}
Comment on lines +20 to +25

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 MEDIUM RISK

Validate that the per-PR pointer appears in the expected top section, rather than using an unrestricted substring search, so the checker actually enforces the documented top-pointer requirement.


const sessionSections = handoff.match(/^## Session handoff/gm) ?? []
if (sessionSections.length > 0) {
problems.push(
Expand Down Expand Up @@ -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}/.`,
)
Loading