Repository navigation
Description
Problem
A taskbook with a few hundred items stops being a board and becomes a backlog nobody reads. On my own board (109 live items, 145 archived) a hand review on 2026-10-26 found that about a quarter of open tasks had no verb (~/containers, htop, VLC (cask)), notes split into bare tags with no content and 800-character runbooks, and 11 CA tasks repeated the same three sentences of rationale. Items like that are not actionable, and for an ADHD reader an item that cannot be acted on is an item that silently costs attention every time it scrolls past. Anyone running taskbook at 1000+ items has the same problem, diagnosis or not.
A second audience is agents. Models write to the board over tb --mcp now (#3 adds links and a size envelope for the same reason), and they produce exactly the failure modes above unless something pushes back at write time. commitlint did this for commit messages: a small rule file, a predictable error, and the writer learns the shape.
Proposal: a validation engine for items
A rule table plus an engine that evaluates every item (or one item, at write time) and reports findings with a severity.
Rule file, TOML, schema v1. One [[rule]] per predicate:
| field | values |
|---|---|
id |
stable slug, printed in output |
applies |
task / note / any |
state |
tasks only: pending / in_progress / done / open (default any) |
severity |
error / warn / info; exit 1 only when an error fired |
message |
text; {days} {ref} {other} {len} interpolated where the kind provides them |
except_boards |
skip items on any of these boards |
kind |
regex (pattern, flags, negate), count (pattern, max), length (min, max), board (boards), ref (dangling #N; the archive is not consulted, tb renumbers archived items), duplicate (case- and space-folded text), overdue (tasks past _dueDate) |
Regex dialect is the common subset of Oniguruma (jq) and Rust's regex crate: no lookaround, no backreferences. The point is that the same rules.toml drives a jq prototype today and a Rust implementation inside tb later.
The v1 rule set, which is just the hand review encoded:
- task is a bare path, bare URL, or single word (error)
- task under 25 chars (warn), over 300 chars (warn), or chaining more than three steps (warn)
- note that starts with an action verb, or sits on
@todo(error) - note under 25 chars outside inventory boards (warn)
- item on
My Board(error): the tag was quoted into the description - description ending in a literal
@tag(warn):tb -ekeeps old boards and leaves tags as text #Nnaming no live item (error)- two live items with the same text (warn)
- open task past its due date, with days overdue (info)
Prototype
Running now as lint/zk-lint.sh (jq 1.7+, about 90 lines) next to the data in my ~/.taskbook repo. First run over the board after the hand review: 10 errors, 12 warnings, 1 info. It caught two items on My Board, a bare-URL task, three notes tagged @todo and three references to purged items that the hand pass missed. One known false positive: an @Apps inventory note named Install macOS Catalina trips the action-verb rule.
Where it could land in tb
tb --lint(orzk lint): whole-board report, exit code for scripts and motd.- Write-time check in
create_task,create_note,edit_itemon the MCP server and the CLI: error-level findings refuse the write and return the message, so an agent gets the same feedback a human gets from commitlint. - Rules file discovery:
~/.taskbook/lint/rules.toml, with the v1 set as the built-in default.
Open questions: whether warn should ever block a write (I think no); whether the verb check should stay a negative pattern (bare path, URL, single word) or grow a verb list (negative is more robust, a list is more legible); how to express rules that need the whole board (ref, duplicate) in a write-time check that only sees one item.
Related: #3 (links, backlinks, size envelope). While doing the hand review I misread two CLI behaviours as bugs (--tag writes a separate tags field that is only serialized when non-empty; -e sets the description verbatim and boards move with -m). Verified against source and by reproduction; not filing. The --move section of docs/cli-reference.md does have two errors, fixed in a separate doc PR.
Activity