diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 23:39:37 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-14 23:39:37 +0200 |
| commit | c09020c2fb01da24d5befbed78ce3b73b5efbe4c (patch) | |
| tree | 8cd1086588988fafaf238aed8a38a7ec85b0afa3 /docs | |
| parent | 3990586a85e91923c0a3ae1a1f0f61420db555ac (diff) | |
| download | krino-c09020c2fb01da24d5befbed78ce3b73b5efbe4c.tar.gz krino-c09020c2fb01da24d5befbed78ce3b73b5efbe4c.zip | |
content tests are three-valued: unknown when unreadable or read in part
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/design.md | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/docs/design.md b/docs/design.md index 35b0de0..4196894 100644 --- a/docs/design.md +++ b/docs/design.md @@ -199,10 +199,12 @@ as "excluded" in the plan, listed with the form that matched under `-v`, and traced by `explain`; `check` lists every directory's exclusions. Since no rule has run yet, `(matched)` is never true inside an exclude. -An exclude fails closed: when evaluating it reaches a content test that +An exclude fails closed: when its value depends on a content test that cannot read the file (over `max-read`, a tool missing, failing or timing -out), the exclude holds, and the file is set aside as "(content -unreadable)" with the warning. A file whose format has no text at all (an +out, or a document read only in part), the exclude holds, and the file is +set aside as "(content unreadable)" with the warning (§5.4 rule 4). One that +is false whatever the text holds, such as `(exclude (content "x") (type +txt))` on a pdf, does not. A file whose format has no text at all (an image, an archive) is not unreadable: it contains no keyword, so its content tests are simply false and raise no warning. So is a file of no known extension that starts as text and holds binary data further on, such @@ -258,10 +260,16 @@ UTF-8 is replaced by U+FFFD before folding. cheapest first: `type`, `size`, `age` and `matched`, then `name` and `path`, then `duplicate`, then `content`. Content is extracted at most once per file, and only if evaluation reaches a `content` test. -4. If a file's text cannot be extracted, `content` is false and the plan - shows a warning naming the rule that wanted it. A format with no text - (§6, "anything else") is not a failure: `content` is false, silently. Inside an `exclude` the - whole exclude then holds instead (§4.6). +4. If a file's text cannot be extracted, `content` is **unknown** and the + plan shows a warning naming the rule that wanted it. A document read only + in part (an archive entry that would not open) answers a keyword found in + what was read; one not found is unknown. `and`, `or` and `not` combine + unknowns by three-valued (Kleene) logic: `and` is false if any argument is + false, `or` true if any is true, `not` of unknown is unknown, so an + unknown only reaches the top where the text could change the answer. A + rule matches only when its condition is true; an unknown exclude holds + (§4.6). `explain` shows an unknown test as `?`. A format with no text (§6, + "anything else") is not a failure: `content` is false, silently. ### 5.5 Duplicates @@ -896,7 +904,9 @@ What that means, and the tests that hold it (plans 8 and 9): - Undo restores a trash entry only while it is still the file the run put there (size, mtime, recorded path), re-checks every file at execution time, and can finish an undo that stopped part way. -- An exclude whose content test cannot read the file holds (fails closed). +- An exclude whose value depends on a content test that cannot read the + file holds (fails closed); a rule whose value does is not matched, so + `(not (content "x"))` never acts on a file krino could not read. - A file reaches an external tool only as an absolute path, so a name starting with `-` is never read as an option. - A trash entry name from the log must be a plain name inside the Trash, |
