You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Task boards show rollout audit lines as titles for event-only Todos #5289
Personal Workspace task boards show titles such as todo add recorded for todo_584f55f8f3b4 for some open Todos (reproducible with the public examples/status.example.json).
These rows come from build_todo_index (loopx/control_plane/todos/todo_index.py). Todos present in the attention queue use their real text, but a Todo that is only known from the rollout event log (for example because the attention queue carries a bounded Todo list) is indexed from the event itself:
loopx todo add|update|… records the event with summary="todo <command> recorded for <todo_id>" (loopx/cli_commands/todo_event.py);
_indexed_rollout_todo_event uses that summary as both text and title, falling back to "<event_kind> recorded for <todo_id>".
The event carries no Todo text, so the index has nothing better to show, and the audit sentence reaches the operator as if it were the task.
Options
Both change a control-plane contract, so this needs a maintainer decision before a PR:
Record the Todo text on the event — todo_event.py adds a compact, public-safe details.text (same redaction as other Todo text in the status projection), and the index prefers it over the summary. Additive to the append-only event log; events written before the change keep the audit title.
Type the title source in the index — _indexed_rollout_todo_event marks such rows (e.g. title_source: "event_audit"), and the workspace renders them as an event-only Todo (id plus last event) instead of a task title. No event-log change; works for existing events.
They are not exclusive: (1) improves new events, (2) makes existing ones honest.
Acceptance
A rollout-only open Todo never renders … recorded for todo_… as its task title.
Todos present in the attention queue are unchanged.
Opened #5312 for this: the projection now labels event-only Todos by todo_id
(title_source: "event_audit") and keeps the rollout audit sentence in a new latest_event_summary field, so todo add recorded for todo_… is no longer
rendered as a task title.
I took option 2 rather than option 1 because the rollout event log deliberately
declares boundary.raw_task_text_recorded: False
(loopx/rollout_event_log.py), and writing Todo text into details.text would
turn an accepted loopx todo add --text "..." into a hard failure whenever FORBIDDEN_TEXT_MARKERS rejects a benign string (for example Rotate the api_key documentation passes the projection's public-safe
compaction but is rejected by the event log's stricter markers). Option 2 also
corrects existing runtime logs without a migration.
Behavior after the change:
event-only row -> text/title = todo <todo_id>, title_source: "event_audit", audit sentence in latest_event_summary;
attention-queue row -> unchanged text, no title_source, only latest_event_summary follows the newest event.
Validation on the PR head: 11 passed in tests/control_plane/test_status_rollout_event_snapshot.py (three new behavior
tests), 38 passed with the adjacent todo/lifecycle/lane projection suites, a
revert-the-fix mutation fails the three new tests, and examples/status.example.json is refreshed to the fixed shape so the public
dashboard example no longer shows audit lines as titles.
Activity
kokokoXUY commentedon Sep 29, 2026
Opened #5312 for this: the projection now labels event-only Todos by
todo_id(
title_source: "event_audit") and keeps the rollout audit sentence in a newlatest_event_summaryfield, sotodo add recorded for todo_…is no longerrendered as a task title.
I took option 2 rather than option 1 because the rollout event log deliberately
declares
boundary.raw_task_text_recorded: False(
loopx/rollout_event_log.py), and writing Todo text intodetails.textwouldturn an accepted
loopx todo add --text "..."into a hard failure wheneverFORBIDDEN_TEXT_MARKERSrejects a benign string (for exampleRotate the api_key documentationpasses the projection's public-safecompaction but is rejected by the event log's stricter markers). Option 2 also
corrects existing runtime logs without a migration.
Behavior after the change:
text/title=todo <todo_id>,title_source: "event_audit", audit sentence inlatest_event_summary;title_source, onlylatest_event_summaryfollows the newest event.Validation on the PR head: 11 passed in
tests/control_plane/test_status_rollout_event_snapshot.py(three new behaviortests), 38 passed with the adjacent todo/lifecycle/lane projection suites, a
revert-the-fix mutation fails the three new tests, and
examples/status.example.jsonis refreshed to the fixed shape so the publicdashboard example no longer shows audit lines as titles.