feat(runtime-host,cli): render Task Ledger mutations as a durable semantic timeline
- Dominant language
- TypeScript
- Stars
- 5.4k
- Forks
- 502
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 715
Description
## Problem
Task Ledger mutations are currently rendered as generic tool calls. In the TUI this produces implementation-shaped rows such as:
```text
● Task Create tasks: subject: ... subject: ...
● Task Update T1
```
Replacing those rows with `first subject +N more` or `T1 → completed` is not sufficient: the user still cannot see the created plan or identify the updated task without remembering an internal ID.
## Authority gap
This is not a string-formatting problem.
- `task_create` input has subjects but no durable task IDs; IDs exist only after the mutation commits.
- `task_update` commonly has an ID and status/evidence but no subject.
- `task.ledger.query` exposes the current snapshot, while the public change notification identifies only the Session, affected IDs, and timestamp.
- The durable Task Ledger event internally owns the mutation snapshot and tool-call correlation, but surfaces cannot currently query a stable mutation history.
Projecting an old transcript row from the current snapshot would make history drift after rename and could collapse several updates into the latest state. The Runtime Host therefore needs to expose a durable, tool-call-correlated Task mutation projection (or an equivalent stable query) before surfaces render a semantic timeline.
## Desired experience
After a create commits:
```text
● New tasks
○ T1 Inspect Git repository state
○ T2 Inspect project structure
○ T3 Inspect runtime versions
```
Before IDs exist, a live create may show staged subjects but must not invent IDs:
```text
● Planning tasks
○ Inspect Git repository state
○ Inspect project structure
```
Updates use the task snapshot owned by that exact durable mutation:
```text
◐ T1 · Inspect Git repository state
✓ T1 · Inspect Git repository state
! T1 · Inspect Git repository state
Waiting for repository access
```
## Scope and sequencing
1. Define a Host-owned, stable `TaskMutationPresentation` (name illustrative) correlated to the originating tool call and backed by the durable Task Ledger event.
2. Deliver a self-contained Runtime Host + TUI vertical slice.
3. Evaluate Desktop separately: Desktop already has a live Task Ledger panel, so transcript presentation must not duplicate that surface without a UX decision.
The shared contract may be reused across surfaces, but each surface renderer should remain independently reviewable.
## Acceptance criteria
- Historical mutation rows do not change when a task is later renamed or updated.
- Multiple rapid updates remain distinguishable and ordered.
- A committed create shows every task created by that mutation with its real ID and subject.
- A live create does not show an ID before commit assigns it.
- An update identifies the task by subject, keeps the ID as secondary information, and shows the new status.
- Blocked/failed/completed detail uses the reason or evidence from that exact mutation.
- TUI compact and expanded presentations consume the same canonical mutation projection.
- Completeness does not rely on today's global `Ctrl+O` behavior; if a list is truncated, the Task presentation owns a reliable way to reveal all items.
- Task credentials, evidence, and subjects obey the existing display-redaction and size-boundary contracts.
## Non-goals
- Do not infer historical mutations from the latest Task Ledger snapshot.
- Do not add Task-specific `first item +N more` formatting to the generic tool invocation formatter.
- Do not make the generic live `argsPreview` introduced by #3376 the Task identity authority.
## Related
- #3336
- #3338
- #3376
Contributor guide
Assessment
This issue has not been assessed yet.