Lens v2

playground — every verdict computed live today = 2026-08-19
{ }river
Predicates select rows.
Scope selects the universe. Shape arranges. Reducers calculate. Views render. Every edge case is judged against these five.
bare word → a view
Always, and only. board:status is not a view with a field — board is not a property key. Write group:status board.
key:value → everything else
Filter, scope, shape, reduce.
:tag: · "text"
Tags keep their colons because that is how they are written in the document.

cardinality

group: sort: limit: render: and the view are 0..1 — repeating one is a parse error, never last-wins. Everything else is many. is:todo is:done is legal: an empty intersection is not a malformed line.

execution

SOURCE → SCOPE → FILTER → SORT → LIMIT → GROUP → REDUCE → RENDER

Canonical syntax order is for storage and diffing; it has nothing to do with evaluation. limit: is global and applies before grouping. sort: orders rows within each group.

negation

One rule everywhere: -key:value matches blocks that do not have that key with that value — absence counts. So -is:done returns notes and meals too. For open tasks only, write is:task -is:done.

is:

Names a value and infers the field. Its vocabulary is exactly what is drawn on a block — the TODO/DONE keyword and the type badge — so there is nothing to memorize. Properties have no face and never join it: priority:high, never is:high.

diagnosis

Repaired beats refused; refused beats silent. A query returning nothing shows cumulative counts term by term, because an intersection can be empty without any single term being wrong.