Moves are not deletions for stamp attribution; re-stamp on move

Resolves the 06-vs-08 contradiction: 06's Lanework External fallback
demotes on true deletions only (id vanished from the board, per the
message engine's whole-board id matching), not folder moves. A bare mv
leaves the moved card unstamped, so 08 now teaches re-stamping on every
move as well as every write.

Claude-Session: https://claude.ai/code/session_01HJ7PhFNmQ19bvy9RMD6GSb
This commit is contained in:
2026-07-26 15:49:14 -04:00
parent 8e7c565e07
commit 4b20f8499b
2 changed files with 3 additions and 3 deletions
+1 -1
View File
@@ -50,7 +50,7 @@ Agent and hand edits arrive through the watcher like any change and get auto-com
**Where the user's git identity comes from** (no git install is assumed, and the sandbox doesn't read `~/.gitconfig` — honest limits, not bugs): **repo-local `.git/config` wins when present** — standard git semantics, readable in-sandbox because it lives under the board root, and the natural state of adopted/cloned boards. The board popover's git section exposes name/email fields that **write that repo-local config** — the setting *is* the file, portable to any git client, per-board by nature (work and personal boards can differ). Absent repo config, the **derived default** applies: the macOS account's full name plus `shortname@hostname` — git's own no-config fallback shape, zero ceremony. Commits pushed to a forge under the derived email won't link to a forge account; the popover fields are the fix when that matters. A debounce window containing both kinds is **split into two commits**, never mixed (flush-before-overwrite already orders them: foreign first, then the user's overwrite). Honest limit: the app distinguishes app-mediated from foreign, not human from agent — a hand edit in a text editor and an agent write look identical *unless the writer says otherwise via `modified-by` (below)*. Agents wanting precise attribution are encouraged (via the agent guide, 08-agent-integration.md) to commit their own changes; the app follows along. **Where the user's git identity comes from** (no git install is assumed, and the sandbox doesn't read `~/.gitconfig` — honest limits, not bugs): **repo-local `.git/config` wins when present** — standard git semantics, readable in-sandbox because it lives under the board root, and the natural state of adopted/cloned boards. The board popover's git section exposes name/email fields that **write that repo-local config** — the setting *is* the file, portable to any git client, per-board by nature (work and personal boards can differ). Absent repo config, the **derived default** applies: the macOS account's full name plus `shortname@hostname` — git's own no-config fallback shape, zero ceremony. Commits pushed to a forge under the derived email won't link to a forge account; the popover fields are the fix when that matters. A debounce window containing both kinds is **split into two commits**, never mixed (flush-before-overwrite already orders them: foreign first, then the user's overwrite). Honest limit: the app distinguishes app-mediated from foreign, not human from agent — a hand edit in a text editor and an agent write look identical *unless the writer says otherwise via `modified-by` (below)*. Agents wanting precise attribution are encouraged (via the agent guide, 08-agent-integration.md) to commit their own changes; the app follows along.
**`modified-by` refines foreign attribution** (the self-reported provenance key — 01-storage-format.md): when every file changed in a foreign debounce window carries the same `modified-by: X`, that commit is authored as **X** with the synthetic email `<slug>@agents.lanework.invalid` (display name verbatim, email local part slugified; the domain marks self-reported identity, distinct from both the user and the generic external author). Any disagreement between stamps, any unstamped changed file, or any folder deletion in the window falls back to `Lanework External`. Same trust level as self-committing — it's what the writer claims, accepted as such; the stale-stamp hand-edit case (01) is the known misattribution edge. Self-committing remains the precise path; the stamp is the lightweight middle. **`modified-by` refines foreign attribution** (the self-reported provenance key — 01-storage-format.md): when every file changed in a foreign debounce window carries the same `modified-by: X`, that commit is authored as **X** with the synthetic email `<slug>@agents.lanework.invalid` (display name verbatim, email local part slugified; the domain marks self-reported identity, distinct from both the user and the generic external author). Any disagreement between stamps, any unstamped changed file, or any true deletion in the window falls back to `Lanework External` — a deletion leaves no file to stamp. **A folder move is not a deletion**: items match by id across the whole board (Commit messages above — the same matching that reads a move as a move, not delete+add), so a moved card attributes by its stamp like any changed file. But a bare `mv` rewrites nothing — the moved `index.md` still carries whatever the app last wrote (no stamp) and demotes the window under the unstamped-file rule — so the agent guide teaches re-stamping on move (08-agent-integration.md). Same trust level as self-committing — it's what the writer claims, accepted as such; the stale-stamp hand-edit case (01) is the known misattribution edge. Self-committing remains the precise path; the stamp is the lightweight middle.
**Two writers, one repository — the designed situation, not an edge case.** Self-committing agents mean the auto-committer shares the repo with concurrent `git` processes, and it must be graceful about it: **Two writers, one repository — the designed situation, not an edge case.** Self-committing agents mean the auto-committer shares the repo with concurrent `git` processes, and it must be graceful about it:
+2 -2
View File
@@ -9,7 +9,7 @@ AI agents are first-class users of Lanework boards — not through an API, but t
3. **Fail-fast validation + atomic writes** — a malformed agent write surfaces loudly with the offending path instead of silently corrupting. The right failure mode for letting AI write into a planning system. 3. **Fail-fast validation + atomic writes** — a malformed agent write surfaces loudly with the offending path instead of silently corrupting. The right failure mode for letting AI write into a planning system.
4. **Skip-don't-fail for index-less folders** — an agent interrupted between `mkdir` and writing `index.md` cannot brick the board. 4. **Skip-don't-fail for index-less folders** — an agent interrupted between `mkdir` and writing `index.md` cannot brick the board.
5. **Git trail** (06-history-undo.md) — on git-enabled boards, agent changes are auto-committed, attributed, and undoable like any others. Foreign changes are committed under a synthetic external author, structurally distinct from the user's own commits; an agent can claim its work lightly by stamping `modified-by` (guarantee 6 below), or precisely by committing its changes itself — the app follows along: a held `index.lock` just makes the auto-committer retry/re-debounce, and a tree the agent already committed is a silent no-op that preserves the agent's authorship (06-history-undo.md). The guide says so, and also tells agents to **stage only their own paths** (no `git add -A`) — a sweep would commit the user's not-yet-auto-committed changes under the agent's name. 5. **Git trail** (06-history-undo.md) — on git-enabled boards, agent changes are auto-committed, attributed, and undoable like any others. Foreign changes are committed under a synthetic external author, structurally distinct from the user's own commits; an agent can claim its work lightly by stamping `modified-by` (guarantee 6 below), or precisely by committing its changes itself — the app follows along: a held `index.lock` just makes the auto-committer retry/re-debounce, and a tree the agent already committed is a silent no-op that preserves the agent's authorship (06-history-undo.md). The guide says so, and also tells agents to **stage only their own paths** (no `git add -A`) — a sweep would commit the user's not-yet-auto-committed changes under the agent's name.
6. **`modified-by` self-stamping** (01-storage-format.md) — the lightweight attribution path: an agent stamps files it writes (`modified-by: <your-name>`), and the stamp renders on the card window's modified line and authors the agent's foreign commits (06-history-undo.md) — no git ceremony, and it works on no-git boards, where it is the *only* attribution there is. The app clears the stamp on its own writes, so agents should re-stamp on every write, not once. 6. **`modified-by` self-stamping** (01-storage-format.md) — the lightweight attribution path: an agent stamps files it writes (`modified-by: <your-name>`), and the stamp renders on the card window's modified line and authors the agent's foreign commits (06-history-undo.md) — no git ceremony, and it works on no-git boards, where it is the *only* attribution there is. The app clears the stamp on its own writes, so agents should re-stamp on every write, not once — and on every *move*: a bare folder move rewrites nothing, so the moved card arrives unstamped and the commit falls back to the generic external author (06's fallback demotes on unstamped changed files and true deletions; a move is neither stamped nor a deletion until the agent re-stamps it).
## The agent guide (`CLAUDE.md` at board root) ## The agent guide (`CLAUDE.md` at board root)
@@ -19,7 +19,7 @@ The app silently maintains a `CLAUDE.md` in every board — a condensed, agent-f
- Moving between lanes (folder move), reordering (gapped ranks, only touch the moved item). - Moving between lanes (folder move), reordering (gapped ranks, only touch the moved item).
- Tombstone deletes, colors/icons. - Tombstone deletes, colors/icons.
- New in the rewrite: **attachments** (the `attachments/` convention, importing files). - New in the rewrite: **attachments** (the `attachments/` convention, importing files).
- New in the rewrite: **`modified-by` self-stamping** — stamp files you write; re-stamp every write (the app clears it on its own writes); self-commit instead when you need exact authorship. - New in the rewrite: **`modified-by` self-stamping** — stamp files you write; re-stamp every write *and every move* (the app clears it on its own writes; a bare folder move leaves the card unstamped); self-commit instead when you need exact authorship.
- New in the rewrite: a pointer to the optional **`CLAUDE.user.md`** (see below), instructing agents to read it when present. - New in the rewrite: a pointer to the optional **`CLAUDE.user.md`** (see below), instructing agents to read it when present.
Mechanics: version marker in the first line (`lanework-agent-guide vN`); rewritten when missing or older, never downgraded, left untouched when current or newer. To the loader it's just another ignored file. Mechanics: version marker in the first line (`lanework-agent-guide vN`); rewritten when missing or older, never downgraded, left untouched when current or newer. To the loader it's just another ignored file.