Files
clawmates/migrations/0042_loop_source_research.sql
T
Omar Sobh ce73abe5ab
ci / gates (push) Successful in 7s
ci / frontend (push) Successful in 37s
ci / rust (push) Failing after 13m41s
ci / e2e (push) Has been skipped
ci / publish (push) Has been skipped
loops: bridge research artifact into loop iterations (option C + b)
The bridge lets a coding loop "consume" an integrations research
artifact one INT-XX item per iteration. Options b (order-sequential
iteration) and C (snapshot in task_template + save the pointer for
future refresh) from the design discussion.

Migration 0042 — three new loops columns:
- source_research_topic_id — nullable pointer to research_topics.
- consumed_int_ids TEXT[]   — INT-XX ids the loop has completed.
  Advances when topology_worker parses "COMPLETED: INT-<NN>" markers
  from the run's final output (wired in a follow-up commit).
- current_int_index INT     — monotonic pointer for order-sequential
  iteration. Coordinator addresses INT-<current+1> unless prereqs are
  unmet, in which case it works on the smallest unblocking INT-XX and
  logs the reorder rationale.

Backend:
- cm_db::repo::loops::set_source_research_topic — bind/unbind pointer.
- cm_db::repo::loops::source_research_context   — read pointer + state.
- routes::loops::compose_iteration_task         — new caller-side helper
  that reads the pointer, fetches the topic's latest research_outcome,
  and prepends the artifact + focus instruction to task_template.
- run_now + webhook_receive both pass task_template through
  compose_iteration_task before enqueue. Standalone loops (no pointer)
  behave identically to before.
- CreateLoopRequest accepts `source_research_topic_id`, ownership-
  checked via research_topics::get before persist.

Frontend:
- New ResearchArtifactPicker modal — lists published topics, fetches
  the artifact on pick, returns (topic_id, markdown) to caller.
- LoopsWizard task_template step gains "Import from research artifact"
  button (right-aligned). Click opens the picker. On pick: task
  populates with the artifact markdown, pointer saved, textarea
  expands to 8 rows, small info strip shows "Loop is bound to topic
  <id>. Each iteration will focus on the next unconsumed INT-XX."
- Unlink button reverts to standalone loop mode.

Follow-up (next commit):
- topology_worker completion hook — parse "COMPLETED: INT-<NN>" out
  of the run's final output + update consumed_int_ids +
  current_int_index atomically. Without this, current_int_index stays
  at 0 forever and every iteration works on the same INT.
- Loop card refresh button — re-read source topic's latest outcome
  (useful after a reject-with-revision cycle on the source topic).
2026-07-09 18:47:17 -07:00

28 lines
1.4 KiB
SQL

-- Bridges research artifacts into loops. A loop can be "based on" a
-- published research topic; each iteration prepends the artifact
-- markdown to the coordinator prompt so the team executes ONE
-- integration item per iteration (INT-XX from the integrations outcome).
--
-- source_research_topic_id — nullable pointer. When set, the loop's
-- enqueue path re-reads the topic's latest outcome and prepends it
-- as context. NULL means "standalone loop" (legacy behavior).
--
-- consumed_int_ids — free-form list of INT-XX ids the loop has already
-- completed. Advances when topology_worker parses "COMPLETED: INT-XX"
-- markers out of the run's final output. Coordinator uses this to
-- pick the NEXT unconsumed item.
--
-- current_int_index — monotonic pointer for order-sequential iteration
-- ("option b" in the design discussion). Coordinator addresses
-- INT-<current+1> unless it has unmet prereqs, in which case it
-- works on the smallest unblocking INT-XX and logs the reorder
-- rationale to run_events.
ALTER TABLE loops
ADD COLUMN source_research_topic_id UUID REFERENCES research_topics (id) ON DELETE SET NULL,
ADD COLUMN consumed_int_ids TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[],
ADD COLUMN current_int_index INT NOT NULL DEFAULT 0;
CREATE INDEX loops_source_research_idx
ON loops (source_research_topic_id)
WHERE source_research_topic_id IS NOT NULL;