BEGIN; -- The frozen board remains the plan origin; result versions belong to the board -- that actually received the output after any owner-only move. ALTER TABLE canvas_ai_steps ADD COLUMN applied_board_id uuid; ALTER TABLE canvas_ai_steps ADD FOREIGN KEY(project,workspace_id,applied_board_id) REFERENCES materials(project,workspace_id,id); UPDATE canvas_ai_steps SET applied_board_id=board_id WHERE applied_version IS NOT NULL; CREATE UNIQUE INDEX canvas_ai_canonical_target_busy ON canvas_ai_steps(project,workspace_id,(frozen_input->>'canonical_root'),node_id,(frozen_input->>'target_incarnation')) WHERE status IN('queued','running') AND frozen_input->>'canonical_root' IS NOT NULL; COMMIT;