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:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user