26. Claude appends task boxes to a list of actions#
Date: 2026-10-24 (#191, #193)
Status#
Accepted. Amends 20. Text enrichment: Claude tags, summarises and relates text pages, apart from the text, which said enrichment never edits a page’s text, and applies 22. Page text editable over MCP, made safe by text revisions (Claude-authored text revisions) to scrap’s own photo ingest (9. Claude ingest: Messages API, no tools, one structured call per photo) and enrich.
Context#
scrap already turns an unfixed note with task boxes into a todo, but only the user could write the boxes. A photo of a sticky headed “CURRENT ACTIONS” was ingested as a whiteboard with its transcription in a derived row, and a typed “call the dentist / book MOT / pay invoice” stayed a note: neither could be ticked.
Decision#
Photo ingest and enrich both return
intent(list-of-actions,reference,other),confidenceanditemsfrom one shared prompt section and schema fragment, and use one writer (src/scrap/actions.py).With high confidence, and only on a
notewithkind_fixed0 (or a whiteboard ingest chose) that has no task boxes and has not been edited since Claude read it, the writer appends- [ ] itemlines as one text revision byclaude, which never folds into another. The existing task-box rule makes the page a todo.revert_textundoes it.Appended, not converted. Even when the user’s lines are already plain bullets, the boxes are added below and the original text is left exactly as it was. Converting in place would rewrite the user’s words, and the cost of appending (the list shown twice) is small and one revert away. A photo’s transcription is not copied into the body: its boxes come from the extracted items, and the image stays above them.
Items are untrusted: plain single-line text, at most 30 of at most 200 characters, with list marks, links (and URL schemes and
www., so nothing autolinks), code, tags, emphasis marks, backslashes and character references removed. They are never read as instructions.Never a fixed kind, a saved link, or a page with boxes, so a second reading (Reprocess, Ask Claude, a save) adds nothing. Priority and due dates read from the sticky are not parsed.
Consequences#
Text sent to Claude is unchanged; its output now can change a page’s text, visibly, in one revertible revision (
is:claude-editedfinds it). A wrong high-confidence reading is one revert away, and the prompt tells the model to answerreferenceorotherwhen unsure.A saved text page queues one further enrich job after the revision (a save), which adds no boxes: one more cheap call per converted note.
A
revert_textthat takes the boxes away from a todo that Claude’s own boxes made returns it to the kind it was filed as before: the kind photo ingest chose for a photo page (whiteboard or document), else a note. The kind is derived, not part of the revision, soStore._unboxdoes this only for an unfixed todo with its defaultopenstatus whose previous text had boxes and where no revision by anyone but Claude ever had a box, so the boxes can only be Claude’s (no marker is stored; it is derived from the history, so it holds when a quick MCPedit_pagefolds the revision that added them). A todo the user filed or edited with boxes, an import, or a page whose own text had boxes stays a todo. Thestatus: openfield the todo kind added is left on the page.Intent gating for Slack-style prose, standing directives and relative due dates stay out of scope.