aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/design.md51
1 files changed, 33 insertions, 18 deletions
diff --git a/docs/design.md b/docs/design.md
index 8e4e914..9a15425 100644
--- a/docs/design.md
+++ b/docs/design.md
@@ -1,6 +1,6 @@
# krino design
-Status: draft for review, 2026-09-11. Target release: **0.0.1**.
+Status: describes krino 0.0.1, 2026-09-13.
krino (from Greek κρίνω, "to separate, to judge, to decide") sorts files in
chosen directories by rules. A rule tests a file's type, name, path, size,
@@ -216,12 +216,22 @@ Candidates are the scanned files plus, for `(duplicate "DIR"...)`, every
regular file under those directories (symlinks skipped). Files are grouped
by size. Only groups of two or more are hashed: first the first and last
64 KiB, then SHA-256 of the whole file. Empty files are never duplicates.
+Two names for the same file — the same device and inode, as a hardlink
+creates — are never duplicates of each other; they may still both be
+duplicates of a separate identical file.
The **original** in each group is, in order of preference: a file under one
of the given DIRs, then the oldest by mtime, then the shortest name, then
the name that sorts first. `(duplicate)` is true for every other scanned
file in the group.
+`(duplicate)` conditions with different scopes do not share an original:
+two conditions electing from different candidate sets can each treat a
+different file as the original of the same content, and within one
+directory's rules this can select every copy in a group for deletion. A
+run-wide election that keeps at least one copy of every group is not in
+0.0.1.
+
## 6. Content extraction
| Format | Method |
@@ -427,9 +437,10 @@ not logged; declined files are.
## 10. Undo
- `krino log` lists recent runs: id, time, directories, counts.
-- `krino undo` reverses the most recent run that has not been undone, in
- every directory it touched; `krino undo RUN` a specific one. Undo runs
- cannot themselves be undone.
+- `krino undo` reverses the most recent run, in every directory it
+ touched; if that run is itself an undo run, it is refused. An older run
+ is undone by naming it: `krino undo RUN`. Undo runs cannot themselves be
+ undone.
- Undo builds a plan like any other, shown and approved the same way
(`-y` and `-n` apply).
@@ -526,17 +537,19 @@ Rules for the GUI to come:
- Measured before release on a real downloads directory of a few hundred
files, about half of them PDFs, and reported in the release notes.
**No performance target for 0.0.1.** Measured throughput is dominated by the
- external extractors, not by krino: on a real folder of 265 files, 164 of them
- needing `pdftotext` at roughly 80 ms each, a full plan takes 12-17 s, while a
- synthetic tree of 4405 files needing no extraction takes 1.09 s. A single
- threshold would therefore describe poppler's speed and the shape of one
- folder rather than anything about krino, and would fail or pass for reasons
- outside its control. Report the measurement; promise nothing. `make bench`
- runs the Go benchmarks on generated trees.
+ external extractors, not by krino: on a real folder of about 265 files, 164
+ of them needing `pdftotext` at roughly 80 ms each, full plans measured
+ between about 13 and 20 s across runs, while a synthetic tree of 4405 files
+ needing no extraction takes 1.09 s. A single threshold would therefore
+ describe poppler's speed and the shape of one folder rather than anything
+ about krino, and would fail or pass for reasons outside its control.
+ Report the measurement; promise nothing. `make bench` runs the Go
+ benchmarks on generated trees.
## 14. Build, dependencies, release
-- Go 1.24 or newer. `CGO_ENABLED=0`: static binaries.
+- Go 1.24 or newer. `CGO_ENABLED=0`: static binaries on Linux and FreeBSD;
+ on OpenBSD Go links against the system libc, as that platform requires.
- Go dependencies: `golang.org/x/term` (key-at-a-time input) and
`golang.org/x/text` (Unicode normalisation for `fold`). Everything else is
the standard library, including the s-expression reader and the gitignore
@@ -571,8 +584,7 @@ Repository contents for 0.0.1: `README.md` (60-second quickstart),
`LICENSE`, `CHANGELOG.md`, `Makefile`, `go.mod`, `cmd/`, `internal/`, `scripts/`,
`man/krino.1`, `man/krino.conf.5`, `docs/design.md`,
`docs/sexp-primer.md`, `examples/` (by type, invoices by tax number with
-placeholder numbers, screenshots by date, cleaning up old installers),
-`testdata/`.
+placeholder numbers, screenshots by date, cleaning up old installers).
## 15. Testing
@@ -583,8 +595,10 @@ placeholder numbers, screenshots by date, cleaning up old installers),
path against `git check-ignore --no-index` (skipped if git is absent).
- **Conditions:** truth tables; a property test that random condition trees
give the same result with and without cost reordering.
-- **Extraction:** small fixtures in `testdata/` for each format; PDF and
- legacy-format tests skip when the tool is missing.
+- **Extraction:** the tests generate their fixtures in temporary
+ directories and use fake tools for PDF and the legacy formats (doc, xls,
+ ppt); the real `pdftotext` test skips when the tool is missing. Real
+ office-suite files and real legacy-tool runs are not tested in 0.0.1.
- **Plan, apply, undo:** in temporary directories: build a tree, plan,
apply, check; undo; check the tree is identical to the start (paths,
contents, modes, mtimes). A cross-filesystem move test runs when a tmpfs is
@@ -629,8 +643,9 @@ keyword. Its defects shaped these decisions:
remote is chosen, `go mod edit -module <path>` and one `sed` over the
`"krino/internal/...` imports rename it; nothing else depends on it.
`go install ...@v0.0.1` works only after that.
-2. **License: GPL-3.0-or-later.** Full text in `LICENSE`; every source file
- carries `// SPDX-License-Identifier: GPL-3.0-or-later`.
+2. **License: GPL-3.0-or-later.** Full text in `LICENSE`; every Go file,
+ shell script and man page carries an
+ `SPDX-License-Identifier: GPL-3.0-or-later` line.
## Appendix A: type groups