Skip to content

D302 — Work is a view over open states and unchecked items, not a type

Decision. A work item is either a concept in an open phase for its map, of any type, or an unchecked - [ ] item in any concept, whatever that concept's status. work_list (and the Atlas Work panel through GET .../work) returns them read-only, filtered by concept_list's where. It returns and orders by the frontmatter fields the caller names, and never interprets them. kb_status.work counts them. A map may name a work_map. Work kept elsewhere in that map with no link into it then becomes the scattered_work review kind.

Why. The KBs measured for this keep work in two generic shapes. In the larger one there are no Task concepts at all, 127 journal entries in an open status and 315 open checkboxes spread over 199 pages. A planner keyed on a type would see none of that, and making it visible would need a migration. Open phases (open_statuses, D297) and checkboxes already exist as concepts the server knows. Priority, owner and due date are each KB's own vocabulary. The server stays generic by sorting on them as strings rather than modelling them.

A read-only view keeps every change to work behind the ordinary write tools and their gates. Per-principal assignment and permissions on work belong to the permission work planned for 0.19. Scattered work is flagged only where a contract says where work belongs. A KB that keeps its work in journals gets no noise.

Alternatives rejected. - A Task type with a schema: invisible to KBs that track work in journals and checklists, and it forces a migration before any value. - Write operations on the view (claim, close, move): these would bypass the write gates and need the permission model that does not exist yet. - Interpreting priority/due: every KB names and scales them differently. Ordering by caller-named keys gives the same value without a vocabulary. - Flagging every checkbox outside a backlog: noise for KBs whose journals are where work lives on purpose, so work_map is opt-in. - Trimming other tool descriptions to fit work_list in 22 KiB: D301 had already removed the lists that grow. The remaining text is calling rules. The agent tools/list went from 22,490 to 23,190 bytes, so the budget is 23 KiB, and work_list's own description is capped at 350 characters by a test.

Consequences. The collector (lint.Work) is pure and shares openPhase, the checkbox pattern and code masking with the lifecycle lint, so the view and stale_open/closed_with_open_items cannot disagree, with one deliberate exception: by default the draft family is not work. Tried on a real KB, the view listed study pages in draft as open work. A draft says a page is still being written, not that something in its subject is pending, so it is work only where a map's open_statuses lists it; it still goes stale for stale_open, and its unchecked items stay work. total counts entries, for paging, while open_concepts and by_status count only open-phase concepts: a closed concept listed for its items would otherwise show its closed status as work. The cached view is keyed on the lint inputs and the day, because ages move with the calendar. Visibility is applied outside the cache, and a test pins that a hidden concept never reaches entries or counts. work_list is part of the agent core set: a descriptor-bound host cannot call a hidden tool (D123). scattered_work ranks after promotion_candidate, and lint_ignore dismisses it.