8.4 KiB
| id | slug | title | status | kind | priority | labels | created_at | updated_at | assignee | legacy_ticket | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 20260606-215403-explicit-ticket-workflow-state | explicit-ticket-workflow-state | Replace inferred panel Ticket state with explicit workflow state | open | task | P1 |
|
2026-06-06T21:54:03Z | 2026-06-06T22:14:29Z | null | null |
Background
The first-pass workspace panel derives Ticket phase/action/status from labels, title text, readiness fields, and thread events such as plan, implementation_report, and review. That was useful for bootstrapping the panel, but it makes the panel infer workflow state instead of reading explicit Ticket state.
The desired model is simpler and more durable: Ticket records should carry a small explicit workflow state, while transient execution activity remains derived from live Pod/session state and is not persisted into Ticket frontmatter.
Goal
Replace panel-inferred Ticket workflow state with explicit Ticket workflow fields and update the panel/Orchestrator/Intake flows to use those fields.
Target state model
Use a small durable state machine:
intake -> ready -> queued -> inprogress -> done
Meanings:
intake: Intake Pod and user are clarifying/materializing the Ticket.ready: Intake is complete; the Ticket is ready for a human to queue.queued: Human queued the Ticket; Orchestrator may schedule it when resources/priority allow.inprogress: Orchestrator/coder/reviewer/validator work is underway. Review/rework loops stay inside this state.done: completed/closed.
blocked is not a workflow state. Blocking/user attention is an overlay such as attention_required.
review is not a workflow state. Review/rework/validation are runtime activity or thread events inside inprogress.
Durable fields
Add explicit current-state fields to Ticket frontmatter, for example:
workflow_state: intake | ready | queued | inprogress | done
attention_required: null | "..."
queued_by: null | "user"
queued_at: null | "2026-..."
Exact field names can be refined during implementation, but the semantics should remain:
workflow_stateis the durable Ticket workflow state.attention_requiredis a durable human-attention overlay, not a separate workflow state.queued_by/queued_atare durable facts recorded when the user queues a ready Ticket.
Do not persist activity in Ticket frontmatter. Current activity such as implementing/reviewing/validating should be displayed by combining Ticket state with live Pod/session/role-launch metadata and latest thread events.
Panel display simplification
Once explicit workflow state exists, the panel row should stop showing multiple near-synonymous columns such as priority/action/status/phase. For Ticket rows, the main list should show only the durable state plus identity/title:
<sel> <state> <slug-or-id> <title>
Actions such as Queue, Defer, or Open should move to the actionbar/key-hint area for the selected row, not occupy a permanent row column. Ticket priority and other metadata can appear in the detail pane when useful, not as primary list columns.
Pod rows should follow the same principle:
<sel> <pod-state> <pod-name>
Pod operations such as send/open should also be shown as selected-row key hints/actions, not as a permanent noisy row column.
The panel composer/status area should also be simplified. Do not put verbose target/help/diagnostic text in the status bar. Keep the status bar concise and stable; put transient guidance/errors in the actionbar or detail/diagnostic area instead.
Flow
intake -> readyis completed through Intake Pod conversation and Ticket materialization.ready -> queuedis the normal human panel action.queued -> inprogressis performed by Orchestrator scheduling.inprogress -> doneis performed by Orchestrator/review/close flow when complete.
The panel action currently called Go should become Queue, because the user is queuing a ready Ticket rather than approving implementation details.
Thread/event-log relationship
Current workflow state should live in frontmatter, but every workflow state transition should be explainable through a concise append-only thread event. The thread should become a typed event log, not a freeform conversation transcript.
This is split into companion ticket typed-ticket-thread-event-log so this Ticket can focus on current-state fields and panel semantics while the companion defines/implements the event-log API.
Desired split:
item.mdfrontmatter: current workflow state authority.item.mdbody: current Ticket snapshot.thread.md: typed append-only events such asstate_changed,intake_summary,decision,implementation_report,review, andclose.- Pod/session logs: full conversations/runtime transcript.
State mutations should eventually use backend APIs that update frontmatter and append a state_changed event as one logical operation. Intake should write a concise intake_summary instead of copying the full Intake conversation into the Ticket thread.
Requirements
- Add explicit workflow state fields to the Ticket model/parser/writer and tool/CLI surfaces as needed.
- Migrate or default existing Tickets safely without relying on labels/title/thread-event heuristics as authoritative state.
- Update
yoi panelto displayworkflow_statedirectly. - Simplify Ticket rows to state + identity/title only: remove permanent priority/action/status/phase columns from the main row.
- Simplify Pod rows to pod-state + pod-name only: remove permanent action/kind columns from the main row.
- Move row-specific operations such as Queue/Defer/Open/Send to selected-row actionbar/key hints rather than always-visible row columns.
- Keep composer/status bar text concise; avoid verbose target/help/diagnostic clutter in the status bar.
- Put transient guidance/errors in the actionbar or diagnostic/detail area instead of the status bar.
- Remove or demote current panel heuristics that infer phase/action from labels, title text,
readiness,needs_preflight, or thread event presence. - Rename panel
Goaction toQueueand make it transitionready -> queued. - Queue action must re-check current Ticket state before mutation.
- Queue action records a durable typed
state_changed/ decision event and setsqueued_by/queued_atif those fields are adopted. - Orchestrator should treat
queuedas schedulable and setinprogresswhen it starts work, with a typed state transition event once the companion event-log API exists. - Intake should set
workflow_state = readywhen the Ticket is fully materialized and ready to queue. - Done/close flow should set
workflow_state = doneor derive it consistently from close status. - Do not store transient
activityin Ticket frontmatter. - Preserve no-Ticket workspace Pod-centric panel behavior.
Non-goals
- Building the full typed thread event-log API; companion ticket
typed-ticket-thread-event-logowns that, though this ticket should align with it. - Persisting live Pod activity into Tickets.
- Reintroducing human approve/reject gates for every review loop.
- Reintroducing
--multior:ticket. - Layout-only tuning unrelated to explicit state, except the required state-only row/statusbar simplification described above.
Acceptance criteria
- New/updated Tickets can carry explicit workflow state.
- Panel rows show workflow state from Ticket fields rather than inferred phase/status.
- Ticket rows use a minimal
state + slug/id + titleshape; priority/action/status/phase are not permanent main-list columns. - Pod rows use a minimal
pod-state + pod-nameshape; operations are shown as selected-row key hints/actions, not permanent main-list columns. - Composer/status bar text is concise and does not contain verbose target/help/diagnostic clutter.
- Ready Tickets show
Queuerather thanGoas the selected-row actionbar/key-hint action. - Queue action transitions only
ready -> queuedand rejects stale/invalid states. - Review/rework activity does not create a separate workflow state; it remains
inprogressplus runtime/thread detail. - No persistent
activityfield is required for current Pod activity. - Existing tests cover default/migration behavior, panel display, Queue dispatch, and stale-state rejection.
- Companion ticket
typed-ticket-thread-event-logexists and captures the append-only state transition / Intake summary event-log work if not implemented in the same change series.