Gate relocation noise on a universally seeded .gitignore

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-31 19:06:14 -04:00
parent 11981a2a99
commit cb87ea79c1
2 changed files with 2 additions and 2 deletions
+1 -1
View File
@@ -31,7 +31,7 @@ MyBoard.kanban/ ← board = the document
- `index.md` = YAML frontmatter between `---` delimiters, then Markdown body.
- **Reserved child names** at card level: `attachments/` (specified below) and `comments/` (enhanced schema — see below). Never levels themselves, never identity (identity-bearing siblings are UUIDs).
- **Name shape gates level detection** (settled): only folders passing the identity predicate (the shape-only rule above — 8-4-4-4-12 hex, any case, any version) are lane/card candidates. Anything else — even with an `index.md` inside — is a stray: skipped with a log warning, preserved verbatim, never rendered. A hand-made `notes/` folder or a board nested inside another can never brick a load; the cost — a hand-authored lane named `todo/` doesn't render — is what the warning and the agent guide exist for.
- A UUID-named folder below the root **lacking `index.md` is skipped with a log warning**, not an error — an interrupted two-step create must not brick the board. **Stray tolerance is uniform at every level**: non-reserved files and folders at board, lane, or card level are ignored by the loader, preserved verbatim, never rendered (inside a card, only `index.md` and the reserved child names mean anything). **One carve-out — loose *files* in a card folder are relocated, not tolerated** (settled 2026-07-28, Lanework-owns-the-board): a regular file sitting beside a card's `index.md` (not `attachments/`, not a reserved name) belongs in `attachments/`, and the app moves it there — Finder-style rename on collision — surfacing a graceful warning-tone notice naming the card and files ("Moved 'notes.txt' into attachments — 'Fix login'"; plurals fold). Detection stays read-only in the loader (the Repair precedent); the relocation runs through the Writer as an app-mediated write, commits normally on git boards, and waits out any read-only lock (strays stay tolerated until it clears). The carve-out is exactly that narrow: stray *folders* in a card (a nested clone, a hand-made subfolder), symlinks (never touched, above), and everything at board or lane level keep the verbatim posture — relocating a directory into the flat attachment model would be wrong, and board/lane-level strays (`CLAUDE.user.md`, a `notes/` folder) are legitimate residents. The agent guide teaches the rule (08-agent-integration.md): card files belong in `attachments/`. **Three board-root names are app-claimed, not strays** — the one scope on the verbatim promise: `CLAUDE.md` is app-owned and rewritten on guide version bumps, with a markerless user-authored `CLAUDE.md` relocated to `CLAUDE.user.md` (08-agent-integration.md ▸ The agent guide — that name is claimed too), and adding git seeds `.gitignore` (06-history-undo.md ▸ Repository hygiene; seeded once, then the user's to edit). Agents and hand-editors should treat these names as the app's at board root; everything else is untouched. **A claimed name held by the wrong kind of node is Lanework's to heal — by displacement** (ruled 2026-07-29 — Lanework owns the board, so an invalid artifact on a claimed name is a defect, not a resident): a regular file or symlink squatting `.trash` (a directory name), or a directory or symlink squatting `CLAUDE.md` (a file name), is moved aside by a scheduled heal (Validation and healing below) via the Finder-style rename ladder (`.trash``.trash 2`), **preserved verbatim, never destroyed**, with the relocation-style warning-tone notice naming old and new; the freed name then serves the app (the next delete mints the real `.trash/`; the guide write proceeds). **The rule is level-uniform** (extended 2026-07-29): a card's reserved child names are claimed the same way — a regular file or symlink squatting `attachments` (a directory name) displaces by the same ladder (`attachments``attachments 2`), so imports, Finder drops, and the sidebar listing never fail one gesture at a time against a squatted name; the displaced file, now an ordinary loose file, rides the next relocation into the real `attachments/` — the heals compose. The reserved-but-unconsumed `comments` is the timing principle's own illustration: nothing reads that name until the tracker era, so a wrong-kind holder is a tolerated stray today and joins the scheduled class the day the name becomes load-bearing. This upgrades the agent guide's former untouchable-skip to a displacement — the invariant that survives is displacement-never-destruction. One standing exception: the settled `CLAUDE.user.md`-taken skip stands — that displacement has a designated *destination*, and freeing a destination by a second displacement would cascade renames; the guide write skips with a log as settled (08-agent-integration.md).
- A UUID-named folder below the root **lacking `index.md` is skipped with a log warning**, not an error — an interrupted two-step create must not brick the board. **Stray tolerance is uniform at every level**: non-reserved files and folders at board, lane, or card level are ignored by the loader, preserved verbatim, never rendered (inside a card, only `index.md` and the reserved child names mean anything). **One carve-out — loose *files* in a card folder are relocated, not tolerated** (settled 2026-07-28, Lanework-owns-the-board): a regular file sitting beside a card's `index.md` (not `attachments/`, not a reserved name) belongs in `attachments/`, and the app moves it there — Finder-style rename on collision — surfacing a graceful warning-tone notice naming the card and files ("Moved 'notes.txt' into attachments — 'Fix login'"; plurals fold). Detection stays read-only in the loader (the Repair precedent); the relocation runs through the Writer as an app-mediated write, commits normally on git boards, and waits out any read-only lock (strays stay tolerated until it clears). **`.gitignore` is the noise gate** (ruled 2026-07-31): a file matching the board-root `.gitignore` — standard gitignore pattern semantics against the board-relative path; nested `.gitignore` files are ordinary strays the heal never consults — keeps the ordinary stray posture: skipped, preserved verbatim, logged, never relocated, never announced. The exclusion list is exactly that file, nothing hardcoded — the app seeds `.gitignore` on every board (06-history-undo.md ▸ Repository hygiene: `.DS_Store` plus the writer's own temp pattern `.*.lanework-*`), and fine-tuning what counts as noise over time means fine-tuning the seed or editing the board's copy. On Pro boards the same file governs the committer, so ignored noise neither relocates nor commits — one definition of noise, two consumers. The carve-out is exactly that narrow: stray *folders* in a card (a nested clone, a hand-made subfolder), symlinks (never touched, above), and everything at board or lane level keep the verbatim posture — relocating a directory into the flat attachment model would be wrong, and board/lane-level strays (`CLAUDE.user.md`, a `notes/` folder) are legitimate residents. The agent guide teaches the rule (08-agent-integration.md): card files belong in `attachments/`. **Three board-root names are app-claimed, not strays** — the one scope on the verbatim promise: `CLAUDE.md` is app-owned and rewritten on guide version bumps, with a markerless user-authored `CLAUDE.md` relocated to `CLAUDE.user.md` (08-agent-integration.md ▸ The agent guide — that name is claimed too), and the app seeds `.gitignore` on every board (re-ruled 2026-07-31 — at creation, healed in when missing at open, git or not; 06-history-undo.md ▸ Repository hygiene; seeded, then the user's to edit). Agents and hand-editors should treat these names as the app's at board root; everything else is untouched. **A claimed name held by the wrong kind of node is Lanework's to heal — by displacement** (ruled 2026-07-29 — Lanework owns the board, so an invalid artifact on a claimed name is a defect, not a resident): a regular file or symlink squatting `.trash` (a directory name), or a directory or symlink squatting `CLAUDE.md` (a file name), is moved aside by a scheduled heal (Validation and healing below) via the Finder-style rename ladder (`.trash``.trash 2`), **preserved verbatim, never destroyed**, with the relocation-style warning-tone notice naming old and new; the freed name then serves the app (the next delete mints the real `.trash/`; the guide write proceeds). **The rule is level-uniform** (extended 2026-07-29): a card's reserved child names are claimed the same way — a regular file or symlink squatting `attachments` (a directory name) displaces by the same ladder (`attachments``attachments 2`), so imports, Finder drops, and the sidebar listing never fail one gesture at a time against a squatted name; the displaced file, now an ordinary loose file, rides the next relocation into the real `attachments/` — the heals compose. The reserved-but-unconsumed `comments` is the timing principle's own illustration: nothing reads that name until the tracker era, so a wrong-kind holder is a tolerated stray today and joins the scheduled class the day the name becomes load-bearing. This upgrades the agent guide's former untouchable-skip to a displacement — the invariant that survives is displacement-never-destruction. One standing exception: the settled `CLAUDE.user.md`-taken skip stands — that displacement has a designated *destination*, and freeing a destination by a second displacement would cascade renames; the guide write skips with a log as settled (08-agent-integration.md).
- **Symlinks are never traversed** (settled): the loader and the watcher treat any symbolic link in the board tree — identity-shaped name or not — as a stray: skipped with a log warning, preserved verbatim, never rendered, never followed. A link passing the identity predicate would otherwise render bytes living outside the board that FSEvents never reports — the silently-stale board 02-architecture.md structurally excludes — and a link cycle would make the tree walk non-terminating. Copy flows copy the link itself, never its target: Duplicate, Save as Template, instantiation, cross-board copies, and clipboard staging preserve the link verbatim as they do any stray.
- **Atomic writes**: temp file, rename over `index.md`.
- **Unknown frontmatter keys and their order are preserved verbatim** on every rewrite. This is load-bearing for agent overlays (`project:`, `sphere:`, custom tags) — see 08-agent-integration.md.