-- B07只追加带真实来源的运行观察;与V0046作者自报指标分开。 CREATE TABLE public.muse_run_observation ( observation_id uuid PRIMARY KEY, author_id text NOT NULL CHECK (btrim(author_id) <> ''), source_ids uuid[] NOT NULL CONSTRAINT muse_run_observation_source_ids_nonempty CHECK (cardinality(source_ids) > 0 AND array_position(source_ids,NULL) IS NULL), source_set_hash text NOT NULL CHECK (source_set_hash ~ '^[0-9a-f]{64}$'), phenomenon text NOT NULL CHECK (length(btrim(phenomenon)) BETWEEN 1 AND 200), issue_key text NOT NULL DEFAULT '', state text NOT NULL DEFAULT 'observation' CHECK (state = 'observation'), request_hash text NOT NULL CHECK (request_hash ~ '^[0-9a-f]{64}$'), payload jsonb NOT NULL CONSTRAINT muse_run_observation_sources_present CHECK ( CASE WHEN jsonb_typeof(payload->'sources') = 'array' THEN jsonb_array_length(payload->'sources') > 0 AND NOT jsonb_path_exists(payload, '$.sources[*] ? (!exists(@.runtime.task_id) || !exists(@.runtime.attempt_id) || !exists(@.locator.content_hash) || @.runtime.task_id.type() != "string" || @.runtime.attempt_id.type() != "string" || @.locator.content_hash.type() != "string" || @.runtime.task_id == "" || @.runtime.attempt_id == "" || @.locator.content_hash == "")') ELSE false END), content_hash text NOT NULL CHECK (content_hash ~ '^[0-9a-f]{64}$'), created_at timestamptz NOT NULL DEFAULT clock_timestamp(), UNIQUE(author_id,source_set_hash,phenomenon) ); CREATE INDEX ON public.muse_run_observation(author_id,issue_key,created_at); CREATE TABLE public.muse_run_observation_command ( author_id text NOT NULL, command_id text NOT NULL CHECK (btrim(command_id) <> ''), observation_id uuid NOT NULL REFERENCES public.muse_run_observation(observation_id), request_hash text NOT NULL CHECK (request_hash ~ '^[0-9a-f]{64}$'), PRIMARY KEY(author_id,command_id) ); CREATE TRIGGER muse_run_observation_immutable BEFORE UPDATE OR DELETE ON public.muse_run_observation FOR EACH ROW EXECUTE FUNCTION public.muse_guard_literary_history(); CREATE TRIGGER muse_run_observation_command_immutable BEFORE UPDATE OR DELETE ON public.muse_run_observation_command FOR EACH ROW EXECUTE FUNCTION public.muse_guard_literary_history(); REVOKE ALL ON public.muse_run_observation,public.muse_run_observation_command FROM muse_eval; GRANT SELECT,INSERT ON public.muse_run_observation,public.muse_run_observation_command TO muse_app;