Realign code with the 2026-07-29 findings-resolution rulings

Nine rulings land as code. Reorders don't stamp — one container-change
predicate (WriteOperation.rewritesOrderOnly): within-container reorders
and the renumber rescale rewrite only order, while cross-lane, cross-board,
and trash moves stamp modified and clear modified-by; no trash special
case exists, and the m8 undo inverses conform through the same seam.
Copies are transactions: the root-strict/nested-lenient split retires for
a whole-subtree stampability preflight that refuses loudly naming the
offender, and every item-level copy severs remote/remote-state at every
level (whole-board forks carry them verbatim). Paste refuses, never
degrades: the embedded-index.md materialization and its loss row retire;
a missing staged snapshot produces nothing and posts an error-tone
one-shot named from manifest metadata. Coerce-tier fallbacks log through
the Defect stream with path context attached loader-side. Displacement is
level-uniform: a file squatting attachments inside a card heals by the
same rename ladder as board-root squatters; comments stays tolerated.
Delete Immediately joins card and lane context menus as Delete's
⌥-alternate with its own VO custom action, routed through an explicit
container so the menu target outranks standing selection. Agent guide v7
teaches the stamp discipline and the card-level attachments claim, and
sheds two stale v6 lines (lanes trash now; kind is taught). Verified
conformant, unchanged: edition-aware Undo/Redo disable, trash marquee
full-height backdrop.

Both schemes 1854 tests / 318 suites green; verify-editions 30/30.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-30 06:49:11 -04:00
parent 5ae48de0ea
commit 69084fdff7
27 changed files with 2159 additions and 542 deletions
+29 -9
View File
@@ -8,7 +8,8 @@ import os
///
/// A template is a board folder, so discovery is `BoardLoader.load` and instantiation is a tree copy
/// plus the Writer's own remint-and-restamp machinery (`BoardWriter.remintDescendants`,
/// `stampCopiedDescendant`, `updateIndex`). There is no template schema, no template catalog in
/// `checkCopiedDescendantsAreStampable`, `applyCopyContract`, `stampCopiedDescendant`,
/// `updateIndex`). There is no template schema, no template catalog in
/// Swift, and no second copy path which is 09's "dogfood" clause and 02-architecture.md's single
/// write door, both held by having nothing here to hold them with.
///
@@ -379,19 +380,35 @@ enum TemplateEngine {
/// The born half, on the tree already at the destination: fresh identities, fresh stamps, the
/// chosen title, and the loose-file normalization an import boundary owes.
///
/// **The root is strict and the descendants are lenient**, which is `BoardWriter.copyItem`'s
/// split for its reason: the root *must* be rewritten (it carries the title the user just typed),
/// so a template whose own `index.md` cannot be edited in place refuses the create while a
/// nested card that is readable-but-uneditable is copied byte-verbatim and simply not stamped,
/// because failing a whole create over one hand-dropped flow mapping would be hostile. Its stale
/// `modified-by` surviving is the self-reported-provenance honest limit 01 § Frontmatter already
/// acknowledges.
/// **An instantiation is a copy transaction**, which is `BoardWriter.copyItem`'s posture since
/// 2026-07-29 and for its reason: the whole tree is preflighted for stampability before a single
/// folder is reminted, and a template carrying one readable-but-uneditable card refuses the create
/// whole, naming that card (01-storage-format.md § Frontmatter: "preflights the entire subtree and
/// refuses whole, loudly, naming the offending item never a partial copy, never a silently
/// unstamped descendant").
///
/// This retired the former root-strict/descendants-lenient split, which copied such a card
/// byte-verbatim and skipped its stamp. Two things were wrong with the kindness: an unstamped
/// descendant keeps a `modified-by` naming somebody who never touched this board, and since the
/// tracker sever joined the copy contract a live `remote` claim on an object the new board has
/// no relationship with. "Proceed partially, lose a little" is never a verdict (01's leniency
/// doctrine).
///
/// **The preflight runs on the destination, not the template**, deliberately: the copy has already
/// applied its top-level exclusions, so `.trash/`'s cards which are not part of what a template
/// instantiates cannot refuse a create they were never going to appear in. Nothing is lost by
/// preflighting a step later, because `instantiate`'s construct-then-clean removes the whole
/// destination on any throw (09-templates.md's atomicity).
private static func mintIdentitiesAndStamps(
at root: URL,
title: String,
operation: WriteOperation
) throws(Failure) {
do throws(BoardWriteError) {
// Before the remint, so a refusal names folders by the paths the user's template actually
// has rather than by minted UUIDs they have never seen.
try BoardWriter.checkCopiedDescendantsAreStampable(of: root, operation: operation)
var materialized: [URL] = []
try BoardWriter.remintDescendants(of: root, collecting: &materialized, operation: operation)
@@ -402,7 +419,10 @@ enum TemplateEngine {
// cannot answer, and this write is where a template's kind-less root gains it
// (`BoardWriter.updateIndex`'s on-touch backfill; no template migration, by design).
try BoardWriter.updateIndex(inItemFolder: root, kind: .board, operation: operation) { document in
document.set(FrontmatterKeys.created, to: .date(now))
// `.born` restamps `created`; the copy contract also severs the reserved tracker keys,
// which at board level is the `remote` a template could have carried in from the board
// it was saved from (01 Identity lifecycle, ruled 2026-07-29).
BoardWriter.applyCopyContract(to: &document, stamps: .born, now: now)
document.set(FrontmatterKeys.title, to: .string(title))
}
for folder in materialized {