-- 模型规划只落候选,来源绑定独立保存;正式规划仍由作者决定。 CREATE TABLE public.muse_model_plan_candidate ( candidate_id uuid PRIMARY KEY REFERENCES public.muse_plan_candidate(candidate_id), task_id uuid NOT NULL REFERENCES public.muse_task(task_id), snapshot_id uuid NOT NULL REFERENCES public.muse_context_snapshot(snapshot_id), call_id text NOT NULL, model_evidence jsonb NOT NULL CHECK (jsonb_typeof(model_evidence)='object'), prompt_hash text NOT NULL, created_at timestamptz NOT NULL DEFAULT clock_timestamp(), UNIQUE (task_id, call_id) ); -- 同一快照可能由不同真实调用消费;不能将后一次调用冒充前一次的幂等回执。 DO $migration$ DECLARE old_constraint text; BEGIN SELECT conname INTO old_constraint FROM pg_constraint WHERE conrelid='public.muse_method_usage'::regclass AND contype='u' AND pg_get_constraintdef(oid)='UNIQUE (method_version_id, kind, context_ref, fragment_hash)'; IF old_constraint IS NULL THEN RAISE EXCEPTION '消费键约束缺失,不能盲目替换'; END IF; EXECUTE format('ALTER TABLE public.muse_method_usage DROP CONSTRAINT %I', old_constraint); END $migration$; ALTER TABLE public.muse_method_usage ADD CONSTRAINT method_usage_call_key UNIQUE (method_version_id, kind, context_ref, fragment_hash, task_id, result_ref); -- 历史无任务/调用回执维持原来的单键约束,不将其升级为真实模型消费。 CREATE UNIQUE INDEX method_usage_legacy_key ON public.muse_method_usage (method_version_id, kind, context_ref, fragment_hash) WHERE task_id IS NULL OR result_ref IS NULL;