blob: 382468afd371afa39b3ea378e5ac6d2c9b918a60 [file] [view]
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
# SessionTodo Lifecycle
Status: **Current**. The former Session Task Ledger is **Removed**: its module,
storage, and `workflow_task_ledger_events` table are gone as of workflow schema
12. SessionTodo is the only Session task surface.
This document answers one question for Runtime, Runtime Host, CLI, and Desktop
contributors: who owns a Session's current Todo list, and what must happen to
that list as the Session is read, copied, archived, or removed?
## Mental model
SessionTodo is one small current-state document attached to one Session. It is
closer to replacing a whiteboard checklist than appending to an audit log.
`todo_read` returns the whole ordered list; `todo_write` atomically replaces the
whole ordered list.
For example, this write:
```json
{
"todos": [
{ "content": "inspect the owner", "status": "completed" },
{ "content": "run focused tests", "status": "in_progress" }
]
}
```
commits exactly those two items in that order. A later write containing only
the second item removes the first. There is no item identity, patch operation,
revision, history, hierarchy, owner, evidence, cursor, or watermark.
`completed` is model-reported progress. It is not proof that a command ran, a
test passed, or a file changed; AgentRun, RuntimeEvent, tool results, filesystem,
and git remain the authorities for those facts.
## Authority and data flow
The Runtime Host is the sole interactive authority. Storage owns the durable
document and migration transaction; Runtime exposes the model tools; CLI and
Desktop only render Host-owned results.
```text
model todo_read / todo_write Desktop read-only panel
\ /
Runtime Host SessionTodo coordinator
| admission + Session presence
| commit, then signal-only invalidation
v
SQLite SessionTodo current document
```
`todo_write` is an internal Host tool port rather than a public Client mutation
operation. Desktop reads through `session.todo.query`. A successful replacement
commits before the Host publishes a `todo` domain invalidation. Reads and
first-read initialization are silent because they do not change the effective
current list.
The stored document is canonical product state. Before model or Desktop
display, content passes through the shared Unicode sanitization, secret
redaction, and `<session-todo>` tag-neutralization projection. Display safety
does not rewrite the stored document.
## Document contract
Each item contains only:
- `content`: non-empty normalized text, at most 200 Unicode code points;
- `status`: `pending`, `in_progress`, or `completed`.
The document contains at most 200 items and at most 256 KiB of encoded JSON.
These bounds keep the complete snapshot below the Runtime Host frame budget, so
the operation needs no paging contract.
An initialized empty list is different from no SessionTodo row. That distinction
is what makes explicit clearing deterministic.
## First read
The first Host read of an uninitialized Session, through either `todo_read` or
`session.todo.query`, persists an empty document and returns it. The first
explicit `todo_write` writes the requested complete list directly.
## Copy and branch semantics
Conversation copy initializes the target Todo inside the Host-owned copy
lifecycle, before the target Session is published:
- an ordinary branch whose selected cut includes the latest committed turn
copies the source's current Todo;
- a historical cut, before-revision, or side conversation initializes an
explicit empty Todo document.
Initialization is one SQLite write transaction. The source's current document
is read — an uninitialized source reads as empty, without being written — and
the absent target is inserted in the same transaction. Retrying an identical
initialization is idempotent; a different or corrupt existing target fails
closed instead of being overwritten.
The Runtime Host holds the source and target Session admission lanes during the
copy. A failed copy purges the incomplete target's Todo state before discarding
the preparing Session.
## Archive, removal, backup, and rollback
- Archive retains the current Todo document.
- Remove and incomplete-copy discard purge the Todo document, so a deleted
Session cannot show stale work if its identifier is observed again.
- Backup and restore preserve both non-empty and initialized-empty documents.
Rollback across the cutover means restoring a database backup taken before the
upgrade. That loses Todo edits made after the backup; running an old binary
directly against the upgraded live database is not a supported rollback
guarantee.
Upgrading to workflow schema 12 drops `workflow_task_ledger_events` without
migrating it. A workspace last opened by v0.2.0-incubating-rc1 or earlier loses
its unfinished Tasks; they are not imported into SessionTodo.
## Surface behavior
CLI/TUI renders the settled semantic `todo_read` or `todo_write` tool result.
It does not present `todo_write` arguments as committed state, including when a
durable transcript is reconstructed after restart.
Desktop renders the same current ordered snapshot as a flat read-only list.
Session and request-generation fences reject late responses after navigation;
signal-only invalidations trigger a fresh full read rather than client-side
merging.
No SessionTodo content is appended to a turn-tail prompt or dynamic system
prompt. The model reads it on demand with `todo_read`.
## Code map
- `packages/core/src/session-todo.ts`: document validation, bounds, and shared
display projection.
- `packages/storage/src/session-todo-store.ts`: SQLite persistence, migration,
copy initialization, and purge.
- `packages/runtime-host/src/server/session-todo-coordinator.ts`: Session
admission, presence checks, commit, and invalidation.
- `packages/runtime/src/session-todo-tools.ts`: model-facing read and
whole-document write tools.
- `packages/runtime-host/src/server/session-revision-coordinator.ts` and
`session-retirement-coordinator.ts`: copy and lifecycle integration.
- `apps/desktop/src/main/runtime-host-client.ts`: Desktop query adapter and
display-safe projection.
The legacy Task codecs, replay, and tables are deleted. Nothing may recreate a
second product surface for Session tasks or change this current-document
contract.