One row of the task list rendered by the TUI: enough to render the
list view without round-tripping for each task. event_count joins
events_index so we don’t need a second query per row.
Read only the tail of the JSONL log since the last call. The cheap path
for hot loops (every MCP tool invocation): scan to the marker, ingest
the rest, update the marker.
All tasks for a project, ordered with open ones first (by recency)
then closed ones. The TUI list view binds directly to this — there
is no other consumer, so the shape is tuned for that callsite.
Returns whether a task with this id has been recorded in the derived
state. Cheap O(1) lookup against the tasks primary key. Callers
should run ingest_new_events first if they want to see the latest
JSONL state.