Files
clawmates/migrations/0051_topology_runs_missions.sql
T
Omar SobhandClaude Opus 4.7 f40ec075a5
ci / gates (push) Successful in 6s
ci / frontend (push) Successful in 25s
ci / rust (push) Successful in 4m26s
ci / e2e (push) Skipped
ci / publish (push) Successful in 2m42s
slice 5: task-card parser + background worker
Watches topology_runs' event stream for the INT-XX marker protocol
(see skills/foundation/int-xx-marker-protocol.md) and materializes
mission_tasks rows with typed status so the canvas Tasks tab renders
a live timeline instead of raw agent chatter.

Migration 0051 adds mission_id + mission_phase_id columns to
topology_runs (nullable) so runs enqueued by a mission phase can be
attributed. Populated by future phase executors; NULL for legacy
research/loops runs (parser skips them cleanly).

New Rust surface:
  - task_card_parser::parse(text) — line-scanner over TASK/WORK/
    HANDOFF/TEST_PASS/TEST_FAIL/REVIEW_APPROVE/REVIEW_BLOCK/COMPLETED
    markers. Strict: exact kind + colon + INT- prefix, no in-prose
    matches, no bold/code-fence wrappers.
  - task_card_parser::apply_for_run(pool, run_id) — reads the run's
    mission binding, walks its event payloads, extracts text/output/
    content/message string fields (matching every ZeroClaw event
    shape we see), parses markers, UPSERTs mission_tasks via the
    (phase_id, external_id) unique key from Slice 1.
  - task_card_worker::spawn — 15s poller over runs updated in the
    last 5 minutes. Idempotent + generous window survives server
    restarts + task-scheduling jitter.

Boot wires the worker after the content loaders. Silent no-op when
mission wiring isn't populated yet.

MarkerKind → status mapping (monotonic-forward):
  TASK           → created
  WORK           → working
  HANDOFF        → validating
  TEST_PASS      → validating
  TEST_FAIL      → failed
  REVIEW_APPROVE → validating
  REVIEW_BLOCK   → failed
  COMPLETED      → complete

Follow-ups:
  - Wire phase executor to populate topology_runs.mission_id +
    mission_phase_id (Slice 6/7/8 work)
  - Assign assigned_agent_id via the event's producing agent alias
    (currently always None)
  - SSE stream on /api/missions/{id}/tasks for live canvas updates
    (currently the canvas polls via mission GET)

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-07-19 15:04:57 -07:00

18 lines
800 B
SQL

-- Slice 5 — wire topology_runs to missions so the task-card parser
-- can attribute agent output to the right mission + phase.
--
-- Populated by the phase executor (Slices 4/5/6/7/8) when it enqueues
-- a topology_run on behalf of a mission phase. Left NULL for legacy
-- runs and the existing research/loops paths that pre-date missions.
--
-- The parser (task_card_parser) skips runs where mission_id IS NULL —
-- keeps the surface additive during the Slice 9 transition.
ALTER TABLE topology_runs
ADD COLUMN mission_id UUID REFERENCES missions(id) ON DELETE SET NULL,
ADD COLUMN mission_phase_id UUID REFERENCES mission_phases(id) ON DELETE SET NULL;
CREATE INDEX topology_runs_mission_idx
ON topology_runs (mission_id, created_at DESC)
WHERE mission_id IS NOT NULL;