"""统一合规出口 — interface only (架构文档 §7.5, CR-05, CR-06). **所有对外生成物必须经过 ``publish_asset()``,没有例外。** The signature is fixed here so that business code written against it does not have to change when the implementation lands (T-P1-22 / T-P1-23). Nothing in this package may import a business domain — it must be safe to call from anywhere (架构文档 §4.2 禁止的依赖). import-linter enforces that. Not implemented on purpose; implementing it half-way is worse than not having it, because a half-working moderation call looks like a working one: 1. 内容审核 (fail-close: 审核服务不可用则拒绝发布) — 腾讯云 IMS/TMS 2. 27 位内容编号生成与 ``cp_content_registry`` 登记 3. 显式标识: 图片可见「AI 生成」水印 / 文本提示语 4. 隐式标识: 文件元数据 (属性信息 + 服务提供者编码 + 内容编号) 5. 上传目标 COS 桶并返回签名地址 必须专门测试的点 (§7.5): 图片经 CDN、缩略图处理、客户端保存与再次分享后, 元数据是否仍然存在。很多图片处理链路会剥离 EXIF/XMP。 """ from __future__ import annotations from dataclasses import dataclass from typing import Literal ContentType = Literal["image", "text", "pdf"] ModerationSuggestion = Literal["pass", "review", "block"] _NOT_IMPLEMENTED = ( "compliance is a structural placeholder (T-P1-22 / T-P1-23). " "No generated content may be released to users until 审核 + 水印 + 元数据 + " "内容编号登记 are all in place — CR-05/CR-06 are 不可裁剪." ) @dataclass(frozen=True, slots=True) class ContentRef: ref_type: str ref_id: str @dataclass(frozen=True, slots=True) class ModelInfo: provider: str model: str prompt_id: str | None = None prompt_version: str | None = None @dataclass(frozen=True, slots=True) class PublishedAsset: content_code: str url: str moderation: ModerationSuggestion async def moderate(text: str) -> ModerationSuggestion: """审核不可降级:服务不可用时按拦截处理 (fail-close, 架构文档 §11.4).""" raise NotImplementedError(_NOT_IMPLEMENTED) async def publish_asset( raw: bytes | str, content_type: ContentType, ref: ContentRef, model_info: ModelInfo, ) -> PublishedAsset: raise NotImplementedError(_NOT_IMPLEMENTED)