summaryrefslogtreecommitdiff
path: root/CHANGELOG.md
diff options
context:
space:
mode:
Diffstat (limited to 'CHANGELOG.md')
-rw-r--r--CHANGELOG.md79
1 files changed, 79 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e4dd69..ccb2a62 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,85 @@
## Unreleased
+## 0.0.12 — 2026-09-17
+
+Published, and reviewed. The repository is at
+`https://git.labunix.xyz/krino.git` and the module path is
+`git.labunix.xyz/krino`, so `go install git.labunix.xyz/krino/cmd/krino@latest`
+works from this release on. Then five reviews — security, correctness,
+determinism, performance and the window — found four high-severity defects
+and a number of smaller ones; what follows is what they found and what was
+done about it, each with the measurement or the test that settles it.
+
+**Files that could have been lost**
+
+- A symlink planted in the directory being sorted, named after a rule's
+ destination, redirected a move or a copy out of the tree — and under
+ `(on-conflict overwrite)` trashed a file *outside* it — while the plan the
+ user approved showed only the in-tree text. A step whose destination
+ passes through a symlink at or below the sorted directory now fails. A
+ destination the configuration itself names outside that directory, `~/docs`
+ on another disk say, is the user's own arrangement and is followed as
+ before.
+- A file trashed to make room was logged only when the step that needed its
+ name had finished — for a copy, the whole data transfer later. Killed in
+ that window, krino reported "nothing applied" while the user's file sat in
+ the Trash. It is now logged the moment it is trashed, and a displace that
+ cannot be logged fails the step.
+- A chain ending in `(delete permanent)` never gave back the file it had
+ displaced: the walk stopped at the delete, so the user's only copy stayed
+ in the Trash and `krino log` called the run undone. The displaced file is
+ offered as its own entry in the undo plan.
+- A `(duplicate)` test written in an `(exclude ...)` bought no protection at
+ all: a later rule permanently deleted every copy. Duplicate scopes are now
+ collected from excludes as well as rules.
+- The window could release the directory lock and close the log under a
+ running Apply — by saving rules, saving settings, adding a directory or
+ closing the window — so a file moved that no `krino undo` could see. The
+ tabs refuse to close while their apply is in flight.
+- Deleting one of two forms written on the same line deleted both, and
+ clearing a setting took whatever else shared its line — including the
+ closing paren of `(defaults ...)`, which broke the file the Settings
+ window had just written. Both take a whole line only when the line holds
+ nothing else.
+
+**The directory lock is now the kernel's.** `flock(2)` on the lock file
+replaces "write my pid, and judge whether the pid in the file is still
+alive". A crashed run's lock is released by the kernel, so there is no stale
+lock to detect and no takeover to race over: two runs could previously both
+decide a lock was stale and both take it. A pid reused after a crash no
+longer wedges a directory for ever, and a run that waits for a lock says so
+before it waits.
+
+**Faster, measured on invented corpora**
+
+- A content class is worked out once instead of once per copy: 2000
+ identical files, 1.89s → 0.58s, with byte-identical plans.
+- The search for a free `stem_N` continues instead of starting again at
+ `_1`: 1500 files renamed onto one name, 2.63s → 0.05s.
+- A file's name is folded once rather than once per name test: 4000 names
+ with diacritics over twelve rules, 0.33s → 0.13s.
+- `max-read` now bounds what a file *becomes*, not only what is read, and
+ large extractions are rationed: twelve 40 MB files, peak memory 3294 MB →
+ 728 MB. Small files are untouched.
+
+**Other**
+
+- `{now:FMT}` is the start of the run, as the spec always said, rather than
+ the moment each directory happened to be planned — so a long review cannot
+ split one run's output across two folders, or two dates.
+- The Settings window's sort order, column toggles and preview height were
+ read but never connected to anything; they work now, and changing a
+ setting no longer discards the divider positions.
+- "Keep this copy, replace the other" refuses a second file aimed at the
+ same place, which the engine has always refused to plan.
+- `About`, at the foot of Settings: the version, the licence, the author and
+ the repository.
+- The Plan tab's toolbar reads in the order the work happens, and `Scan`
+ carries the theme's accent.
+- Comments that cited the development process rather than the code are
+ rewritten; the README is a third shorter, with a screenshot.
+
## 0.0.11 — 2026-09-17
The window, worked over from a fortnight's worth of using it: the plan reads