JAM-40: Mission Control task boundary and lifecycle hardening
JAM-40: Mission Control task boundary and lifecycle hardening
Recommended fix: define one explicit intake rule in AGENTS.md for when work becomes a Mission Control task, then route every lifecycle mutation through one canonical server-side transition path that verifies the write before confirming success. Category: Tool, with a small AGENTS behavioral rule update. Do not start with a new skill.
1. Problem Statement and Goal
Mission Control already has the right status model on paper, but it does not yet have one reliable operational path that makes the board reflect reality every time.
Current friction has two parts:
- Task boundary drift. It is not always clear when work should stay chat-native versus become a Mission Control task.
- Lifecycle drift. Status changes can be issued through multiple paths, but there is no single transition mechanism with write verification.
AGENTS.md already defines the intended lifecycle:
- start work:
up-next->in-progress - deliverable ready:
in-progress->needs-review - approved:
needs-review->done
The problem is not missing intent. The problem is missing enforcement.
Goal: define a canonical operational model for task creation and task lifecycle transitions so the board reflects reality, status changes persist, and agents stop using ad hoc status writes.
2. Success Metric
This spec is successful if the implementation that follows can satisfy all of the below:
- Boundary clarity: agents can decide task vs chat with a short deterministic rule set, without improvising.
- Lifecycle reliability: every prototype transition persists after immediate re-read and after UI refresh.
- Single path: all normal status changes use one canonical transition path, not raw full-list replacement.
- Fail closed behavior: ambiguous task matches and invalid transitions return an error instead of guessing.
- Prototype proof: 3 to 10 real task transitions complete cleanly before broader codification.
3. Current State
3.1 Existing rules already define the intended behavior
/Users/vinny/.openclaw/workspace/AGENTS.md already contains mandatory rules for:
- spec completion workflow
- up-next queue workflow
- task status lifecycle
Those rules correctly say the board should reflect reality and that tasks should move as work happens.
3.2 The main status mutation path is still a raw full-array write
AGENTS.md also defines a chat workflow for:
- "move [task name] to [column]"
That workflow reads tasks.json, mutates one task in memory, then performs:
PUT http://localhost:3100/api/tasks- with the full tasks array
This is not a targeted task transition. It is a list replacement.
3.3 The web UI also writes the full task list
mission-control/components/tasks/TasksWorkspace.tsx currently:
- mutates task state optimistically in the browser
- writes the browser cache immediately
- sends
PUT /api/taskswith the full tasks array - polls
/api/tasksevery 5 seconds and can rehydrate the UI from server state
This means status changes are not owned by a single mutation path.
3.4 The data store is partly hardened, partly not
mission-control/lib/tasks-store.ts currently:
- uses atomic rename writes
- uses a lock for
createTask() - does not use the lock for
writeTasks()
mission-control/app/api/tasks/route.ts currently accepts a full-array PUT and passes it directly to writeTasks().
So the system has atomic file writes, but not a canonical per-task transition path, and not a consistent lock boundary for updates.
3.5 Status vocabulary is already drifting across layers
The Mission Control app uses the canonical statuses:
backlogup-nextin-progressneeds-reviewdone
But the task capture skill still advertises and parses:
nextblocked- no canonical
up-next - no canonical
needs-review
mission-control/scripts/capture-task.mjs already contains normalization logic that maps legacy values like next -> up-next and blocked -> backlog + blocked=true, which is another sign that workflow rules and tool interfaces have drifted.
3.6 Current board snapshot is small enough for a real prototype
Current tasks.json snapshot:
| Metric | Value |
|---|---|
| Total tasks | 31 |
| Backlog | 12 |
| Up Next | 2 |
| In Progress | 1 |
| Needs Review | 2 |
| Done | 14 |
Active real tasks available for validation:
| Task | Current status | Assignee | Title |
|---|---|---|---|
| JAM-40 | up-next | Pete | Harden task lifecycle transitions so status changes always stick |
| JAM-39 | up-next | Pete | OpenClaw upgrade test plan + breaking changes review |
| JAM-32 | in-progress | David | Fix auto-commit cron log routing and half-hour auth failure |
| JAM-37 | needs-review | Pete | Fix for resetting only David's #david Discord session |
| JAM-31 | needs-review | Pete | Clean up live stale references safely |
4. Platform Capabilities
This work does not require a new OpenClaw platform feature.
The current stack already supports the right shape:
- local Next.js API routes for deterministic server-side mutations
- local scripts for deterministic task operations
- chat workflows that can call scripts instead of improvising JSON edits
- existing Mission Control UI that can call a targeted endpoint instead of replacing the full list
Browser automation is not required for the fix itself.
5. Community Patterns
Two external patterns are relevant.
First, Linear issue statuses uses a small ordered workflow where tasks move through clearly bounded categories such as backlog, started, review, and done. The useful pattern is not Linear's exact labels. It is the combination of a small state machine and clear transition semantics.
Second, REST API Design: Dealing with concurrent updates describes the lost update problem that appears when multiple clients submit changes based on stale resource state. Mission Control currently uses full-list replacement for normal task updates, which is exactly the class of write path that can lose newer changes.
6. Options
| Option | Shape | Pros | Cons | Verdict |
|---|---|---|---|---|
| A. AGENTS rule only | Tighten AGENTS.md with task-vs-chat rules and lifecycle verbs, but keep current write paths | Fastest, low code, improves operator clarity | Does not fix raw full-array writes, no write verification, status drift can still happen | Not durable |
| B. AGENTS rule + canonical helper/API path | Add a single server-side transition path for lifecycle changes, use it from chat commands and UI status changes | Smallest fix that addresses both behavior and persistence, deterministic, testable | Requires touching AGENTS, API/store, and UI status actions | Recommended |
| C. Skill/workflow layer | Create a dedicated Mission Control task-management skill that interprets start/review/approve actions | Better ergonomics, natural language wrapper, can encode policy | Still needs Option B underneath, more prompt surface area, more maintenance | Later, only if needed |
7. Recommendation
Recommend Option B.
The simplest durable fix is:
- Codify the task boundary in
AGENTS.md. - Create one canonical transition helper/API for lifecycle changes.
- Make chat commands and UI status changes use that path.
- Verify the persisted task after each transition before reporting success.
Do not start with a new skill. A skill would improve ergonomics, but it would not solve the core reliability problem unless the underlying mutation path is fixed first.
This is a staged implementation, because the right fix spans both operator behavior and Mission Control code.
8. Security Considerations
This is primarily a correctness problem, not a data exposure problem, but there are still guardrails to enforce.
- Ambiguous task references: never guess. If title matching returns multiple tasks, stop and ask.
- Wrong-task mutation risk: prefer
displayIdonce a task is identified. - Invalid transitions: reject illegal moves rather than forcing them through.
- False success: never say a transition succeeded until the persisted task is re-read and confirmed.
- Cron: do not use cron as the primary fix. At most, add a narrow secondary audit later if Pete wants a consistency check, but only after the canonical mutation path exists.
9. Implementation Scope
9.1 Canonical operational model: task vs chat
Use this rule set.
| If the work has this property | Treat it as | Why |
|---|---|---|
Explicit capture request: “track this”, “add task”, “capture task”, /mc-task | Mission Control task | User asked for durable tracking |
| Spans multiple turns, async execution, or subagent work | Mission Control task | It outlives the current reply |
| Has a named deliverable, review step, or approval handoff | Mission Control task | Needs lifecycle tracking |
| Needs prioritization, board visibility, or resumption later | Mission Control task | It is board work, not a disposable reply |
| Is a system/workflow/code change Pete will likely revisit | Mission Control task | Durable engineering work should persist |
| Can be fully answered in one reply with no follow-up | Chat-native | No board state needed |
| Is a clarification, quick opinion, or lightweight rewrite with no tracking need | Chat-native | It is interaction, not queued work |
| Is brainstorming with no commitment to execute | Chat-native | Do not spam the board |
Default rule: stay chat-native unless at least one durable-work trigger is present.
Operational rule: if the agent is about to do substantive async or multi-step work and no task exists, create or confirm a Mission Control task before continuing.
9.2 Canonical lifecycle model
Keep the current five statuses. Tighten the meaning of each.
| Status | Meaning | Normal owner state |
|---|---|---|
backlog | Captured, not prioritized | No active execution |
up-next | Prioritized and queued | Ready to start |
in-progress | Someone is actively working now | Executor owns the baton |
needs-review | Deliverable is ready and waiting on Pete | Pete owns the baton |
done | Pete approved or explicitly accepted the result | Closed |
Use explicit transition verbs instead of generic column moves for normal work.
| Transition verb | Allowed move | When to use it |
|---|---|---|
prioritize | backlog -> up-next | Pete or Vinny selects queued work |
start | up-next -> in-progress | Work begins |
resume | needs-review -> in-progress | Pete gave notes and work resumes |
ready | in-progress -> needs-review | Deliverable is ready for Pete |
approve | needs-review -> done | Pete accepts the result |
deprioritize | up-next -> backlog | Queue changes |
Normal-path constraints:
- no direct
up-next->done - no direct
backlog->done - no direct
in-progress->done - no silent auto-transition based on vibes or time elapsed
Assignee handling in v1:
startshould set assignee to the active worker when knownreadyshould set assignee to Peteapprovedoes not need a schema change in v1; preserve current assignee behavior unless explicitly changed later
9.3 Canonical transition path
Add one canonical status mutation path with this behavior:
- Accept a task identifier and a transition verb.
- Acquire the task store lock.
- Read the latest persisted task list.
- Resolve the exact target task.
- Validate the requested transition against the allowed graph.
- Mutate only the target task fields needed for the transition.
- Persist the updated list.
- Re-read the saved task from disk.
- Return success only if the persisted task matches the intended state.
This can be exposed as either:
- a new targeted API endpoint such as
POST /api/tasks/:id/transition, or - a local helper script that calls a targeted API endpoint, or both
Key design point: normal lifecycle changes must stop using raw full-array PUT /api/tasks.
9.4 UI and workflow wiring
Status changes should converge on the same backend path from all normal entry points.
| Entry point | Current behavior | Proposed behavior |
|---|---|---|
| Chat command: “move [task] to [column]” | Read list, mutate in memory, full-list PUT | Replace normal use with start, ready, approve, resume, prioritize, deprioritize, all backed by canonical transition path |
| Task board drag/drop | Optimistic local mutation, full-list PUT | Call canonical transition path for status changes |
| Modal status edit | Full-list PUT | If status changed, use canonical transition path or route through per-task PATCH |
| Capture skill | Legacy status vocabulary | Limit creation to canonical statuses and only for task creation, not lifecycle mutation |
9.5 Why this is the minimum durable fix
The current failure mode is not just “people forgot.” It is structural:
- lifecycle rules already exist
- status writes are still implemented as list replacement
- the UI and chat paths do not share one verified mutation path
- status vocabulary already differs across AGENTS, skill docs, and scripts
So a policy-only fix will not hold.
9.6 Prototype validation plan
Run a small live prototype on real tasks before codifying this as settled workflow.
| Prototype | Transition | Expected result |
|---|---|---|
| 1 | JAM-39 up-next -> in-progress via start | Task persists as in-progress after immediate re-read and page refresh |
| 2 | JAM-39 in-progress -> needs-review via ready | Task persists as needs-review, assignee becomes Pete |
| 3 | JAM-39 needs-review -> done via approve | Task persists as done |
| 4 | JAM-37 needs-review -> in-progress via resume | Task leaves review and resumes active work |
| 5 | JAM-37 in-progress -> needs-review via ready | Revised deliverable returns to review cleanly |
| 6 | JAM-40 up-next -> in-progress via start | New work starts through the same canonical path |
Validation checklist for each prototype transition:
- API or helper response returns the intended task and status
- immediate read of
tasks.jsonconfirms the same status - UI reload still shows the same status
- unrelated tasks remain unchanged
- invalid transitions fail with a clear error
- ambiguous references fail closed
9.7 Files likely touched during implementation
Primary files:
/Users/vinny/.openclaw/workspace/AGENTS.md/Users/vinny/.openclaw/workspace/mission-control/lib/tasks-store.ts/Users/vinny/.openclaw/workspace/mission-control/app/api/tasks/route.ts/Users/vinny/.openclaw/workspace/mission-control/components/tasks/TasksWorkspace.tsx/Users/vinny/.openclaw/workspace/mission-control/scripts/capture-task.mjs/Users/vinny/.openclaw/workspace/skills/mission-control-task-capture/SKILL.md/Users/vinny/.openclaw/workspace/skills/mission-control-task-capture/scripts/capture-from-chat.mjs
Likely additions:
- targeted task transition endpoint or helper
- allowed-transition map shared by UI and API
- small transition test harness
9.8 Non-goals for v1
- redesigning the whole Mission Control board
- adding a new task schema unless the prototype proves it is necessary
- solving every possible stale-write issue for every task field on day one
- cron-based healing as the primary mechanism
- auto-creating tasks for routine chat replies
10. Context Loading
When implementing this spec, load these files first:
/Users/vinny/.openclaw/workspace/AGENTS.md/Users/vinny/.openclaw/workspace/mission-control/lib/tasks-store.ts/Users/vinny/.openclaw/workspace/mission-control/app/api/tasks/route.ts/Users/vinny/.openclaw/workspace/mission-control/components/tasks/TasksWorkspace.tsx/Users/vinny/.openclaw/workspace/mission-control/data/tasks.json/Users/vinny/.openclaw/workspace/skills/mission-control-task-capture/SKILL.md/Users/vinny/.openclaw/workspace/skills/mission-control-task-capture/scripts/capture-from-chat.mjs/Users/vinny/.openclaw/workspace/mission-control/scripts/capture-task.mjs
11. Guardrails
- Use one canonical transition path for normal status changes.
- Do not report success without read-after-write verification.
- Do not guess on ambiguous title matches.
- Do not mark work
donebeforeneeds-review, except for an explicit admin override path. - Do not create Mission Control tasks for ordinary one-reply chat work.
- Do not use cron as the primary mechanism for task correctness.
- Keep the implementation small and deterministic. Prefer script/API logic over prompt-only policy.
12. Handoff
Suggested next step
Review this spec, then split implementation into one narrow build task for lifecycle transitions and one narrow cleanup task for rule and vocabulary alignment.
Recommended subtask split
Subtask 1: Implement canonical Mission Control lifecycle transitions
Suggested Mission Control task text:
Add a canonical per-task transition path for Mission Control lifecycle changes. Replace raw full-list status writes in chat workflows and UI status changes with targeted transitions that validate allowed moves, write under lock, and verify persistence before returning success.
Subtask 2: Align Mission Control task intake rules and capture vocabulary
Suggested Mission Control task text:
Update AGENTS.md and the mission-control-task-capture skill so task creation follows the new task-vs-chat rubric and uses canonical status vocabulary: backlog, up-next, in-progress, needs-review, done. Remove legacy
nextandblockedlanguage from user-facing guidance.
Ready for review
Yes.