muse-agent-example/db/ddl/103-example评测隔离引擎强制.sql
zizi c501a4a5cb 框架(评测隔离): 实现六原则的引擎强制层
- DDL 103:run_type 插入后不可变触发器(评测性锚点钉死);生产只读角色 muse_read + RLS(评测候选对生产读默认不可见,app.eval_visible opt-in 才可见);已验证 root可见/muse_read不可见/opt-in可见
- invariant_checks.py:常设不变量(从靠预防迁到靠发现)——I1评测候选未接受/I2正文来源不追溯评测候选/I3评测质量结果可过滤/I4 oracle红线/I5 COMPLETED轮次封存(声明==实际落库),已跑通全PASS
- 原则1/2(口号升级/代价明账)已落 SoT;原则3/4/5/6 实现层完成
2026-08-01 01:24:43 +08:00

49 lines
2.3 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 评测隔离引擎强制(harness 改造原则 4:强制收拢到引擎单点 + run_type 钉死)。
-- 设计拍板 2026-08-01(docs/2026-08-01-评测harness改造设计.md 原则 4/6)。
-- 核心:评测与生产同库,靠逻辑隔离(访问分离);强制必须压到引擎单点,不靠每条查询自觉过滤。
-- 1) run_type 插入后不可变——评测性这个锚点钉死,不能先改成 production 再接受。
-- 2) (eval, accepted) 永不可达——既有 trg_example_candidate_no_eval_accept 已守;run_type 不可变后更硬。
-- 3) 生产只读角色 muse_read + RLS——评测行对生产读默认不可见,显式 opt-in(app.eval_visible)才可见。
-- 注意:root 是 superuser,RLS 对其无效;muse_read 是非超级用户角色,RLS 对它生效。
-- 生产读路径应改用 muse_read 连接(切换为后续代码改动),admin/看板用 root 可见全部(含评测,带标记)。
-- ── 1) run_type 插入后不可变 ──
CREATE OR REPLACE FUNCTION reject_run_type_change()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW.run_type IS DISTINCT FROM OLD.run_type THEN
RAISE EXCEPTION 'run_type 插入后不可变(评测隔离引擎强制,原 % 新 %)', OLD.run_type, NEW.run_type;
END IF;
RETURN NEW;
END;
$$;
CREATE OR REPLACE TRIGGER trg_example_candidate_run_type_immutable
BEFORE UPDATE ON example_candidate
FOR EACH ROW EXECUTE FUNCTION reject_run_type_change();
-- ── 2) 生产只读角色 muse_read(非超级用户,RLS 对其生效)──
DO $$
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'muse_read') THEN
CREATE ROLE muse_read NOLOGIN;
END IF;
END
$$;
GRANT SELECT ON example_candidate TO muse_read;
GRANT SELECT ON example_run TO muse_read;
GRANT SELECT ON example_run_receipt TO muse_read;
GRANT SELECT ON example_quality_result TO muse_read;
-- ── 3) RLS:评测候选对生产读默认不可见,显式 opt-in(app.eval_visible='true')才可见 ──
ALTER TABLE example_candidate ENABLE ROW LEVEL SECURITY;
ALTER TABLE example_candidate FORCE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS eval_isolation_candidate ON example_candidate;
CREATE POLICY eval_isolation_candidate ON example_candidate
FOR SELECT
USING (run_type IS DISTINCT FROM 'eval' OR current_setting('app.eval_visible', true) = 'true');