Conversation
`land` is the tool the nightly ~/today sweep and every one-time landing lane
(loose ~/*.md, dated dirs, home canon, Downloads, ~/sept7 prose, root
relocations) run to move working files into notes without trusting that the
copy worked.
land copy <src>... --dest <dir> copy-then-verify, writes the packet
land verify <packet-dir> recompute every hash and count in it
land diff <src> <packet-dir> the rsync -rn --checksum equivalence check
The manifest is the shape built by hand for the 2026-09-16 orchestration-day
packet: a header with file count, total bytes and exclusions carrying reasons,
rows of {source, preserved, bytes, sha256, mtime, source_session}. That packet
verifies unchanged (697 rows == 697 files, sha256 all match). Older packets
without mtime or source_session warn rather than fail.
The copy keeps cp -p semantics and relative structure, never follows a symlink
(each becomes a kind: symlink row with its target), renames a nested .git to
dot-git and records renamed_from with the source-side path, and leaves out any
file over the 95 MiB ceiling with its reason in the README. Sources are only
ever read.
The secret guard runs over the whole plan before the first byte is written, so
an abort leaves no half-packet: names matching *.env, *token*, *secret*,
*credential*, id_ed25519* and *.age (overridable with --allow-secret-names),
and text content matching a GitHub token, an OpenAI-style key, an AWS access
key id or a PEM private key block (not overridable). It names the file and
never the value.
checks.land builds its own fixture lane in $TMPDIR — nested .git, symlink,
3-byte file, excluded glob, sparse file over the ceiling — and pins that a
flipped byte or a stray file fails verify, that the sources are untouched
afterwards, and that a count fault is not reported as a hash fault.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
Review note from the first real use (Downloads lanes, 12 packets, 3,222 files, all verify/diff exit 0):
None of these blocks the merge; the lanes landed with the correct spellings and an explicit override. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backlog row CNA-M07: the landing tool
land, used by the nightly~/todaysweep and by every one-time landing lane (loose~/*.md, dated dirs, home canon, Downloads,~/sept7prose, root relocations).Nothing here is wired into a host or a timer. It is a package, an overlay entry and a flake check.
What it does
copywrites a packet: the copied tree pluspreservation-<YYYY-MM-DD>.jsonandREADME.mdat its root. The manifest is the shape built by hand for the 2026-09-16 orchestration-day packet — a header carrying file count, total bytes and exclusions with reasons, and rows of{source, preserved, bytes, sha256, mtime, source_session}.Rules the copy obeys, each because a packet is evidence and not a backup:
cp -psemantics (mtime and mode preserved), relative structure kept;.gitdirectory or gitfile is renamed todot-gitin the copy, and the row recordsrenamed_fromwith the path it had at the source;kind: symlinkand itstarget, recreated verbatim in the copy;verifyrecomputes sha256 for every row and checks the row count againstfind -type fminus the packet's two artifacts.diffis thersync -rn --checksumequivalence check to run before any source is removed.Secret guard
Names matching
*.env,*token*,*secret*,*credential*,id_ed25519*,*.ageabort the run unless--allow-secret-names. Text content matching a GitHub token, an OpenAI-style key, an AWS access key id or a PEM private key block aborts with no override. Either way it names the file and never the value.Backward compatibility
The existing hand-built packet verifies untouched:
The older
nyu-2026-09-15manifest has nomtimeand nosource_session. Those rows warn, they do not fail — every one of its 209 hashes matches. It still exits non-zero because that manifest genuinely covers 209 of the 261 files in its directory, and the receipt says so in those words rather than blaming sha256.Tests
checks.landbuilds its own fixture lane in$TMPDIR— a nested.git, a symlink, a 3-byte file, a glob-excluded file and a sparse file over the ceiling — and drives copy, verify and diff over it. 30 tests. What is pinned: the manifest row count equalsfind -type f; the dot-git rename and itsrenamed_from; the symlink row; mode and mtime survive the copy; the sources are byte-identical afterwards; a flipped byte, a stray file and a missing file each fail verify; source drift fails diff; a moved packet still verifies; the guards abort before writing; and a count fault is never reported as a hash fault.rsyncis in the check's build inputs so the cross-check runs in CI and not only where the host happens to have it.Reviewer notes
rsyncis a second opinion, never the authority: a packet legitimately differs from its source in two recorded ways (the rename and the exclusions), sodiffalways hashes and adds the rsync pass only when neither applies.flake.nixshows 55 lines of pre-existingnixfmtdrift elsewhere in the file. It was left alone; only the added block is formatted.🤖 Generated with Claude Code