Commit Graph
4 Commits
Author SHA1 Message Date
Connor JohnstoneandClaude Opus 5 caa367feb2 Fix review.sh inventing 12 removals that the prune never makes
It round-tripped the pruned text through a shell variable, and command
substitution strips every trailing newline while printf added exactly one
back, so any file whose pruned output ended in more than one blank line
diffed against a reshaped copy of itself. Comparing files directly instead
brings review.sh to 270 removals across 118 files, matching validate.py,
which derives the same number from the drop set rather than from a diff.

The counting was wrong too: a removed `- [x] foo` is `-- [x] foo` in a
unified diff, so the `^-[^-]` pattern skipped every checkbox it was meant
to be counting.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PU5ZFfQFtDTFqqhvMTWdGH
2026-09-09 18:35:25 -04:00
Connor JohnstoneandClaude Opus 5 1053310d32 Add review.sh to regenerate the whole-corpus prune diff on demand
The plan gates the timer on reviewing this diff, and the same gate should
be re-runnable after any change to the rule.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PU5ZFfQFtDTFqqhvMTWdGH
2026-09-09 18:34:20 -04:00
Connor JohnstoneandClaude Opus 5 213e285c37 Add the server rollover, its systemd units, and an installer
Never modifies an existing note. It only creates today's file when that
file is absent, so the blast radius is one new file and re-running is a
no-op.

Two bugs that only a real run on the server could surface. tempfile
creates 0600 and os.replace preserves it, so notes would have landed
private in a tree where everything is 0644 and both sftpgo and syncthing
read; the previous note's mode is now carried over rather than hardcoded.
And --dry-run fell into a degenerate branch once today's file existed,
emitting a bare heading exactly when a preview is most wanted, so it now
always previews from the newest note that is not today.

The unit is sandboxed, and that was verified against the NFS mount rather
than assumed: writes to the notes directory succeed, and writes to its
parent are refused.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PU5ZFfQFtDTFqqhvMTWdGH
2026-09-09 18:33:54 -04:00
Connor JohnstoneandClaude Opus 5 185b45dbfc Add the prune rule, its tests, and a corpus validator
The rule PLAN.md describes and the rationale it gives for that rule
disagree on one shape that turns out to be common. 235 checkboxes in the
corpus sit under a plain bullet used as a group label, and by the letter
of the rule those have no checkbox ancestor, so a finished one would be
dropped on its own. But section 4 already argues the opposite case for
checkbox parents: a finished item under an unfinished group is context,
not cruft, and a label like `- Trellis "Ergonomics" Fixes` is a group in
every sense that matters.

Resolved in favour of the rationale, which collapses both cases into one
rule. A top-level bullet is any bullet with no bullet ancestor in its
section. It is dropped, with its subtree, exactly when that subtree holds
at least one checkbox and all of them are [x]. Prose bullets hold none and
so are never eligible, which is the property section 4 wanted.

Validated across all 228 notes with zero invariant failures: no heading,
no unfinished item and no checkbox-free subtree is ever removed, and no
group label is left with its children gone. 270 lines would be dropped
across 118 files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PU5ZFfQFtDTFqqhvMTWdGH
2026-09-09 18:30:29 -04:00