muse-agent-example/db/ddl/101-example-raw.sql
zizi 98355893ab 框架(数据库+运行时): 落库 101 raw 两表,建 raw 落库机制 persist_raw,raw 合同改写
- example_raw_lease(元数据) + example_raw_content(全文),访问控制+append-only,
  (lease_id,content_sha256) 幂等、kind 拒 candidate(候选不进 raw)、密钥列级 CHECK
- persist_raw.py:租约+全文落库,写入前密钥标记过滤(实测拒 api_key),dry-run 已验证
- runtime SKILL.md raw 合同改写:落库为主、仓外 vault 降为可选备份、废时效语义、密钥双禁;
  评测 harness COMPLETED 判据改造记为重活后续
2026-07-31 22:56:57 +08:00

91 lines
5.4 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.

-- raw 元数据与全文两表:example_raw_lease(租约/元数据)+ example_raw_content(全文,访问控制)。
-- 设计拍板 2026-07-30(docs/2026-07-30-落库与看板设计.md §2.7 + §4 raw 合同改写)。
-- raw 合同已改写(创始人批准):放弃时效语义,改靠**访问控制 + append-only**——
-- 完整 prompt/response/未接受候选/标准答案/原书全文/供应商响应进库可看全文(看板可读),
-- 仓外 vault 降级为可选备份;retain_until 只留档、不触发自动删除;密钥/token 绝不入表。
-- 两表都 append-only(禁 UPDATE/DELETE/TRUNCATE)——raw 是不可变证据。
-- 全部对象 IF NOT EXISTS / OR REPLACE,重复 apply 幂等。
-- ══ example_raw_lease:raw 租约/元数据(append-only)══
CREATE TABLE IF NOT EXISTS example_raw_lease (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
vault_id CHAR(32), -- vault 标识(兼容旧 raw_vault 的 vaultId)
run_id VARCHAR(64), -- → example_run.run_id(软引用)
source_version VARCHAR(128), -- 来源版本
content_hashes JSONB, -- 本租约下内容哈希清单
purpose VARCHAR(64), -- 用途(generation/evaluation/…)
status VARCHAR(20) NOT NULL DEFAULT 'open', -- open/migrated/closed(历史状态,不再是删期限闸门)
retain_until TIMESTAMP, -- 批准的留存期限(留档溯源;进库后不触发自动删除)
archive_id VARCHAR(64), -- 仓外备份标识(若仍做可选备份)
archive_sha256 CHAR(64),
file_count INTEGER,
total_bytes BIGINT,
run_authorization_id VARCHAR(128), -- 本次运行授权标识(运行时对象,不查库、不指 96)
source_work_id BIGINT, -- raw 来源参考书 → example_reference_work.id(出处溯源)
creator VARCHAR(64) NOT NULL DEFAULT '',
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
tenant_id BIGINT NOT NULL DEFAULT 0,
CONSTRAINT chk_example_raw_lease_status CHECK (status IN ('open','migrated','closed'))
);
CREATE INDEX IF NOT EXISTS idx_example_raw_lease_run ON example_raw_lease(run_id) WHERE run_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS idx_example_raw_lease_work ON example_raw_lease(source_work_id) WHERE source_work_id IS NOT NULL;
-- ══ example_raw_content:raw 全文(append-only,访问控制)══
-- 访问控制:默认不进普通检索,看全文须显式指定;看板可看全文;密钥/token/凭据列级 + 写入前过滤双禁。
CREATE TABLE IF NOT EXISTS example_raw_content (
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
lease_id BIGINT, -- → example_raw_lease.id(软引用,可空)
kind VARCHAR(32) NOT NULL, -- prompt/response/source_text/oracle/supplier(无 candidate——候选正文单存候选表)
run_id VARCHAR(64), -- → example_run.run_id(软引用)
role VARCHAR(32), -- 产生角色(writer/detector/judge/…)
content_sha256 CHAR(64) NOT NULL, -- 内容哈希(裸 64 hex)
content TEXT NOT NULL, -- 全文
creator VARCHAR(64) NOT NULL DEFAULT '',
create_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
tenant_id BIGINT NOT NULL DEFAULT 0,
CONSTRAINT chk_example_raw_content_kind
CHECK (kind IN ('prompt','response','source_text','oracle','supplier')),
CONSTRAINT chk_example_raw_content_sha256
CHECK (content_sha256 ~ '^[0-9a-f]{64}$')
);
-- 唯一键 (lease_id, content_sha256):同一租约内重试幂等去重;跨租约各留一行(授权归属不串)
CREATE UNIQUE INDEX IF NOT EXISTS uk_example_raw_content
ON example_raw_content(lease_id, content_sha256);
CREATE INDEX IF NOT EXISTS idx_example_raw_content_run ON example_raw_content(run_id) WHERE run_id IS NOT NULL;
-- append-only + TRUNCATE 防护(raw 是不可变证据)
CREATE OR REPLACE FUNCTION example_reject_truncate()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
RAISE EXCEPTION '% 是 append-only 表,禁止 TRUNCATE', TG_TABLE_NAME;
END;
$$;
CREATE OR REPLACE FUNCTION reject_example_raw_lease_mutation()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
RAISE EXCEPTION 'example_raw_lease 是 append-only 表,禁止 UPDATE/DELETE';
END;
$$;
CREATE OR REPLACE TRIGGER trg_example_raw_lease_append_only
BEFORE UPDATE OR DELETE ON example_raw_lease
FOR EACH ROW EXECUTE FUNCTION reject_example_raw_lease_mutation();
CREATE OR REPLACE TRIGGER trg_example_raw_lease_no_truncate
BEFORE TRUNCATE ON example_raw_lease
FOR EACH STATEMENT EXECUTE FUNCTION example_reject_truncate();
CREATE OR REPLACE FUNCTION reject_example_raw_content_mutation()
RETURNS TRIGGER LANGUAGE plpgsql AS $$
BEGIN
RAISE EXCEPTION 'example_raw_content 是 append-only 表,禁止 UPDATE/DELETE';
END;
$$;
CREATE OR REPLACE TRIGGER trg_example_raw_content_append_only
BEFORE UPDATE OR DELETE ON example_raw_content
FOR EACH ROW EXECUTE FUNCTION reject_example_raw_content_mutation();
CREATE OR REPLACE TRIGGER trg_example_raw_content_no_truncate
BEFORE TRUNCATE ON example_raw_content
FOR EACH STATEMENT EXECUTE FUNCTION example_reject_truncate();