The 2026-07-29 integrity design pass, consolidated (DESIGN/01 -
Validation and healing; DESIGN/02 - Components): IntegrityRules
(Storage, pure) is the one home for the identity predicate and
canonical form (BoardWriter.canonicalIdentity deleted, ItemID and the
loader forward to it), the per-field rulebook, uneditable shapes,
per-kind index validation, the reserved-name tables, and the trash
kind discriminator (values trusted - kind: lane/card explicit,
unrecognized falls to shape). LoadResult's ad-hoc channels fold into
one typed Defect stream (looseCardFiles / legacyTombstone /
claimedNameSquatted, per-defect heal signatures); the old accessors
survive as computed views.
HealScheduler (LiveStore) states the six-step heal pattern once -
resting-clear, lock gate, isWritableFile gate (now covering all four
heals), signature memo armed-before-attempt with explicit
clear-on-success, disk re-verify in each write half, one banner-posture
table (BannerCenter keeps all phrasing). The three hand-rolled healers
run on it with behavior preserved - including the
relocation-notice-despite-partial-failure quirk, deliberately. Heals
run at the reload tail AND at registry acquire, closing the
migration-never-fires-at-open asymmetry. Displacement runs first: a
squatted .trash would otherwise fail the migration and arm its memo
against an unchanged picture.
Claimed-name squatters (ruled today, 62c47a2) displace by the shared
Finder-style rename ladder - preserved verbatim, symlinks moved as
links, nothing stamped; AgentGuide's untouchable-skip upgrades to
displace-then-write, the CLAUDE.user.md-taken skip stands. kind stamps
on every create and backfills on any index rewrite via the on-touch
seam (placement resolver stamps nothing when the parent is unknown -
a guessed kind is worse than an absent one; board-root writers declare
theirs). Heal writes mark their EchoLedger receipts (inert in base;
pro-m1's committer will split them into their own commits). The
renumber ask-renumber-ask-again two-step is one shared helper, adopted
at all nine call sites.
69 tests added. 1738 green on both schemes.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
A real agent incident (2026-07-29): moving cards with mv <lane>/* swept
the lane's own index.md along with the card folders, overwriting the
destination lane's identity file and leaving the source lane index-less
(the Implementation board briefly lost its lane titles; restored from
its auto-commit history). Both guide generations taught the correct
named-folder form but never said why it is load-bearing.
v6 adds the one-folder-at-a-time bullet to Moving and reordering:
a lane folder holds its own index.md beside its cards, so a glob
sweeps the identity file with them. Boards heal to v6 on their next
open per the first-line marker rule. The guide tests now derive
their expected marker and current/newer versions from
AgentGuide.version instead of a hardcoded literal, so the next bump
cannot silently break them.
1669 green on both schemes.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
The v5 guide prose, verified two ways. A scripted walkthrough gave a
fresh agent nothing but the guide and a demo board: it created a card
(fresh lowercase UUID, correct bottom rank), moved one to a lane top
with modified and modified-by re-stamped, deleted one into .trash/,
attached a file into attachments/, picked `fern` off the palette table,
and quoted a colon title — and the resulting board loads through
BoardLoader with zero warnings. The walkthrough's one finding is fixed:
the trash-arrival rule now reads formulaically ("smallest order minus
1024") instead of the spatially ambiguous "below the smallest order".
Content drift-guards join the suite: every palette name the app resolves
must appear in the guide (a Palette rename now fails a test instead of
teaching agents dead colors), the rewrite's conventions are present by
name (.trash/, attachments/, modified-by, CLAUDE.user.md, the
stage-only-your-own-paths rule), and the pathfinder's retired vocabulary
(media/, tombstones) cannot resurface — the only deleted: mention is the
warning never to write it.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
The app-owned agent guide at every board root (DESIGN/08 ▸ The agent
guide): version-gated by a first-line marker (v5, superseding the
pathfinder's v4 guides on real boards), rewritten when missing or older,
byte-for-byte untouched when current or newer. A markerless CLAUDE.md is
displaced to CLAUDE.user.md when that name is free — never clobbered —
and the guide write is skipped with a log when it isn't. Symlinks,
folders, and read-only volumes are skipped in silence; the write rides
performWrite's bracket as an app-mediated Writer operation (new
WriteOperation.agentGuide), so the echo lands appMediated and the
Pro-era committer can attribute it honestly later.
Hooked at store acquire (beside the loose-file relocation, after the
watcher exists) and on every successful reload — the guide self-heals
from foreign deletion or rollback, pre-wiring 06's acknowledged undo
bounce. The refresh memo arms before each attempt and clears on a
successful write, so a failing write can't hot-loop and a foreign
deletion stays healable. First-line-only marker parsing (no Regex);
guide content is one swappable literal, finalized under the next card.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY