diff --git a/DESIGN/01-storage-format.md b/DESIGN/01-storage-format.md index 1a0623c..41e973d 100644 --- a/DESIGN/01-storage-format.md +++ b/DESIGN/01-storage-format.md @@ -46,13 +46,15 @@ MyBoard.kanban/ ← board = the document | `schema` | integer | yes | `1` for this design | | `title` | string | no | Optional at every level — the display name everywhere. Lanes/cards: a missing title shows the untitled placeholder. Boards: a missing title falls back to the folder name (see Board below) | | `created` | ISO-8601 | no | Set at creation, with timezone | -| `modified` | ISO-8601 | no | Updated on every app write | +| `modified` | ISO-8601 | no | Updated on every app write **that rewrites this `index.md`** — see below | | `modified-by` | string | no | Self-reported writer identity, set by external writers only; the app clears it on every write — see below | | `deleted` | ISO-8601 | no | Tombstone — see Deletion | | `background` | string | no | Palette name or `#RRGGBB[AA]` — see 03-board-ui.md | | `icon` | string | no | SF Symbol name, per-level defaults | | `iconColor` | string | no | Palette name or hex | +**`modified`'s scope — content provenance, not file activity (settled).** The stamp updates on every app write that rewrites the item's `index.md`, and only those — it describes the item's *content* (title, body, frontmatter), never its files. Two designed app writes therefore don't bump it, deliberately: **raw-source Apply** writes the validated buffer byte-for-byte (05-card-window.md — the verbatim contract outranks stamping, the same reason it doesn't clear `modified-by` below), and **attachment operations** never touch `index.md` at all — load-bearing, not an oversight: Add Attachment stays enabled during an open raw-source edit precisely because it can't fight the buffer (03-board-ui.md ▸ toolbar). Accepted consequence: the card window's "Modified ⟨date⟩" line (05-card-window.md) can read older than the card's latest attachment activity — attachment history lives where files do (the sidebar shows them; on git boards the Attach/Remove commits are the activity trail — 06-history-undo.md). + **`modified-by` — self-reported provenance (settled).** An external writer (agent, script) may stamp a file it writes with a short free-form identity (`modified-by: claude`). The app never sets it and **clears it on every app-mediated write** — absence means "the board's user, via the app"; the file is being rewritten anyway, so clearing costs no extra write. Consequences compose from existing rules: copies arrive cleared (paste and duplicate are app writes), template instantiation strips it alongside its timestamp restamp (09-templates.md), Save as Template keeps it inertly. The key is schema-owned, not an unknown key — unknown-key preservation doesn't apply to it. Downstream surfaces: the card window's modified line renders it (05-card-window.md), and it refines foreign commit attribution (06-history-undo.md). Honest limit: it is self-reported — a hand edit that leaves an old stamp in place inherits its attribution until the next app write clears it. One carve-out: **raw-source Apply** (05-card-window.md) writes byte-for-byte and does *not* clear a stamp the user typed or kept — the outlet exists to write anything, and the validated-then-verbatim contract outranks the clearing rule. ### Board (`/index.md`)