Files
Agent-System/deploy/postgres/archive/pre-goose/2026-09-11-message-export-policy.sql
T
weichenandCursor 265f09c1f2 fix(server): cache health probes, surface SSE marshal errors, fail closed on missing duties
Health checks reuse a two-second snapshot and bound the schema query. Task SSE writes an error frame when an event cannot be encoded. ResolveDocTask errors when the frozen plan has no duty row, while explicit none-duties stay zero. Drop the unwired semantic-summary replace env, record the intentional dev versus release model split, document the test/main cutover path, and archive pre-goose SQL.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 09:16:18 +00:00

52 lines
2.2 KiB
SQL

-- =============================================================================
-- Migration: 2026-09-11-message-export-policy.sql
-- Description: 为 chat_messages 新增正文类型、权威导出策略、版本与 SHA256 哈希
-- =============================================================================
-- 1. 结构变更:新增消息导出权威列
ALTER TABLE chat_messages
ADD COLUMN IF NOT EXISTS content_kind TEXT NOT NULL DEFAULT '',
ADD COLUMN IF NOT EXISTS export_policy TEXT NOT NULL DEFAULT 'none',
ADD COLUMN IF NOT EXISTS content_revision INT NOT NULL DEFAULT 1,
ADD COLUMN IF NOT EXISTS content_sha256 TEXT NOT NULL DEFAULT '';
-- 2. 导出策略枚举约束检查 (full | copy_only | none)
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'chk_chat_export_policy'
) THEN
ALTER TABLE chat_messages
ADD CONSTRAINT chk_chat_export_policy
CHECK (export_policy IN ('full', 'copy_only', 'none'));
END IF;
END $$;
-- 3. 索引优化:快速基于消息与版本校验
CREATE INDEX IF NOT EXISTS idx_chat_messages_export_policy
ON chat_messages(id, export_policy);
CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- 4. 存量消息安全保守回填:旧消息默认为 none,仅纯文本 assistant 消息标记为 copy_only
UPDATE chat_messages
SET
content_kind = CASE
WHEN role = 'user' THEN 'conversational_text'
WHEN role = 'system' THEN 'system_notice'
WHEN role = 'assistant' AND (metadata ? 'interactive_card') THEN 'action_card'
WHEN role = 'assistant' AND length(trim(content)) > 0 THEN 'document_text'
ELSE 'conversational_text'
END,
export_policy = CASE
WHEN role = 'assistant' AND NOT (metadata ? 'interactive_card') AND length(trim(content)) >= 10 THEN 'full'
WHEN role = 'assistant' AND length(trim(content)) > 0 THEN 'copy_only'
ELSE 'none'
END,
content_revision = 1,
content_sha256 = CASE
WHEN length(content) > 0 THEN encode(sha256(convert_to(content, 'UTF8')), 'hex')
ELSE ''
END
WHERE export_policy = 'none' AND role = 'assistant' AND length(trim(content)) > 0;