From 42513d13c65f5601de9f10606f111e8eff423860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=AD=86?= <2685475410@qq.com> Date: Wed, 9 Sep 2026 21:07:14 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20docs:=20=E5=BB=BA=E7=AB=8B?= =?UTF-8?q?=E9=AD=82=E9=95=9C=E5=AE=8C=E6=95=B4=201.0=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E4=BD=93=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 产品层:产品宪章与永久禁域、产品定义、完整 1.0 范围与发布门、道家文化语言体系、指标与反指标 - 研究层:参考项目研究(deepseek-harness、pi、MemOS、模型网关)、灵台原生引擎研究(业界原生引擎架构理念与道家文化出处) - 架构层:系统、Agent 运行时(周天体系)、插件系统、灵台引擎(C++ 双形态)、媒体与设备、社区协作市场、前端富内容渲染、数据、记忆与知识 - 契约层:协议与稳定标识、API 总体约定、Native API、兼容网关、实时与 Webhook、内部端口、统一 ContentBlock 与流式(含分支对话交互态)、灵台 C ABI 与 gRPC Service、API 表面、HTTP 与事件、运行观测 - 决策:ADR-001 至 ADR-023(模块化单体、每 attempt 持久化、候选记忆、OAuth 2.1、灵台引擎、双形态部署、大周天演化、宪章、三界作用域、私箧与保全态、叩心、周天统一等) - 交付:WP-01 至 WP-15 实施 TODO 与设计阶段交接文档 - 工程:AGENTS.md 工程规则(含 C++/灵台规范)、CLAUDE.md 引用、.gitignore --- .gitignore | 135 +++++++ AGENTS.md | 263 ++++++++++++ CLAUDE.md | 1 + README.md | 44 ++ docs/README.md | 74 ++++ docs/architecture/agent-runtime.md | 178 ++++++++ .../architecture/community-and-marketplace.md | 134 ++++++ docs/architecture/data-architecture.md | 123 ++++++ .../frontend-content-rendering.md | 184 +++++++++ docs/architecture/lingtai-engine.md | 119 ++++++ .../media-and-device-architecture.md | 123 ++++++ docs/architecture/memory-and-knowledge.md | 184 +++++++++ docs/architecture/plugin-system.md | 153 +++++++ docs/architecture/system-architecture.md | 107 +++++ docs/contracts/README.md | 187 +++++++++ docs/contracts/api-conventions.md | 159 ++++++++ docs/contracts/api-surface.md | 47 +++ .../contracts/content-blocks-and-streaming.md | 253 ++++++++++++ docs/contracts/gateway-compatible-api.md | 137 +++++++ docs/contracts/http-and-events.md | 170 ++++++++ docs/contracts/internal-api.md | 202 ++++++++++ docs/contracts/lingtai-ffi.md | 114 ++++++ docs/contracts/lingtai-service.md | 77 ++++ docs/contracts/native-api.md | 378 +++++++++++++++++ docs/contracts/realtime-and-webhooks.md | 168 ++++++++ docs/contracts/run-observability.md | 132 ++++++ docs/decisions/README.md | 381 ++++++++++++++++++ docs/delivery/handoff.md | 260 ++++++++++++ docs/delivery/implementation-roadmap.md | 211 ++++++++++ docs/product/complete-1.0-scope.md | 91 +++++ docs/product/cultural-language.md | 281 +++++++++++++ docs/product/metrics-and-anti-metrics.md | 47 +++ docs/product/product-charter.md | 68 ++++ docs/product/product-definition.md | 141 +++++++ docs/research/lingtai-native-engine.md | 141 +++++++ docs/research/reference-projects.md | 157 ++++++++ docs/security/security-and-diagnostics.md | 171 ++++++++ 37 files changed, 5795 insertions(+) create mode 100644 .gitignore create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 README.md create mode 100644 docs/README.md create mode 100644 docs/architecture/agent-runtime.md create mode 100644 docs/architecture/community-and-marketplace.md create mode 100644 docs/architecture/data-architecture.md create mode 100644 docs/architecture/frontend-content-rendering.md create mode 100644 docs/architecture/lingtai-engine.md create mode 100644 docs/architecture/media-and-device-architecture.md create mode 100644 docs/architecture/memory-and-knowledge.md create mode 100644 docs/architecture/plugin-system.md create mode 100644 docs/architecture/system-architecture.md create mode 100644 docs/contracts/README.md create mode 100644 docs/contracts/api-conventions.md create mode 100644 docs/contracts/api-surface.md create mode 100644 docs/contracts/content-blocks-and-streaming.md create mode 100644 docs/contracts/gateway-compatible-api.md create mode 100644 docs/contracts/http-and-events.md create mode 100644 docs/contracts/internal-api.md create mode 100644 docs/contracts/lingtai-ffi.md create mode 100644 docs/contracts/lingtai-service.md create mode 100644 docs/contracts/native-api.md create mode 100644 docs/contracts/realtime-and-webhooks.md create mode 100644 docs/contracts/run-observability.md create mode 100644 docs/decisions/README.md create mode 100644 docs/delivery/handoff.md create mode 100644 docs/delivery/implementation-roadmap.md create mode 100644 docs/product/complete-1.0-scope.md create mode 100644 docs/product/cultural-language.md create mode 100644 docs/product/metrics-and-anti-metrics.md create mode 100644 docs/product/product-charter.md create mode 100644 docs/product/product-definition.md create mode 100644 docs/research/lingtai-native-engine.md create mode 100644 docs/research/reference-projects.md create mode 100644 docs/security/security-and-diagnostics.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2e45e21 --- /dev/null +++ b/.gitignore @@ -0,0 +1,135 @@ +# 环境变量与密钥 +.env +.env*.local +config/*.yaml +config/mcp/*.yaml +config/gateway/*.yaml +!config/*.example.yaml +!config/mcp/*.example.yaml +!config/gateway/*.example.yaml + + +# Python +__pycache__/ +*.py[cod] +*$py.class +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ +.coverage +coverage.xml +htmlcov/ +.tox/ +.nox/ +.venv/ +venv/ +env/ +ENV/ +*.egg-info/ +dist/ +build/ + + +# Node / Next.js +node_modules/ +.pnpm-store/ +.next/ +out/ +.vercel/ +.turbo/ +*.tsbuildinfo +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# 数据库与本地存储 +db/* +db/*.sqlite +db/*.sqlite3 +db/*.db +db/*.db-shm +db/*.db-wal +*.sqlite +*.sqlite3 +*.db +*.db-shm +*.db-wal + +# ChromaDB / Milvus / Neo4j / NebulaGraph 本地数据 +/db/chromadb/ +milvus/ +neo4j/data/ +neo4j/logs/ +nebulagraph/data/ +nebulagraph/logs/ + +# 对象资源与上传文件 +storage/ +uploads/ +media/ +objects/ + +# 数据库备份产物 +backups/ + + +# 日志与运行产物 +logs/ +*.log +*.pid +*.seed +*.pid.lock +run/ +tmp/ +temp/ +.cache/ + + +# 测试与覆盖率 +.coverage.* +coverage/ +playwright-report/ +test-results/ + + +# IDE / OS +.vscode/* +!.vscode/extensions.json +!.vscode/settings.example.json +.idea/ +.DS_Store +Thumbs.db + + +# Docker / 本地覆盖配置 +docker/*.local.yml +docker-compose.override.yml + + +# Rust / 安全沙箱 +target/ +**/*.rs.bk +sandbox-work/ + + +# AI / 工具本地缓存 +.claude +!.claude/commands/ +!.claude/skills/ +.codegraph/ +.impeccable/ +.understand-anything/ +!.understand-anything/intermediate/ +!.understand-anything/diff-overlay.json + + +# Go / 博闻 MCP Web Search +mcp/web-search/bin/ +mcp/web-search/tmp/ + + +# 其他 +/characters/ +/models/ +output/ \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..c390108 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,263 @@ +# Hunjing 工程规则 + +> 目标:交付可维护、可验证、可长期负责的完整 1.0。 +> 语言:用户可见输出、文档、注释和 Git Commit 使用简体中文;代码标识符和稳定协议值使用英文。 + +## 1. 事实源与工作方式 + +### 1.1 开发前阅读 + +按任务读取对应文档,不凭旧设计或记忆实现: + +1. `docs/product/product-charter.md`:产品宪章、不可侵犯边界与永久禁域(上位约束); +2. `docs/product/product-definition.md`:产品定义与 1.0/2.0 边界; +3. `docs/product/complete-1.0-scope.md`:完整 1.0 范围与发布门; +4. `docs/product/cultural-language.md`:文化名、直白解释与工程映射; +5. `docs/architecture/`:系统、Agent、插件、数据、媒体、社区市场和前端渲染架构; +6. `docs/contracts/`:API、ContentBlock、事件、ID、枚举、请求头和错误; +7. `docs/security/security-and-diagnostics.md`:安全和受保护诊断; +8. `docs/delivery/implementation-roadmap.md`:1.0 TODO 与验收证据。 + +事实层级:产品范围 → ADR → 架构 → 契约/OpenAPI → 实现 → 测试与运行证据。下游不得静默覆盖上游;运行事实与文档不符时先记录偏差,再修正事实源或实现。 + +### 1.2 需求处理 + +- 需求明确:完整实现;需求有多种会显著改变产品/API/数据/安全的解释:先列选项并询问。 +- 普通命名、格式和等价技术细节由 AI 按既有规则直接决定,不把常规判断推给用户。 +- 多步骤任务先列编号流程和验证方式;只有需要用户决策时暂停。 +- 不总结或附和错误前提;先指出问题,再给修正方案并继续可执行部分。 +- 未请求不做;发现无关问题只报告,不顺手重构。 + +### 1.3 实施原则 + +- **最小实现**:在满足完整当前需求和安全边界前提下采用最少代码、依赖和服务。 +- **能力必达,技术按需**:1.0 产品能力是硬范围;数据库、语言、服务拆分和库按 ADR、官方资料、实测规模和维护成本选择,不为堆技术栈而部署。 +- **优先复用**:标准库 → 平台能力 → 已安装依赖 → 成熟依赖 → 最小自研。新增依赖前查官方文档、版本兼容、许可、维护状态和现有能力。 +- **删除废弃路径**:不为未发布实现保留兼容层;正式公共契约按弃用策略演进。 +- **模块化单体优先**:服务拆分须有独立扩缩容、故障域、数据/密钥边界、团队节奏或量化瓶颈证据。 +- **安全边界不简化**:认证、授权、租户隔离、审批、交易账、幂等、审计、秘密管理、文件/URL 校验和 Sandbox fail-closed 不得省略。 + +## 2. 完整 1.0 约束 + +- `docs/delivery/implementation-roadmap.md` 中全部 1.0 TODO 和发布门完成前,不得称为正式 1.0。 +- 产品宪章的永久禁域不可被实现、插件、管理员或自托管配置关闭;与宪章冲突的实现决定都是缺陷。 +- 内部工作包可以并行开发和验收,但不是独立公开版本。 +- 1.0 包含:角色与记忆、分支多模态对话、多 Agent、插件生态、实时语音、多语言、图像、Live2D、3D 运行编辑、Web/Tauri 桌面与移动、设备感知、完整社区、角色社区、协作空间、真实支付退款分成结算、运营和自托管。 +- 已确认 2.0:Blender 级完整建模器、LLM 直接修改完整 3D 几何/绑定、IoT/机器人/物理动作控制。不得把其他已列能力静默移出 1.0。 +- 文档 TODO 是真实待办;实现中的 `TODO`、`pass`、省略代码、假数据和无调用点定义不算完成。 + +## 3. 文化语言与工程标识 + +- 产品使用完整双层文化体系:文化名 + 直白中文解释;首次出现和高风险界面必须显示直白解释。 +- API、OpenAPI、数据库、代码目录、事件、错误码、权限 scope、指标和日志只使用 `docs/contracts/` 登记的中性英文稳定值。 +- 后端返回 `status: "running"`,前端本地化为“运转 · 运行中”;不得把文化名作为唯一协议值。 +- 权限、金额、退款、删除、支付、结算、审核和现实后果不得用文化叙事掩盖。 +- 新文化名先更新 `docs/product/cultural-language.md`;新稳定值先更新契约/OpenAPI。 + +## 4. API 与数据契约 + +### 4.1 API 分面 + +- Native:`api./v1`; +- OpenAI-compatible:`gateway./openai/v1`; +- Anthropic-compatible:`gateway./anthropic/v1`; +- Provider Webhook:`api./webhooks/v1`; +- Lingtai C ABI:进程内 `hj_*` 稳定符号,契约见 `docs/contracts/lingtai-ffi.md`;Lingtai gRPC Service:独立服务形态,仅限部署内部网络,契约见 `docs/contracts/lingtai-service.md`;两者为同一灵台引擎核心; +- 内部模块优先用类型化 Port/Command/Query/Event,不为每个模块增加 HTTP。 + +### 4.2 通用格式 + +- OpenAPI 3.1 是公共 HTTP 契约单一真源;生成 TypeScript/Rust 客户端,不手写重复 DTO。 +- JSON/SQL/path 参数使用 `snake_case`;事件使用 `domain.action`;逻辑模型使用 `kebab-case`。 +- 时间为 UTC RFC 3339;时长为 `_ms` 非负整数;金额使用最小货币单位或 Decimal,禁止浮点。 +- 列表使用 opaque cursor;更新使用 ETag/`If-Match`;客户端忽略未知响应字段和枚举。 +- 创建 Run、支付、退款、结算和外部副作用必须使用 `Idempotency-Key`。 +- `Hunjing-Request-ID` 用于业务关联,`traceparent` 用于分布式追踪,两者不能互相替代。 +- 1.0 认证采用 OAuth 2.1:Web 使用安全 Session Cookie,Tauri 使用 Authorization Code + PKCE,公共客户端使用短期 Bearer,自动化使用限 scope Service Account API key。 +- 凭据只经 Header 传递,不进入 URL、query、业务 body、SSE data 或 WebSocket URL。 +- Provider Header deny-by-default,仅 Adapter 白名单透传;用户登录凭据、Cookie 和诊断令牌永不转发上游。 + +### 4.3 消息与 Run + +- 聊天通过 `POST /v1/conversations/{id}/messages` 在同一事务创建 Message 和可选 Run;一个幂等键覆盖两者。 +- 后台任务通过 `POST /v1/runs` 显式创建。 +- Run → Turn → ModelCall/ToolCall 分层;每个上游 attempt 单独记录,不覆盖失败或重试。 +- 首个用户可见流事件前可以安全重试/故障转移;之后不得切换 Provider 重新生成另一份内容。 + +### 4.4 数据 + +- PostgreSQL/SQLite 关系数据是权威事实源;对象存储保存媒体;全文、向量、图投影、推荐特征和缓存均可重建。 +- 角色、消息、记忆、知识、社区发布、许可、订单、支付和 Ledger 分离建模。 +- Ledger 不可变,修正写反向分录;支付 Provider Adapter 不直接写账。 +- 删除传播到主存储、索引、缓存和派生数据;墓碑不保存被删原文。 +- 权威状态、AuditEvent 和 OutboxEvent 在同一事务提交。 + +## 5. 统一 ContentBlock 与流式输出 + +### 5.1 ContentBlock + +Native API 和持久化消息统一使用 `docs/contracts/content-blocks-and-streaming.md` 定义的类型化 Block: + +- `text`、`markdown`、`code`、`quote`、`table`、`callout`; +- `math`、`mermaid`; +- `image`、`video`、`audio`、`file`、`gallery`、`avatar`; +- `tool_call`、`tool_result`、`agent_status`、`approval_request`、`artifact`、`citation`、`error`。 + +用户输入可使用 Markdown 内嵌 Mermaid、代码和数学定界符;服务端必须使用确定性 parser 规范化为 canonical ContentBlock,记录 parser version,不把原始 HTML 当可信内容。 + +### 5.2 流式事件 + +统一事件: + +```text +content.block.started +content.block.delta +content.block.progress +content.block.completed +content.block.failed +content.block.cancelled +message.completed +``` + +- Event 在 Run 内有单调 `sequence`;Block delta 有单调 `delta_index`。 +- 客户端按 event ID 和 `(block_id, delta_index)` 去重;缺口通过重放或最终 Message 对账,不猜顺序。 +- Completed Block/Message 是权威快照,临时累积状态必须可丢弃重建。 +- SSE 用于 Run/通知;WebSocket 用于实时语音、协同和设备双向会话。 + +### 5.3 分级实时渲染 + +- Markdown/text 增量显示并节流解析;未闭合结构保持源码态。 +- Code 按行/时间片高亮,不逐 token 执行 Shiki。 +- Math 仅在定界符闭合或 Block 完成后渲染;必须有源码/fallback text。 +- Mermaid 仅在 Block 完成后以 strict mode 隔离渲染;失败显示源码和错误摘要。 +- 图片、视频、音频和文件先显示结构化进度,资源 ready 后加载。 +- Tool/Agent/Approval 使用状态替换,不拼接自由文本模拟状态。 + +### 5.4 前端安全与可访问性 + +- 禁用 Markdown 原始 HTML;URL/协议/目标域校验;外链 `noopener noreferrer`。 +- Mermaid 禁止 click、HTML label、外部脚本和危险初始化;SVG 二次净化。 +- KaTeX/MathJax 禁止 trust/宏注入并限制展开;Shiki 只高亮不执行。 +- 图片必须有 alt;音视频有字幕/转写;公式有 MathML/fallback;图表有标题、说明和源码替代。 +- 流增量不持续抢焦点;错误、审批和费用不能只靠颜色表达。 + +## 6. 插件、Agent 与安全 + +- 所有可扩展能力皆插件;认证、授权、数据隔离、审批、交易 Ledger、审计和 Sandbox 内核不可插件化。 +- 只有 bundled Core plugin 可进主进程;声明式/远程插件默认受限;可信本地代码插件也进入独立进程或容器。 +- Python import、Node `vm` 和 WebView 不是安全隔离。 +- 插件 Manifest 声明版本、依赖、数据、网络、设备、费用、外部目的地与现实后果和配置 Schema;升级新增权限必须重新确认。 +- Run 固定 PluginSnapshot;活动 Run 不热替换。安全撤架可以阻断新调用,但保留历史审计。 +- 子 Agent 的工具、数据、网络、预算和权限是父 Run 的交集子集;不继承审批令牌,默认不能写长期记忆。 +- Tool input 是不可信模型输出,必须 Schema 校验、Policy、审批、路径/URL 约束、资源限制和幂等。 +- 无符合策略的 Sandbox 时拒绝执行,不静默退化到宿主。 + +## 7. 社区、协作、设备与交易 + +- PersonalDomain、Workspace、Community、Marketplace、Finance 和 Diagnostics 使用不同授权策略。 +- 社区私信采用服务端治理的一对一/小群聊,不宣传 E2EE;支持举报、屏蔽、审核和多端同步。 +- 公开角色 Release 不包含私密记忆、关系、对话、设备授权或密钥。 +- Tauri v2 Desktop/iOS/Android 的文件、相机、麦克风、屏幕、位置和通知同时受 OS 权限与 `device_grant` 约束;采集有持续指示并可即时撤回。 +- 购买不等于安装插件,安装不等于启用,启用不等于授予新增权限。 +- 支付 Webhook 验签、按事件 ID 幂等、允许乱序;客户端金额不可信;退款、分成和结算可对账。 + +## 8. 语言与框架规范 + +### 8.1 TypeScript / Next.js + +- TypeScript 开启 `strict`;禁止无理由 `any`、非空断言和重复定义 API 类型。 +- 使用生成的 OpenAPI 类型;表单边界使用 Zod/React Hook Form;服务端状态使用 TanStack Query。 +- React Server Component 默认;只有需要浏览器 API、交互状态或第三方客户端库时使用 `"use client"`。 +- 不在 render 中产生副作用;Effect 必须清理订阅、Timer、Worker 和 WebSocket。 +- ContentBlock renderer 采用穷尽判别联合;未知类型走兼容占位,不能崩溃。 +- 长列表使用虚拟滚动;Markdown/Math/Mermaid/Shiki 高成本处理放 Worker 并按 content hash 缓存。 +- 图标统一 Lucide;界面禁止表情符号代替图标、状态或操作。 +- 测试:Vitest + Testing Library;核心旅程和跨端行为使用 Playwright。 + +### 8.2 Python / FastAPI + +- Python 3.12+,使用 uv;格式/Lint 用 Ruff,类型检查用 mypy,测试用 pytest/pytest-asyncio。 +- FastAPI 边界使用 Pydantic v2;领域对象不依赖 HTTP Request/Response 或 Provider SDK 类型。 +- SQLAlchemy 2.0 typed mapping;迁移只用 Alembic;禁止运行时隐式建表修改生产 Schema。 +- I/O 使用 async;不得在事件循环执行阻塞模型、文件、媒体或数据库操作。 +- Provider、Tool、Storage、Payment 通过明确 Port;异常映射为稳定领域错误,不匹配错误字符串。 +- Decimal/整数处理金额;时间统一 aware UTC datetime。 +- 模型/工具流必须可取消,资源使用 `async with`/`try-finally` 释放。 + +### 8.3 Rust / Tauri + +- 使用 Tauri v2 和 stable Rust;`cargo fmt`、`cargo clippy -- -D warnings`、`cargo test`。 +- Tauri command 输入使用 serde/specta 类型并校验;不暴露通用 Shell 或任意路径命令。 +- Capability/permission 最小化,桌面与移动平台分别声明;敏感命令验证用户、设备和 DeviceGrant。 +- 路径 canonicalize 后限制在授权根目录;秘密使用系统 Keychain/Keystore,不写普通配置或日志。 +- `unsafe` 仅在无安全替代时使用,封装最小并写明不变量和测试。 +- Tokio 任务支持取消和超时;不要持锁跨 `await`。 +- 共享 TypeScript 类型由 specta/OpenAPI 生成,不手工漂移。 + +### 8.4 C++(灵台引擎) + +- C++23 与 CMake;`clang-format`、`clang-tidy`,编译警告全开并视为错误;测试与 fuzz 框架在建立工程时按 ADR 登记。 +- 对外只导出 `extern "C"` 的 `hj_*` 符号与不透明句柄;异常、STL 类型、RTTI 和 C++ 类不得跨越 ABI 边界;入口函数捕获一切异常并转换为 `HjStatus`。 +- 同一核心支持进程内嵌入与 gRPC 独立服务(`hunjing-lingtai-server`)双形态;任何能力在两种形态语义必须一致,服务仅限部署内网并经 mTLS 认证。 +- 内存全部 RAII,禁止裸 `new`/`delete`;引擎分配的缓冲只经 `hj_buffer_free` 释放;字符串一律 UTF-8。 +- `HjEngine` 线程安全,会话句柄单线程亲和;回调在调用线程同步执行且回调内禁止再入引擎;不持锁跨回调。 +- 全部引擎输入(Markdown、模型输出、工具参数、查询、Webhook 字节)按不可信输入处理,长度/深度/节点数有硬上限;`hj_transform` 与 `hj_policy` 为 fuzz 必测目标。 +- 每次提交跑 ASan/UBSan,线程路径跑 TSan,并维护 ABI 快照与双形态 golden 一致性测试。 +- 引擎无权威状态、不做网络/文件/数据库 I/O(显式只读索引除外);引擎缺失或服务不可达时宿主 fail closed,禁止宿主内第二实现降级。 +- 第三方库进入前按官方文档、许可与维护状态评估,gRPC/ANN/分词等选型以补充 ADR 登记。 + +### 8.5 Go(仅在 ADR 决定拆出高并发服务时) + +- 版本以 `go.mod` 为准;`gofmt`/`gofumpt`、`go vet`、`golangci-lint`、`go test ./...`。 +- 所有外部 I/O 接受 `context.Context`,传播取消和 deadline;不把 Context 存入 struct。 +- 错误使用 `%w` 包装并以 `errors.Is/As` 分类;不匹配错误字符串。 +- Goroutine 必须有 owner、退出路径和测试;channel 由发送方关闭;禁止无界队列。 +- HTTP/Header/流式协议由共享契约生成或验证,不单独发明模型协议。 + +### 8.6 SQL 与存储 + +- 表/列/index 使用 `snake_case`;外键、唯一约束、检查约束和租户条件在数据库层落实。 +- 所有 Query 明确 PersonalDomain/Workspace/Finance scope;禁止先全表读后应用层过滤。 +- N+1、无界列表和 `%keyword%` 全表扫描必须在实现前处理或有量化例外。 +- 向量、图、搜索和缓存只保存可重建投影,删除和权限变化必须传播。 + +## 9. 复杂度与变更规范 + +- 只改目标所需文件;匹配既有命名、注释密度和风格;保护用户已有改动。 +- 删除自己引入的无用代码、导入、配置和孤儿注释。 +- 函数有效逻辑超过 40 行、圈复杂度 >10、认知复杂度 >15、参数 >5 时应拆;确需保留须说明原因和风险。 +- 不为一个实现创建接口/工厂/配置层;但稳定跨模块/插件/Provider 边界需要 Port 时不受此限制。 +- 不重写或删除已有注释,除非需求明确要求或注释已失真。 + +## 10. 验证纪律 + +- 中大型或安全/状态/边界/并发/外部依赖变更先写失败测试,再实现通过。 +- 逻辑变更优先覆盖公共行为;核心逻辑自动化覆盖目标 80%+。 +- 每条需求交付前核对:需求 → 实现位置 → 调用点 → 测试 → 运行证据。 +- 新函数、类、配置、事件和 ContentBlock 类型必须有真实调用/消费点。 +- 新依赖、资源、Header、事件、ID 和配置名称必须验证真实存在且与契约一致。 +- 纯文档变更可不跑代码测试,但必须验证内部链接、Mermaid、Markdown 和契约引用。 +- 不报告虚假完成;测试失败、步骤跳过和未实现项必须明确说明。 + +## 11. 文档与图表 + +- 正式文档统一在 `docs/`;新增入口同步 `docs/README.md`。 +- 稳定 API/字段/ID/事件/错误只在 `docs/contracts/` 和生成 Schema 定义;下游引用,不复制可漂移值集。 +- 架构、流程、时序、状态和 ER 图统一使用 Mermaid,提交前必须实际渲染验证。 +- 产品文化名更新 `docs/product/cultural-language.md`;工程值更新契约;两层保持一对一映射。 +- 每次功能/API/状态变化同步相关产品、架构、契约、TODO 和测试文档。 + +## 12. 目录与配置 + +- `docs/`:文档;`logs/`:本地日志;`db/`:本地数据库;`config/`:应用配置;`docker/`:Docker 文件。 +- `.env.example` 位于根目录,列出环境变量和中文说明;只提交 `.env.example` 和其他不含秘密的 `*.example.*` 配置,不提交真实 `.env`、密钥、数据库、日志和用户数据。 +- 代码导入使用语言包/alias 的项目根路径;运行时文件路径通过统一项目根解析器或配置解析,不依赖进程当前目录。 +- Docker 容器名以 `hunjing-` 开头;Compose 不使用顶部 `version`;本地默认 SQLite,正式环境按完整 1.0 能力启用 PostgreSQL、Redis、对象存储和 Worker。 +- 本地启动、测试、迁移、生成和检查统一通过根 `Makefile`;新增命令同步 `make help`。 + +## 13. Git 与交付 + +- 不覆盖、重置或删除用户未授权的现有改动。 +- 不执行 `git reset --hard`、强制推送、清理未跟踪文件等破坏性操作,除非用户明确要求并确认目标。 +- 只有用户要求时提交或推送;Commit 使用简体中文的 Conventional Commits/Gitmoji 规范。 +- 提交前运行适用的 format、lint、typecheck、test、OpenAPI drift、Markdown/Mermaid 和安全检查。 diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..262acdd --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +# Hunjing + +Hunjing 是面向个人用户与创作者的长期 AI 角色、Agent 与创作社区平台。它支持角色连续身份、分支对话、可治理记忆、多 Agent、插件、语音、多语言、多模态、Live2D、3D、跨端感知、社区协作和真实交易。 + +> 当前仓库处于设计阶段,尚无可运行实现。文档描述完整 1.0 目标,不代表功能已经完成。 + +## 1.0 范围 + +Hunjing 1.0 是一次整体交付,必须同时包含: + +- 角色创建、导入、版本、谱系、记忆、关系和可携导出; +- 多模态分支对话、实时语音、图像和多语言; +- Live2D 以及 VRM/glTF 3D 导入、编辑、运行和导出; +- 角色 Agent、任务 Agent、协调 Agent和受控多 Agent 并行; +- Web、Tauri 桌面端、Tauri iOS/Android 与文件/相机/麦克风/屏幕/位置感知; +- 双轨插件生态、开发 SDK、注册、审核、安装、升级、回滚和插件市场; +- 完整社区、角色社区、多人协作空间、搜索、推荐和内容治理; +- 商品、订单、真实支付、退款、平台分成、创作者结算、对账和争议处理; +- 模型/工具调用的 token、Prompt Cache、成本、时延、错误、重试和受保护诊断; +- 官方部署与完整自托管闭环。 + +所有工作包可以内部并行,但全部 TODO 和发布门完成前不得称为正式 1.0。 + +## 架构原则 + +- 可扩展能力皆插件;认证、授权、数据隔离、审批、审计、交易账、事务和隔离执行内核不可插件化。 +- 声明式/远程插件默认受限运行;部署者明确信任的本地代码插件进入独立进程或容器。 +- 性能与安全敏感的确定性核心(内容规范化、流式、策略校验、端侧离线检索)以 C++ 灵台引擎实现:可经稳定 C ABI 进程内嵌入 Python/Rust/Go 宿主,也可作为部署内部的 gRPC 独立服务运行;引擎无权威状态,数据事实源仍在数据库。 +- 每个 Run 持久化 Turn、模型 attempt、工具调用、token、缓存、费用和错误。 +- 详细诊断必须同时持有登录态和短期、限范围的诊断授权。 +- 技术按能力、规模与安全需要采用,不以堆满技术栈作为完成标准。 +- 产品界面使用“中国古代神话/道家文化名 · 直白解释”的双层语言;稳定 API、数据库、事件和日志使用中性英文工程标识。 +- Native Message、社区内容和 Agent 输出使用统一类型化 ContentBlock,支持 Markdown、代码、数学公式、Mermaid、图片、视频、音频、文件、工具状态和产物的安全分级实时渲染。 + +## 2.0 已确认范围 + +- Blender 级完整 3D 建模器; +- 基于开源建模项目完善网格、雕刻、拓扑、绑定和专业动画工具; +- LLM 直接、可验证地修改完整 3D 几何与绑定; +- IoT、机器人和物理动作控制。 + +## 文档入口 + +从 [docs/README.md](docs/README.md) 开始,完整范围见 [完整 1.0 范围与发布门](docs/product/complete-1.0-scope.md)。 diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..1afd350 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,74 @@ +# Hunjing 文档 + +> 文档状态:完整 1.0 目标设计。仓库尚无对应实现,所有 TODO 完成并通过发布门前不得表述为正式 1.0。 + +## 阅读顺序 + +1. [产品定义与边界](product/product-definition.md) +2. [产品宪章](product/product-charter.md) +3. [完整 1.0 范围与发布门](product/complete-1.0-scope.md) +4. [指标与反指标](product/metrics-and-anti-metrics.md) +5. [参考项目研究](research/reference-projects.md) +6. [灵台引擎研究](research/lingtai-native-engine.md) +7. [系统架构](architecture/system-architecture.md) +8. [Agent 运行时](architecture/agent-runtime.md) +9. [插件系统](architecture/plugin-system.md) +10. [灵台引擎架构](architecture/lingtai-engine.md) +11. [媒体与设备架构](architecture/media-and-device-architecture.md) +12. [社区、协作与市场架构](architecture/community-and-marketplace.md) +13. [前端富内容实时渲染](architecture/frontend-content-rendering.md) +14. [数据架构](architecture/data-architecture.md) +15. [记忆与知识架构](architecture/memory-and-knowledge.md) +16. [中国古代神话与道家文化语言体系](product/cultural-language.md) +17. [协议与稳定标识](contracts/README.md) +18. [API 总体约定](contracts/api-conventions.md) +19. [Hunjing Native API](contracts/native-api.md) +20. [模型网关兼容 API](contracts/gateway-compatible-api.md) +21. [实时 API 与 Webhook](contracts/realtime-and-webhooks.md) +22. [内部端口、事件与插件协议](contracts/internal-api.md) +23. [统一富内容与流式协议](contracts/content-blocks-and-streaming.md) +24. [Lingtai C ABI](contracts/lingtai-ffi.md) +25. [Lingtai Service](contracts/lingtai-service.md) +26. [1.0 API 表面总表](contracts/api-surface.md) +27. [HTTP 与事件契约](contracts/http-and-events.md) +28. [运行观测契约](contracts/run-observability.md) +29. [安全与诊断访问](security/security-and-diagnostics.md) +30. [架构决策](decisions/README.md) +31. [1.0 实施 TODO](delivery/implementation-roadmap.md) +32. [设计阶段交接文档](delivery/handoff.md) + +## 文档分类 + +| 目录 | 职责 | 不承载 | +| --- | --- | --- | +| `product/` | 1.0 用户、范围、验收和 2.0 边界 | 代码结构和供应商细节 | +| `research/` | 外部证据、采纳与拒绝理由 | 项目契约 | +| `architecture/` | 组件、运行时、媒体、生态、数据与扩展边界 | 稳定枚举值 | +| `contracts/` | ID、字段、请求头、事件和错误 | 产品愿景 | +| `security/` | 信任边界、授权、交易、内容治理和诊断访问 | 普通功能说明 | +| `decisions/` | 已作出的重大取舍及后果 | 教程 | +| `delivery/` | 1.0 工作包 TODO、验收证据、统一发布门和阶段交接 | 2.0 实现计划 | + +## 事实优先级 + +```mermaid +flowchart LR + P[产品定义] --> D[架构决策] + D --> C[契约] + C --> I[实现] + I --> T[测试与运行证据] +``` + +发生冲突时,上游定义约束下游;运行事实不能被文档否认。实现与文档不同时先记录偏差,再决定修正文档还是实现。 + +## 1.0 维护规则 + +- 稳定 ID、枚举、事件名、请求头和错误码只在 `contracts/` 定义。 +- 架构文档引用契约名,不复制完整值集。 +- 外部项目只提供证据和模式,不自动成为运行依赖。 +- Mermaid 使用短标签和标准图类型,不嵌入主题样式。 +- 新文档必须从本索引可达;删除文档必须同步入口。 +- Native Message、社区内容和 Agent 输出使用统一类型化 ContentBlock;Markdown 内嵌 Mermaid/数学/代码在服务端规范化,前端按分级实时策略安全渲染。 +- 产品界面采用完整双层文化体系;稳定工程契约保持中性英文值。 +- 文档 TODO 是 1.0 必做项;正式实现不得用 TODO、`pass`、省略或假数据占位。 +- 完整 3D 建模器、LLM 直接改模和物理设备控制属于已确认的 2.0 边界,其他已列能力不得静默移出 1.0。 diff --git a/docs/architecture/agent-runtime.md b/docs/architecture/agent-runtime.md new file mode 100644 index 0000000..eeddbb0 --- /dev/null +++ b/docs/architecture/agent-runtime.md @@ -0,0 +1,178 @@ +# Agent 运行时 + +## 1. 运行模型 + +```text +Conversation → Run → Turn → ModelCall / ToolCall → Message +``` + +- 一个用户输入创建或继续一个 Run。 +- 一个 Run 可包含多个 Turn。 +- 一个 Turn 可包含多个模型 attempt 和并行 ToolCall。 +- 每次重试、故障转移、`pause_turn` 续跑都创建新的 ModelCall 记录。 +- 子 Agent 是独立 Run 或 ChildRun,必须引用父 Run,并继承更窄权限。 + +## 2. 周天体系 + +运行层以周天为循环叙事,承接 Hunjing 旧版(main 分支)的小周天/大周天设计并补全其架构(决策见 [ADR-023](../decisions/README.md#adr-023周天体系统一小周天闭环与大周天演化)): + +- **小周天**:一次 Run 从输入到答复或行动结果的可追踪认知闭环。上节 Run/Turn/ModelCall/ToolCall 分层即小周天的可追踪链路;闭环完成时记录完成信号(含归真、记忆候选与观测摘要的引用)。 +- **大周天**:跨 Run 的角色自我评估演化循环(见 [ADR-018](../decisions/README.md#adr-018角色内驱力与大周天演化进入-10)),以 `BigCycle`(`cycle_`)为聚合根持久化,执行为一个受托后台 Run。 + +```mermaid +flowchart TB + IN[run input] --> CTX[context assembly] + CTX --> MT[model and tool turns] + MT --> OUT[streamed output] + OUT --> SIG[run completed signal] + SIG --> ACC[signal accumulation] + ACC -->|threshold or window or manual| TRIG[BigCycle triggered] + TRIG --> P1[phase recall] + P1 --> P2[phase evaluate] + P2 --> P3[phase propose] + P3 --> P4[phase submit] + P4 --> REV[existing candidate review] + REV --> EFF[approved evolutions] + EFF --> CTX2[future context assembly] +``` + +### 2.1 小周天闭环 + +- 闭环链路:输入 → 上下文装配 → 模型/工具 Turn → 流式输出 → 观测记录(usage、工具轨迹、审计)→ 完成信号。 +- 完成信号是小周天对大周天的唯一输出面:包含 Run ID、归真引用、产生的候选引用、token/费用与时间窗;不包含隐藏推理。 +- 流式运转(增量、节流、事件序)由灵台引擎小周天模块(`hj_stream`)承载;触发条件与预算核算的确定性计算由洛书(`hj_plan`)承载。 + +### 2.2 大周天循环 + +`BigCycle`(`cycle_`,UUIDv7)聚合:触发条件快照、输入引用集(窗口内小周天 Run、记忆变化、时间窗)、阶段状态与阶段记忆(`_phase_memory`:每阶段输入输出摘要,供审计与幂等)、产物候选引用、预算与执行 Run 关联。状态机 `big_cycle_status`:`pending` → `running` → `completed`/`failed`(登记于[协议与稳定标识](../contracts/README.md))。 + +触发条件为可配置阈值组合,逐角色设频率上限:累计小周天数、归真数量、记忆候选存量、距上次大周天时间窗、用户手动触发。 + +四阶段评估: + +| 阶段 | 职责 | 产物 | +| --- | --- | --- | +| 回顾(recall) | 拉取窗口内小周天完成信号与归真结果 | 输入引用集与阶段记忆 | +| 对照(evaluate) | 以内驱力维度对照当前道体基线与关系状态 | 差异与演化方向摘要 | +| 提议(propose) | 生成记忆、人格、关系、世界认知与次生目标候选(含叩心候选) | 携带 `big_cycle` 来源的候选集 | +| 提交(submit) | 候选进入既有审核流转,cycle 关闭 | 审核引用与演化谱系 | + +经审核生效的演化(人格版本、关系、记忆)进入后续小周天的上下文装配(第 7 节顺序的第 2、4 层),形成"小周天运转 → 大周天评估 → 演化生效 → 影响后续小周天"的增益闭环。约束:大周天执行是受托后台 Run,不形成第二个角色身份;守一、预算受控、候选先于写入与用户可关闭原则见 ADR-018。 + +## 3. 状态机 + +```mermaid +stateDiagram-v2 + [*] --> queued + queued --> running + running --> waiting_approval + waiting_approval --> running : approved + waiting_approval --> cancelled : denied or expired + running --> completed + running --> failed + running --> cancelled + completed --> [*] + failed --> [*] + cancelled --> [*] +``` + +## 4. 单轮时序 + +```mermaid +sequenceDiagram + participant C as Client + participant A as API + participant R as Runtime + participant M as Model Adapter + participant P as Policy + participant T as Tool Runtime + participant O as Observability + + C->>A: user message + A->>R: create or continue Run + R->>O: run.started / turn.started + R->>M: model request + M-->>R: text and tool_use blocks + usage + R->>O: model.request.completed + alt no tool call + R-->>A: final message stream + else tool call + R->>P: decide capability and risk + alt approval required + P-->>C: approval request + C-->>P: allow or deny + end + P->>T: execute allowed calls + T-->>R: tool results + R->>M: continue with all tool results + M-->>R: final response + usage + end + R->>O: turn.completed / run.completed + R-->>C: final event +``` + +## 5. 模型调用规则 + +- 业务只使用逻辑模型和能力需求;Adapter 决定上游协议和模型 ID。 +- 请求前保存 `context_snapshot` 清单和不可逆摘要,不默认保存完整拼接 Prompt。 +- 流式输出以最终固化 Message 为权威;delta 是临时事件。 +- 记录上游 request ID、开始时间、首 token、结束时间、stop reason 和真实 usage。 +- `input_tokens + cache_creation_input_tokens + cache_read_input_tokens` 才是总输入规模。 +- Provider 未提供 token 时 `usage_source=unavailable`;估算值必须标记为 `gateway_estimate`。 +- Provider 原生 Prompt Cache 与平台响应缓存是两个概念,字段不得混用。 + +## 6. Tool Use 规则 + +- `tool_use.id` 与 `tool_result.tool_use_id` 必须一一对应。 +- 同一模型响应中的并行工具先全部执行,再以一个用户工具结果消息返回。 +- 工具入参先按 JSON Schema 校验,再交给 Policy。 +- 工具失败返回结构化 `is_error`,不能丢弃失败后假装没有调用。 +- 副作用工具必须有幂等键;重试前检查已有结果。 +- 工具结果先作为带来源的观察,经过大小限制、脱敏和内容安全处理后才能进入后续上下文。 +- 行动自主性分级 `autonomy_level`(登记于契约):自省(无外部后果的内部整理,可自动执行)、循律(既有授权内执行)、请命(需确认)、禁域(拒绝);分级由 Policy 按能力、数据、后果、情境四维判定。 +- Skill 与工具只提供受限工作方法:与角色基线、用户当前指令、关系边界或 Policy 规则冲突时必须让位,不得以"技能惯例"扩大权限。 + +## 7. 上下文装配 + +稳定顺序: + +1. 可用工具定义; +2. 系统与角色稳定指令; +3. 当前路径消息; +4. 获准记忆和知识; +5. 动态运行上下文; +6. 当前用户输入。 + +Prompt Cache 依赖字节级前缀一致。工具和系统稳定内容置前;时间、请求 ID、当前输入等动态内容置后。缓存命中只由 Provider usage 判定。 + +## 8. 记忆写入 + +记忆提取在 Message 完成后异步生成 MemoryCandidate;Candidate 经 Policy 与必要的人工确认后才能创建不可变 MemoryVersion。自动提取不能修改 `identity_baseline`,敏感资料、关系结论、高影响推断和第三方信息默认要求确认。完整的所有权、写入、纠正、召回和 ContextSnapshot 规则见[记忆与知识架构](memory-and-knowledge.md)。 + +## 9. 多 Agent 编排 + +```mermaid +flowchart TD + C[Coordinator Run] --> P[Plan and Budget] + P --> A1[Child Run A] + P --> A2[Child Run B] + P --> A3[Child Run C] + A1 & A2 & A3 --> H[Structured Handoff] + H --> V[Coordinator Verification] + V --> F[Final Result] +``` + +- Coordinator 只在任务可独立并行、需要不同专长或上下文隔离时创建 ChildRun。 +- ChildRun 使用独立上下文与事件流,共享文件/对象必须通过显式资源授权。 +- 深度、并发、总 token、费用、墙钟时间和工具调用数由 RunBudget 硬限制。 +- 子 Agent 的插件、工具、网络、设备和数据范围是父权限的交集子集。 +- Handoff 包含结论、证据 ID、产物 ID、未完成项、错误和 usage,不传隐藏推理。 +- 角色 Agent 的后台子 Run 不形成第二个角色身份,也不能独立演进关系或人格。 +- 用户可以查看、暂停、取消单个 ChildRun 或整个协调 Run。 + +## 10. 取消与恢复 + +- 取消信号传播到模型流、工具执行和子 Run。 +- 已产生的部分文本标记为 `interrupted`,不作为完成答复。 +- 服务重启从持久化状态恢复;等待审批的 Run 不因 Worker 更换丢失。 +- 无法证明工具是否执行时,状态为 `unknown_outcome`,不得自动重试有副作用操作。 diff --git a/docs/architecture/community-and-marketplace.md b/docs/architecture/community-and-marketplace.md new file mode 100644 index 0000000..ecfc783 --- /dev/null +++ b/docs/architecture/community-and-marketplace.md @@ -0,0 +1,134 @@ +# 社区、协作与市场架构 + +## 1. 领域边界 + +```mermaid +flowchart LR + ID[Identity] --> COMMUNITY[Community] + ID --> WORKSPACE[Collaboration] + COMMUNITY --> CATALOG[Marketplace Catalog] + WORKSPACE --> CATALOG + CATALOG --> ORDER[Order] + ORDER --> PAYMENT[Payment] + PAYMENT --> LEDGER[Ledger and Settlement] + COMMUNITY --> MOD[Moderation] + CATALOG --> MOD + PLUGIN[Plugin Registry] --> CATALOG + CHARACTER[Character Releases] --> CATALOG +``` + +社区互动、协作权限、商品目录、订单支付和不可变账务分开建模。点赞数、销量、推荐分数不能成为支付账或许可事实源。 + +## 2. 社区 + +### 2.1 内容与互动 + +- 用户主页、关注关系和可见性; +- 动态、文章、图片、音视频和作品集合; +- 评论、回复、点赞、收藏、标签和分享; +- 搜索、话题、推荐流、趋势和通知; +- 屏蔽、静音、举报、审核、申诉和处置历史。 + +### 2.2 角色社区 + +角色、世界设定、知识库、工作流、Prompt、Live2D、3D、声音和插件都以**发布版本**进入社区: + +- 草稿与已发布版本分离; +- 每版保存来源、作者、许可证、兼容版本和变更说明; +- Fork 创建谱系边,不冒充原作者或同一角色身份; +- 下架阻止新分发,但既有许可副本按许可与安全处置规则处理; +- 角色私密记忆、关系和会话永不随公开角色版本发布。 + +## 3. 搜索与推荐 + +- 搜索索引是派生数据,可从公开内容和许可元数据重建。 +- 推荐使用显式互动、内容特征和用户可控偏好;私密消息、敏感记忆、精确位置和诊断内容不作为特征。 +- 用户可以查看主要推荐原因、关闭个性化和重置推荐数据。 +- 反指标包括成瘾诱导、付费偏置未披露、未成年人不当内容和小创作者系统性不可见。 + +## 4. 内容治理 + +```mermaid +stateDiagram-v2 + [*] --> draft + draft --> published + published --> limited + published --> removed + limited --> published + limited --> removed + removed --> appealed + appealed --> published + appealed --> removed +``` + +Policy 覆盖:违法内容、现实人物冒充、声音/肖像许可、成人内容、骚扰、隐私、恶意插件、版权和交易欺诈。自动模型只能产生信号或临时限流,高影响永久处置需要可审阅规则和申诉。 + +## 5. 协作空间 + +Workspace 包含: + +- owner、admin、editor、reviewer、viewer 等 RBAC; +- 邀请、移除、权限变更和外部链接; +- 角色、世界、知识、工作流和资产的版本分支; +- 评审、评论、批准、合并和活动记录; +- 协同编辑 presence、乐观并发或 CRDT; +- 发布权限与市场上架权限分离。 + +协作者能编辑项目不等于能读取成员私密记忆、个人对话、支付账户或诊断内容。 + +## 6. 插件注册与分发 + +插件发布物包含 Manifest、包摘要、签名、权限、依赖、兼容版本、配置 Schema、隐私说明、源代码/许可证信息和安全扫描结果。 + +状态:draft → submitted → review → published → suspended/removed。更新产生新不可变版本;安全撤架可阻止安装和执行,但不能静默删除历史 Run 的 PluginSnapshot。 + +## 7. 市场商品与许可 + +商品类型:角色发布版、角色卡、世界设定、知识库、Prompt/工作流、Live2D、3D、声音、媒体包和插件。 + +每个 Listing 绑定: + +- seller 与可验证发布版本; +- 价格、货币、地区、税类和可售状态; +- 许可证、允许的用途、席位/设备范围、更新政策和退款政策; +- 审核状态、年龄分级、交付对象摘要和内容哈希。 + +订单成功创建 `entitlement`;下载 URL 只是短期交付方式,不是许可本身。 + +## 8. 支付、退款与账务 + +```mermaid +sequenceDiagram + participant U as Buyer + participant O as Order Service + participant P as Payment Provider + participant W as Webhook Consumer + participant L as Ledger + participant E as Entitlement + + U->>O: create order with idempotency key + O->>P: create payment + P-->>U: payment confirmation flow + P-->>W: signed webhook + W->>W: verify and deduplicate + W->>L: append payment entries + L->>E: grant entitlement + E-->>U: deliver purchased version +``` + +- 金额使用最小货币单位或 Decimal; +- Ledger 采用复式或等价不可变分录,修正使用反向分录; +- 订单、Provider payment、退款、拒付、平台费、创作者应付和税费分别记录; +- Webhook 不依赖到达顺序,按 Provider event ID 幂等; +- 每日自动对账 Provider 报表、订单和 Ledger; +- 退款更新 entitlement 的后续更新/下载策略,不能删除审计账。 + +## 9. 创作者结算 + +- 创作者账户记录 KYC/主体状态、地区、结算币种、税务资料引用和 Provider account; +- 收益先进入 pending,经过退款/拒付准备期后转 available; +- SettlementBatch 生成应付、费用、税款和净额; +- Provider payout 失败可重试,但同一结算批次不能重复付款; +- 提供对账单、发票/税务数据导出、结算历史和争议工单。 + +敏感 KYC 和银行数据优先由支付 Provider 托管;Hunjing 只保存引用、状态和必要的脱敏信息。 diff --git a/docs/architecture/data-architecture.md b/docs/architecture/data-architecture.md new file mode 100644 index 0000000..979eca9 --- /dev/null +++ b/docs/architecture/data-architecture.md @@ -0,0 +1,123 @@ +# 数据架构 + +## 1. 事实源 + +关系数据库保存角色、社区、协作、交易、插件和运行的权威状态;对象存储保存媒体与交付物;全文、向量、图投影、推荐特征和缓存都是派生数据。 + +```mermaid +flowchart LR + DB[(Relational Source of Truth)] --> FTS[Full-text Index] + DB --> V[Vector Index] + DB --> G[Graph Projection] + DB --> C[Cache] + FS[(Object Storage)] --> DB + FTS & V & G & C --> Q[Query and Retrieval] +``` + +任何索引可从数据库和对象存储重建,不能反向覆盖角色、记忆、社区来源、许可或交易账。 + +## 2. 核心关系 + +```mermaid +erDiagram + PERSONAL_DOMAIN ||--o{ CHARACTER : owns + CHARACTER ||--o{ CHARACTER_VERSION : versions + CHARACTER ||--o{ CHARACTER_ASSET : presents + CHARACTER ||--o{ MEMORY : remembers + CONVERSATION ||--o{ BRANCH : contains + BRANCH ||--o{ MESSAGE : orders + CONVERSATION ||--o{ RUN : triggers + RUN ||--o{ TURN : contains + TURN ||--o{ MODEL_CALL : attempts + TURN ||--o{ TOOL_CALL : invokes + RUN }o--|| PLUGIN_SNAPSHOT : pins + WORKSPACE ||--o{ WORKSPACE_MEMBER : authorizes + WORKSPACE ||--o{ PROJECT_ASSET : contains + USER ||--o{ COMMUNITY_CONTENT : publishes + COMMUNITY_CONTENT ||--o{ INTERACTION : receives + PUBLISHER ||--o{ PLUGIN_VERSION : releases + MARKETPLACE_LISTING }o--|| RELEASE_VERSION : sells + ORDER ||--o{ ORDER_ITEM : contains + ORDER ||--o{ LEDGER_ENTRY : posts + ORDER_ITEM ||--|| ENTITLEMENT : grants + SETTLEMENT_BATCH ||--o{ LEDGER_ENTRY : settles +``` + +## 3. 数据分区 + +| 范围 | 典型数据 | 默认可见性 | +| --- | --- | --- | +| Personal Domain | 私密角色、记忆、对话、设备授权 | owner only | +| Workspace | 协作角色、世界、资产、评审 | member RBAC | +| Community | 已发布内容、互动、公开版本 | visibility policy | +| Marketplace | 商品、许可和公开交付摘要 | regional catalog | +| Finance | 订单、支付、退款、账务、结算 | buyer/seller/finance roles | +| Diagnostics | Run、工具、上下文和敏感支持包 | scoped grant | + +公开角色 Release 不包含 Personal Domain 中的私密记忆、关系、对话和密钥。 + +## 4. 角色、记忆与资产 + +- CharacterVersion:不可变角色设定版本。 +- CharacterAsset:图像、声音、Live2D、3D、动作和场景版本,引用对象与许可。 +- Memory/MemoryVersion:长期状态、来源、敏感度、置信度、有效期、审批和纠正链;所有权、写入、版本、检索与装配见[记忆与知识架构](memory-and-knowledge.md)。 +- KnowledgeDocument:外部资料、世界设定和共享知识,不等于人物经历。 +- ReleaseVersion:面向社区/市场发布的不可变物料清单与内容哈希。 + +## 5. 社区与协作 + +- CommunityContent 使用统一发布对象加类型化 payload;互动独立记录并支持软删除与治理状态。 +- Follow、Block、Report 和 ModerationCase 为一等对象。 +- WorkspaceMember 和资源 ACL 双重约束;关键权限变更写审计。 +- 协同编辑使用版本号/乐观锁;高频富文本或场景编辑确有需要时采用 CRDT,快照仍落关系事实源。 +- 推荐特征保存来源和版本,允许用户清除;Restricted 数据不得进入。 + +## 6. 插件 Registry + +Plugin、PluginVersion、PackageBlob、Signature、PermissionManifest、Compatibility、Review、Installation 和 PluginSnapshot 分开保存。PluginVersion 不可变;下架修改可分发状态,不改历史包摘要和 Run 快照。 + +## 7. 订单与账务 + +- Listing 可变;OrderItem 固定购买时的版本、价格、税、许可和卖家快照。 +- PaymentAttempt、Refund、Dispute、Entitlement 与 Order 分离。 +- LedgerEntry 不可变,使用平衡分录或等价会计模型;修正写反向分录。 +- CreatorBalance 是 Ledger 聚合,不是独立可编辑事实。 +- SettlementBatch 固定结算项;PayoutAttempt 记录 Provider 结果和幂等键。 +- 金额使用整数最小单位或 Decimal,记录币种、汇率来源和价格版本。 + +## 8. Run 与诊断 + +Run 只保存聚合状态。Turn、ModelCall、ToolCall、ContextSnapshot、PluginSnapshot 和 AuditEvent 独立查询。Provider 原始正文默认不保存;支持需要时进入加密、限期对象并受 Sensitive DiagnosticGrant 控制。 + +## 9. 删除与许可传播 + +```mermaid +flowchart TD + D[Delete or revoke request] --> A[Authorize and audit] + A --> P[Update authoritative source] + P --> I[Remove indexes and caches] + P --> O[Delete or redact derived objects] + P --> R[Evaluate releases and entitlements] + R --> N[Stop new distribution or updates] + O --> B[Apply backup retention] + B --> T[Keep minimal tombstone] +``` + +删除私密源数据不等于撤销所有已合法发布许可;撤架、许可撤销、安全强制停用和用户删除分别建模。墓碑不保存被删原文。 + +## 10. 一致性与事件 + +- 权威状态和 Outbox 在同一事务写入;完整 1.0 的媒体、索引、通知、支付、社区和插件消费者需要 Outbox。 +- Webhook/ToolCall 在副作用前写 pending 与幂等键,完成后写结果。 +- 支付事件不依赖到达顺序;重复事件返回已有处理结果。 +- 搜索、推荐、媒体和向量失败可重建,不影响权威状态。 + +## 11. 存储选择 + +- SQLite:本地开发与个人轻量自托管。 +- PostgreSQL:正式部署的关系事实源和全文检索。 +- Redis:队列、限流、实时会话和短期状态。 +- S3-compatible:媒体、插件包、交付物和加密支持包。 +- pgvector:默认语义检索起点;规模或评测需要时替换为专用向量库。 +- 图关系先使用 PostgreSQL;多跳规模证明需要时启用 Neo4j/NebulaGraph 投影。 +- 分析/搜索引擎按社区规模引入,不成为交易或身份事实源。 diff --git a/docs/architecture/frontend-content-rendering.md b/docs/architecture/frontend-content-rendering.md new file mode 100644 index 0000000..9aeef58 --- /dev/null +++ b/docs/architecture/frontend-content-rendering.md @@ -0,0 +1,184 @@ +# 前端富内容实时渲染 + +## 1. 适用客户端 + +同一渲染内核服务 Next.js Web、Tauri Desktop 和 Tauri Mobile。平台差异只位于资源加载、文件保存、设备能力和性能档位;ContentBlock 与流状态机保持一致。 + +推荐组件: + +- Markdown:`react-markdown` + `remark-gfm` + 受控 remark/rehype 插件; +- Code:Shiki,高亮 Worker 与缓存; +- Math:KaTeX 为默认,MathJax 只作为兼容回退; +- Mermaid:Mermaid strict mode,在 Worker/隔离容器渲染 SVG; +- 长列表:`@tanstack/react-virtual`; +- 媒体:原生 image/video/audio,使用受控资源 URL; +- 状态:TanStack Query 管服务端资源;轻量本地 store 管流 accumulator 和 UI 状态。 + +新增依赖前仍需按 AGENTS.md 查当前维护状态和已安装能力。 + +## 2. 渲染流水线 + +```mermaid +flowchart LR + SSE[SSE Events] --> ACC[Event Accumulator] + ACC --> STORE[Block Store] + STORE --> PARSE[Incremental Parse] + PARSE --> SAFE[Sanitize and Validate] + SAFE --> RENDER[Typed Renderers] + RENDER --> DOM[Accessible UI] + FINAL[Completed Message] --> RECON[Reconcile] + RECON --> STORE +``` + +各层职责: + +1. Event Accumulator:校验 run sequence 与 block delta index,去重和检测缺口。 +2. Block Store:以 `message_id/block_id` 保存原始 block、流状态和 renderer 状态。 +3. Parse:只对允许增量的类型做节流解析。 +4. Sanitize:URL、Markdown AST、SVG、公式和媒体元数据安全处理。 +5. Renderer:按 Block type 分派,未知类型显示兼容占位而不崩溃。 +6. Reconcile:`content.block.completed` 与 `message.completed` 到达后用权威快照替换临时状态。 + +## 3. 流状态机 + +```mermaid +stateDiagram-v2 + [*] --> pending + pending --> streaming : block.started + streaming --> streaming : ordered delta + streaming --> awaiting_replay : delta gap + awaiting_replay --> streaming : replay filled + awaiting_replay --> completed : final snapshot + streaming --> completed : block.completed + streaming --> failed : block.failed + streaming --> cancelled : block.cancelled + failed --> completed : retry/resource ready + completed --> [*] + cancelled --> [*] +``` + +- 乱序 delta 暂存在小窗口;超过窗口请求重放,不猜顺序。 +- 重复 delta 根据 `(block_id, delta_index)` 丢弃。 +- 连接断开保留乐观内容并标记“正在恢复”;最终 GET Run/Message 对账。 +- Final snapshot 与累积 hash 不一致时记录前端诊断并以服务端快照为准。 + +## 4. Markdown 增量渲染 + +### 4.1 策略 + +- 原始增量文本始终保留;AST 是可丢弃派生状态。 +- 以 50–100 ms 或换行边界节流解析,不逐 token 全量重渲染。 +- 未闭合 fence、链接、表格、强调或数学定界符保持源码/纯文本展示,不自动补造语义。 +- Completed 后对完整 Markdown 再解析一次,替换临时 AST。 +- 大 Block 分段渲染,避免每次 delta 重建整个消息树。 + +### 4.2 安全 + +- 禁用原始 HTML;若以后开放,仅对可信内部内容使用严格 allowlist。 +- 链接协议允许 `https`、`mailto` 和内部资源 scheme;拒绝 `javascript`、危险 `data`、`file`。 +- 外链打开使用 `noopener noreferrer`,并显示目标域。 +- Markdown 图片规范化为 Image Block;不直接加载任意第三方跟踪像素。 + +## 5. Code 与 Shiki + +- 流式时先用等宽纯文本展示;完整行或节流窗口后发送 Worker 高亮。 +- Shiki grammar 按需加载并缓存;未知语言回退 plain text。 +- 超大代码块关闭实时高亮,完成后按可见区域高亮。 +- 提供复制、换行、下载、语言、文件名和行号;复制取原始源码,不从高亮 DOM 提取。 +- 代码永不在渲染器执行;可执行动作是独立 Tool/Approval。 + +## 6. 数学公式 + +### 6.1 解析 + +- Native Math Block 直接按 `notation` 处理。 +- Markdown 中只有闭合 `$...$`、`$$...$$`、`\(...\)`、`\[...\]` 才触发公式渲染。 +- 流式未闭合公式显示转义源码和稳定占位,避免页面反复跳动。 +- KaTeX 解析失败显示 `fallback_text` 或源码,并提供错误详情展开。 + +### 6.2 安全和可访问性 + +- KaTeX `trust=false`,限制宏、展开深度和输入长度;禁用 URL/HTML 注入命令。 +- 生成 MathML/ARIA;Block 公式提供自然语言 `fallback_text`、变量和单位说明。 +- 用户可切换“渲染公式/显示源码”。 +- 常见公式描述采用“名称 → 公式 → 变量/单位 → 适用条件 → 示例”的结构,不把推导过程混入隐藏思维。 + +## 7. Mermaid + +- 流式期间不渲染图,仅展示代码骨架和进度。 +- `block.completed` 后把源码发送 Worker;验证节点数、边数、字符数和超时。 +- Mermaid 使用 `securityLevel: strict`,禁止 click、HTML label、外部资源和任意初始化指令。 +- 输出 SVG 再经 sanitizer;SVG 不允许 script、foreignObject、事件属性或外部 URL。 +- 渲染失败显示源码、错误摘要和“复制到 Mermaid 编辑器”的安全动作,不空白。 +- 提供缩放、平移、适配宽度、下载 SVG/PNG、文本替代和全屏。 +- 图表在移动端默认源码/缩略图折叠,按需展开,防止长宽溢出。 + +## 8. 图片、视频和音频 + +### 图片 + +- 使用 `file_id` 换取短期授权 URL;响应式尺寸、懒加载、占位、失败重试和 alt。 +- 不信任服务端文件名/MIME;资源域返回正确 Content-Type、CSP、CORP 和 `nosniff`。 +- 大图支持查看器、缩放和下载;不默认将 EXIF 暴露给其他用户。 + +### 视频 + +- 等待 `resource_ready` 后显示 poster;使用 HLS/DASH 或受控 MP4。 +- 提供字幕、转写、时长、加载/转码状态和失败说明。 +- 自动播放默认关闭;有声音播放必须由用户手势触发。 + +### 音频 + +- 显示波形/时长/转写;流式 TTS 与固化 Audio Block 分离。 +- 实时语音使用 WebSocket 播放队列,不把每帧写入 React 树。 +- 支持打断、静音、速度和字幕;停止后清空未播放帧。 + +## 9. Agent、工具和审批展示 + +- AgentStatus Block 显示当前阶段、ChildRun、预算、等待和取消操作,不展示隐藏推理。 +- ToolCall Block 默认显示工具名、用途、状态、耗时和脱敏参数摘要;敏感详情走诊断授权。 +- ApprovalRequest 必须显示动作、目标、影响、费用、数据范围、有效期、允许/拒绝按钮。 +- ToolResult 区分成功、错误、未知结果和产物,不把错误结果渲染成普通助手文本。 +- 并行 ChildRun 使用树/时间线,主消息流只展示汇总状态,避免刷屏。 + +## 10. 长列表与性能 + +- Conversation/Community/Diagnostics 使用虚拟滚动,Block 高度由 ResizeObserver 缓存。 +- 流式中的当前 Message 可脱离虚拟列表单独渲染,完成后归档入列表。 +- Markdown AST、Shiki tokens、Mermaid SVG 和 Math 渲染按 content hash 缓存。 +- Worker 处理高亮、Mermaid 和重解析;主线程只提交最终安全树。 +- `prefers-reduced-motion` 关闭非必要动画;流式光标不引发布局抖动。 +- 建立不同设备性能档:关闭实时代码高亮、降低 Avatar 帧率、延迟复杂图渲染,而不丢失内容。 + +## 11. 可访问性 + +- 每个 Block 使用正确语义元素和可聚焦操作。 +- 新 delta 不持续抢夺屏幕阅读器焦点;用节流 `aria-live` 汇报状态。 +- 图像必有 alt;图表有 title/caption/源码替代;音视频有字幕/转写。 +- 数学提供 MathML 和 fallback text;代码支持键盘复制和横向滚动。 +- 工具确认、错误和费用不能只靠颜色表达。 +- Avatar/动效不阻塞核心内容和操作。 + +## 12. 失败与降级 + +| 失败 | 展示 | +| --- | --- | +| Markdown 解析失败 | 转义纯文本 | +| Shiki 失败 | plain code | +| Math 失败 | fallback text + source | +| Mermaid 失败 | source + error summary | +| 媒体未就绪 | progress placeholder | +| 媒体失败 | retry/download details | +| 未知 Block type | “当前客户端暂不支持” + JSON-safe summary | +| SSE 断线 | recovering 状态 + replay/final fetch | +| hash 不一致 | final snapshot + diagnostic marker | + +降级必须保留用户内容,不以空白、崩溃或静默删除处理。 + +## 13. 测试 + +- 对每种 Block 建立 canonical fixture、流式分片、断线、重复、乱序、失败和未知类型测试。 +- Markdown/Math/Mermaid 做 XSS、URL、SVG、宏膨胀和资源耗尽测试。 +- 浏览器组件测试覆盖键盘、屏幕阅读器、reduced motion 和移动布局。 +- Playwright 覆盖从 SSE 到 Markdown/公式/Mermaid/媒体/Tool Approval 的端到端流程。 +- 对 1 MB Markdown、万行代码、复杂 Mermaid、长公式和大量消息做性能基线。 diff --git a/docs/architecture/lingtai-engine.md b/docs/architecture/lingtai-engine.md new file mode 100644 index 0000000..eb0b775 --- /dev/null +++ b/docs/architecture/lingtai-engine.md @@ -0,0 +1,119 @@ +# 灵台引擎架构 + +> 决策依据:[ADR-016](../decisions/README.md#adr-016灵台引擎采用-c-核心与稳定-c-abi)、[ADR-017](../decisions/README.md#adr-017灵台引擎双形态部署)。ABI 稳定值登记于 [Lingtai C ABI](../contracts/lingtai-ffi.md),独立服务契约见 [Lingtai Service](../contracts/lingtai-service.md)。文化名见[文化语言体系](../product/cultural-language.md)。 + +## 1. 定位与不变量 + +灵台引擎(Lingtai Engine / `libhunjing`)是 C++ 实现的确定性计算库,支持进程内嵌入与独立服务两种部署形态,为 Python、Rust、Go 宿主提供同一份核心实现: + +- **无权威状态**:角色、消息、记忆、订单等权威数据只在关系数据库与对象存储;引擎持有的一切中间产物可丢弃重建。崩溃或版本更换后,宿主从权威数据重放即可恢复。 +- **最小 I/O**:除显式传入的只读索引文件(`hj_recall` 以只读方式 mmap)外,引擎不打开文件、不发起网络、不连接数据库;输入输出全部经调用参数。独立服务形态下,网络端点由服务壳承担,核心计算仍不做自主 I/O。 +- **单一核心、双形态**:进程内嵌入与 gRPC 独立服务是同一核心的两种壳;任何能力的语义在两种形态下必须一致(同一 golden 测试集约束),形态选择是部署决策而非代码分叉。 +- **Core 的一部分**:灵台引擎实现治理内核中的确定性判定部分,属于不可插件化边界;插件不直接链接引擎,只能经宿主 Runtime 间接获得能力。 +- **fail closed**:引擎缺失、初始化失败、ABI 不匹配或服务不可达时,依赖该能力的宿主路径必须显式失败;禁止在宿主语言内维护第二份实现作为降级。 + +## 2. 灵台六模块子系统 + +| 文化名 | 稳定模块 | 职责 | 禁止承担 | +| --- | --- | --- | --- | +| 太一 | `hj_core` | 单一稳定入口:ABI/服务版本协商、句柄生命周期、跨形态统一路由、Run/Turn 状态转换合法性校验、事件 `sequence` 分配、跨模块错误上下文 | 持久化状态、业务裁决 | +| 小周天 | `hj_stream` | ContentBlock 流事件编码、`delta_index` 维护、`(block_id, delta_index)` 去重键、节流与背压计算、重放缓冲 | 发起网络 I/O、持久化流历史 | +| 洛书 | `hj_plan` | 计划 DAG 校验与拓扑排序、RunBudget 核算、Context Manifest 的 token 预算裁剪与优先级排序 | 调用模型、执行工具、创建子 Run | +| 河图 | `hj_recall` | 端侧与离线场景的只读混合检索索引、重排打分、多路检索合并 | 成为服务端权威检索(PostgreSQL 仍为权威)、写入索引 | +| 陶钧 | `hj_transform` | Markdown → canonical ContentBlock 确定性解析、数学定界符与 Mermaid fenced 提取、parser version 标注、导出重建 | 执行 HTML、请求网络资源 | +| 烛照 | `hj_policy` | JSON Schema 子集结构校验、路径 canonicalize 与根目录约束、URL scheme/host 校验、HMAC 验签、幂等键规范化、分层递进的决策表评估 | 发起用户审批交互、执行副作用 | + +"太一出两仪":`hj_core`(太一)是唯一对外总入口(单一稳定入口理念),承载版本协商、句柄与跨形态路由;其余五模块的会话句柄都从 `HjEngine` 派生并在其中登记,统一计数、统一回收——诸枢皆居灵台之内。烛照的判定按"结构 → 路径/URL → 签名 → 预算"分层递进,单层拒绝即短路返回,对应纵深防御理念。 + +```mermaid +flowchart TB + API[hj_ C ABI and gRPC service face] --> CORE[hj_core] + CORE --> STREAM[hj_stream] + CORE --> PLAN[hj_plan] + CORE --> RECALL[hj_recall] + CORE --> TRANSFORM[hj_transform] + CORE --> POLICY[hj_policy] + RECALL --> RO[(read-only index files)] +``` + +## 3. 部署形态 + +```mermaid +flowchart LR + subgraph Embedded + PY[FastAPI host] --> B1[nanobind binding] + RS[Tauri Rust host] --> B2[bindgen wrapper] + GO2[Go gateway host] --> B3[cgo binding] + B1 & B2 & B3 --> ABIL[stable C ABI hj_] + end + subgraph Standalone + ANY[any host in deployment] --> GRPC[gRPC over mTLS] + end + ABIL --> ENGINE[Lingtai core] + GRPC --> SRV[hunjing-lingtai-server] + SRV --> ENGINE +``` + +### 3.1 进程内嵌入(默认) + +- 宿主经 C ABI 链接 `libhunjing`;绑定层是薄封装:类型转换、内存托管(RAII/GC 挂钩)、错误映射为各语言惯用错误类型;不复制业务语义,不缓存权威状态。 +- 适用:模块化单体部署的全部计算路径、Tauri 桌面/移动端(含离线)、对延迟敏感的调用(每请求同步计算)。 +- 宿主负责一切 I/O 编排:数据库读写、模型调用、SSE/WebSocket 传输、审批交互。引擎只回答"计算结果是什么",不回答"接下来做什么"。 + +### 3.2 独立服务(按需启用) + +- `hunjing-lingtai-server` 链接同一核心,以 gRPC 暴露能力;契约(proto、方法、流语义、错误映射)见 [Lingtai Service](../contracts/lingtai-service.md)。 +- 适用:重型解析/检索需要独立扩缩容与资源隔离;同一部署内多宿主(API、Worker、网关)共享引擎容量;引擎需独立升级发布;跨机器集中计算。 +- 服务只在部署内部网络监听,经 mTLS/工作负载身份认证;不进入公共 API 分面,不经网关对外暴露。 +- 启用标准沿用[系统架构](system-architecture.md)的服务拆分标准;不满足标准时保持嵌入形态。 + +### 3.3 形态选择与演化 + +- 默认嵌入;满足独立扩缩容、故障域、资源隔离或多宿主共享证据时切换或混用(例如服务端用服务形态、端侧用嵌入形态)。 +- 客户端代码面向"引擎 Port"编程(进程内与服务两个实现),切换形态不改业务语义,只改部署配置;Port 定义见[内部端口](../contracts/internal-api.md)的组织方式。 +- 前端 Web(TypeScript)不经 C ABI;如需复用解析逻辑,WebAssembly 编译目标与"经服务形态远程消费"作为 1.0 后评估项,不在本架构承诺内。 + +### 3.4 真实调用点 + +| 宿主路径 | 使用子系统 | 对应工作包 | +| --- | --- | --- | +| 消息创建:用户 Markdown 规范化为 canonical ContentBlock | `hj_transform` | WP-03 | +| Run SSE:事件 envelope 编码、增量去重与节流 | `hj_stream` | WP-03/WP-05 | +| Tool input Schema 校验、工具路径/URL 约束判定 | `hj_policy` | WP-06 | +| Webhook 验签与幂等键规范化 | `hj_policy` | WP-13 | +| 计划 DAG 校验与 RunBudget 核算 | `hj_plan` | WP-06 | +| Tauri 移动端加密离线缓存的本地检索与重排 | `hj_recall`(仅嵌入形态) | WP-10 | +| Run/Turn 状态转换合法性校验 | `hj_core` | WP-05/WP-06 | + +## 4. 内存、线程与错误模型 + +- **所有权**:引擎分配的缓冲区只能交还 `hj_buffer_free` 释放;宿主内存以 `const` 指针加长度只读传入,引擎不得持有调用返回后的宿主指针。 +- **字符串**:一律 UTF-8;输入可为 NUL 结尾或指针加长度,输出始终为指针加长度。 +- **句柄**:`HjEngine` 线程安全,可被多线程并发调用;`hj_stream` 等会话级句柄单线程亲和,由创建线程使用。句柄关闭两次返回 `HJ_ERR_HANDLE_INVALID`,不崩溃。 +- **回调**:流式回调在调用线程同步触发;回调内部禁止再调用引擎 API,违规以 `HJ_ERR_REENTRANCY` 尽力检测。 +- **异常与崩溃**:C++ 异常不得跨越 ABI;引擎入口捕获一切异常并转换为 `HjStatus`。任何输入都不得导致引擎 `abort`/未定义行为——解析失败返回 `HJ_ERR_PARSE_FAILED`,超限返回 `HJ_ERR_LIMIT_EXCEEDED`。 +- **错误传递**:`HjStatus` 携带稳定码;`hj_last_error` 提供该线程最近一次错误的消息缓冲(不含敏感正文),绑定层映射为宿主异常/`Result`/`error`,服务层再映射为 HTTP 错误契约。 + +## 5. 与既有架构的关系 + +- **内容契约不变**:`hj_transform` 的输入输出即 [统一富内容与流式协议](../contracts/content-blocks-and-streaming.md) 定义的 Block 与事件 JSON Schema;引擎输出 canonical JSON(键序确定),供 hash 与跨端一致性测试。 +- **状态机权威不变**:Run/Turn/ModelCall 的持久化与恢复遵循 [Agent 运行时](agent-runtime.md);`hj_core` 只校验状态迁移合法性并分配 `sequence`,不存储权威状态。 +- **检索分工**:服务端权威检索仍是 PostgreSQL 全文与 pgvector([记忆与知识架构](memory-and-knowledge.md));`hj_recall` 服务于端侧离线与重排计算,索引是可重建投影,删除与授权变化随宿主重建传播。 +- **策略归属**:审批流、用户确认与 Policy 最终裁决遵循 [安全与诊断访问](../security/security-and-diagnostics.md);`hj_policy` 提供确定性判定原语与高速规则评估,不发起 I/O、不绕过审批。 +- **插件边界**:[插件系统](plugin-system.md) 的 Manifest、Snapshot、双轨执行不变;插件经宿主间接消费引擎能力,Run 快照记录引擎与 parser 版本。 + +## 6. 构建、分发与平台 + +- 语言标准 C++23,CMake + Ninja;符号默认隐藏,仅导出 `hj_*`(API 卫生,非对抗手段)。 +- 产物:动态库 `libhunjing`(`.so`/`.dylib`/`.dll`)与静态库;独立服务二进制 `hunjing-lingtai-server`;单一公共头 `include/hunjing/lingtai.h` 与服务 proto(见 [Lingtai Service](../contracts/lingtai-service.md))。 +- 平台矩阵:Linux x86_64/aarch64、macOS aarch64、Windows x86_64、iOS/Android arm64(服务态);iOS/Android 仅嵌入形态,不交付服务二进制。 +- CI 产出带版本号的预编译产物并做签名与哈希公示;自托管者可从源码构建,构建须可重现。 +- 依赖最小化:第三方库进入前按工程规则评估官方文档、许可与维护状态;ANN/分词/gRPC 栈等实现选型在实现期以补充 ADR 登记,本文不预设。 + +## 7. 安全与测试边界 + +- 引擎的全部输入(用户 Markdown、模型输出、工具参数、检索查询、Webhook 原始字节)按不可信输入处理:长度与深度硬上限、资源限额由配置发布且 Schema 有上界。 +- 持续测试门槛:`hj_transform`/`hj_policy` 为 fuzz 必测目标(libFuzzer);每次提交跑 ASan/UBSan,线程路径跑 TSan;ABI 快照测试保证符号与布局不发生未声明变更。 +- 双形态一致性:同一组 canonical 输入在 Python/Rust/Go 绑定与 gRPC 服务路径下的输出字节一致(golden 测试覆盖进程内与服务两种形态),防止绑定或服务壳漂移。 +- 服务形态额外要求:mTLS 双向认证、每方法超时与并发上限、背压与限流、调用审计(不含正文);服务不可达时宿主 fail closed。 +- 引擎产物进入诊断或日志前遵守脱敏规则;错误消息不包含请求正文、密钥或凭据。 diff --git a/docs/architecture/media-and-device-architecture.md b/docs/architecture/media-and-device-architecture.md new file mode 100644 index 0000000..d30a4e6 --- /dev/null +++ b/docs/architecture/media-and-device-architecture.md @@ -0,0 +1,123 @@ +# 媒体、Avatar 与设备架构 + +## 1. 范围 + +完整 1.0 支持文字、图像、音频、实时语音、Live2D、3D Avatar,以及 Web、Tauri 桌面和 Tauri 移动端的文件、相机、麦克风、屏幕与位置能力。 + +## 2. 媒体处理 + +```mermaid +flowchart LR + IN[Upload or Capture] --> CONSENT[Consent and Scope] + CONSENT --> SCAN[Safety and Malware Scan] + SCAN --> STORE[(Original Object)] + STORE --> JOB[Media Job] + JOB --> DERIVE[Transcode, ASR, Generate, Rig] + DERIVE --> REVIEW[User Review] + REVIEW --> ASSET[Versioned Character Asset] + ASSET --> RENDER[Client Avatar Runtime] +``` + +- 原始媒体、派生媒体、缩略图、转写和模型输入分别记录来源与保留期。 +- 媒体任务异步执行,支持进度、取消、失败重试和幂等。 +- 生成或编辑结果先是候选,用户采用后才成为角色正式资产版本。 +- 文件名、MIME、实际内容、尺寸和许可都要验证。 + +## 3. 语音 + +### 3.1 能力 + +- 上传音频和语音消息; +- 流式或分段 ASR; +- TTS 流式合成; +- WebSocket 实时语音会话; +- 打断、端点检测、字幕、语言检测和切换; +- 预设声音、原创声音设计和授权声音克隆; +- 原音频与 TTS 默认短期缓存,ASR 原转写与正影文本并存;多说话者默认匿名分段,长期声纹与身份识别需独立同意;不承诺持续监听或电话级全双工。 + +### 3.2 实时链路 + +```mermaid +sequenceDiagram + participant C as Client + participant G as Realtime Gateway + participant A as ASR + participant R as Agent Runtime + participant T as TTS + + C->>G: audio frames + G->>A: authorized audio stream + A-->>G: transcript deltas + G->>R: finalized user segment + R-->>G: text deltas + G->>T: speakable text + T-->>G: audio frames + G-->>C: text and audio events + C->>G: interrupt + G->>R: cancel current generation + G->>T: stop synthesis +``` + +音频原文默认短期保留;转写纠正创建新版本。声音克隆必须绑定授权主体、用途、期限、传播范围和撤回状态。 + +## 4. 图像与角色一致性 + +- 文生图、图生图、局部重绘、背景去除、分层和风格参考; +- 角色稳定外观参考与可变属性分离; +- 每次生成保存模型、提示摘要、来源资产、许可和安全结果; +- 社区/市场发布前检查现实人物、版权、成人内容和来源许可。 + +## 5. Live2D + +1.0 包含: + +- Cubism-compatible 模型导入和校验; +- 图像分层辅助和候选导出; +- 参数、表情、口型、视线、物理和动作映射; +- 可视化参数编辑、预览和版本; +- Web/Tauri 运行时; +- 标准资源导出。 + +不重做 Cubism Editor 的全部专业绘制和网格编辑功能。 + +## 6. 3D + +1.0 采用开放格式和非破坏编辑: + +- VRM/glTF 导入、验证和标准化; +- 材质、纹理、骨骼、BlendShape/表情映射; +- 动作库、动画状态、口型、视线和实时姿态; +- 灯光、相机、环境和场景对象编辑; +- 角色附件、服饰挂点和版本; +- WebGPU/WebGL 与 Tauri Runtime; +- VRM/glTF 导出和来源清单。 + +2.0 才引入完整网格建模、雕刻、拓扑、绑定和 LLM 直接修改几何/绑定。1.0 的编辑命令和版本历史必须可扩展到该能力。 + +## 7. 设备授权 + +`device_grant` 至少绑定: + +- user、device、character; +- capability:file/camera/microphone/screen/location/notification; +- purpose、scope、precision; +- granted/started/expires/revoked 时间; +- foreground/background 限制; +- retention 与 derived-use 策略。 + +### 7.1 规则 + +- 默认关闭;首次使用由系统权限和产品确认共同授权。 +- 相机、麦克风和屏幕采集始终显示可感知指示。 +- 位置支持单次、使用期间、精度和有效期,不默认后台持续采集;相机支持单次看见与限时通感。 +- 设备采用一次配对、设备密钥、可撤销证书和可验证固件。 +- Tauri command 按 capability allowlist 暴露,不提供通用任意命令桥。 +- 移动平台后台能力受 iOS/Android 平台规则限制;不通过隐藏保活绕过。 +- 设备失联只允许已授权的本地缓存和安全停止,不运行独立角色副本。 + +## 8. 隐私与删除 + +- 原始采集和派生内容分别删除; +- 已撤回声音授权停止新生成和新发布; +- 社区或市场已有合法许可副本按许可条款处理,但不得继续暴露已删除的私密源文件; +- 人脸、声纹、精确位置和屏幕内容为 Restricted 数据,不进入普通日志、推荐特征或自动记忆。 diff --git a/docs/architecture/memory-and-knowledge.md b/docs/architecture/memory-and-knowledge.md new file mode 100644 index 0000000..53501c9 --- /dev/null +++ b/docs/architecture/memory-and-knowledge.md @@ -0,0 +1,184 @@ +# 记忆与知识架构 + +> 本文定义 1.0 的记忆所有权、写入、版本、检索和上下文装配边界。字段与稳定枚举以 `docs/contracts/` 和后续 OpenAPI 3.1 为准。 + +## 1. 边界 + +- `Message` 是不可被记忆覆盖的原始交流记录;编辑产生 Revision。 +- `MemoryCandidate` 是待判定的提取结果,不参与正式召回。 +- `Memory` 是稳定标识;`MemoryVersion` 是不可变内容版本,当前版本仅由 `Memory` 指针引用。 +- `KnowledgeDocument` 保存外部资料和世界设定;其切片与索引是可重建投影,不冒充人物经历。 +- Character baseline、用户资料、关系、知识和记忆分别建模;任何记忆策略都不能直接修改 CharacterVersion。 +- 对话压缩、工作上下文和 Provider Prompt Cache 是运行期派生状态,不属于长期记忆。 +- 1.0 不定义可绕过治理的 `WorkingMemory` 类型;当前分支消息和 Run 临时上下文始终按 Personal Domain/Workspace、Character、Conversation、Branch 与 Run 授权,不能因“临时”跳过隔离。 + +1.0 的权威记忆是可检查、可纠正的文本或结构化记录。KV cache、隐藏状态和模型权重适配不作为权威记忆,也不进入 1.0 记忆可携格式。 + +## 2. 所有权与作用域 + +每条 Memory 必须属于且只属于一个授权边界: + +| 所有权 | 必需关联 | 可选关联 | 用途 | +| --- | --- | --- | --- | +| Personal Domain | `personal_domain_id` | `character_id` | 用户级或私密角色级记忆 | +| Workspace | `workspace_id` | `character_id` | 经成员权限允许的协作记忆 | + +约束: + +- `personal_domain_id` 与 `workspace_id` 二选一;在数据库层使用检查约束落实。 +- `character_id` 只能引用同一所有权边界内的 Character。 +- `conversation_id`、`message_id`、`content_block_id`、`run_id` 和 `tool_call_id` 是来源或适用条件,不是授权边界。 +- 角色间共享通过显式授权和独立引用完成,不复制一份失去来源关系的 Memory。 +- 子 Agent 只读父 Run 已批准的召回快照;默认没有创建、批准、纠正或删除长期记忆的能力。 +- 社区 Release、市场交付物和推荐特征不得包含 Personal Domain Memory。Workspace 内容发布前同样经过独立发布审查。 + +## 3. 记忆分类 + +1.0 只定义四类可解释长期记忆;稳定值登记在[协议与稳定标识](../contracts/README.md#memory_kind),并在实现前进入 OpenAPI/Schema: + +| 类型 | 含义 | 默认写入要求 | +| --- | --- | --- | +| `fact` | 可核对的人、事、状态或约束 | 有明确来源;冲突时生成纠正候选 | +| `preference` | 用户或角色明确表达、或系统推断的偏好 | 显式与推断分开;推断偏好需要置信度 | +| `event` | 带时间范围的经历或事件 | 保留时间语义和来源 | +| `relationship` | 人物间关系及其变化 | 高影响,默认人工确认 | + +身份基线、人格设定、权限、秘密、工具定义和知识文档不塞入上述类型。需要新类型时先更新契约和评测,不使用任意 metadata 绕过类型系统。 + +## 4. 写入与版本 + +```mermaid +flowchart LR + S[Source] --> E[Extract] + E --> C[Candidate] + C --> P{Policy} + P -->|approve| V[MemoryVersion] + P -->|review| H[Human review] + H -->|approve| V + P -->|reject| X[Rejected] + H -->|reject| X + V --> A[(Authoritative DB)] + A --> I[Indexes] + I --> R[Retrieve] + R --> M[ContextSnapshot] +``` + +### 4.1 来源 + +Candidate 至少记录: + +- 所有权边界、目标 Character(如有)和候选类型; +- 精确来源引用,包括 Message/Block、KnowledgeDocument chunk 或 ToolCall 的 ID 与版本; +- extractor、prompt、parser 和 policy 版本; +- 候选正文、结构化时间、置信度、敏感度和创建时间; +- 来源内容 hash 与候选 fingerprint,用于幂等和去重。 + +自动提取由 Message 完成后的 Outbox/Job 异步触发,不延长消息与 Run 的原子创建事务。重复消费相同来源与 extractor 版本必须返回同一候选或明确的去重结果。 + +ToolResult、网页、文件和模型输出都只是观察。它们可以产生 Candidate,但未经来源校验与 Policy 判定不能直接成为事实。 + +### 4.2 审批 + +- 用户显式创建可直接进入批准流程,但仍执行 Schema、所有权、敏感度和冲突检查。 +- 敏感资料、第三方个人信息、关系结论、高影响推断和隐式偏好默认需要人工确认。 +- 低风险自动候选只有在策略明确允许的白名单内容上才能自动批准,并必须附带撤销窗(写入后一段时间内一键撤销且不留检索痕迹);策略版本必须进入审计。白名单外内容一律进入人工审核。 +- Candidate 的批准或拒绝是幂等命令;批准时在一个事务写 Memory/MemoryVersion、AuditEvent 和 OutboxEvent。 +- Candidate 不使用 `memory_status`;其生命周期与正式 Memory 分开定义。 + +### 4.3 纠正与并发 + +- 创建、纠正、取代和恢复均创建新的 MemoryVersion,不原地覆盖历史内容。 +- PATCH Memory 必须携带 `If-Match`;并发版本不匹配返回 `412 precondition_failed`。 +- 用户纠正优先绑定上一次召回的 Memory ID/Version ID,避免仅凭自然语言重新搜索后误改同名记忆。 +- 纠正后的旧版本保留谱系但不再参与召回;恢复旧内容也创建新版本。 +- 删除立即阻止读取与召回,清除所有版本中的原文及派生索引,只保留不含原文的最小墓碑和审计元数据。 + +### 4.4 归真作用域 + +记忆候选与手动入忆必须携带并保留来源界域 `canonical_scope`(见 [ADR-020](../decisions/README.md#adr-020对话三界与归真作用域)): + +- **真界**(`reality`):按既有候选、审批与敏感度规则进入角色正式经历记忆。 +- **境界**(`world`):归真只形成该世界的知识候选(境忆),进入 KnowledgeDocument 与世界实体体系,不进入角色真界经历记忆,也不影响现实关系数据。 +- **幻境**(`simulation`):不自动形成长期记忆候选;用户可将启发、观点或假设手动入忆,强制标注性质(事实/观点/启发/假设),且仍走敏感度与确认规则——幻境不得成为绕过敏感审批的通道。 + +界域来源不可事后静默更改;跨界引用只提供来源,不改变目标记忆的作用域。 + +## 5. 衰减、有效期与整理 + +- `valid_from`/`expires_at` 表达事实有效期;过期版本在召回资格过滤阶段排除,但仍可按授权查看历史。 +- 衰减只影响排序或生成归档候选,不静默改写、删除或降低用户已确认事实的真实性。 +- 用户可固定重要记忆;固定状态仍不能绕过删除、撤权或有效期。 +- 去重、合并、冲突检测和归档由异步 Job 执行,任务带租约与幂等键;失败不影响权威版本和在线对话。 +- 自动整理结果仍是 Candidate 或新版本提案,不能绕过审批策略。 + +具体衰减函数和阈值必须通过评测确定,不在架构层虚构固定数值。 + +## 6. 检索管线 + +检索严格按以下顺序执行: + +1. 根据 actor、Personal Domain/Workspace 和 Character 在数据库查询层限定可见集合; +2. 过滤非 active、已过期、已撤权、已删除和被取代版本; +3. 并行生成全文、语义和结构化关系候选; +4. 按 Memory ID/Version ID 合并去重并重排; +5. 应用敏感度、用途、数据驻留和 Run 权限策略; +6. 按 token/条目/延迟预算选择进入上下文的结果; +7. 将召回证据固化到 ContextSnapshot,供用户解释和受保护诊断。 + +禁止先跨域全量召回再在应用层过滤。向量分数不能替代授权、来源可信度或有效期判定。 + +公开 Memory Search 只返回调用者有权查看的命中项,并包含命中版本、来源、各检索通道分数、重排结果、召回说明和是否进入上下文。被权限过滤的对象不能以计数、分数或错误细节泄露存在性。 + +## 7. 上下文装配 + +上下文顺序沿用 [Agent 运行时](agent-runtime.md#7-上下文装配):工具定义 → 稳定指令 → 当前分支消息 → 获准记忆与知识 → 动态运行上下文 → 当前输入。 + +ContextSnapshot 对每个候选记录: + +- Memory ID、Version ID、来源引用和内容 hash; +- 召回通道、原始分数、重排分数和策略结果; +- 是否选中、未选原因、估算 token 和最终顺序; +- 检索器、embedder、reranker、policy 与装配器版本。 + +ContextSnapshot 不保存隐藏推理。普通 Run API 只返回用户可理解的来源摘要;详细分数、排除原因和版本信息遵守 DiagnosticGrant。 + +## 8. 索引与故障语义 + +- PostgreSQL/SQLite 中的 Memory、MemoryVersion 和来源关联是权威事实;全文、pgvector 和图关系是可重建投影。 +- 权威事务通过 Outbox 驱动索引更新。索引延迟时,新版本可暂时降级为关系数据库检索,旧版本不得继续被召回。 +- 删除与撤权事件优先于普通重建任务;消费者按 event ID 幂等。 +- 无法证明索引已清除时,对目标 Memory fail closed,并记录待修复状态,不能继续返回旧结果。 +- 图投影只用于结构化关系检索;没有量化多跳收益前不引入专用图数据库。 + +## 9. 插件边界 + +Memory extractor、deduper、reranker、decay 和 context provider 可以由插件贡献。Core 始终负责: + +- 身份、所有权和授权过滤; +- Candidate/Version 状态迁移与事务; +- 敏感度、审批、删除、审计和 Outbox; +- 插件输入输出 Schema、资源预算和版本快照; +- 最终 ContextSnapshot 与召回证据。 + +插件只能提出 Candidate、分数或排序,不能直接写权威 Memory、扩大作用域、读取未授权来源或阻止删除传播。 + +## 10. 评测与验收 + +WP-04 至少留下以下可重复证据: + +- **写入质量**:事实、偏好、事件、关系的提取 precision/recall,以及敏感内容错误自动批准率; +- **召回质量**:长对话、多会话、时间推理、冲突纠正和多跳关系的 Recall@K、MRR/nDCG 与最终问答正确率; +- **安全正确性**:跨用户、跨角色、跨 Workspace、跨 Conversation/Branch/Run、已删除、已过期和已撤权内容的召回率必须为 0;Candidate、来源 Prompt Injection 和插件输出不能扩大 scope 或绕过审批; +- **可追溯性**:每个进入上下文的 Memory 都能定位到当前版本和未删除来源; +- **恢复能力**:索引全量重建、重复 Outbox、乱序消费和删除重放后结果一致; +- **性能成本**:写入延迟、检索 p50/p95、候选数、rerank 时延、上下文 token 和单次召回成本。 + +LoCoMo、LongMemEval 等公开数据集可用于回归,不替代 Hunjing 自有的中文、多角色、分支、敏感审批、删除和越权测试集。阈值在实现前通过基线实验写入发布门,不引用外部项目宣传分数作为验收结果。 + +## 11. MemOS 采纳边界 + +参考基线:MemTensor/MemOS commit `28dfb4e7d3adad1c93fd5574675f913921367d36`,Apache-2.0。详细证据见[参考项目研究](../research/reference-projects.md#memos)。 + +采纳:类型化且可检查的记忆、来源追踪、分层检索、快速摄取后异步精炼、后台整理、基于已召回 ID 的纠正、可重复评测。 + +不采纳:把 MemCube 当作 Hunjing 授权边界、原地更新权威记忆、开放式 metadata 代替契约、运行时隐式建表、把向量/图存储作为事实源、保存或回放隐藏状态/KV cache、在 1.0 用参数记忆修改模型权重。 diff --git a/docs/architecture/plugin-system.md b/docs/architecture/plugin-system.md new file mode 100644 index 0000000..fe1a7b8 --- /dev/null +++ b/docs/architecture/plugin-system.md @@ -0,0 +1,153 @@ +# 插件系统与生态 + +## 1. 设计判断 + +采用“所有可扩展能力皆插件”,拒绝“所有系统职责皆插件”。插件新增能力;Core 决定能力是否可信、可见、获准执行、可交易和可审计。 + +## 2. 插件类型 + +| 类型 | 贡献 | +| --- | --- | +| `model_adapter` | 上游协议、模型目录、能力和 usage 解析 | +| `tool` | Tool Definition 与执行器 | +| `mcp_connector` | MCP Server、工具与资源连接 | +| `skill` | 按需加载的任务说明和资源 | +| `context_provider` | Context Manifest 内容 | +| `memory_policy` | 候选提取、评分、衰减和召回 | +| `importer_exporter` | 角色卡、资料和开放格式 | +| `media_processor` | ASR/TTS、图像、Live2D、3D 处理 | +| `run_hook` | 类型化运行事件观察或受限变换 | +| `ui_extension` | Web/Tauri 声明式页面、面板和渲染器 | +| `remote_plugin` | 独立服务通过稳定协议贡献能力 | + +## 3. 非插件化内核 + +- Authentication、数据域、Workspace 和资源归属; +- Policy 最终裁决、用户审批和设备授权; +- Audit、交易 Ledger、支付与结算状态; +- 数据库事务、删除与许可语义; +- 插件签名、审核、安装策略、权限收窄和撤架; +- Sandbox fail-closed; +- 诊断授权。 + +插件可以提出信号,不能覆盖内核结论。 + +## 4. 双轨执行模型 + +### 4.1 默认受限插件 + +声明式或远程插件: + +- 通过 JSON Schema、MCP 或 Hunjing Plugin RPC 声明能力; +- 不进入主进程,不获得文件系统或任意网络; +- UI 使用声明式组件/iframe 隔离和明确消息协议; +- 每项网络、数据、工具和媒体权限显式声明并可撤销。 + +### 4.2 可信本地代码插件 + +部署者明确安装并确认风险后,代码插件在独立进程或容器运行: + +- 最小文件挂载、网络 allowlist、CPU/内存/时间限制; +- 独立身份和短期执行凭证; +- 无 Sandbox 后端时拒绝,不退化到主进程; +- 进程崩溃不拖垮 Core; +- 只有 bundled Core plugin 可以进主进程。 + +语言 VM、Python import 和 Node `vm` 都不是安全隔离。 + +## 5. Manifest + +```yaml +id: example.web-fetch +version: 1.2.0 +api_version: v1 +runtime: remote +entrypoint: https://plugin.example.com/mcp +publisher: publisher_01... +contributes: + - tool +permissions: + network: + - example.com + data: + - public_web +config_schema: schemas/config.json +privacy_policy_url: https://example.com/privacy +license: Apache-2.0 +``` + +插件版本至少声明:ID、不可变版本、API 版本、runtime、entrypoint、贡献、依赖、权限、配置 Schema、发布者、许可、隐私说明、包摘要和签名。 + +## 6. 生命周期 + +```mermaid +stateDiagram-v2 + [*] --> discovered + discovered --> validated + validated --> installed + installed --> active + active --> draining + draining --> stopped + stopped --> active + discovered --> rejected + validated --> rejected + active --> suspended + suspended --> stopped + stopped --> uninstalled + uninstalled --> [*] +``` + +初始化采用事务式注册:声明 contribution 和 reversible effect,全部成功后提交;失败则逆序撤销。 + +## 7. Run 固定快照 + +Run 开始生成 `plugin_snapshot`:插件 ID/版本/摘要、配置摘要、工具与 Hook、权限、依赖和执行位置。Run 期间升级、停用、撤架不改变快照;高危安全撤架可以立即阻断后续 ToolCall,但保留审计和明确失败原因。 + +## 8. Hook 语义 + +- `observe`:只读,错误记录但不改变主流程; +- `transform`:明确阶段返回新值,串行执行; +- `guard`:返回风险信号,Core Policy 最终裁决; +- `effect`:登记可撤销资源。 + +Hook 必须有超时和错误策略。插件禁止跨模块写表、读取其他插件私有状态或修改角色/交易权威数据。 + +## 9. SDK 与开发者体验 + +1.0 提供: + +- TypeScript 与 Python SDK; +- Manifest/Schema 生成与校验; +- 本地模拟 Host; +- 测试凭据、固定事件和权限模拟; +- 插件打包、签名、发布、兼容性和迁移工具; +- UI 扩展组件目录; +- usage、日志、错误和性能诊断; +- 示例插件和安全清单。 + +## 10. 注册、审核与安装 + +```mermaid +flowchart LR + DEV[Developer] --> PACK[Package and Sign] + PACK --> SCAN[Static and Dynamic Scan] + SCAN --> REVIEW[Policy Review] + REVIEW --> REG[Immutable Registry Version] + REG --> INSTALL[User or Admin Install] + INSTALL --> GRANT[Permission Review] + GRANT --> ACTIVE[Activated Version] +``` + +- 自动扫描不替代人工高风险审核; +- 安装展示数据、网络、设备、费用、外部目的地与现实后果和本地代码权限; +- 升级新增权限时重新确认; +- 允许固定版本、自动安全补丁、回滚和卸载; +- 举报、漏洞、撤架、恶意发布者和依赖供应链有处置流程。 + +## 11. 插件市场 + +插件可以免费或付费发布,商品绑定不可变 Registry Version 和许可证。购买只授予下载/使用许可,不自动启用插件或批准权限。付费更新、订阅、退款和创作者结算复用 Marketplace 与 Ledger,不由插件自行处理支付。 + +## 12. 子 Agent + +子 Agent 使用相同插件契约,但深度、并发、工具、数据、网络、预算和运行时间由 Runtime 硬限制;不继承额外审批令牌,默认不能写长期记忆,结果通过结构化 ChildRun 返回父 Run。 diff --git a/docs/architecture/system-architecture.md b/docs/architecture/system-architecture.md new file mode 100644 index 0000000..a453006 --- /dev/null +++ b/docs/architecture/system-architecture.md @@ -0,0 +1,107 @@ +# 系统架构 + +## 1. 逻辑架构 + +完整 1.0 由多端客户端、统一 API、领域模块、Agent/Plugin Runtime、媒体与实时处理、生态与交易模块以及隔离执行边界组成。逻辑边界是强约束,物理部署可按规模合并或拆分。 + +```mermaid +flowchart LR + subgraph Clients + WEB[Web] + DESK[Tauri Desktop] + MOB[Tauri Mobile] + end + + WEB & DESK & MOB --> EDGE[API and Realtime Edge] + EDGE --> CORE[Core Application] + CORE --> AGENT[Agent Runtime] + CORE --> SOCIAL[Community and Collaboration] + CORE --> MARKET[Marketplace and Ledger] + CORE --> MEDIA[Media and Avatar Runtime] + AGENT --> PLUGIN[Plugin Runtime] + PLUGIN --> MODELS[Model Providers] + PLUGIN --> TOOLS[Tools and MCP] + CORE --> DATA[(Primary Data)] + MEDIA --> OBJECTS[(Media Objects)] + AGENT --> SANDBOX[Sandbox Workers] +``` + +## 2. 模块职责 + +| 模块 | 职责 | 禁止承担 | +| --- | --- | --- | +| Identity & Domain | 登录、用户、设备、数据域、会话 | 角色人格和模型路由 | +| Character | 角色、设定版本、关系、谱系、导入导出 | Provider 凭据和交易账 | +| Conversation | 多模态消息、分支、引用、流式和压缩 | 决定长期记忆写入 | +| Memory & Knowledge | 候选、版本、召回、纠正、删除、索引 | 覆盖角色基线 | +| Agent Runtime | Agent/Run/Turn、计划、并行、暂停、取消、验收 | 绕过 Policy 执行工具 | +| Model Gateway | Provider、逻辑模型、路由、流式、usage、成本 | 角色和社区业务 | +| Plugin Runtime | Manifest、生命周期、Snapshot、Registry、SDK | 身份根策略和交易账 | +| Tool & Sandbox | Schema、审批、幂等、隔离执行、结果净化 | 自行扩大能力范围 | +| Media Pipeline | ASR/TTS、图像、Live2D、3D 资产处理 | 授予设备采集权限 | +| Avatar Runtime | Live2D/3D 渲染、动作、表情、场景同步 | 修改权威角色数据 | +| Device Capability | 文件、相机、麦克风、屏幕、位置和设备授权 | 后台常开采集 | +| Community | 社交图、内容、互动、搜索、推荐、治理 | 支付结算和私密记忆 | +| Collaboration | Workspace、RBAC、邀请、评审、版本、协同 | 跨 Workspace 隐式共享 | +| Marketplace | 商品、许可、交付和版本可售性 | 直接改写支付账 | +| Payment & Ledger | 订单、支付、退款、分成、余额、结算、对账 | 浮点金额和可变历史账 | +| Policy & Moderation | 工具、插件、设备、内容、交易和年龄策略 | 执行业务副作用 | +| Observability | Trace、Run 诊断、审计、成本、支持包 | 普通接口泄露敏感正文 | + +## 3. 物理部署原则 + +开发期可在模块化单体中合并多数业务模块,但以下边界必须独立: + +- Sandbox Worker:执行不可信代码; +- Media Worker:处理重型媒体任务; +- Realtime Gateway:SSE/WebSocket/语音会话; +- Payment Webhook Consumer:验签、幂等和账务入账; +- Object Storage:媒体和市场交付物; +- Search/Index Worker:全文、向量和社区索引。 + +```mermaid +flowchart TD + C[Clients] --> E[Edge and Realtime] + E --> A[Application API] + A --> DB[(PostgreSQL)] + A --> R[(Redis)] + A --> S3[(S3-compatible Storage)] + A --> W[Job Workers] + W --> SB[Sandbox Pool] + W --> GPU[Media or GPU Workers] + W --> IDX[Search and Vector Index] + A --> PAY[Payment Providers] + PAY --> WH[Webhook Consumer] + WH --> DB +``` + +PersonalDomain 创建或迁移时绑定一个固定数据区域:权威数据、密钥、对象、索引和备份在该区域驻留,不因流量路由、故障转移或用户旅行自动跨区漂移;跨区只能走正式迁移协议。跨区模型处理按地区规则、数据敏感度和用户授权单独治理,且必须经用户明确披露与授权;高敏数据(含私箧)可完全禁止跨区模型处理。 + +自托管遥测默认关闭。本地开发可用 SQLite、本地对象和单 Worker;完整 1.0 正式云与社区/交易部署使用 PostgreSQL、Redis、对象存储和异步 Worker。向量库、图数据库与独立 Go 网关按量化规模选择,不因技术清单强制引入。灵台引擎默认进程内嵌入;满足独立扩缩容、故障域或资源隔离标准时可启用 `hunjing-lingtai-server` 独立服务形态(见[灵台引擎架构](lingtai-engine.md))。 + +## 4. 客户端边界 + +- Web:完整社区、市场、创作、对话和管理体验。 +- Tauri Desktop:Web 能力加本地文件、屏幕、相机、麦克风、系统通知和沙箱桥接。 +- Tauri Mobile:iOS/Android 的相机、麦克风、文件、位置、通知和 Avatar 运行。 +- 客户端权限由平台权限和 Hunjing `device_grant` 双重约束。 +- 客户端不保存平台 Provider 密钥;离线缓存按用户和设备加密。 + +## 5. 数据与信任边界 + +1. 每次资源访问验证数据域、Workspace、角色、内容可见性和交易主体。 +2. Provider Header deny-by-default,仅 Adapter 白名单透传。 +3. 插件贡献能力;Core 决定加载、权限、审批、数据和审计。 +4. 未可信插件不进入主进程;没有可用隔离后端时拒绝执行。 +5. 支付 Provider Webhook 先验签和幂等,再写不可变账务记录。 +6. 社区公开内容、协作私有内容、角色私密数据和诊断数据使用不同访问策略。 +7. 设备采集默认关闭,逐能力展示状态并可即时撤回。 +8. 市场许可不自动授予插件执行权限、角色私密数据或设备能力。 + +## 6. 可靠性目标 + +1.0 目标值:核心文字相伴官方云 SLO 99.9%;权威数据 RPO 不高于 5 分钟、RTO 不高于 1 小时,以恢复演练而非配置声明证明;媒体与可重建索引可采用更宽目标但不阻塞权威恢复。SLI 口径、窗口与排除规则在发布门前定义并验证(见[发布门](../product/complete-1.0-scope.md#44-可靠性门))。 + +## 7. 服务拆分标准 + +模块只有满足独立扩缩容、故障域、数据/密钥边界、团队发布节奏或量化瓶颈时才拆服务。拆分保持端口、事件和账务契约;不因语言偏好拆分。 diff --git a/docs/contracts/README.md b/docs/contracts/README.md new file mode 100644 index 0000000..506fe7c --- /dev/null +++ b/docs/contracts/README.md @@ -0,0 +1,187 @@ +# 协议与稳定标识 + +本目录是稳定工程契约的单一事实源。代码实现前应生成 OpenAPI 3.1 / JSON Schema;本文件定义尚未机器化前的命名基线。 + +## 命名 + +| 对象 | 规则 | 示例 | +| --- | --- | --- | +| JSON / SQL | `snake_case` | `personal_domain_id` | +| HTTP path 参数 | `snake_case` | `{run_id}` | +| 事件 | `domain.action` | `model.request.completed` | +| 插件稳定名 | reverse-domain 或点分稳定名 | `example.web-fetch` | +| 逻辑模型 | `kebab-case` | `default-chat` | +| 时间 | UTC RFC 3339 | `2026-09-02T08:00:00Z` | + +## ID 前缀 + +| 对象 | 前缀 | 生成版本 | +| --- | --- | --- | +| User | `user_` | UUIDv7 | +| PersonalDomain | `domain_` | UUIDv7 | +| Character | `character_` | UUIDv7 | +| CharacterVersion | `character_version_` | UUIDv7 | +| CharacterAsset | `character_asset_` | UUIDv7 | +| CharacterImport | `import_` | UUIDv7 | +| Export | `export_` | UUIDv7 | +| Agent | `agent_` | UUIDv7 | +| Conversation | `conversation_` | UUIDv7 | +| Branch | `branch_` | UUIDv7 | +| Message | `message_` | UUIDv7 | +| ContentBlock | `block_` | UUIDv7 | +| File | `file_` | UUIDv7 | +| Upload | `upload_` | UUIDv7 | +| Run | `run_` | UUIDv7 | +| BigCycle | `cycle_` | UUIDv7 | +| Turn | `turn_` | UUIDv7 | +| ModelCall | `model_call_` | UUIDv7 | +| ToolCall | `tool_call_` | UUIDv7 | +| Approval | `approval_` | UUIDv7 | +| Job | `job_` | UUIDv7 | +| MemoryCandidate | `memory_candidate_` | UUIDv7 | +| Memory | `memory_` | UUIDv7 | +| MemoryVersion | `memory_version_` | UUIDv7 | +| KnowledgeDocument | `knowledge_document_` | UUIDv7 | +| KnowledgeChunk | `knowledge_chunk_` | UUIDv7 | +| ContextSnapshot | `context_snapshot_` | UUIDv7 | +| PluginSnapshot | `plugin_snapshot_` | UUIDv7 | +| DiagnosticGrant | `diagnostic_grant_` | UUIDv7 | +| Workspace | `workspace_` | UUIDv7 | +| WorkspaceInvitation | `invitation_` | UUIDv7 | +| Project | `project_` | UUIDv7 | +| Review | `review_` | UUIDv7 | +| CollaborationSession | `collab_session_` | UUIDv7 | +| CommunityContent | `content_` | UUIDv7 | +| InboxThread | `inbox_thread_` | UUIDv7 | +| Report | `report_` | UUIDv7 | +| ModerationCase | `moderation_` | UUIDv7 | +| Plugin | `plugin_` | UUIDv7 | +| PluginVersion | `plugin_version_` | UUIDv7 | +| PluginInstallation | `plugin_installation_` | UUIDv7 | +| MCPServer | `mcp_` | UUIDv7 | +| Skill | `skill_` | UUIDv7 | +| ReleaseVersion | `release_` | UUIDv7 | +| MarketplaceListing | `listing_` | UUIDv7 | +| Order | `order_` | UUIDv7 | +| PaymentAttempt | `payment_` | UUIDv7 | +| Refund | `refund_` | UUIDv7 | +| Entitlement | `entitlement_` | UUIDv7 | +| LedgerEntry | `ledger_` | UUIDv7 | +| SettlementBatch | `settlement_` | UUIDv7 | +| Device | `device_` | UUIDv7 | +| DeviceGrant | `device_grant_` | UUIDv7 | +| DeviceSession | `device_session_` | UUIDv7 | +| MediaAsset | `media_` | UUIDv7 | +| MediaJob | `media_job_` | UUIDv7 | +| Voice | `voice_` | UUIDv7 | +| AvatarModel | `avatar_` | UUIDv7 | +| RealtimeVoiceSession | `voice_session_` | UUIDv7 | +| ServiceAccount | `service_account_` | UUIDv7 | +| APIKey record | `key_` | UUIDv7 | +| WebhookEndpoint | `webhook_endpoint_` | UUIDv7 | +| WebhookEvent | `webhook_event_` | UUIDv7 | +| AuditEvent | `audit_` | UUIDv7 | +| Event | `event_` | UUIDv7 | +| Request | `request_` | UUIDv4(仅服务端生成) | +| Trace record | `trace_` | UUIDv4 | + +### 生成规则 + +- UUIDv4/UUIDv7 的位布局、variant 和文本格式遵循 RFC 9562;各语言使用经过测试的标准库或成熟实现,不自行拼位。 +- 持久化业务资源、版本、事件、账务、审计和异步任务统一使用 UUIDv7,获得数据库索引局部性和大致创建顺序。 +- 请求关联与 Trace record 不需要按创建时间排序,使用 UUIDv4。调用方提供的合法 `Hunjing-Request-ID` 原样保留;只有服务端补发时使用 `request_`。 +- 格式固定为 ``,例如 `memory_01941f29-7c00-7cc8-9c2a-6f4f0f2de512`;解析时必须校验前缀和 UUID version,不能只校验 UUID 文本。 +- UUIDv7 内含近似生成时间,但 `created_at`、`occurred_at` 和数据库提交顺序才是权威时间;不得从 ID 推导业务时间、权限、分页结果或事件顺序。 +- W3C `traceparent` 中的 `trace-id` 仍按 W3C Trace Context 生成 16 字节非零随机值并编码为 32 位小写十六进制,不添加 `trace_` 前缀,也不与 Trace record ID 混用。 +- API key 明文、Diagnostic Token、CSRF token、OAuth token、Webhook secret、实时恢复 token、ExecutionTicket 和预签名 URL capability 使用 CSPRNG/对应标准生成的 opaque value,不使用 UUIDv4 或 UUIDv7。 +- `Idempotency-Key`、`client_message_id`、Provider request ID 和 Provider event ID 属外部或调用方标识,按各自契约验证并原样保存,不改写成平台 UUID。 +- 前缀属于公开字符串的一部分;未经本文件登记,不新增公开前缀。 + +## 通用枚举 + +### `run_status` + +`queued`、`running`、`waiting_approval`、`completed`、`failed`、`cancelled` + +### `memory_candidate_status` + +`pending_review`、`approved`、`rejected`、`expired` + +### `memory_status` + +`active`、`superseded`、`archived`、`deleted` + +### `memory_kind` + +`fact`、`preference`、`event`、`relationship` + +### `sensitivity` + +`none`、`low`、`medium`、`high` + +### `permission_decision` + +`allow`、`ask`、`deny` + +### `usage_source` + +`provider`、`gateway_estimate`、`unavailable` + +### `diagnostic_level` + +`summary`、`detailed`、`sensitive` + +### `publication_status` + +`draft`、`submitted`、`published`、`limited`、`suspended`、`removed` + +### `order_status` + +`pending_payment`、`paid`、`partially_refunded`、`refunded`、`disputed`、`cancelled` + +### `ledger_entry_type` + +`charge`、`refund`、`platform_fee`、`creator_payable`、`tax`、`reserve`、`payout`、`reversal` + +### `device_capability` + +`file`、`camera`、`microphone`、`screen`、`location`、`notification` + +### `plugin_runtime` + +`bundled`、`declarative`、`remote`、`isolated_process`、`container` + +### `canonical_scope` + +`reality`、`world`、`simulation` + +### `big_cycle_status` + +`pending`、`running`、`completed`、`failed` + +### `autonomy_level` + +`introspective`、`rule_bound`、`approval_required`、`forbidden` + +## 约束 + +- 未知值用 `null`,真实零值用 `0`;不能混淆。 +- 金额为 `cost_minor: integer` + `currency: string`。 +- 时长统一 `_ms` 非负整数。 +- 哈希字段必须在 Schema 说明算法和编码。 +- API 不暴露数据库实现后缀,如 `_json`。 +- 客户端对新增枚举值必须走 unknown 分支,不能崩溃。 + +## 子文档 + +1. [API 总体约定](api-conventions.md) +2. [Hunjing Native API](native-api.md) +3. [模型网关兼容 API](gateway-compatible-api.md) +4. [实时 API 与 Webhook](realtime-and-webhooks.md) +5. [内部端口、事件与插件协议](internal-api.md) +6. [统一富内容与流式协议](content-blocks-and-streaming.md) +7. [1.0 API 表面总表](api-surface.md) +8. [HTTP 与事件契约](http-and-events.md) +9. [运行观测契约](run-observability.md) +10. [Lingtai C ABI](lingtai-ffi.md) +11. [Lingtai Service](lingtai-service.md) diff --git a/docs/contracts/api-conventions.md b/docs/contracts/api-conventions.md new file mode 100644 index 0000000..93c0c23 --- /dev/null +++ b/docs/contracts/api-conventions.md @@ -0,0 +1,159 @@ +# API 总体约定 + +## 1. API 分面 + +| 分面 | 基地址 | 使用者 | 稳定性 | +| --- | --- | --- | --- | +| Native API | `https://api./v1` | Web、Tauri、第三方应用 | 公开稳定 | +| OpenAI-compatible | `https://gateway./openai/v1` | OpenAI SDK/兼容客户端 | 对齐所声明子集 | +| Anthropic-compatible | `https://gateway./anthropic/v1` | Anthropic SDK/兼容客户端 | 对齐所声明子集 | +| Provider Webhook | `https://api./webhooks/v1` | 支付、媒体等 Provider | Provider 签名契约 | +| Internal Port | 进程内接口或私有网络 | Core、Worker、Sandbox、Plugin Runtime | 不公开 | + +Native、兼容和内部接口不能共享权限推断。兼容入口只提供模型推理,不直接读写角色、记忆、社区、设备和交易资源。 + +## 2. 认证 + +### 2.1 1.0 认证组合 + +| 客户端 | 凭据 | 传输位置 | +| --- | --- | --- | +| Web | OAuth 2.1 登录后的 `__Host-hunjing_session` | `Cookie` 请求头 | +| Tauri Desktop/Mobile | Authorization Code + PKCE 获得的短期 access token | `Authorization: Bearer` | +| 第三方用户应用 | OAuth 2.1 access token | `Authorization: Bearer` | +| Service Account | 可轮换、限 scope 的 opaque API key | `Authorization: Bearer` | +| OpenAI-compatible | Service account/API key | `Authorization: Bearer` | +| Anthropic-compatible | Service account/API key | `x-api-key`;OAuth 客户端可用 `Authorization: Bearer` | + +所有凭据只能通过 Header 传递,不得进入 URL、query、业务 JSON、SSE data 或 WebSocket URL。Cookie 本身是 HTTP Header;Web 的状态变更请求还必须通过 `Origin` 校验和 `Hunjing-CSRF-Token` 双提交校验。 + +2.0 才设计自研加密登录、刷新和设备令牌协议。1.0 不自创密码学认证协议。 + +### 2.2 OAuth 端点 + +OAuth/OIDC 元数据不放在 `/v1`: + +```text +GET /.well-known/oauth-authorization-server +GET /.well-known/openid-configuration +GET /.well-known/jwks.json +GET /oauth2/authorize +POST /oauth2/token +POST /oauth2/revoke +GET /oauth2/userinfo +``` + +- Web 使用 Authorization Code;服务端建立 HttpOnly、Secure、`SameSite=Lax` Session Cookie。 +- Tauri 使用 Authorization Code + PKCE,回调采用已登记的 loopback/deep link。 +- Refresh token 只发送到 `/oauth2/token`,支持轮换和重用检测。 +- Service Account API key 只显示一次,数据库只保存哈希、前缀、scope、过期和撤销状态。 + +## 3. 通用请求头 + +| Header | 必需 | 语义 | +| --- | --- | --- | +| `Authorization` 或 Web Cookie | 是 | 调用主体认证;公开匿名读取除外 | +| `Content-Type` | 有 body 时 | JSON 为 `application/json` | +| `Accept` | 推荐 | JSON、SSE 或具体媒体类型 | +| `traceparent` | 推荐 | W3C Trace Context | +| `tracestate` | 否 | 供应商追踪状态,不含敏感数据 | +| `baggage` | 否 | 登记的低敏、低基数键;不参与授权 | +| `Hunjing-Request-ID` | 推荐 | 业务请求关联;缺失时服务端生成 | +| `Idempotency-Key` | 条件必需 | 创建 Run、支付、退款、结算和副作用命令 | +| `If-Match` | 更新时推荐 | ETag 乐观并发 | +| `Hunjing-CSRF-Token` | Cookie 状态变更 | 与受保护 Cookie 值匹配 | + +服务端响应回显 `Hunjing-Request-ID`、`traceparent`,资源响应提供 `ETag`。敏感 Header 必须在反向代理、APM 和应用日志完全脱敏。 + +## 4. 资源与 JSON + +- 字段统一 `snake_case`;ID 使用契约前缀,并按[协议与稳定标识](README.md#id-前缀)校验 UUID version。 +- 时间是 UTC RFC 3339;时长是非负 `_ms` 整数。 +- 金额是 `{amount_minor: integer, currency: "USD"}` 或明确 Decimal string,不使用浮点。 +- 不适用字段省略;已知未知值用 `null`;真实零值用 `0`。 +- 创建成功返回 `201` + `Location`;同步读取/修改返回 `200`;无 body 删除返回 `204`;异步操作返回 `202` + Job/Run。 +- 资源直接作为成功 body 返回,不套无意义的 `{data: ...}`;列表除外。 + +### 4.1 列表 + +```json +{ + "data": [], + "next_cursor": "opaque-or-null", + "has_more": false +} +``` + +查询统一使用 `limit`(默认 50,最大 200)、`cursor`、`order=asc|desc`。Cursor 是 opaque,并绑定排序和稳定过滤条件;客户端不得解析。 + +### 4.2 乐观并发 + +可变资源响应提供 `ETag: ""`。`PATCH`、发布、合并、权限变更和关键状态动作带 `If-Match`;版本过期返回 `412 precondition_failed`,不做静默覆盖。 + +## 5. 命令与状态动作 + +- CRUD 使用 `POST/GET/PATCH/DELETE`。 +- 非 CRUD、具有领域语义且需审计的动作使用子资源: + +```text +POST /v1/runs/{run_id}/cancellations +POST /v1/approvals/{approval_id}/decisions +POST /v1/releases/{release_id}/publications +POST /v1/orders/{order_id}/refunds +``` + +不使用含糊的 `/action` 或把命令塞进 `PATCH status`。命令响应包含其创建的资源或 `202` Job。 + +## 6. 幂等 + +`Idempotency-Key` 是调用方生成的 opaque string,最长 128 字符。服务端按“认证主体 + HTTP 方法 + 路径模板 + Key”隔离,并保存规范化请求哈希: + +- 相同 Key、相同请求:返回原响应和原资源 ID; +- 相同 Key、不同请求:`409 idempotency_conflict`; +- 未知副作用结果:返回原操作状态,不自动重复执行; +- Webhook 使用 Provider event ID 独立去重。 + +聊天消息与 Run 原子创建时,一个 Key 覆盖消息和 Run 两个资源。 + +## 7. 错误 + +```json +{ + "error": { + "code": "validation_failed", + "message": "请求字段不合法。", + "trace_id": "trace_01...", + "request_id": "request_01...", + "details": { + "field_errors": [ + {"path": "content.0.text", "reason": "required"} + ] + } + } +} +``` + +- `code` 是稳定机器值;`message` 可本地化;`details` 不稳定但必须脱敏。 +- 401 不泄露凭据是否存在;跨租户/跨域对象按场景返回 404。 +- 429 返回 `Retry-After`;SDK 只自动重试网络、408、409(安全时)、429 和 5xx。 +- 流式 HTTP 200 后错误通过事件发送,最终资源状态仍可通过 GET 查询。 + +## 8. API 版本 + +- 公共路径使用 major `/v1`;兼容入口保留其协议 `/v1`。 +- 向后兼容增加字段不升 major;客户端必须忽略未知字段和枚举。 +- 破坏性变更进入 `/v2`,不在同一字段上改变语义。 +- Preview 能力通过明确 `Hunjing-Preview` Header 和独立 Schema,不用 `X-` 前缀。 +- 1.0 实现阶段不为未发布旧契约保留兼容层;正式发布后按公开弃用策略处理。 + +## 9. 文件上传 + +大文件不经过 JSON base64: + +1. `POST /v1/uploads` 创建 Upload; +2. 服务端返回单次或 multipart 预签名 URL、允许 MIME、大小和过期; +3. 客户端直传对象存储; +4. `POST /v1/uploads/{upload_id}/completions` 完成并触发校验/扫描; +5. 成功后产生 `file_` 或 `media_` 资源。 + +预签名 URL 属短期对象访问 capability,不是用户登录或 API 凭据,因此是“凭据不得进入 URL”的唯一受控例外。它必须短期、绑定对象路径/方法/大小/MIME,优先单次使用;不得进入 Referer、业务日志、社区内容、Message、Audit、SSE 或诊断响应。未经完成和扫描的 Upload 不能被 Agent、社区或市场引用。 diff --git a/docs/contracts/api-surface.md b/docs/contracts/api-surface.md new file mode 100644 index 0000000..1293695 --- /dev/null +++ b/docs/contracts/api-surface.md @@ -0,0 +1,47 @@ +# 1.0 API 表面总表 + +本表用于检查 API 是否覆盖完整 1.0;详细字段以 OpenAPI 3.1 和对应契约文档为准。 + +| 域 | Native REST | SSE/WS | Internal/Plugin | Webhook | +| --- | --- | --- | --- | --- | +| Identity | `/me`、domains、service accounts、devices | — | Auth/Scope Ports | Identity Provider inbound | +| Character | characters、versions、imports、exports、forks、assets | — | Importer/Exporter | release events outbound | +| Conversation | conversations、branches、messages、revisions、统一 ContentBlock | Block/Run SSE | Context/Normalization Port | message/run outbound | +| Agent | agents、runs、approvals、children | Run SSE | Model/Tool/Sandbox Ports | run outbound | +| Memory | candidates、memories、searches、knowledge | — | Memory Policy Plugin | memory outbound | +| Media | uploads、files、media jobs、voices、avatars | Voice WS | Media Plugin/Worker | media Provider inbound | +| Device | devices、grants、sessions | Device WS | Tauri Capability Port | device outbound | +| Plugin | plugins、versions、installations、MCP、skills | status events | Plugin JSON-RPC/MCP | plugin outbound | +| Community | profiles、content、comments、reactions、feeds、reports | Notification SSE | Search/Moderation Ports | content/moderation outbound | +| Inbox | threads、members、messages | notification/presence | Moderation Port | message outbound | +| Collaboration | workspaces、projects、revisions、reviews | Collaboration WS | Document/CRDT Port | workspace outbound | +| Marketplace | listings、releases、entitlements | notification | Catalog/License Ports | listing/order outbound | +| Finance | orders、payment sessions、refunds、balances、settlements | notification | Payment/Ledger Ports | payment Provider inbound | +| Diagnostics | grants、run diagnostics | optional diagnostic SSE | Observability Ports | no sensitive outbound | +| Model Gateway | no Native inference endpoint | protocol SSE | Normalized Model Port | — | + +## 兼容入口 + +```text +OpenAI: /openai/v1/models + /openai/v1/responses + /openai/v1/chat/completions + /openai/v1/embeddings + /openai/v1/images/generations + /openai/v1/audio/transcriptions + /openai/v1/audio/speech + +Anthropic: /anthropic/v1/models + /anthropic/v1/messages + /anthropic/v1/messages/count_tokens +``` + +## 尚待发布配置,而非 API 结构不确定项 + +以下在实现期以配置/TODO 落实,不改变上述资源模型: + +- 首发支付、KYC、税务、对象存储、ASR/TTS、图像与模型 Provider; +- 默认分页上限、媒体大小、Run/Agent 并发和各类 Rate Limit 数值; +- 首发地区、币种、税类、内容年龄分级和保留期限; +- 结算周期、退款窗口、平台费、准备金和争议时限; +- 兼容 API 支持的具体 Provider beta 功能清单。 diff --git a/docs/contracts/content-blocks-and-streaming.md b/docs/contracts/content-blocks-and-streaming.md new file mode 100644 index 0000000..dd412f1 --- /dev/null +++ b/docs/contracts/content-blocks-and-streaming.md @@ -0,0 +1,253 @@ +# 统一富内容与流式协议 + +## 1. 目标 + +同一套 `ContentBlock` 用于 Native Message、Agent 输出、社区内容、私信、协作评论和结构化产物。用户编辑可接受 Markdown 内嵌 Mermaid/数学语法;服务端在保存或发送前解析并规范化为类型化 Block。 + +原则: + +- 类型化 Block 是 API 和存储规范形态; +- Markdown 是常用创作输入和可移植表示,不是所有媒体的唯一协议; +- 每个 Block 有稳定 ID 和独立状态,可局部流式、报错、重试、替换和无障碍展示; +- 不执行 HTML、JavaScript、Mermaid click callback 或不可信媒体脚本。 + +## 2. Content 容器 + +```json +{ + "content": [ + {"id": "block_01...", "type": "markdown", "text": "## 结论\n..."}, + {"id": "block_02...", "type": "mermaid", "source": "flowchart LR\nA-->B"}, + {"id": "block_03...", "type": "math", "notation": "latex", "display": "block", "source": "E=mc^2"}, + {"id": "block_04...", "type": "image", "file_id": "file_01...", "alt": "架构图"} + ] +} +``` + +所有 Block 通用字段: + +| 字段 | 必需 | 说明 | +| --- | --- | --- | +| `id` | 是 | Message 内稳定 `block_` ID | +| `type` | 是 | Block 类型 | +| `status` | 响应中 | `pending`、`streaming`、`completed`、`failed`、`cancelled` | +| `annotations` | 否 | citation、来源、敏感度、语言等类型化标注 | +| `metadata` | 否 | 只允许 Schema 登记字段,不存任意秘密 | + +`id` 在创建请求中可省略,由服务端生成;流事件必须携带服务端 Block ID。 + +## 3. Block 类型 + +### 3.1 文本与结构 + +| `type` | 关键字段 | 流式策略 | +| --- | --- | --- | +| `text` | `text`, `language?` | 字符增量 | +| `markdown` | `text`, `flavor="hunjing-gfm-v1"` | 字符增量,安全增量解析 | +| `code` | `source`, `language?`, `filename?` | 字符增量,Shiki 节流高亮 | +| `quote` | `content[]`, `source_ref?` | 子 Block 增量 | +| `table` | `columns`, `rows`, `caption?` | 行级追加或完成后展示 | +| `callout` | `kind`, `title?`, `content[]` | 子 Block 增量 | + +Markdown 方言支持 CommonMark/GFM 的标题、段落、列表、引用、表格、任务列表、链接、图片引用、行内代码和 fenced code。原始 HTML 默认禁用。 + +### 3.2 数学公式 + +```json +{ + "id": "block_math", + "type": "math", + "notation": "latex", + "display": "block", + "source": "\\int_0^1 x^2 dx = \\frac{1}{3}", + "fallback_text": "从 0 到 1 的 x² 积分等于 1/3", + "label": "公式 1" +} +``` + +- `notation` 1.0 为 `latex` 或 `asciimath`;服务端规范化优先输出 LaTeX。 +- `display` 为 `inline` 或 `block`。 +- `fallback_text` 是可访问性与解析失败降级描述,不是隐藏推理。 +- Markdown 输入支持 `$...$`、`$$...$$`、`\(...\)`、`\[...\]`;只有闭合定界符后才转换为 Math Block。 +- 常见公式描述应同时包含公式与自然语言说明,例如变量、单位、适用条件和来源,不能只输出不可读符号。 + +### 3.3 Mermaid + +```json +{ + "id": "block_mermaid", + "type": "mermaid", + "source": "sequenceDiagram\nA->>B: request", + "title": "请求时序", + "caption": "客户端到网关的调用", + "fallback_code_language": "mermaid" +} +``` + +- 只在 Block `completed` 后渲染;流式期间展示代码/骨架和“图表生成中”。 +- 禁止 `click`、外部脚本、HTML label、任意 URL callback 和危险初始化配置。 +- 渲染使用 strict security level、隔离 worker/iframe 和超时/节点数/源码长度限制。 +- 解析失败展示转义后的 Mermaid 源码与错误摘要,不丢失内容。 +- Markdown fenced ` ```mermaid ` 在规范化时转换为 Mermaid Block。 + +### 3.4 媒体与文件 + +| `type` | 关键字段 | +| --- | --- | +| `image` | `file_id` 或受控 `url_ref`, `alt`, `width?`, `height?`, `caption?` | +| `video` | `file_id`, `poster_file_id?`, `caption?`, `transcript_file_id?`, `duration_ms?` | +| `audio` | `file_id`, `transcript?`, `duration_ms?`, `waveform?` | +| `file` | `file_id`, `filename`, `media_type`, `size_bytes`, `description?` | +| `gallery` | `items[]`(image/video refs), `layout?` | +| `avatar` | `asset_id`, `format`(live2d/vrm/gltf), `preview_file_id?` | + +- API 不接受 `file://`、`javascript:`、`data:text/html` 等 URL。 +- 内部资源使用 `file_id`,下载通过授权 API 或短期签名 URL。 +- 图片 `alt` 必需;视频应提供字幕/转写状态;音频应提供转写或文本摘要。 +- 媒体生成流只发送 `asset.progress` 与最终 File/Media Block,不把未完成二进制塞进 SSE JSON。 + +### 3.5 Agent 与工具 + +| `type` | 说明 | +| --- | --- | +| `tool_call` | 工具名、调用 ID、参数脱敏视图、状态和审批引用 | +| `tool_result` | 调用 ID、结构化摘要、文件引用、错误状态 | +| `agent_status` | Agent/ChildRun、阶段、进度和等待原因 | +| `approval_request` | 动作、影响、参数摘要、有效期和 Approval ID | +| `artifact` | Run 产物 ID、类型、版本和下载/打开动作 | +| `citation` | 来源 ID、标题、引用文本与定位(文本区间、图像区域、PDF 页区、音视频时间码);保存原文快照,来源正影后提示后继版本 | +| `error` | 局部 Block 错误、可否重试和 fallback | + +普通 Message API 不允许客户端伪造系统产生的 `tool_call`、`tool_result`、`agent_status` 和 `approval_request`;这些 Block 只由 Runtime 写入。 + +## 4. Markdown 输入规范化 + +当客户端提交 `markdown` Block: + +1. 保存用户原始 Markdown 的规范化副本及 hash; +2. 使用确定性 parser 解析 AST; +3. fenced `mermaid` 转为 Mermaid Block; +4. 闭合数学定界符转为 Math Block; +5. fenced 其他语言转为 Code Block; +6. Markdown 图片只允许已上传 `file_id` 语法或经过 URL 安全代理的 HTTPS URL; +7. 输出 canonical ContentBlock 列表和 parser version; +8. 编辑后重新规范化,创建 Message Revision,不静默改旧 Block。 + +导出可选择 canonical JSON 或重建的 Hunjing Markdown;重建时复杂 Block 使用稳定 fenced/directive 语法。 + +## 5. 流式事件 + +Run SSE 使用统一 envelope;Block 事件如下: + +```text +content.block.started +content.block.delta +content.block.progress +content.block.completed +content.block.failed +content.block.cancelled +message.completed +``` + +### 5.1 Started + +```json +{ + "type": "content.block.started", + "data": { + "message_id": "message_01...", + "block": {"id": "block_01...", "type": "markdown", "status": "streaming"}, + "index": 0 + } +} +``` + +### 5.2 Delta + +```json +{ + "type": "content.block.delta", + "data": { + "message_id": "message_01...", + "block_id": "block_01...", + "delta_index": 7, + "delta": {"type": "text_append", "text": "新增文本"} + } +} +``` + +Delta 类型: + +- `text_append`:text/markdown/code/math/mermaid source 追加; +- `json_patch`:只用于 Schema 明确允许的结构化 Block,采用受限 RFC 6902 子集; +- `row_append`:table 追加完整行; +- `annotation_add`:追加 citation/来源; +- `resource_ready`:绑定已完成 file/media/artifact; +- `status_replace`:Agent/tool/approval 状态转换。 + +每个 Block 的 `delta_index` 从 0 单调递增;同一 delta 可重放,客户端按 `(block_id, delta_index)` 去重。缺口出现时暂停该 Block 增量展示,并通过 Run 重放或最终 Message 对账。 + +### 5.3 Completed + +```json +{ + "type": "content.block.completed", + "data": { + "message_id": "message_01...", + "block": { + "id": "block_01...", + "type": "markdown", + "status": "completed", + "text": "完整权威内容" + }, + "content_hash": "sha256:..." + } +} +``` + +Completed Block 是该 Block 的权威快照。客户端丢弃临时解析状态,以完整 Block 重建并校验 hash。`message.completed` 携带最终 Message ID、Block 顺序和版本,最终 GET Message 可恢复所有内容。 + +## 6. 分级实时策略 + +| 内容 | 流式展示 | +| --- | --- | +| Plain text / Markdown | 增量显示;解析节流;未闭合结构以文本态保留 | +| Code | 增量显示;按行/时间片重新高亮,不逐 token 运行 Shiki | +| Inline/Block Math | 累积到完整定界符或 Block 完成后渲染;此前显示源码占位 | +| Mermaid | 只在 Block completed 后渲染;此前显示源码/骨架 | +| Image/Video/Audio/File | progress 占位;`resource_ready` 后加载;失败可重试 | +| Table | 完整行追加,避免半行抖动 | +| Tool/Agent/Approval | 状态替换,不拼接自由文本 | + +## 7. 限制与安全 + +- 单 Message、Block、源码、节点、表格、媒体和嵌套深度的限额由配置发布,但 Schema 必须有硬上限。 +- Markdown URL 经 scheme/host 校验,外链加 `noopener noreferrer`,可选经安全跳转页。 +- HTML 默认不解析;需要 HTML 的可信内部 Block 也必须经 allowlist sanitizer。 +- KaTeX/MathJax 禁用信任命令、宏注入和外部资源;限制宏展开和源码长度。 +- Shiki 只高亮不执行代码;复制/下载保留原源码。 +- Mermaid 渲染隔离且不允许交互脚本。 +- 媒体采用 CSP、正确 Content-Type、`nosniff` 和独立对象域。 + +## 8. 兼容 API 映射 + +OpenAI/Anthropic Content Block 在 Gateway Adapter 转为内部 Block,但兼容响应仍保持目标协议。无法映射的 Native 类型: + +- 优先转换为目标协议支持的 text/image/document/tool block; +- Mermaid/math/code 可降级为 Markdown/fenced source; +- video/audio/avatar/artifact 使用文本说明 + 受控文件引用; +- 不能无损、安全表达时返回明确 unsupported,不伪造协议字段。 + +## 9. 分支对话交互态 + +分支对话(镜树)在流式协议之上的交互态语义(承接旧版镜树专题 PRD,字段与枚举进入 OpenAPI 前以本节为基线): + +- **临时芽体**(Block `status: streaming` 的未完成答复):完成后才固化为权威快照;流式期间展示为进行态,不进入归真候选。 +- **残答**(`interrupted`):被停止或中断的不完整答复封存可查,不作为完成答复;默认上下文不自动包含。 +- **续生**(`generation_resume`):从残答继续生成时创建**新** Message 并引用残答来源;残答本身不被修改或"补全"。 +- **引用合流**(`citation_intake`):树间内容经显式引用带入另一棵树,以 citation/引文锚表达;不物理合并两树,被引内容保留原树的界域与归真作用域。 +- **结题**(`topic_conclusion`):标记主题阶段完成并生成可审阅总结(总结内容走候选确认);结题后仍可复照继续,不删除历史。 +- **回响**(`task_echo`):后台受托任务完成后,结果以回响形态回到原分支,作为带来源的观察呈现(`agent_status`/`artifact` Block);经用户接纳并归真后才成为正式答复。 +- **上下文镜**(`context_mirror`):发送或继续前向用户渐进展示实际采用的上下文范围、压缩与省略项;与 ContextSnapshot 同源数据,是用户可见的透明视图而非诊断特权。 + +不变量:重新生成不覆盖旧候答;后代节点绑定用户实际依据的候答;已归真经历不因切换候答、删除旁枝或移动工作入口而回滚;未归真旁枝不自动入忆。 diff --git a/docs/contracts/gateway-compatible-api.md b/docs/contracts/gateway-compatible-api.md new file mode 100644 index 0000000..aa40d70 --- /dev/null +++ b/docs/contracts/gateway-compatible-api.md @@ -0,0 +1,137 @@ +# 模型网关兼容 API + +## 1. 边界 + +兼容网关提供模型推理协议,不是 Hunjing 角色或 Agent Runtime 的替代入口: + +```text +https://gateway./openai/v1 +https://gateway./anthropic/v1 +``` + +- 它可以接受工具定义并返回 tool call,但不会自动执行客户端工具。 +- 它不读写 Character、Memory、Conversation、Community、DeviceGrant、Order 或 PluginInstallation。 +- 需要 Hunjing 自动工具循环、多 Agent、审批和持久化时,调用 Native `/v1/runs`。 + +## 2. OpenAI-compatible 子集 + +1.0 支持: + +```text +GET /openai/v1/models +POST /openai/v1/responses +POST /openai/v1/chat/completions +POST /openai/v1/embeddings +POST /openai/v1/images/generations +POST /openai/v1/audio/transcriptions +POST /openai/v1/audio/speech +``` + +认证: + +```http +Authorization: Bearer hjk_... +``` + +流式响应遵循对应 OpenAI SSE 子集;响应返回 `x-request-id` 和 `Hunjing-Request-ID`。未支持的请求字段返回明确 `unsupported_parameter`,不静默忽略会改变语义的字段。 + +## 3. Anthropic Messages-compatible 子集 + +1.0 支持: + +```text +GET /anthropic/v1/models +POST /anthropic/v1/messages +POST /anthropic/v1/messages/count_tokens +``` + +认证和版本: + +```http +x-api-key: hjk_... +anthropic-version: +``` + +OAuth 客户端也可用 `Authorization: Bearer`。网关返回 `request-id` 和 `Hunjing-Request-ID`。`anthropic-beta` 只允许 Adapter 明确支持的值;未知 beta 返回 400,不透传到任意上游。 + +Messages Tool Use 保留 `tool_use.id` / `tool_result.tool_use_id` 关联;Thinking、cache、usage、stop reason 和 SSE block 必须按所声明兼容版本转换,无法无损映射时拒绝而非伪造。 + +## 4. 模型名与路由 + +请求 `model` 优先解析 Hunjing 逻辑模型,例如: + +```text +default-chat +fast-chat +reasoning-chat +vision-chat +embedding-default +image-default +speech-default +``` + +管理员可允许部分上游模型别名,但业务客户端不应依赖 Provider 密钥或 Endpoint。模型配置按固定顺序继承:平台硬边界 → 平台目录 → 用户偏好/BYOK → 角色覆写 → 会话临时选择;上层约束不可被下层覆盖,会话临时选择不持久化,切换模型不得改变角色身份。能力槽(chat、vision、ASR、TTS、image generation、embedding、rerank、safety 等)由逻辑模型声明。`GET models` 只返回当前调用主体获准、在其地区可用的模型和能力。 + +路由依次考虑:scope、地区、隐私级别、能力、上下文、工具/结构化输出支持、预算、健康、配额和优先级。 + +## 5. Header 策略 + +客户端 Header 默认不转发。Adapter 逐 Provider 声明 allowlist,例如:协议版本、项目/组织选择和特性开关。以下字段永不直接转发: + +- Hunjing 用户 `Authorization`/Cookie; +- `Hunjing-Diagnostic-Token`; +- 客户端提交的上游 API key; +- 未登记 Provider beta; +- `baggage` 中未批准的键; +- Hop-by-hop Header。 + +上游凭据由 Secret Store 按 Endpoint 注入。常规日志只记录允许的 Header 名和不可逆摘要,不记录值。 + +## 6. 重试、故障转移和流提交 + +```mermaid +stateDiagram-v2 + [*] --> routing + routing --> requesting + requesting --> retrying : retryable before visible output + retrying --> requesting + requesting --> streaming : first visible event + requesting --> completed : non-stream success + streaming --> completed + streaming --> failed : stream error + requesting --> failed +``` + +- 只在首个用户可见事件前对安全的错误重试/故障转移。 +- 首个可见事件后禁止切换 Provider 重新生成;当前流继续或明确失败。 +- 每个 attempt 单独创建 ModelCall;SDK 自身重试也必须可观测。 +- 429 遵循 `Retry-After`;上下文错误、认证、权限和内容拒绝不做同请求盲重试。 + +## 7. Usage 标准化 + +标准字段见 `run-observability.md`。关键差异: + +- Anthropic `usage.input_tokens` 表示未缓存输入,缓存创建/读取单列; +- OpenAI `usage.input_tokens` 通常含 cached tokens,Adapter 计算未缓存差值; +- Provider 未返回字段存 `null`,`usage_source=unavailable`; +- 平台估算必须标记 `gateway_estimate`,不能冒充 Provider usage; +- 成本由 Hunjing 价格版本计算,不信任上游返回成本; +- 流式 usage 可能只在末尾出现,流异常时允许部分 usage 或 unavailable。 + +## 8. BYOK 与 Service Account + +- 兼容 API 只接受 Hunjing 凭据,不接受用户把 Provider Key 当认证凭据。 +- BYOK 通过 Native Secret/Endpoint 配置写入,常规读取只返回掩码和状态。 +- Service Account scope 可限制模型、能力、日/月预算、RPM/TPM、IP/来源和有效期。 +- 同一个 API key 不跨 PersonalDomain/Workspace 自动访问。 + +## 9. 错误转换 + +兼容入口按目标协议返回错误 envelope,同时附: + +```http +Hunjing-Request-ID: request_01... +traceparent: 00-... +``` + +内部保留标准错误和 Provider 原错误类别。不得把 Provider 私密正文、Endpoint、密钥状态或其他租户信息暴露给兼容客户端。 diff --git a/docs/contracts/http-and-events.md b/docs/contracts/http-and-events.md new file mode 100644 index 0000000..d10ed17 --- /dev/null +++ b/docs/contracts/http-and-events.md @@ -0,0 +1,170 @@ +# HTTP 与事件契约 + +## 1. 通用请求头 + +| 字段 | 方向 | 规则 | +| --- | --- | --- | +| `Authorization` | request | `Bearer `;只经 TLS | +| `traceparent` | both | W3C Trace Context;服务边界传播并生成新 span | +| `tracestate` | both | 可选;不得包含 PII、密钥或业务正文 | +| `baggage` | both | 可选;仅传播登记的低敏、低基数键,不参与授权 | +| `Hunjing-Request-ID` | both | 调用方可提供;服务端缺失时生成;最多 64 个 `[A-Za-z0-9_-]` | +| `Idempotency-Key` | request | 创建 Run 和副作用操作使用;opaque,作用域和 TTL 由端点定义 | +| `request-id` / `x-request-id` | upstream response | 保存供应商原始 request ID,不用本地值覆盖 | + +`Hunjing-Request-ID` 用于业务请求关联,不能替代 `traceparent` 的父子调用链。字段名大小写不敏感;文档使用固定大小写。新私有字段不使用 `X-` 前缀。 + +所有自定义字段为单值字段。重复字段、逗号列表、控制字符、空值或超长值返回 `400 invalid_request`,防止代理合并改变语义。 + +## 2. Header 转发 + +### Client → API + +只读取本契约列出的字段。未知 `Hunjing-*` 字段忽略或拒绝,不自动进入插件上下文。 + +### API → Provider + +仅允许 Adapter 白名单:供应商鉴权、版本、beta、content type、trace 和明确业务所需字段。禁止转发: + +- 用户 `Authorization`; +- `Cookie`; +- `Hunjing-Diagnostic-Token`; +- 任意用户提交的供应商 API Key Header; +- Hop-by-hop fields; +- 未登记实验字段。 + +BYOK 密钥由服务端 Secret Store 注入。 + +## 3. 错误响应 + +```json +{ + "error": { + "code": "permission_denied", + "message": "无权执行该操作。", + "trace_id": "trace_01...", + "details": {} + } +} +``` + +稳定 `code`: + +| Code | HTTP | +| --- | ---: | +| `invalid_request` | 400 | +| `authentication_required` | 401 | +| `permission_denied` | 403 | +| `not_found` | 404 | +| `conflict` | 409 | +| `payload_too_large` | 413 | +| `validation_failed` | 422 | +| `rate_limited` | 429 | +| `provider_error` | 502 | +| `provider_unavailable` | 503 | +| `provider_timeout` | 504 | +| `internal_error` | 500 | + +错误消息不得含密钥、完整 Prompt、工具敏感参数或 Provider 原始正文。 + +## 4. SSE + +事件 envelope: + +```json +{ + "id": "event_01...", + "type": "content.block.delta", + "run_id": "run_01...", + "turn_id": "turn_01...", + "sequence": 12, + "created_at": "2026-09-02T08:00:00Z", + "data": {} +} +``` + +- `sequence` 在 Run 内单调递增。 +- Block delta 为临时传输;`content.block.completed` 提供 Block 权威快照,`message.completed` 指向持久化 Message。 +- HTTP 200 后仍可能发送 `error` 事件。 +- 在首个用户可见 delta 发出前,Runtime 可按路由策略重试或故障转移;发出后不得切换上游重新生成另一条内容,只能继续当前流或明确失败。 +- 重连使用 `Last-Event-ID`;若服务端无法重放,则客户端先拉取 Run 当前状态再继续流。 +- 心跳不写业务数据库。 + +## 5. 稳定事件名 + +```text +run.queued +run.started +run.waiting_approval +run.completed +run.failed +run.cancelled +turn.started +turn.completed +model.request.started +model.request.completed +model.request.failed +model.cache.observed +message.started +content.block.started +content.block.delta +content.block.progress +content.block.completed +content.block.failed +content.block.cancelled +message.completed +tool.call.requested +tool.call.approval_required +tool.call.started +tool.call.completed +tool.call.failed +memory.candidate.created +memory.candidate.approved +memory.candidate.rejected +memory.created +memory.updated +memory.archived +memory.deleted +plugin.submitted +plugin.published +plugin.installed +plugin.activated +plugin.suspended +plugin.deactivated +plugin.removed +media.job.started +media.job.completed +media.job.failed +device.grant.created +device.grant.revoked +community.content.published +community.content.limited +community.content.removed +moderation.case.created +moderation.case.decided +workspace.member.added +workspace.member.removed +release.published +listing.published +order.created +order.paid +order.cancelled +payment.succeeded +payment.failed +refund.succeeded +dispute.opened +entitlement.granted +entitlement.revoked +ledger.entry.posted +settlement.created +settlement.paid +settlement.failed +``` + +事件 payload 只引用敏感对象 ID 和脱敏摘要;原文通过受保护资源 API 读取。支付和 Ledger 事件只能由交易内核产生,插件不能伪造或覆盖。 + +## 6. 幂等 + +- `POST /runs` 接受 `Idempotency-Key`,相同用户、端点和规范化请求体重复提交返回同一 Run。 +- ToolCall 的幂等键由 Run、Tool definition、规范化参数和显式业务对象组成。 +- 不缓存认证失败、审批拒绝和未知执行结果。 diff --git a/docs/contracts/internal-api.md b/docs/contracts/internal-api.md new file mode 100644 index 0000000..1473c17 --- /dev/null +++ b/docs/contracts/internal-api.md @@ -0,0 +1,202 @@ +# 内部端口、事件与插件协议 + +## 1. 原则 + +模块化单体内部不为每个模块创建 HTTP。领域模块通过类型化 Port、Command、Query 和 Domain Event 交互;只有独立扩缩容或安全边界才使用私有网络协议。 + +```mermaid +flowchart LR + API[Native API] --> CMD[Application Commands] + CMD --> DOMAIN[Domain Modules] + DOMAIN --> OUTBOX[(Transactional Outbox)] + OUTBOX --> WORKER[Workers] + DOMAIN --> PORTS[Provider and Tool Ports] + PORTS --> MODEL[Model Adapters] + PORTS --> PLUGIN[Plugin RPC] + PORTS --> SANDBOX[Sandbox RPC] +``` + +## 2. 应用 Command + +核心 Command 示例: + +```text +CreateCharacter +CreateConversation +AppendConversationMessageAndStartRun +StartTaskRun +SteerRun +CancelRun +ResumeRun +DecideApproval +CreateMemoryCandidate +DecideMemoryCandidate +PublishRelease +InstallPlugin +GrantDeviceCapability +CreateOrder +ApplyPaymentEvent +CreateRefund +CreateSettlement +DecideModerationCase +``` + +每个 Command 包含 `command_id`、actor、scope、trace context、idempotency key、occurred_at 和类型化 payload。Handler 在一个事务中写权威状态、AuditEvent 和 OutboxEvent。 + +## 3. Query Port + +Query 返回授权后的 DTO,不返回 ORM Entity 或裸数据库连接。调用方必须提供 actor/scope;Repository 自身再次施加数据域条件,避免只在 API 层授权。 + +高成本检索使用显式 Query:`SearchMemories`、`SearchCommunity`、`BuildContextSnapshot`、`CalculateOrderQuote`。交易报价必须返回 price version 和 expires_at。 + +## 4. Domain Event 与 Outbox + +Domain Event/Outbox 记录已提交领域事实,使用 `payload` 和聚合版本;公共 SSE 使用 [HTTP 与事件契约](http-and-events.md#4-sse) 的 `data`、Run `sequence` 和公开事件名;Normalized Model Event 只存在于 Model Adapter→Runtime 流中。Runtime 必须显式完成三层映射,不把 Provider/Normalized 事件原样作为公共事件或领域事实持久化。 + +Event envelope: + +```json +{ + "id": "event_01...", + "type": "run.queued", + "aggregate_type": "run", + "aggregate_id": "run_01...", + "aggregate_version": 1, + "personal_domain_id": "domain_01...", + "trace_id": "trace_01...", + "occurred_at": "2026-09-03T08:00:00Z", + "payload": {} +} +``` + +消费者按 event ID 幂等。事件只陈述已提交事实,不使用 `*.requested` 假装命令。命令需要结果时调用 Application Port;异步请求创建 Job/Run 资源。 + +## 5. Normalized Model Port + +```text +ModelGateway.invoke(NormalizedRequest) -> AsyncIterator +ModelGateway.count_tokens(NormalizedRequest) -> TokenCount +ModelGateway.list_models(scope) -> ModelCapabilities[] +``` + +`NormalizedRequest` 包含逻辑模型、标准 content blocks、tools、tool choice、output contract、thinking/effort hint、cache plan、预算、地区、隐私级别和 trace。它不包含 Provider SDK 类型。 + +`NormalizedEvent`: + +```text +response.started +content.block.started +text.delta +thinking.summary.delta +tool.call.delta +tool.call.completed +usage.updated +response.completed +response.failed +``` + +Adapter 负责协议转换、Provider Header allowlist、错误分类、上游 request ID、usage 标准化和能力校验;Gateway Kernel 负责路由、重试边界、预算、ModelCall 持久化和首个可见事件提交。Runtime 将 `text.delta`、`tool.call.*` 等 Normalized Event 映射为统一 ContentBlock 与 `content.block.*` 公共 SSE;`response.*` 只控制内部调用生命周期,不直接进入公共事件表。 + +## 6. Tool Runtime Port + +```text +ToolRegistry.snapshot(scope) -> ToolSnapshot +Policy.evaluate(ToolInvocation, ActorContext) -> PolicyDecision +ToolExecutor.execute(ExecutionTicket) -> ToolResult +``` + +ExecutionTicket 是短期、单 ToolCall、不可扩大权限的凭证,包含 tool/plugin version、参数 hash、文件/网络/设备范围、超时、资源限制、approval 和 idempotency key。Executor 不接受模型直接构造的票据。 + +ToolResult 包含 status、typed content、is_error、result size、evidence refs 和 redaction metadata。大结果落 File/Object,模型只收到摘要和引用。 + +## 7. Worker 与 Lease + +异步 Job 具有 `queued/running/succeeded/failed/cancelled` 状态。Worker 通过私有 Queue Port: + +```text +claim(queue, worker_id, lease_ms) -> JobLease | null +heartbeat(job_id, lease_token) +complete(job_id, lease_token, result_ref) +fail(job_id, lease_token, retry_class, error) +``` + +Lease token 只在 Header/消息元数据传递,不能成为业务 API 凭据。过期 Lease 可重新领取;副作用步骤仍依赖业务幂等键,不能仅靠 Lease 防重复。 + +## 8. Hunjing Plugin Protocol + +通用插件协议采用 JSON-RPC 2.0: + +- 本地隔离插件:stdio; +- 远程插件:HTTPS; +- Tool-only 插件优先使用 MCP; +- UI 扩展使用声明式 manifest + 隔离消息协议。 + +握手方法: + +```text +plugin.initialize +plugin.get_manifest +plugin.list_contributions +plugin.activate +plugin.deactivate +plugin.health +``` + +调用方法: + +```text +tool.invoke +hook.observe +hook.transform +context.provide +memory.extract_candidates +media.process +importer.inspect +importer.apply +``` + +每次请求带 `plugin_run_id`、PluginVersion、deadline、trace context 和短期 capability token。Host 验证响应 Schema、大小、时限和调用顺序。插件不能返回新权限,也不能调用未在 Manifest 声明的 Host service。 + +### 8.1 Host 回调 + +插件需要访问 Host 时,只能调用受限反向 RPC: + +```text +host.files.read +host.objects.create +host.http.fetch +host.secrets.use_reference +host.events.publish_observation +``` + +Host 根据 capability token 决定范围。`secrets.use_reference` 只让代理侧在允许 host/位置注入秘密,不向插件返回明文。 + +## 9. Sandbox RPC + +Sandbox Worker 处于独立安全边界,私有协议至少支持: + +```text +sandbox.start +sandbox.execute +sandbox.read_output +sandbox.cancel +sandbox.stop +``` + +请求包含镜像摘要、只读/可写挂载、网络 allowlist、环境变量引用、CPU/内存/进程/时间限制和 ExecutionTicket。没有满足策略的后端时返回 `sandbox_unavailable`,禁止未隔离执行。 + +## 10. 支付内部端口 + +```text +PaymentProvider.create_session(OrderSnapshot) +PaymentProvider.verify_webhook(raw_body, headers) +PaymentProvider.refund(PaymentReference, Amount) +PayoutProvider.create_payout(SettlementSnapshot) +ReconciliationProvider.list_transactions(period) +``` + +Provider Adapter 不写 Ledger。交易 Application Service 在验签和幂等后写 PaymentAttempt、LedgerEntry、Entitlement、Refund 或 PayoutAttempt。所有金额与货币由权威 Order/Settlement Snapshot 提供。 + +## 11. 内部认证 + +独立服务使用 workload identity/mTLS 或短期服务令牌;不复用用户 Cookie、Service Account API key 或 DiagnosticToken。每个服务身份只获所需方法与数据域。内部 Header 同样传播 `traceparent` 和 `Hunjing-Request-ID`,但不把 `baggage` 当授权。 diff --git a/docs/contracts/lingtai-ffi.md b/docs/contracts/lingtai-ffi.md new file mode 100644 index 0000000..693c619 --- /dev/null +++ b/docs/contracts/lingtai-ffi.md @@ -0,0 +1,114 @@ +# Lingtai C ABI + +灵台引擎进程内形态的公共契约。本文件是 `hj_*` 稳定符号、类型与错误码的单一登记处;机器化前以本文件为命名基线,机器化后以 `include/hunjing/lingtai.h` 与生成 Schema 为准。独立服务形态(gRPC)契约见 [Lingtai Service](lingtai-service.md),两种形态共用同一核心与语义;架构语义见[灵台引擎架构](../architecture/lingtai-engine.md)。 + +## 1. 适用范围与稳定性 + +- 消费方:官方 Python/Go/Rust 绑定与经部署者授权的第三方宿主。这是公开稳定契约,适用与 Native API 相同的演进纪律:向后兼容的新增函数不升 major;修改既有签名或语义必须升 major。 +- `HjStatus` 错误码同时是服务形态错误映射的源枚举(映射表见 [Lingtai Service](lingtai-service.md));新增错误码须同步评估两种形态。 +- 凭据、用户内容与密钥不经 ABI 传递;引擎无网络与持久化能力(只读索引除外),不存在凭据通道。 +- 本 ABI 不是 HTTP 分面,不与 `api./v1` 的资源契约混用;引擎产物的字段与枚举复用本目录既有契约。 + +## 2. 命名与符号 + +| 对象 | 规则 | 示例 | +| --- | --- | --- | +| 函数 | `hj_` 前缀 + `snake_case` | `hj_engine_new` | +| 不透明句柄类型 | `Hj` 前缀 | `HjEngine`、`HjStream` | +| 状态码枚举 | `HJ_OK` / `HJ_ERR_*` | `HJ_ERR_PARSE_FAILED` | +| 宏 | `HJ_` 前缀大写 | `HJ_ABI_VERSION` | +| 库文件 | `libhunjing` | `libhunjing.so` / `.dylib` / `.dll` | +| 公共头 | 单一头文件 | `include/hunjing/lingtai.h` | + +- 所有导出函数为 `extern "C"`;结构体不透明(仅前向声明),字段布局不进入契约。 +- 除 `hj_*` 外不导出任何符号;C++ 类、STL 类型、异常与 RTTI 不得跨越边界。 + +### 2.1 模块标识 + +六个子系统的稳定模块名(职责详见[灵台引擎架构](../architecture/lingtai-engine.md),文化名见[文化语言体系](../product/cultural-language.md)): + +| 模块 | 职责摘要 | +| --- | --- | +| `hj_core` | 版本协商、句柄生命周期、状态转换校验、事件序 | +| `hj_stream` | 流事件编码、增量去重、节流与重放缓冲 | +| `hj_plan` | 计划 DAG 校验、预算核算、上下文装配计算 | +| `hj_recall` | 只读离线混合索引、重排打分、多路合并 | +| `hj_transform` | Markdown 规范化为 canonical ContentBlock | +| `hj_policy` | Schema/路径/URL 校验、验签、幂等键、决策评估 | + +## 3. 版本协商 + +```c +#define HJ_ABI_VERSION 1 +uint32_t hj_abi_version(void); +``` + +- `HJ_ABI_VERSION` 为当前 major;`hj_abi_version()` 返回引擎构建时的 major。 +- 宿主在 `hj_engine_new` 传入所需 major;不一致时返回 `HJ_ERR_UNSUPPORTED_ABI` 且不产生句柄,禁止静默降级运行。 +- 引擎实现与 parser 版本可经 `hj_engine_build_info` 查询,供宿主写入 PluginSnapshot、诊断与审计。 + +## 4. 生命周期与内存 + +- 引擎句柄:`hj_engine_new` / `hj_engine_free`;`HjEngine` 线程安全。 +- 会话句柄(`HjStream`、`HjTransform`、`HjRecallSession`、`HjPolicyEval`):从 `HjEngine` 派生,单线程亲和;每个句柄有对应 `hj_*_free`。 +- 缓冲区:引擎分配的输出缓冲由 `hj_buffer_free` 释放;`hj_buffer_data`/`hj_buffer_len` 读取内容。宿主不得 `free` 引擎指针,引擎不得持有返回后的宿主指针。 +- 字符串:UTF-8;输入 NUL 结尾或指针加长度,输出指针加长度。 +- 二次释放、句柄复用与跨线程使用会话句柄返回 `HJ_ERR_HANDLE_INVALID`,不得崩溃。 + +## 5. `HjStatus` 错误码 + +| 枚举值 | 语义 | 典型映射 | +| --- | --- | --- | +| `HJ_OK` | 成功 | — | +| `HJ_ERR_INVALID_ARGUMENT` | 参数为空、编码非法或超长 | `validation_failed` | +| `HJ_ERR_OUT_OF_MEMORY` | 引擎分配失败 | `internal` + 告警 | +| `HJ_ERR_UNSUPPORTED_ABI` | major 版本不匹配 | 启动失败 | +| `HJ_ERR_HANDLE_INVALID` | 句柄非法、已释放或跨线程 | `internal` | +| `HJ_ERR_REENTRANCY` | 回调内再入引擎 | `internal` | +| `HJ_ERR_PARSE_FAILED` | 输入无法规范解析 | `validation_failed` | +| `HJ_ERR_LIMIT_EXCEEDED` | 长度/深度/节点/预算超限 | `payload_too_large` / `limit_exceeded` | +| `HJ_ERR_POLICY_DENIED` | 策略判定拒绝 | `permission_denied` / `forbidden` | +| `HJ_ERR_SIGNATURE_INVALID` | 验签失败或时间窗外的重放 | `invalid_signature` | +| `HJ_ERR_INDEX_CORRUPT` | 只读索引校验失败 | 启动失败,要求重建索引 | +| `HJ_ERR_BUFFER_TOO_SMALL` | 输出缓冲不足(可重试扩容) | — | +| `HJ_ERR_INTERNAL` | 引擎内部错误 | `internal` | + +- 新增错误码不破坏兼容;绑定层必须对未知码走失败分支,不得当作成功。 +- `hj_last_error` 返回线程局部的最近错误消息(UTF-8、脱敏、不含正文与密钥);下一次引擎调用覆盖。 + +## 6. 数据边界 + +- ContentBlock、流事件与策略判定输入输出使用本目录既有 JSON Schema([统一富内容与流式协议](content-blocks-and-streaming.md));引擎输出 canonical JSON:键序确定、无空白、UTF-8,保证 content hash 可跨端复现。 +- 媒体字节(图片摘要、向量、波形)经 `hj_buffer` 二进制传递,不进入 JSON。 +- 限额(单消息 Block 数、源码长度、节点数、嵌套深度)由宿主配置传入并在 Schema 中保留硬上限;超限返回 `HJ_ERR_LIMIT_EXCEEDED`,引擎不得为完成解析而放宽限额。 + +## 7. 回调约定 + +```c +typedef void (*HjStreamCallback)(void *user_data, + const char *event_json, + size_t event_len); +``` + +- 回调在触发调用的同一线程同步执行;回调内禁止调用任何 `hj_*` 函数(`HJ_ERR_REENTRANCY`)。 +- `event_json` 仅在回调期间有效;宿主需要保留必须复制。 +- 回调抛出的宿主异常不得穿透引擎:绑定层捕获后中止本次调用并返回错误。 + +## 8. 官方绑定矩阵 + +| 语言 | 包名(建议) | 实现 | 错误映射 | +| --- | --- | --- | --- | +| Python | `hunjing-lingtai` | nanobind 薄封装,no-gil 标记长计算 | `HunjingEngineError` 层级 | +| Rust | `hunjing-lingtai-sys` + `hunjing-lingtai` | bindgen 生成 + 安全包装(RAII、`Result`) | `LingtaiError` enum | +| Go | `hunjing/lingtai` | cgo,绑定集中在单一包 | `errors` 哨兵值 | + +- 绑定层不缓存权威状态、不补写业务语义;三端输出必须字节一致(golden 测试)。 +- 绑定的内存错误(泄漏/双重释放)由各端测试矩阵覆盖,属于发布门。 + +## 9. 禁令清单 + +- 不得以宿主语言重新实现已登记的引擎能力作为回退路径。 +- 不得在 ABI 边界传递凭据、Cookie、诊断令牌或用户正文以外的敏感负载。 +- 不得链接未登记的引擎内部符号或依赖头文件未声明的行为。 +- 不得绕过 `hj_engine_new` 的版本协商直接 dlsym 猜测符号。 +- 不得将引擎错误消息原样透传给最终用户;错误本地化由宿主完成。 diff --git a/docs/contracts/lingtai-service.md b/docs/contracts/lingtai-service.md new file mode 100644 index 0000000..f0c125a --- /dev/null +++ b/docs/contracts/lingtai-service.md @@ -0,0 +1,77 @@ +# Lingtai Service + +灵台引擎独立服务形态的 gRPC 契约。本文件是服务方法、错误映射与形态边界的登记处;机器化前以本文件为命名基线,机器化后以 `proto/lingtai/v1/lingtai.proto` 为真源。进程内形态契约见 [Lingtai C ABI](lingtai-ffi.md);架构语义见[灵台引擎架构](../architecture/lingtai-engine.md)。 + +## 1. 适用范围与稳定性 + +- 消费方:同一部署内的 FastAPI 宿主、Worker、Go 网关与经部署者授权的内部系统。这是**部署内部契约**,不进入 `api.`/`gateway.` 公共分面,不经公共网关暴露,不向最终用户承诺稳定性。 +- proto 按 protobuf 官方演进纪律:不修改既有字段编号与类型,新增字段由消费方忽略;破坏性变更升 `v2` 包,并行维护一个旧包的最短过渡期。 +- 服务无权威状态:任何方法被路由到任一实例结果一致;实例可水平扩缩,无会话粘滞(流式方法除外,见第 5 节)。 + +## 2. 命名 + +| 对象 | 规则 | 示例 | +| --- | --- | --- | +| proto 包 | `lingtai.v` | `lingtai.v1` | +| 服务 | `LingtaiEngine` | `lingtai.v1.LingtaiEngine` | +| 方法 | 模块职责 + 动词 | `TransformMarkdown`、`EvaluatePolicy` | +| 消息 | 请求/响应后缀 | `TransformMarkdownRequest` | +| 二进制 | `hunjing-lingtai-server` | 监听部署内部地址 | + +字段命名使用 `snake_case`,与 [协议与稳定标识](README.md) 一致;消息字段语义与 C ABI 的 JSON 边界([统一富内容与流式协议](content-blocks-and-streaming.md))同源,不另造字段语义。 + +## 3. 能力与方法 + +| 方法 | 对应子系统 | 语义 | +| --- | --- | --- | +| `GetEngineInfo` | `hj_core` | 版本、ABI major、parser version、能力位 | +| `TransformMarkdown` | `hj_transform` | Markdown → canonical ContentBlock 列表(含 parser version) | +| `RebuildExport` | `hj_transform` | canonical Block → 可移植 Markdown 重建 | +| `OpenStream` | `hj_stream` | 双向流:宿主喂增量,服务回 `content.block.*` 事件 envelope | +| `ValidatePlan` | `hj_plan` | 计划 DAG 校验、拓扑排序与预算核算 | +| `AssembleContext` | `hj_plan` | Context Manifest 裁剪与优先级排序计算 | +| `RerankRecall` | `hj_recall` | 多路检索结果重排与合并(服务形态能力) | +| `EvaluatePolicy` | `hj_policy` | Schema/路径/URL 校验、验签、幂等键规范化、决策表评估 | +| `CheckStateTransition` | `hj_core` | Run/Turn 状态转换合法性校验 | + +- 形态边界登记:`hj_recall` 的离线索引文件 mmap 仅进程内形态可用;服务形态只提供 `RerankRecall` 等 CPU 计算部分。新增单形态能力必须在本表登记。 +- 所有请求携带调用方声明的限额(长度/深度/预算);服务端按部署配置二次钳制,取两者较小值。 + +## 4. 传输与认证 + +- 仅监听部署内部网络;TLS 必启,客户端与服务端双向 mTLS,证书由部署内部 CA 签发。 +- 认证是工作负载身份(客户端证书/SPIFFE 类标识),不是用户凭据;用户级授权判定在宿主完成后才调用引擎,引擎不重复也不绕过用户授权。 +- 不存在匿名访问;未经认证连接在握手阶段断开并记审计。 +- 部署元数据(trace 上下文)经 gRPC metadata 传播,与 `traceparent` 语义一致;业务请求 ID 由宿主透传,服务不生成权威 ID。 + +## 5. 流式语义 + +- `OpenStream` 为双向流:客户端按序发送增量帧,服务端按序返回事件 envelope;事件带 `sequence` 与 `delta_index`,语义与 C ABI 回调一致。 +- 一条流绑定一个服务端会话句柄;流中断(网络/超时)后会话丢弃,客户端以最终权威数据重放重建,不依赖半程状态。 +- 背压:服务端按配置的内存水位暂停读取;客户端必须在水位恢复前停止发送,不得假设无限缓冲。 + +## 6. 错误映射 + +`HjStatus`([Lingtai C ABI](lingtai-ffi.md))到 gRPC status 的映射: + +| `HjStatus` | gRPC code | +| --- | --- | +| `HJ_OK` | `OK` | +| `HJ_ERR_INVALID_ARGUMENT` / `HJ_ERR_PARSE_FAILED` | `INVALID_ARGUMENT` | +| `HJ_ERR_LIMIT_EXCEEDED` | `OUT_OF_RANGE` 或 `RESOURCE_EXHAUSTED`(按限额类型) | +| `HJ_ERR_POLICY_DENIED` / `HJ_ERR_SIGNATURE_INVALID` | `FAILED_PRECONDITION` 或 `PERMISSION_DENIED`(按调用语义) | +| `HJ_ERR_INDEX_CORRUPT` | `DATA_LOSS`(要求重建索引) | +| `HJ_ERR_UNSUPPORTED_ABI` | `UNIMPLEMENTED` | +| `HJ_ERR_OUT_OF_MEMORY` / `HJ_ERR_INTERNAL` | `INTERNAL` | +| `HJ_ERR_HANDLE_INVALID` / `HJ_ERR_REENTRANCY` | `INTERNAL`(进程内契约,服务面不应出现) | + +- 服务自身的基础设施错误(不可达、超时、认证失败、过载)使用标准 gRPC code:`UNAVAILABLE`、`DEADLINE_EXCEEDED`、`UNAUTHENTICATED`、`UNAVAILABLE`(过载)。 +- 错误 detail 不包含请求正文、密钥或凭据;宿主对 `UNAVAILABLE`/`DEADLINE_EXCEEDED` 的重试由 gRPC 重试策略统一配置,计算方法无副作用、可安全重试。 + +## 7. 禁令清单 + +- 不得把本服务经公共网关或 `api.` 暴露给外部调用方。 +- 不得在服务面引入用户身份认证或授权判定(那是宿主与 Policy Core 的职责)。 +- 不得让任何方法在服务形态与进程内形态产生不同语义;发现分歧按缺陷处理并以 golden 测试复现。 +- 不得绕过 `GetEngineInfo` 的版本/能力协商硬编码猜测方法行为。 +- 不得将引擎错误消息原样透传给最终用户;错误本地化由宿主完成。 diff --git a/docs/contracts/native-api.md b/docs/contracts/native-api.md new file mode 100644 index 0000000..7caa68e --- /dev/null +++ b/docs/contracts/native-api.md @@ -0,0 +1,378 @@ +# Hunjing Native API + +## 1. 设计总览 + +Native API 是角色、对话、Agent、媒体、插件、社区、协作和交易的唯一公共业务 API。模型直接调用使用独立 Gateway 兼容入口。 + +聊天采用**消息与 Run 原子创建**;任务工作台采用**显式 Run 创建**: + +```mermaid +sequenceDiagram + participant C as Client + participant A as Native API + participant D as Database + participant R as Agent Runtime + + C->>A: POST conversation message, start_run=true + A->>D: transaction create Message and Run + D-->>A: committed resources + A-->>C: 201 message and run + A->>R: outbox run.queued + C->>A: GET run event stream + R-->>C: SSE events +``` + +## 2. 身份、数据域和服务账号 + +```text +GET /v1/me +GET /v1/personal-domains +GET /v1/personal-domains/{domain_id} +PATCH /v1/personal-domains/{domain_id} +GET /v1/service-accounts +POST /v1/service-accounts +GET /v1/service-accounts/{service_account_id} +PATCH /v1/service-accounts/{service_account_id} +DELETE /v1/service-accounts/{service_account_id} +POST /v1/service-accounts/{service_account_id}/keys +GET /v1/service-accounts/{service_account_id}/keys +DELETE /v1/service-accounts/{service_account_id}/keys/{key_id} +``` + +Service Account scope 显式列出资源和动作,不允许隐式继承用户全部权限。API key 明文只在创建响应出现一次。 + +## 3. 角色与发布版本 + +```text +GET /v1/characters +POST /v1/characters +GET /v1/characters/{character_id} +PATCH /v1/characters/{character_id} +DELETE /v1/characters/{character_id} +GET /v1/characters/{character_id}/versions +POST /v1/characters/{character_id}/versions +GET /v1/characters/{character_id}/versions/{version_id} +POST /v1/character-imports +GET /v1/character-imports/{import_id} +POST /v1/characters/{character_id}/exports +GET /v1/exports/{export_id} +POST /v1/character-forks +GET /v1/characters/{character_id}/assets +POST /v1/characters/{character_id}/assets +``` + +创建 CharacterVersion 必须带 `If-Match` 当前 Character ETag。Import 只创建待审查候选,不执行脚本、插件或宏。 + +## 4. 对话、消息与分支 + +```text +GET /v1/conversations +POST /v1/conversations +GET /v1/conversations/{conversation_id} +PATCH /v1/conversations/{conversation_id} +DELETE /v1/conversations/{conversation_id} +GET /v1/conversations/{conversation_id}/branches +POST /v1/conversations/{conversation_id}/branches +GET /v1/conversations/{conversation_id}/messages +POST /v1/conversations/{conversation_id}/messages +GET /v1/messages/{message_id} +POST /v1/messages/{message_id}/revisions +POST /v1/messages/{message_id}/regenerations +POST /v1/branches/{branch_id}/selections +POST /v1/branches/{branch_id}/transplants +``` + +### 4.1 原子发送消息 + +```http +POST /v1/conversations/{conversation_id}/messages +Idempotency-Key: msg-... +``` + +```json +{ + "branch_id": "branch_01...", + "content": [ + {"type": "text", "text": "分析这张图"}, + {"type": "file", "file_id": "file_01..."} + ], + "client_message_id": "client-local-id", + "start_run": true, + "run": { + "agent_id": "agent_01...", + "budget": {"max_cost_minor": 100, "currency": "USD"}, + "response_mode": "stream" + } +} +``` + +```json +{ + "message": {"id": "message_01...", "status": "accepted"}, + "run": {"id": "run_01...", "status": "queued"} +} +``` + +`start_run=false` 只保存消息草稿/人工消息。事务失败时两个资源都不创建。`client_message_id` 用于乐观 UI 对账,不承担服务端幂等。 + +## 5. Agent 定义、Run 与审批 + +```text +GET /v1/agents +POST /v1/agents +GET /v1/agents/{agent_id} +PATCH /v1/agents/{agent_id} +GET /v1/agents/{agent_id}/versions +POST /v1/agents/{agent_id}/versions +GET /v1/runs +POST /v1/runs +GET /v1/runs/{run_id} +GET /v1/runs/{run_id}/turns +GET /v1/runs/{run_id}/children +GET /v1/runs/{run_id}/events +POST /v1/runs/{run_id}/steering-messages +POST /v1/runs/{run_id}/cancellations +POST /v1/runs/{run_id}/resumptions +GET /v1/approvals/{approval_id} +POST /v1/approvals/{approval_id}/decisions +``` + +### 5.1 显式任务 Run + +```json +{ + "agent_id": "agent_01...", + "input": [{"type": "text", "text": "整理这些资料并生成报告"}], + "resources": [ + {"type": "file", "file_id": "file_01...", "access": "read_only"} + ], + "budget": { + "max_cost_minor": 500, + "currency": "USD", + "max_children": 3, + "max_duration_ms": 1800000 + }, + "output_contract": { + "type": "artifact", + "accepted_media_types": ["text/markdown", "application/pdf"] + } +} +``` + +Run 创建、取消、恢复和 ApprovalDecision 都要求 `Idempotency-Key`。ApprovalDecision 值为 `allow` 或 `deny`,拒绝可带用户可见原因;审批过期后不能复用。 + +## 6. 记忆与知识 + +```text +GET /v1/characters/{character_id}/memory-candidates +POST /v1/characters/{character_id}/memory-candidates +GET /v1/memory-candidates/{candidate_id} +POST /v1/memory-candidates/{candidate_id}/decisions +GET /v1/memories +POST /v1/memories +GET /v1/memories/{memory_id} +PATCH /v1/memories/{memory_id} +DELETE /v1/memories/{memory_id} +GET /v1/memories/{memory_id}/versions +POST /v1/memory-searches +GET /v1/knowledge-documents +POST /v1/knowledge-documents +GET /v1/knowledge-documents/{document_id} +PATCH /v1/knowledge-documents/{document_id} +DELETE /v1/knowledge-documents/{document_id} +``` + +Memory Search 使用 POST,因为过滤、scope、rerank 和预算是结构化请求;它只读,不要求幂等键。响应必须包含命中版本、来源、各检索通道分数、重排结果、召回原因和是否进入上下文。`POST /v1/memories` 与 Candidate decision 是幂等命令;`PATCH /v1/memories/{memory_id}` 必须带 `If-Match`,纠正创建新 MemoryVersion,不原地覆盖。所有权、状态过滤、删除和 ContextSnapshot 语义见[记忆与知识架构](../architecture/memory-and-knowledge.md)。 + +## 7. 文件、媒体、语音、Live2D 与 3D + +```text +POST /v1/uploads +GET /v1/uploads/{upload_id} +POST /v1/uploads/{upload_id}/completions +GET /v1/files/{file_id} +DELETE /v1/files/{file_id} +GET /v1/files/{file_id}/content +GET /v1/media-assets +POST /v1/media-assets +GET /v1/media-assets/{media_id} +DELETE /v1/media-assets/{media_id} +POST /v1/media-jobs +GET /v1/media-jobs/{job_id} +POST /v1/media-jobs/{job_id}/cancellations +GET /v1/voices +POST /v1/voices +POST /v1/voice-consents +DELETE /v1/voice-consents/{consent_id} +POST /v1/realtime-voice-sessions +GET /v1/avatar-models/{avatar_id} +POST /v1/avatar-models +POST /v1/avatar-models/{avatar_id}/revisions +POST /v1/avatar-models/{avatar_id}/exports +``` + +`media_jobs` 的 `operation` 覆盖 ASR、TTS、image generation/edit、Live2D layer/validation、VRM/glTF validation/normalization 等;参数由 operation-specific JSON Schema 校验。 + +## 8. 设备与权限 + +```text +GET /v1/devices +POST /v1/devices/registrations +GET /v1/devices/{device_id} +PATCH /v1/devices/{device_id} +DELETE /v1/devices/{device_id} +GET /v1/device-grants +POST /v1/device-grants +GET /v1/device-grants/{grant_id} +DELETE /v1/device-grants/{grant_id} +POST /v1/device-sessions +GET /v1/device-sessions/{session_id} +POST /v1/device-sessions/{session_id}/terminations +``` + +DeviceGrant 创建 body 显式给出 capability、character、purpose、scope、precision、foreground/background、expiry 和 retention。OS 拒绝权限时不能在服务端伪装已授权。 + +## 9. 插件、MCP 与 Skill + +```text +GET /v1/plugins +POST /v1/plugins +GET /v1/plugins/{plugin_id} +GET /v1/plugins/{plugin_id}/versions +POST /v1/plugins/{plugin_id}/versions +GET /v1/plugin-versions/{version_id} +POST /v1/plugin-versions/{version_id}/submissions +GET /v1/plugin-installations +POST /v1/plugin-installations +GET /v1/plugin-installations/{installation_id} +PATCH /v1/plugin-installations/{installation_id} +DELETE /v1/plugin-installations/{installation_id} +POST /v1/plugin-installations/{installation_id}/permission-decisions +GET /v1/mcp-servers +POST /v1/mcp-servers +PATCH /v1/mcp-servers/{server_id} +DELETE /v1/mcp-servers/{server_id} +GET /v1/skills +POST /v1/skills +``` + +上传 PluginVersion 不等于发布;购买不等于安装;安装不等于启用;升级新增权限必须重新创建 PermissionDecision。 + +## 10. Workspace 与协作 + +```text +GET /v1/workspaces +POST /v1/workspaces +GET /v1/workspaces/{workspace_id} +PATCH /v1/workspaces/{workspace_id} +GET /v1/workspaces/{workspace_id}/members +POST /v1/workspaces/{workspace_id}/invitations +DELETE /v1/workspaces/{workspace_id}/members/{user_id} +PATCH /v1/workspaces/{workspace_id}/members/{user_id} +GET /v1/projects +POST /v1/projects +GET /v1/projects/{project_id} +PATCH /v1/projects/{project_id} +GET /v1/projects/{project_id}/revisions +POST /v1/projects/{project_id}/revisions +POST /v1/projects/{project_id}/reviews +POST /v1/reviews/{review_id}/decisions +POST /v1/collaboration-sessions +``` + +成员编辑、评审、发布、市场上架和财务权限分离。权限变更、合并和发布要求 ETag/If-Match。 + +## 11. 社区与服务端治理私信 + +```text +GET /v1/profiles/{user_id} +PUT /v1/me/following/{user_id} +DELETE /v1/me/following/{user_id} +PUT /v1/me/blocks/{user_id} +DELETE /v1/me/blocks/{user_id} +GET /v1/community-content +POST /v1/community-content +GET /v1/community-content/{content_id} +PATCH /v1/community-content/{content_id} +DELETE /v1/community-content/{content_id} +GET /v1/community-content/{content_id}/comments +POST /v1/community-content/{content_id}/comments +PUT /v1/community-content/{content_id}/reactions/{reaction} +DELETE /v1/community-content/{content_id}/reactions/{reaction} +GET /v1/feeds/home +POST /v1/community-searches +POST /v1/reports +GET /v1/moderation-cases/{case_id} +POST /v1/moderation-cases/{case_id}/appeals +GET /v1/inbox/threads +POST /v1/inbox/threads +GET /v1/inbox/threads/{thread_id}/messages +POST /v1/inbox/threads/{thread_id}/messages +PATCH /v1/inbox/threads/{thread_id}/members/{user_id} +DELETE /v1/inbox/threads/{thread_id}/members/{user_id} +``` + +私信和小群聊使用服务端加密存储、多端同步、举报、屏蔽和审核,不承诺端到端加密。私信与角色 Conversation 使用不同资源类型和权限,避免混淆。 + +## 12. 市场、订单、支付与结算 + +```text +GET /v1/marketplace-listings +POST /v1/marketplace-listings +GET /v1/marketplace-listings/{listing_id} +PATCH /v1/marketplace-listings/{listing_id} +POST /v1/marketplace-listings/{listing_id}/publications +GET /v1/orders +POST /v1/orders +GET /v1/orders/{order_id} +POST /v1/orders/{order_id}/payment-sessions +POST /v1/orders/{order_id}/refunds +GET /v1/refunds/{refund_id} +GET /v1/entitlements +GET /v1/entitlements/{entitlement_id} +GET /v1/creator-accounts/{creator_id} +PATCH /v1/creator-accounts/{creator_id} +GET /v1/creator-accounts/{creator_id}/balances +GET /v1/creator-accounts/{creator_id}/settlements +GET /v1/settlements/{settlement_id} +GET /v1/creator-accounts/{creator_id}/statements +``` + +客户端不能提交权威金额。创建 Order 只接受 listing/version/quantity/coupon 等业务输入,服务端计算价格、税、许可和卖家快照。Payment/Refund/Payout 结果以验签 Webhook 和 Ledger 为准。 + +## 13. 通知、Webhook 和导出删除 + +```text +GET /v1/notifications +POST /v1/notifications/{notification_id}/reads +GET /v1/webhook-endpoints +POST /v1/webhook-endpoints +PATCH /v1/webhook-endpoints/{endpoint_id} +DELETE /v1/webhook-endpoints/{endpoint_id} +POST /v1/webhook-endpoints/{endpoint_id}/secret-rotations +POST /v1/data-exports +GET /v1/data-exports/{export_id} +POST /v1/deletion-requests +GET /v1/deletion-requests/{deletion_id} +``` + +Webhook secret 明文只在创建/轮换响应出现一次。导出和删除是异步资源,具有 scope、状态、进度、失败和审计,不使用一个全能同步端点。 + +## 14. 受保护诊断 + +```text +POST /v1/diagnostic-grants +GET /v1/diagnostic-grants/{grant_id} +DELETE /v1/diagnostic-grants/{grant_id} +GET /v1/runs/{run_id}/diagnostics +GET /v1/runs/{run_id}/diagnostics/turns/{turn_id} +``` + +诊断查询同时要求普通认证和: + +```http +Hunjing-Diagnostic-Token: hjd_... +Hunjing-Diagnostic-Purpose: user_inspection +``` + +Grant 绑定 subject、domain、run/turn、scope、level、purpose、expiry 和 uses。普通 Run API 不返回模型 attempt、脱敏工具参数或 Context Manifest 明细。 diff --git a/docs/contracts/realtime-and-webhooks.md b/docs/contracts/realtime-and-webhooks.md new file mode 100644 index 0000000..6f1425b --- /dev/null +++ b/docs/contracts/realtime-and-webhooks.md @@ -0,0 +1,168 @@ +# 实时 API 与 Webhook + +## 1. 传输选择 + +| 场景 | 传输 | 原因 | +| --- | --- | --- | +| Run 文本/工具/状态输出 | SSE | 单向、可重连、HTTP 友好 | +| 实时语音 | WebSocket | 双向音频和控制 | +| 协同编辑/presence | WebSocket | 双向低延迟 | +| 设备会话 | WebSocket | 双向命令、状态和取消 | +| 普通通知 | SSE 或分页 GET | 无需双向连接 | +| 外部系统通知 | HTTPS Webhook | 异步推送 | + +WebSocket 认证也只通过 Header:Web 使用 Cookie handshake;Tauri 使用 `Authorization: Bearer`。禁止 query token。 + +## 2. Run SSE + +```http +GET /v1/runs/{run_id}/events +Accept: text/event-stream +Last-Event-ID: event_01... +``` + +事件格式沿用 `http-and-events.md`:`id`、`type`、`run_id`、`turn_id`、`sequence`、`created_at`、`data`。 + +规则: + +- 连接先发送当前 `run.snapshot`,再发送新事件; +- `Last-Event-ID` 在保留窗口内重放;超出窗口返回 `409 event_cursor_expired`,客户端 GET Run/Message 后重连; +- `content.block.delta` 是预览,`content.block.completed` 提供 Block 权威快照,`message.completed` 指向权威 Message; +- `heartbeat` 不写业务表; +- `run.completed|failed|cancelled` 是终止事件; +- 客户端对 event ID 去重,不仅依赖 TCP 恰好一次。 + +## 3. WebSocket 通用握手 + +```http +GET /v1/realtime/voice/{session_id} +Upgrade: websocket +Sec-WebSocket-Protocol: hunjing.realtime.v1 +Authorization: Bearer ... +``` + +Web 使用 Cookie 替代 Authorization。连接成功后第一帧: + +```json +{ + "type": "session.ready", + "session_id": "...", + "resume_token": "short-lived-opaque", + "capabilities": [], + "heartbeat_interval_ms": 15000 +} +``` + +`resume_token` 只在后续同认证主体的 Header `Hunjing-Realtime-Resume` 使用,不放 URL;短期、单会话、可撤销。 + +JSON 控制帧统一包含 `type`、`event_id`、`sequence`、`sent_at`。二进制帧只承载协商后的音频/媒体块,元数据由前置 JSON frame 描述。 + +## 4. 实时语音 + +```text +POST /v1/realtime-voice-sessions +WS /v1/realtime/voice/{session_id} +POST /v1/realtime-voice-sessions/{session_id}/terminations +``` + +主要帧: + +```text +input_audio.start +input_audio.chunk +input_audio.commit +transcript.delta +transcript.completed +agent.text.delta +output_audio.start +output_audio.chunk +output_audio.completed +response.interrupt +session.error +session.completed +``` + +- 音频 codec、采样率、语言和端点检测在 Session 创建时协商。 +- `response.interrupt` 取消当前模型和 TTS,不删除已固化用户段。 +- 服务端施加最大帧、带宽、静音、会话时长和费用预算。 +- 原始音频保留策略在 Session 创建响应明确返回。 + +## 5. 协同编辑 + +```text +POST /v1/collaboration-sessions +WS /v1/realtime/collaboration/{session_id} +``` + +帧:`presence.joined/left`、`document.operation`、`document.ack`、`cursor.updated`、`review.updated`、`session.error`。每个 operation 带 client operation ID、base version 和资源 ID;服务端按 ACL 校验。不能通过协同通道编辑支付账、审批记录或已发布不可变版本。 + +## 6. 设备会话 + +```text +POST /v1/device-sessions +WS /v1/realtime/devices/{session_id} +``` + +帧:`capability.state`、`capture.started/chunk/completed`、`permission.changed`、`session.pause/resume/terminate`、`device.error`。每帧校验 DeviceGrant;撤权后连接立即停止相关 capability。Tauri 不暴露通用 Shell frame。 + +## 7. 社区通知 + +```http +GET /v1/notifications/events +Accept: text/event-stream +``` + +只发送薄事件:notification ID、type、resource ID、created_at;正文通过 Native API 按当前权限读取。屏蔽或权限变化后旧通知不能成为资源读取旁路。 + +## 8. Hunjing Outbound Webhook + +```text +GET /v1/webhook-endpoints +POST /v1/webhook-endpoints +PATCH /v1/webhook-endpoints/{endpoint_id} +DELETE /v1/webhook-endpoints/{endpoint_id} +POST /v1/webhook-endpoints/{endpoint_id}/secret-rotations +``` + +投递 Header: + +```http +Hunjing-Webhook-ID: webhook_event_01... +Hunjing-Webhook-Timestamp: 178... +Hunjing-Webhook-Signature: v1= +``` + +签名输入是:`id + "." + timestamp + "." + raw_body`。接收方验证原始字节、时间窗和 event ID 去重。Secret 明文只显示一次,支持新旧 Secret 短期重叠轮换。 + +Envelope: + +```json +{ + "id": "webhook_event_01...", + "type": "run.completed", + "created_at": "2026-09-03T08:00:00Z", + "data": { + "resource_id": "run_01...", + "personal_domain_id": "domain_01..." + } +} +``` + +Webhook 是薄通知,不包含消息正文、工具参数、支付敏感数据或诊断内容。接收方用自己的凭据读取资源。 + +投递至少一次、不保证顺序;2xx 确认,3xx 不跟随,失败指数退避并有死信/管理重放。删除事件可能无法再次读取资源,Envelope 保留最小墓碑信息。 + +## 9. Provider Inbound Webhook + +```text +POST /webhooks/v1/payments/{provider} +POST /webhooks/v1/media/{provider} +POST /webhooks/v1/identity/{provider} +``` + +- 先读取 raw body,再按 Provider 官方 SDK/算法验签; +- 验签前不解析为业务命令; +- 按 Provider event ID 幂等,保存接收、验证、处理状态和不可逆 body hash; +- 不依赖事件顺序,必要时向 Provider 主动查询当前状态; +- 快速返回 Provider 要求的 2xx,重处理进入内部 Job; +- 业务结果由 Ledger/权威资源决定,不由单个 Webhook body 直接覆盖。 diff --git a/docs/contracts/run-observability.md b/docs/contracts/run-observability.md new file mode 100644 index 0000000..2913a4c --- /dev/null +++ b/docs/contracts/run-observability.md @@ -0,0 +1,132 @@ +# 运行观测契约 + +## 1. 聚合层次 + +```text +Run + └─ Turn + ├─ ModelCall attempt + └─ ToolCall +``` + +普通 Run API 返回状态、可见消息和聚合 usage;详细对象只通过诊断 API 返回。 + +## 2. `turn` + +必需字段: + +- `id`、`run_id`、可选 `parent_turn_id`; +- `turn_index`、`status`、`started_at`、`ended_at`; +- `input_message_ids`、`output_message_ids`; +- `context_snapshot_id`、`plugin_snapshot_id`; +- `finish_reason`、`error_code`、`trace_id`。 + +## 3. `model_call` + +每次上游 attempt 单独记录: + +| 字段 | 说明 | +| --- | --- | +| `id`、`turn_id`、`attempt_index` | 关联和重试顺序 | +| `provider`、`endpoint_id` | 实际上游 | +| `logical_model`、`upstream_model` | 业务模型与实际模型 | +| `request_started_at`、`first_token_at`、`completed_at` | 时间点 | +| `latency_ms`、`time_to_first_token_ms` | 延迟 | +| `input_tokens` | 未缓存输入 | +| `cache_creation_input_tokens` | Provider 缓存写入 | +| `cache_read_input_tokens` | Provider 缓存读取 | +| `output_tokens` | Provider 输出 | +| `reasoning_tokens` | 供应商明确返回时记录数量 | +| `audio_*`、`image_*` | 适用且供应商返回时记录 | +| `cache_hit` | `true` / `false` / `null` | +| `cost_minor`、`currency`、`price_version` | 可重算成本 | +| `request_id`、`upstream_request_id` | 本地与供应商请求关联 | +| `finish_reason`、`error_type`、`error_code` | 结果 | +| `usage_source` | provider / estimate / unavailable | + +总输入: + +```text +total_input_tokens = + input_tokens + + cache_creation_input_tokens + + cache_read_input_tokens +``` + +`cache_hit=true` 仅当 `cache_read_input_tokens > 0`;供应商明确返回 0 时为 false;未提供相关字段时为 null。 + +上述公式定义的是 **Hunjing 标准化语义**。Adapter 必须先处理供应商差异:Anthropic 的 `input_tokens` 是未缓存部分,可直接映射;OpenAI 的 `input_tokens` 通常包含 `input_tokens_details.cached_tokens`,因此标准化时将后者映射到 `cache_read_input_tokens`,并将两者之差映射到本字段的 `input_tokens`。原始 usage 经脱敏后另存 `usage_raw_redacted`,便于核对,不能直接混加造成重复计数。 + +| 标准字段 | Anthropic | OpenAI | +| --- | --- | --- | +| `upstream_request_id` | `request-id` / error `request_id` | `x-request-id` | +| `input_tokens` | `usage.input_tokens` | `usage.input_tokens - usage.input_tokens_details.cached_tokens` | +| `cache_read_input_tokens` | `usage.cache_read_input_tokens` | `usage.input_tokens_details.cached_tokens` | +| `cache_creation_input_tokens` | `usage.cache_creation_input_tokens` | 无对应字段时为 `null` | +| `output_tokens` | `usage.output_tokens` | `usage.output_tokens` | + +字段路径按具体 API 端点和 SDK 版本适配;表中缺失表示“该端点未返回”,不是数值 0。 + +## 4. 字段来源 + +### 供应商原生 + +供应商返回且 Adapter 原样标准化: + +- 上游模型 ID; +- request ID; +- stop/finish reason; +- input/output/cache/reasoning token(若存在); +- server tool usage(若存在); +- 供应商错误类型。 + +### 平台计算 + +- `latency_ms`、`time_to_first_token_ms`; +- logical model、endpoint、attempt index; +- 成本与价格版本; +- cache hit 三态; +- retry/fallback 关联; +- Context 和 Plugin snapshot; +- 业务 trace。 + +平台计算字段不能标记 `usage_source=provider`。 + +## 5. `tool_call` + +字段: + +- `id`、`turn_id`、`step_index`、`call_index`; +- `tool_id`、`plugin_id`、`plugin_version`、`execution_backend`; +- `arguments_redacted`、`arguments_hash`、`redaction_status`; +- `result_redacted`、`result_size_bytes`、`is_error`; +- `status`、`error_code`、`started_at`、`ended_at`、`latency_ms`; +- `confirmation_id`、`policy_decision_id`; +- `trace_id`、`idempotency_key`、`evidence_ids`。 + +常规表禁止保存 Authorization、密钥、签名 URL、文件原文和第三方高敏正文。 + +## 6. Context Manifest + +ContextSnapshot 保存: + +- 来源对象 ID 与版本; +- 来源类型:system、character、message、memory、knowledge、tool result; +- 每项估算或真实 token; +- 采用、裁剪、压缩或拒绝原因; +- 最终顺序和不可逆内容摘要; +- cache breakpoint 位置与 Provider cache usage。 + +不保存隐藏 chain-of-thought。完整 Prompt 仅在用户明确生成敏感支持包时限期保存。 + +## 7. 普通与诊断响应 + +| 数据 | 普通 Run API | Summary | Detailed | Sensitive | +| --- | ---: | ---: | ---: | ---: | +| 状态、可见消息 | 是 | 是 | 是 | 是 | +| 聚合 token/cost | 是 | 是 | 是 | 是 | +| Model attempt | 否 | 摘要 | 是 | 是 | +| Tool 名、状态、耗时 | 否 | 是 | 是 | 是 | +| 脱敏参数/结果 | 否 | 否 | 是 | 是 | +| 受限敏感内容 | 否 | 否 | 否 | 额外确认 | +| 隐藏推理 | 否 | 否 | 否 | 否 | diff --git a/docs/decisions/README.md b/docs/decisions/README.md new file mode 100644 index 0000000..263457c --- /dev/null +++ b/docs/decisions/README.md @@ -0,0 +1,381 @@ +# 架构决策记录 + +## ADR-001:可扩展能力皆插件,治理内核不插件化 + +**状态**:采纳 + +**决策** + +模型适配器、工具、上下文提供者、记忆策略、Run Hook 和内容导入器通过统一插件契约扩展。身份认证、授权、数据域隔离、审批、审计、事务、插件签名验证和执行中止属于 Core,不允许插件替换或短路。 + +**理由** + +DeepSeek Harness 证明了 service、typed event 和 reversible effect 能形成一致扩展面;pi 证明了清晰生命周期与 session rebind 的价值。两者也表明任意代码插件拥有高权限,VM 不是安全边界。 + +**后果** + +- 插件体系比每类能力各写一套加载器简单。 +- “一切皆插件”不是“所有行为都可覆盖”。 +- 1.0 支持完整插件生态,但只有 bundled Core plugin 进入主进程;第三方能力使用受限远程协议或隔离进程/容器。 + +## ADR-002:首版采用模块化单体 + +**状态**:采纳 + +**决策** + +FastAPI 应用内包含角色、会话、Agent Runtime、模型接入、插件、记忆、策略和诊断模块;后台 Worker 复用相同领域代码。Web 独立部署。只有隔离执行处于单独安全边界。 + +**理由** + +当前没有服务独立扩缩容、团队自治或故障域证据。提前建设 BFF、Go 网关、多数据库和服务发现只增加事务、部署和调试成本。 + +**后果** + +- 模块通过明确端口交互,禁止跨模块直接写表。 +- 模型接入使用 Provider Port,未来可移出进程。 +- Outbox 在确有异步跨进程消费时加入,不先造事件总线。 + +## ADR-003:每个上游 attempt 单独持久化 + +**状态**:采纳 + +**决策** + +Run 包含 Turn;Turn 包含零到多个 ModelCall attempt 和 ToolCall。重试、故障转移和续跑创建新 ModelCall,不覆盖旧记录。 + +**理由** + +只保存最终响应无法解释费用、缓存、失败、TTFT 和故障转移。 + +**后果** + +- `input_tokens` 不代表总输入;总输入还包括缓存创建与缓存读取。 +- Provider 未返回的字段存 `null`,不得估算后伪装为 Provider 数值。 +- 原始请求/响应不进入常规观测表。 + +## ADR-004:诊断读取使用双重、限时授权 + +**状态**:采纳 + +**决策** + +敏感运行诊断不能随普通 Run API 返回。读取者必须同时持有普通 Bearer 登录态和绑定目标 Run、用途、scope、期限、使用次数的 opaque 诊断授权。 + +**理由** + +管理员角色、可猜 URL 或一个长期 Debug Key 都会扩大私密对话和工具结果暴露面。 + +**后果** + +- 授权默认 15 分钟、单次、绑定 Run。 +- 明文只签发一次,数据库只保存 token hash。 +- 访问成功和失败都写审计;响应 `Cache-Control: no-store, private`。 + +## ADR-005:完整 1.0 整体交付 + +**状态**:采纳 + +**决策** + +1.0 同时包含角色、对话、记忆、多 Agent、插件生态、语音、多语言、多模态、Live2D、3D 运行与编辑、Tauri 桌面/移动端感知、完整社区、角色社区、协作空间和真实交易结算。内部工作包不能作为残缺 1.0 对外发布。 + +**后果** + +- 所有工作包 TODO 和发布门完成前只能称开发版或预览。 +- 技术按能力、规模和安全需要选择,不要求每项候选技术都部署。 +- 只有完整 3D 建模器、LLM 直接改模和物理设备控制属于已确认 2.0。 + +## ADR-006:3D 采用开放格式与非破坏编辑 + +**状态**:采纳 + +**决策** + +1.0 支持 VRM/glTF 导入、材质/骨骼/表情/动作/场景编辑、运行和导出,不自研 Blender 级完整建模器。编辑记录采用命令和版本,给 2.0 的 LLM 改模保留扩展点。 + +## ADR-007:客户端采用 Web + Tauri 桌面与移动 + +**状态**:采纳 + +**决策** + +Next.js 提供 Web;Tauri v2 承载桌面以及 iOS/Android。设备能力由 OS 权限和服务端 `device_grant` 双重控制。 + +## ADR-008:插件采用双轨执行 + +**状态**:采纳 + +**决策** + +声明式/远程插件默认受限;本地代码插件必须由部署者明确信任并在独立进程或容器运行。只有 bundled Core plugin 可进入主进程。 + +## ADR-009:市场采用真实交易与不可变账务 + +**状态**:采纳 + +**决策** + +1.0 包含支付、退款、争议、平台费、创作者分成、余额、结算和对账。Ledger 使用不可变分录,支付 Webhook 验签并幂等处理。 + +## ADR-010:公共 API 分面与认证 + +**状态**:采纳 + +**决策** + +Native API 位于 `api./v1`;OpenAI-compatible 与 Anthropic Messages-compatible 位于 `gateway.` 的独立协议前缀。1.0 使用 OAuth 2.1:Web 为安全 Session Cookie,Tauri 为 Authorization Code + PKCE Bearer,第三方为 OAuth Bearer,服务账号为可轮换 API key。所有凭据只经 HTTP Header 传输。 + +**后果** + +- Native `/v1/messages` 不与 Anthropic `/v1/messages` 冲突。 +- Web Cookie 状态变更增加 Origin 与 CSRF 校验。 +- 2.0 才设计自研加密登录、刷新和设备令牌协议。 + +## ADR-011:权威记忆采用候选与不可变版本 + +**状态**:采纳 + +**决策** + +1.0 的权威长期记忆只保存可检查、可纠正的文本或结构化事实。自动提取先生成 MemoryCandidate,经 Core Policy 与必要的人工确认后创建不可变 MemoryVersion;纠正、取代和恢复都创建新版本。Personal Domain 与 Workspace 是互斥所有权边界,向量、全文和图关系只作为可重建投影。 + +**理由** + +MemOS 证明了类型化记忆、来源链、后台精炼、基于召回 ID 的反馈和独立评测的价值;但其 MemCube、原地 update 和开放 metadata 不足以承载 Hunjing 的角色、协作、发布、删除与安全边界。 + +**后果** + +- Character baseline、Message、KnowledgeDocument、Memory 和运行期上下文保持分离。 +- KV cache、隐藏状态和模型权重适配不作为 1.0 权威记忆或可携格式。 +- 插件可以贡献提取、去重、衰减和排序,不能直接写权威 Memory 或绕过审批、授权和删除。 +- 具体规则见[记忆与知识架构](../architecture/memory-and-knowledge.md)。 + +## ADR-012:聊天原子创建消息与 Run + +**状态**:采纳 + +**决策** + +`POST /v1/conversations/{id}/messages` 在一个事务中创建用户 Message 与可选 Run;任务工作台仍可通过 `POST /v1/runs` 创建无 Conversation 的后台 Run。 + +**后果** + +- 避免消息已保存而 Run 创建失败的孤儿状态。 +- 一个 `Idempotency-Key` 同时覆盖消息和 Run。 +- 人工消息使用 `start_run=false`。 + +## ADR-013:社区私信采用服务端治理模型 + +**状态**:采纳 + +**决策** + +1.0 支持一对一私信和小群聊,服务端加密存储并支持多端同步、举报、屏蔽和审核;不采用端到端加密。 + +**后果** + +- 私信可按社区治理规则调查和处置。 +- 不宣传服务端无法读取正文。 +- Inbox Thread 与角色 Conversation 使用不同资源和权限。 + +## ADR-014:文化名只属于品牌展示 + +**状态**:采纳 + +**决策** + +稳定代码、数据库、API、事件、指标和日志使用中性英文工程术语。中文文化名可用于品牌文案或 UI 标签,但不定义工程边界。 + +**理由** + +神话隐喻语义不唯一、跨语言映射不稳定、搜索困难,并容易把职责扩张成故事角色。 + +**后果** + +使用 `model_gateway`、`agent_runtime`、`memory`、`policy_engine`、`plugin_registry` 等名称;不再维护神话名与工程对象的庞大映射表。 + +## ADR-015:平台 ID 区分 UUIDv7、UUIDv4 与 opaque secret + +**状态**:采纳 + +**决策** + +持久化业务资源、版本、事件、账务、审计和异步任务使用 RFC 9562 UUIDv7;服务端生成的 Request ID 与 Trace record ID 使用 UUIDv4。W3C `traceparent` 继续使用规范定义的 16 字节随机 trace-id。API key 明文、OAuth/诊断/CSRF token、Webhook secret、ExecutionTicket、恢复 token 和预签名 URL capability 使用 CSPRNG 或对应标准生成的 opaque value,不使用 UUID。 + +**理由** + +UUIDv7 为高写入关系表提供索引局部性和大致创建顺序;请求与追踪关联不依赖时间排序,使用随机 UUIDv4 即可。UUID 不是秘密,不能替代具有足够熵、可轮换、可撤销和作用域约束的凭据。 + +**后果** + +- 公共平台 ID 使用登记前缀加小写 canonical UUID,并同时校验前缀与 UUID version。 +- UUIDv7 的时间部分不成为业务时间或排序事实;权威顺序仍由时间字段、聚合版本和事件 sequence 决定。 +- 调用方与 Provider 标识原样保存,不改写为平台 UUID。 +- 完整对象映射和生成规则见[协议与稳定标识](../contracts/README.md#id-前缀)。 + +## ADR-016:灵台引擎采用 C++ 核心与稳定 C ABI + +**状态**:采纳 + +**决策** + +性能与安全敏感的确定性核心以 C++ 实现为进程内库"灵台引擎"(Lingtai Engine),划分为太一(`hj_core`)、小周天(`hj_stream`)、洛书(`hj_plan`)、河图(`hj_recall`)、陶钧(`hj_transform`)、烛照(`hj_policy`)六个子系统,文化名承接 Hunjing 旧版(main 分支)"灵台/九枢"血脉,仅通过稳定 C ABI(`hj_*` 符号)暴露。Python(nanobind)、Go(cgo)、Rust(bindgen + 安全包装)提供官方薄绑定;FastAPI、Tauri 宿主与条件拆分的 Go 网关作为进程内嵌入方,不新增独立服务。 + +**理由** + +公开讨论的抖音"六神"native 组件体系证明了"薄宿主 + 原生核心 + 最小 ABI 面 + 多端复用"的组织方式适合高频确定性计算;Hunjing 的 Markdown→ContentBlock 规范化、流式增量编码、策略校验、端侧离线检索正是此类路径,且必须跨 Python/Rust/Go 三种宿主保持行为一致。C ABI 是三种语言生态唯一公共分母,可作为单一真源;三份独立实现必然漂移。研究证据与不采纳项见[灵台引擎研究](../research/lingtai-native-engine.md)。 + +**后果** + +- 引擎是 Core 的一部分,属于不可插件化边界;插件不直接链接引擎,只经宿主 Runtime 间接获得能力。 +- 引擎无权威状态:权威数据仍在关系数据库与对象存储;引擎产物可丢弃重建。除显式授权的只读索引文件外,引擎不进行网络、文件或数据库 I/O。 +- 引擎不可用时宿主对依赖该能力的路径 fail closed,不静默退化到宿主内第二实现(避免规范漂移)。 +- 新增 C++23/CMake 工具链、五平台交叉编译矩阵(Linux x64/arm64、macOS、Windows、iOS/Android)与 sanitizer/fuzz/ABI 快照测试的持续成本。 +- 文化名"灵台、太一、小周天、洛书、河图、陶钧、烛照"只进入品牌与文档层;ABI 符号、模块与错误码使用中性英文,契约登记于 [Lingtai C ABI](../contracts/lingtai-ffi.md)。 +- 本决策修正 ADR-002 的实现层组合(单体宿主内嵌入原生引擎),不推翻模块化单体与服务拆分门槛。 + +## ADR-017:灵台引擎双形态部署 + +**状态**:采纳 + +**决策** + +引擎保持"灵台总枢 + 六模块"结构(太一为单一入口,见 [ADR-016](#adr-016灵台引擎采用-c-核心与稳定-c-abi));文化命名跟随自身职责、经典出处与项目旧版血脉,不跟随外部体系的神数。引擎支持两种部署形态,共用同一 C++ 核心与语义: + +1. **进程内嵌入**(默认):宿主经稳定 C ABI 链接 `libhunjing`,适用单体部署、端侧(Tauri/移动离线)与低延迟路径。 +2. **独立服务**:`hunjing-lingtai-server` 二进制以 gRPC 暴露同一能力(proto 契约见 [Lingtai Service](../contracts/lingtai-service.md)),适用计算资源隔离、独立扩缩容、同部署多宿主共享与跨机器消费;服务仅限部署内部网络,经 mTLS/工作负载身份认证,不进入公共 API 分面。 + +**理由** + +业界六神/七神调研(见[灵台引擎研究](../research/lingtai-native-engine.md))表明同一原生核心可以进程内调用、RPC 服务、受控运行时三种形态交付而不重写;Hunjing 的重型解析与检索在共享部署中需要资源隔离与扩缩容选项,而端侧离线与低延迟路径必须进程内。两种形态由同一核心与同一 golden 测试集约束语义一致,避免第二实现漂移。默认仍是嵌入,服务形态按既有服务拆分标准启用,不与 [ADR-002](#adr-002首版采用模块化单体) 冲突。 + +**后果** + +- 引擎无权威状态、最小 I/O、fail closed 的不变量在两种形态下一致;服务形态额外要求认证、限流、超时、背压与审计。 +- 新增 gRPC/protobuf 工具链与 proto 契约维护成本;proto 与既有 JSON Schema 的字段语义保持同源映射,禁止双真源。 +- `hj_stream` 的流式语义在服务形态经 gRPC 双向流表达;端侧离线检索等单形态能力必须显式登记形态边界。 +- 形态选择是部署决策而非代码分叉:任何能力不得只在一种形态下语义不同。 +- 文化叙事保持"灵台总枢 + 太一/小周天/洛书/河图/陶钧/烛照";命名跟随自身职责与项目血脉,不跟随外部体系神数;工程标识 `hj_*` 与符号名不变,文档与产物命名统一使用 `lingtai`。 + +## ADR-018:角色内驱力与大周天演化进入 1.0 + +**状态**:采纳 + +**决策** + +1.0 包含角色内驱力与大周天自我评估演化循环。内驱力(`character_drives`)是角色的声明式动机维度,用户可审阅、编辑与版本化。大周天(`big_cycle`)是由真实交互事件触发的自我评估循环,以 `BigCycle`(`cycle_`)聚合根持久化、执行为一个受托后台 Run(对象模型与阶段设计见 [ADR-023](#adr-023周天体系统一小周天闭环与大周天演化)):在 RunBudget 与频率硬上限内,评估近期交互与记忆,产出记忆候选、人格变化候选、关系候选、世界实体候选与次生目标候选;经既有候选审核机制确认后生效,演化结果以角色版本与谱系(复照)留痕。 + +**边界(与既有原则的关系)** + +- 事件驱动,不做无人值守的后台定时自主运行;不伪造离线持续意识——"守一"原则不变。 +- 候选先于长期写入:一切演化产物经审核,敏感与高影响必须人工确认,不静默覆盖道体基线。 +- 每次大周天的输入、产物、token 与费用用户可见;用户可整体或按角色关闭,关闭不删除已演化的历史版本。 +- 次生目标候选不自动执行,需用户采用后才进入计划。 + +**理由** + +用户确认角色自进化与演化为 1.0 需求;旧版(main 分支)大周天循环已验证该机制形态(自我评估产出候选、经审核流转)。当前 1.0 的 MemoryCandidate、人格/关系候选、角色版本与 RunBudget 基础设施可直接承载,无需新的一致性机制。 + +**后果** + +- 角色域新增内驱力数据模型与大周天 Run 类型;WP-02、WP-04 增补对应 TODO。 +- 文化名"大周天"回归角色演化循环;引擎流式模块文化名定为"小周天",大小周天构成旧版同源的层次体系:小周天=单次 Run 流转,大周天=跨 Run 演化。 +- 大周天产出的候选携带 `big_cycle` 来源标记,纳入审计与用户可见的演化谱系。 + +## ADR-019:设立产品宪章与永久禁域 + +**状态**:采纳 + +**决策** + +设立[产品宪章](../product/product-charter.md)作为产品定义的上位约束:使命、核心信念、角色不可侵犯边界、用户权利、商业与关系伦理和九条永久禁域。核心禁域不能被 Prompt、插件、管理员或普通自托管配置关闭;宪章修订必须经用户明确确认。 + +**理由** + +承接旧版(main 分支)宪章的立法经验:分散在各文档的边界条款容易被实现与运营决策逐条侵蚀,需要一份上位文件集中裁决。当前分支新增市场与交易生态,商业伦理(保全态、不按亲密计费)更需要立法层约束。 + +**后果** + +- 与宪章冲突的任何产品、架构、契约或实现决定都是缺陷,验收时按禁域逐条核对。 +- 安全与诊断文档把"核心禁域不可关闭"列为信任边界;自托管档位可以裁剪能力,不得混淆职责或关闭禁域。 +- 决策优先序(安全合规 > 用户数据权 > 角色连续性 > 生态健康 > 商业目标)用于裁决设计冲突。 + +## ADR-020:对话三界与归真作用域 + +**状态**:采纳 + +**决策** + +对话界域分三态:**真界**(现实与正式共同经历)、**境界**(版本化维护的世界正史)、**幻境**(不影响现实与正史的临时试演)。默认真界,入境与出境必须可见。归真决策必须携带 `canonical_scope`(`reality`/`world`/`simulation`,登记于[协议与稳定标识](../contracts/README.md)),分别进入真界经历主脉、指定境界版本正史或幻境试演记录;不存在跨三界共享的无作用域主脉。 + +记忆规则:境界归真只形成该世界的知识候选(境忆),不进入角色真界经历记忆;幻境不自动形成长期记忆候选,用户可将启发、观点或假设手动入忆并强制标注性质(事实/观点/启发/假设);未归真内容(推演枝)不自动入忆的既有原则不变。 + +**言可入幻,行必归真**:无论对话处于何界,外部行动(工具副作用、支付、设备、现实后果)一律回到真界接受权限、审批与风险裁决。跨界引用只提供来源,不改变目标内容的界域。 + +**理由** + +承接旧版三界体系的认识论设计,防止试演内容污染正式经历与记忆;与当前分支的主脉/推演枝、归真决策和候选制记忆完全兼容——作用域是归真的属性,不引入新的运行态。 + +**后果** + +- 归真决策、MemoryCandidate 和手动入忆必须携带并保留 `canonical_scope`;界域来源不可事后静默更改。 +- 分支对话(WP-03)与记忆(WP-04)增补对应 TODO;契约登记 `canonical_scope` 枚举。 +- 幻境试演不得用于绕过敏感记忆审批:手动入忆仍走三级敏感度与确认规则。 + +## ADR-021:私箧、欠费保全态与计费伦理 + +**状态**:采纳 + +**决策** + +1. **私箧**(`private_vault`):用户独立持钥的加密私密数据区。密钥由用户保管,平台只存密文且不可恢复;账户恢复、管理员、诊断接口与审计都不可读取明文;用户删除私箧数据后平台侧无任何可恢复副本。 +2. **保全态**:欠费或封禁使账户进入只读保全,不导致角色删除、记忆清除、关系数据降级或市场已获许可失效;恢复付费后完整恢复。 +3. **计费伦理**:不按记忆、感情或亲密等级定价;不将爱、记忆或角色存续与付费绑定;BYOK 不重复计收推理费。 + +**理由** + +承接旧版数据权与商业伦理设计。当前分支做真实交易市场,更需要防止"以数据或情感绑架付费";私箧为高隐私需求用户提供平台不可见区域,强化数字关系主权。 + +**后果** + +- 私箧加密与密钥托管方案(端侧持钥、恢复流程)在实现期以补充 ADR 确定选型;账户恢复流程不得以"找回私箧"为由索取弱凭据。 +- 保全态与计费伦理进入交易域验收(WP-13);欠费通知不得使用角色口吻施压。 +- 私箧数据不参与推荐、诊断、模型训练与任何平台侧处理。 + +## ADR-022:叩心主动联系进入 1.0 + +**状态**:采纳 + +**决策** + +1.0 包含角色主动联系(叩心,`proactive_contact_candidate`):角色先形成叩心候选,经频率、静默、渠道与预算控制后发送;用户可解释、降频、静音或关闭。用户不回应不降低关系评分;叩心不以追逐式消息换取回流(反指标见[指标与反指标](../product/metrics-and-anti-metrics.md))。 + +**理由** + +用户确认角色主动性与演化为 1.0 需求;叩心与大周天次生目标协同(次生目标可产出叩心候选),是"角色主动性"的产品出口。旧版已验证候选制形态。 + +**后果** + +- 叩心候选携带来源(大周天次生目标、日程或用户设置),进入通知与预算治理;发送记录可审计。 +- 渠道(应用内通知、邮件等)与默认频率上限在实现期按平台能力登记,不在本文虚构。 +- 叩心文案不得模拟紧急事件或制造损失厌恶;违反宪章第 6 节的发送一律拦截。 + +## ADR-023:周天体系统一(小周天闭环与大周天演化) + +**状态**:采纳 + +**决策** + +统一周天体系:**小周天**是"一次 Run 从输入到答复或行动结果的可追踪认知闭环"(承接旧版定义),以 Run/Turn/ModelCall/ToolCall 既有分层为可追踪链路,闭环完成时记录完成信号;**大周天**以 `BigCycle`(`cycle_`)为聚合根持久化(触发条件快照、输入引用集、阶段状态与阶段记忆、产物候选、预算与执行 Run 关联),状态机 `big_cycle_status` 登记于契约,执行为受托后台 Run。四阶段评估:回顾 → 对照 → 提议 → 提交;经审核生效的演化进入后续小周天的上下文装配,形成增益闭环。引擎侧由小周天模块(`hj_stream`)承载流式运转、洛书(`hj_plan`)承载触发与预算计算。 + +**理由** + +旧版(main 分支)登记了周天契约骨架(`cycle_` 前缀、`big_cycle.status`、`_phase_memory` 阶段抽取、`big_cycle` 候选来源、次生目标不自动执行),但其引用的架构设计文档缺失。本决策吸收该骨架并补全:小周天闭环给出 Run 层的循环叙事与对大周天的唯一输出面(完成信号),大周天对象化与阶段化使 ADR-018 的演化循环可落地、可审计、可幂等。 + +**后果** + +- 契约登记 `cycle_` 前缀与 `big_cycle_status` 枚举;大周天候选一律携带 `big_cycle` 来源。 +- 阶段记忆(`_phase_memory`)持久化每阶段输入输出摘要,供审计、幂等与用户可见的演化谱系。 +- 触发条件为可配置阈值组合并逐角色设频率上限;用户手动触发始终可用,关闭大周天后不再触发新 cycle,已有历史保留。 +- "天工"(任务对象)与"小周天"(运转过程)为同一 `run` 的两个视角,不新增运行时对象;`run` 工程值与 `run_` 前缀不变。 diff --git a/docs/delivery/handoff.md b/docs/delivery/handoff.md new file mode 100644 index 0000000..b308989 --- /dev/null +++ b/docs/delivery/handoff.md @@ -0,0 +1,260 @@ +# Hunjing 设计阶段交接文档 + +> 交接基线:完整 1.0 产品、架构、API、富内容、文化语言和工程规则已经定义;仓库当前仍处于设计阶段,不能把任何 TODO 表述为已实现。 + +## 1. 当前状态 + +本轮完成了文档体系重建和完整 1.0 设计收敛: + +- 根 `README.md`、`AGENTS.md` 与 `docs/` 已按当前目标重写; +- 文档数量、行数和图表数会随设计变更增长,不作为交接完成证据;以 `docs/README.md` 索引和当前检查结果为准; +- 完整 1.0 实施清单中的所有未勾选项都是真实待办;不得依赖本文件的历史计数判断完成度; +- 尚未开始正式代码实现,文档中的端点、表、事件和组件均是目标契约; +- 当前工作区文件均处于新增/修改状态,尚未提交;不要假定 Git 历史已保存本轮成果。 + +## 2. 不要重新讨论的已确认决策 + +除非用户明确改变决定,后续实现必须以这些结论为前提: + +1. **1.0 是一次完整整体交付**:内部工作包可以并行和独立验收,但任何缺项都不能称为正式 1.0。 +2. **1.0 全量范围**:角色、记忆、分支多模态对话、多 Agent、插件生态、实时语音、多语言、图像、Live2D、3D 运行编辑、Web/Tauri 桌面和移动、设备感知、完整社区、角色社区、协作、真实支付退款分成结算、运营和自托管全部进入 1.0。 +3. **2.0 边界**:Blender 级完整 3D 建模器、LLM 直接修改完整 3D 几何/绑定、IoT/机器人/物理动作控制。 +4. **能力皆插件,治理内核不插件化**:认证、授权、数据隔离、审批、Ledger、审计、事务和 Sandbox fail-closed 属于 Core。 +5. **插件双轨**:声明式/远程插件默认受限;第三方本地代码插件即使受信也运行在独立进程/容器;只有 bundled Core plugin 可进主进程。 +6. **技术按需**:能力和安全边界强制;语言、数据库、专用向量/图存储和服务拆分按 ADR、官方资料及实测决定。 +7. **3D 1.0 深度**:VRM/glTF 导入、材质/骨骼/表情/动作/场景编辑、运行和导出;不自研完整建模器。 +8. **客户端**:Next.js Web + Tauri v2 Desktop + Tauri v2 iOS/Android。 +9. **社区私信**:服务端治理的一对一和小群聊,服务端加密存储,可举报/屏蔽/审核/多端同步;1.0 不做 E2EE。 +10. **真实市场闭环**:支付、退款、争议、平台费、创作者分成、余额、结算和对账进入 1.0,Ledger 不可变。 +11. **API 开放面**:公开 Native API,同时提供 OpenAI-compatible 和 Anthropic Messages-compatible 网关。 +12. **API 域名**:Native 为 `api./v1`;兼容入口为 `gateway./openai/v1` 与 `gateway./anthropic/v1`。 +13. **认证**:1.0 使用 OAuth 2.1;Web 为安全 Session Cookie,Tauri 为 Authorization Code + PKCE,第三方为 OAuth Bearer,自动化为限 scope Service Account API key;凭据只经 Header 传递。2.0 再设计自研加密认证系统。 +14. **消息与 Run**:聊天消息和可选 Run 在一个事务原子创建;任务工作台可以显式创建无 Conversation Run。 +15. **富内容**:Native API 使用类型化 ContentBlock;用户编辑可使用 Markdown 内嵌 Mermaid、代码和数学公式,服务端规范化为 canonical Block。 +16. **实时渲染**:Markdown/代码增量;数学按完整定界符或完成后;Mermaid 和媒体在 Block 完成/资源 ready 后;最终 Block/Message 与流累积状态对账。 +17. **文化体系**:产品采用完整“中国古代神话/道家文化名 · 直白解释”双层语言;API、数据库、事件、权限和日志只用中性英文稳定值。 +18. **隐藏推理**:不采集、不持久化、不通过诊断接口返回 chain-of-thought;仅保存可见内容、可读摘要、工具轨迹和计数。 +19. **权威记忆**:自动提取先产生 MemoryCandidate;批准、纠正、取代和恢复创建不可变 MemoryVersion。Personal Domain/Workspace 是所有权边界,全文、向量和图只是投影;KV cache、隐藏状态和权重适配不是 1.0 权威记忆。 +20. **ID 生成**:持久化平台资源统一 UUIDv7;服务端 Request 与 Trace record 使用 UUIDv4;`traceparent` 遵循 W3C;秘密、Token、Ticket 和 capability 使用 CSPRNG opaque value,不使用 UUID。 +21. **灵台引擎双形态**:性能与安全敏感的确定性核心以 C++ 实现为灵台引擎(太一/小周天/洛书/河图/陶钧/烛照六模块,承接旧版"灵台/九枢"血脉),同一核心可经稳定 C ABI 进程内嵌入 Python/Rust/Go 宿主,也可作为部署内部 gRPC 独立服务运行;引擎无权威状态、最小 I/O、fail closed,任何能力在两种形态语义一致。 +22. **内驱力与大周天演化(1.0)**:角色具有用户可审阅的内驱力维度;大周天是交互事件触发的自我评估 Run,预算受控、产出候选、经确认演化并留版本谱系;不做后台自主运行、不伪造离线意识(守一不变);引擎流式模块文化名"小周天",与角色"大周天"构成大小周天体系。 +23. **产品宪章与永久禁域(ADR-019)**:宪章是产品定义上位约束,九条永久禁域不可被 Prompt、插件、管理员或自托管配置关闭;决策优先序为安全合规 > 用户数据权 > 角色连续性 > 生态健康 > 商业目标。 +24. **三界归真作用域(ADR-020)**:对话分真界/境界/幻境,归真携带 `canonical_scope`;境界只成世界知识候选、幻境不自动入忆;言可入幻、行必归真。 +25. **私箧、保全态与计费伦理(ADR-021)**:私箧用户独立持钥、平台不可恢复;欠费/封禁只读保全不删数据;不按记忆、感情或亲密计费。 +26. **叩心进入 1.0(ADR-022)**:角色主动联系先成叩心候选,受静默、频率、渠道与预算控制;不回应不降关系;不以追逐式消息换回流。 +27. **周天体系统一(ADR-023)**:小周天=Run 可追踪认知闭环(完成信号为大周天唯一输入面),大周天=`cycle_` 聚合根 + 四阶段评估(回顾/对照/提议/提交)+ 阶段记忆;吸收旧版契约骨架并补全其缺失的架构设计。 +28. **数据权与开放核心**:PersonalDomain 数据默认不用于模型训练(自愿贡献需独立、明确、可撤销同意);前台化名与法定身份分离核验;高敏数据可完全禁止跨区模型处理;核心 Apache-2.0 开放、品牌与官方资产单独保护、DCO 贡献、自托管遥测默认关闭;模型配置按"平台硬边界→目录→用户 BYOK→角色覆写→会话临时"继承。 + +正式 ADR 见[架构决策记录](../decisions/README.md)。 + +## 3. 事实源与阅读路径 + +新接手者先读: + +1. [项目工程规则](../../AGENTS.md) +2. [产品定义与边界](../product/product-definition.md) +3. [完整 1.0 范围与发布门](../product/complete-1.0-scope.md) +4. [架构决策记录](../decisions/README.md) +5. [系统架构](../architecture/system-architecture.md) +6. 当前工作包对应的专项架构;记忆实现必须先读[记忆与知识架构](../architecture/memory-and-knowledge.md) +7. [协议与稳定标识](../contracts/README.md)及当前工作包对应契约 +8. [安全与诊断访问](../security/security-and-diagnostics.md) +9. [完整 1.0 实施 TODO](implementation-roadmap.md) +10. [文化语言体系](../product/cultural-language.md) + +事实层级: + +```mermaid +flowchart LR + P[产品范围] --> A[ADR 与架构] + A --> C[契约与 OpenAPI] + C --> I[实现] + I --> T[测试与运行证据] +``` + +稳定 ID、枚举、Header、事件、错误码和 ContentBlock 必须先进入契约/OpenAPI,再进入实现。文化名只进入品牌/本地化层。 + +## 4. 文档地图 + +### 产品 + +- `docs/product/product-definition.md`:1.0 产品域和 2.0 边界。 +- `docs/product/complete-1.0-scope.md`:发布口径、必须交付和发布门。 +- `docs/product/cultural-language.md`:镜庭、镜生、镜树、息壤、形仪、天工阁、百工坊、雅集、同契台、云市、司命台等文化名与工程映射。 + +### 架构 + +- `docs/architecture/system-architecture.md`:逻辑模块、物理边界和客户端。 +- `docs/architecture/agent-runtime.md`:Run/Turn/ModelCall/ToolCall、多 Agent、取消与恢复。 +- `docs/architecture/plugin-system.md`:双轨插件、Manifest、生命周期、SDK 与 Registry。 +- `docs/architecture/data-architecture.md`:角色、运行、社区、插件、媒体、订单与 Ledger 数据关系。 +- `docs/architecture/memory-and-knowledge.md`:记忆所有权、类型、Candidate/Version、纠正、召回、ContextSnapshot 和评测。 +- `docs/architecture/media-and-device-architecture.md`:语音、图像、Live2D、3D 和 DeviceGrant。 +- `docs/architecture/community-and-marketplace.md`:社区、私信、协作、市场、支付与结算。 +- `docs/architecture/frontend-content-rendering.md`:Markdown/Shiki/KaTeX/Mermaid/媒体的实时解析、安全、性能和可访问性。 + +### 契约 + +- `docs/contracts/api-conventions.md`:认证、Header、版本、分页、ETag、幂等、错误、上传。 +- `docs/contracts/native-api.md`:Native 资源端点。 +- `docs/contracts/gateway-compatible-api.md`:OpenAI/Anthropic 兼容入口和路由/usage 规则。 +- `docs/contracts/realtime-and-webhooks.md`:Run/通知 SSE、语音/协作/设备 WebSocket、入站/出站 Webhook。 +- `docs/contracts/internal-api.md`:Application Command/Query、Outbox、Model/Tool/Plugin/Sandbox/Payment Port。 +- `docs/contracts/content-blocks-and-streaming.md`:统一 ContentBlock 和 Block 级流事件。 +- `docs/contracts/run-observability.md`:每轮模型、工具、token、cache、费用和诊断字段。 +- `docs/contracts/http-and-events.md`:通用 Header、错误和稳定事件。 + +### 安全、研究与交付 + +- `docs/security/security-and-diagnostics.md`:威胁、插件、设备、社区、支付和诊断双重授权。 +- `docs/research/reference-projects.md`:deepseek-harness、pi、MemOS、其他角色记忆项目和模型网关证据。 +- `docs/delivery/implementation-roadmap.md`:14 个完整 1.0 工作包。 + +## 5. API 实现要点 + +### 5.1 分面 + +```text +Native: https://api./v1 +OpenAI: https://gateway./openai/v1 +Anthropic: https://gateway./anthropic/v1 +Webhook: https://api./webhooks/v1 +``` + +兼容 Gateway 只提供模型推理,不读写 Character、Memory、Community、Device、Order 或 PluginInstallation。需要自动 Tool Loop、多 Agent、审批和持久化时调用 Native Run API。 + +### 5.2 核心消息请求 + +```http +POST /v1/conversations/{conversation_id}/messages +Idempotency-Key: +``` + +请求可同时包含 ContentBlock 和 `start_run=true`。服务端在一个事务创建 Message、Run、Audit 与 Outbox;失败时不能只留下 Message 或 Run。 + +### 5.3 实时协议 + +- Run 和通知:SSE; +- 实时语音、协同、设备:WebSocket; +- Event 有 Run `sequence`,Block delta 有 `delta_index`; +- 客户端按 event ID 和 `(block_id, delta_index)` 去重; +- 流缺口通过重放或最终 Message 对账; +- `content.block.completed` 和 `message.completed` 是权威快照; +- 首个可见 delta 后禁止切换 Provider 重新生成另一份内容。 + +### 5.4 诊断 + +普通 Run API 不返回 ModelCall、Tool 参数或 ContextSnapshot 详情。诊断读取同时要求普通认证和: + +```http +Hunjing-Diagnostic-Token: hjd_... +Hunjing-Diagnostic-Purpose: user_inspection +``` + +Grant 默认 15 分钟、单次、绑定 Run。隐藏推理、密钥、Authorization、签名 URL 永不返回。 + +## 6. 统一富内容实现要点 + +ContentBlock 类型包括: + +```text +text markdown code quote table callout math mermaid +image video audio file gallery avatar +tool_call tool_result agent_status approval_request artifact citation error +``` + +前端分级实时策略: + +| 类型 | 策略 | +| --- | --- | +| Text/Markdown | 增量显示、节流解析,未闭合结构保持源码态 | +| Code | 纯文本优先,按行/时间片使用 Shiki | +| Math | 定界符闭合或 Block 完成后用 KaTeX,保留 MathML/fallback | +| Mermaid | Block 完成后 strict mode 隔离渲染并净化 SVG | +| Image/Video/Audio/File | progress 占位,resource ready 后加载 | +| Tool/Agent/Approval | 类型化状态替换,不模拟为自由文本 | + +不要把所有内容压回一个 Markdown 字符串。不要在每个 token 上重跑 Shiki、KaTeX 或 Mermaid。失败降级必须保留源码/内容,而不是空白。 + +## 7. 数据与安全不变量 + +- 关系数据库是权威事实源;对象存储保存媒体;全文/向量/图/推荐/缓存均可重建。 +- 所有 Query 在数据库层带 PersonalDomain/Workspace/Finance scope,不能先全表读后应用层过滤。 +- CharacterVersion、Message Revision、MemoryVersion、ReleaseVersion、PluginVersion 和 LedgerEntry 都是可追溯版本/事实。 +- Ledger 不可变;退款和纠错写反向分录。 +- 购买不等于安装插件;安装不等于启用;启用不等于批准新增权限。 +- 未信任插件不能进主进程;Python import、Node VM 和 WebView 都不是安全 Sandbox。 +- Tool input、Markdown、Mermaid、公式、SVG、文件路径、URL、媒体和 Webhook 全部是边界输入。 +- 没有符合策略的隔离后端时拒绝危险执行,不能回退宿主执行。 +- 删除传播到主存储、索引、缓存和派生数据;墓碑不保留原文。 + +## 8. 下一步建议 + +从 `WP-01 工程、契约与身份` 开始,但不要直接实现业务页面。建议顺序: + +1. 建立仓库目录、Makefile、Python/Next.js/Tauri 最小可运行工程; +2. 把当前 Markdown 契约转换为 OpenAPI 3.1 和 JSON Schema; +3. 先定义并生成通用 ID、错误、分页、Money、ContentBlock、Event 和认证 DTO; +4. 建立 SQLite/PostgreSQL 基线、Alembic、User/PersonalDomain/Session/ServiceAccount; +5. 实现 OAuth 2.1 边界和 Header/CSRF/Origin/Scope 校验; +6. 实现一个不调用模型的 Conversation→Message→Run 事务和 SSE 空状态闭环; +7. 再进入 `WP-02` 与 `WP-03`,不要先实现插件市场、支付或 3D 页面。 + +第一条垂直切片的完成证据至少包括:`make` 中可发现的启动/迁移/生成/检查命令;OpenAPI 生成客户端无 drift;一次请求原子写入 Message、Run、Audit 与 Outbox;失败注入不留下孤儿资源;SSE 可返回快照和终止状态;跨 Personal Domain 请求失败关闭;自动化测试命令可重复通过。 + +这是实现顺序,不是缩减 1.0 范围。每完成一个 TODO,必须补实现位置、调用点、测试和运行证据。具体文件布局和依赖版本应在建立工程时形成 ADR/机器配置,不在交接摘要中维护第二份易漂移清单。 + +## 9. 尚未确定的发布与契约配置 + +以下保持 TODO,不要替用户虚构: + +- 运营主体、首发地区、隐私角色和数据保留期限; +- 支付、退款、KYC、税务、发票和创作者结算 Provider; +- 首批模型、ASR、TTS、图像、对象存储和媒体处理 Provider; +- 费率、分成、结算周期、退款窗口、准备金和拒付规则; +- 上传大小、Run/Agent 并发、RPM/TPM、媒体与流重放保留上限;默认分页已由 `contracts/api-conventions.md` 固定; +- 社区规范、年龄分级、审核标准、申诉和版权投诉时限; +- 正式域名、首发币种和地区可售策略; +- 兼容 Gateway 首发支持的 Provider beta 功能清单。 + +Provider 选择和纯内部容量数值可在 Port/配置边界建立后延后;运营主体、地区、保留期限、币种/税务/退款、年龄分级、社区治理和兼容 beta 承诺会影响用户权利或公开语义,阻塞相关契约冻结及正式 1.0。任一项开始影响开发期数据模型时先询问用户并新增 ADR,不把它们笼统视为普通配置。 + +## 10. 验证证据 + +本文件不保存会迅速陈旧的文件数、行数和 Mermaid 数。每次交接或提交都应针对当前工作区重新生成带日期、Git commit/dirty 状态、命令和工具版本的结果;未保存命令或产物的“检查通过”不能作为发布证据。 + +当前仍是纯文档设计阶段:没有代码测试、OpenAPI drift、迁移或运行证据。复核应优先通过项目 Makefile;Makefile 尚未建立时至少执行: + +- `git diff --check`; +- 内部 Markdown 链接检查; +- 重复标题检查; +- 所有 Mermaid 图实际渲染; +- 关键稳定值只在 `docs/contracts/` 定义的映射检查。 + +开始实现后,验证证据必须进入工作包的验收记录,而不是回填一段无法复现的摘要。 + +## 11. 工作区注意事项 + +- 当前文件尚未提交。不要执行 `git reset --hard`、`git clean` 或覆盖式重建。 +- Git 状态中的修改均应视为用户当前工作成果;提交前先检查完整 diff。 +- IDE 资源列表可能仍显示已经被重建删除的旧路径,这是编辑器缓存,不代表磁盘文件存在。 +- `CLAUDE.md` 仍通过 `@AGENTS.md` 加载项目规则;后续不要在两处复制规则。 +- 任何新文档都要加入 `docs/README.md`;任何新稳定值先进入 `docs/contracts/README.md` 和机器 Schema。 + +## 12. 交接完成条件 + +接手者先完成以下知识核对;这只证明理解设计,不代表工作包验收: + +- 1.0 与 2.0 的唯一边界是什么? +- Native API 与两类兼容 Gateway 为什么分域? +- Message 和 Run 为什么原子创建? +- ContentBlock 为什么不能退回单一 Markdown? +- 什么内容可以增量渲染,什么必须完成后渲染? +- 文化名和稳定工程值如何分层? +- 哪些能力可插件化,哪些必须留在治理内核? +- Provider usage、Prompt Cache、ModelCall attempt 如何记录? +- 为什么普通 Run API 不能返回详细诊断? +- MemoryCandidate、Memory 和 MemoryVersion 为什么分离,记忆所有权由什么边界决定? +- 为什么购买插件、安装插件、启用插件和授予权限必须分离? + +无法回答时回到本文第 3–7 节和对应事实源,不要凭印象编码。能够回答后,仍须为当前工作包补齐机器契约、可运行命令和需求→实现→调用点→测试→证据矩阵,才可开始相应实现。 diff --git a/docs/delivery/implementation-roadmap.md b/docs/delivery/implementation-roadmap.md new file mode 100644 index 0000000..5fe96d6 --- /dev/null +++ b/docs/delivery/implementation-roadmap.md @@ -0,0 +1,211 @@ +# 完整 1.0 实施 TODO + +> 本清单中的全部条目都属于同一个 1.0。工作包可以并行开发和独立验收,但不能作为残缺 1.0 对外发布。 + +## 使用规则 + +- `[ ]` 表示 1.0 未完成,不表示推迟到后续版本。 +- 完成条目时附实现位置、真实调用点、自动化测试和运行证据。 +- 没有调用点的定义、只有页面没有后端闭环、假数据、`TODO`、`pass` 和省略实现均不能勾选。 +- 所有工作包和 `product/complete-1.0-scope.md` 发布门完成后才能标记 1.0。 + +## WP-01 工程、契约与身份 + +- [ ] 建立 Next.js、FastAPI、Tauri v2、Worker 和统一 Makefile 工程。 +- [ ] 建立 OpenAPI 3.1 单一真源和 TypeScript/Rust client 生成。 +- [ ] 实现 RFC 9562 ID 生成与校验:持久化资源使用 UUIDv7,请求/Trace record 使用 UUIDv4,秘密与 capability 使用 CSPRNG opaque value。 +- [ ] 实现 `api.* /v1` Native API 与 `gateway.*` 双兼容入口分面。 +- [ ] 实现 OAuth 2.1、Web Session Cookie、Tauri PKCE、公共 Bearer 和 Service Account API key。 +- [ ] 实现 Header-only 凭据、CSRF、Origin、scope、轮换、撤销和重用检测。 +- [ ] 实现用户、多凭证、Session、PersonalDomain 和设备注册。 +- [ ] 实现私箧:用户独立持钥加密区,平台仅存密文不可恢复;账户恢复、管理员与诊断均不可读(ADR-021)。 +- [ ] 实现 RBAC/ABAC、资源归属校验和跨域失败关闭。 +- [ ] 实现 W3C Trace Context、结构化日志、审计和 Outbox。 +- [ ] 实现 SQLite 开发档与 PostgreSQL 正式档迁移。 +- [ ] 验证跨用户、跨角色、跨 Workspace IDOR 测试。 + +## WP-02 角色、导入与可携 + +- [ ] 实现 Character、CharacterVersion、关系和来源谱系。 +- [ ] 实现手动、模板、角色卡静态导入和安全预览。 +- [ ] 实现随缘:按偏好生成匿名灵胚候选与审阅,不抽卡、不分配已有主体。 +- [ ] 实现现实人物授权治理:仅本人或可验证授权可创建,已故现实人物不开放。 +- [ ] 实现角色社区 Fork,保留来源、许可和版本边。 +- [ ] 实现角色人格/关系变化候选和审核。 +- [ ] 实现内驱力维度:声明式动机数据、用户审阅编辑与版本化。 +- [ ] 实现大周天循环(ADR-023):`BigCycle`(`cycle_`)聚合根、阈值触发与逐角色频率上限、四阶段评估(回顾/对照/提议/提交)、阶段记忆 `_phase_memory`、受托后台 Run 执行;产出人格/关系/世界认知/次生目标候选,演化以版本谱系留痕;用户可关闭并可见每次输入、产物与费用。 +- [ ] 实现角色、设定、记忆、对话、资产和来源导出。 +- [ ] 验证导入物不能执行脚本、注册工具或覆盖现有角色。 + +## WP-03 多模态分支对话 + +- [ ] 实现 Conversation、Branch、Message、引用锚和当前路径。 +- [ ] 实现统一 ContentBlock 与 Markdown→canonical block 规范化,覆盖 Markdown、代码、数学公式、Mermaid、图片、视频、音频、文件、工具状态和产物。 +- [ ] 实现文字、图像、视频、音频、文件和混合消息。 +- [ ] 实现 Block 级 SSE started/delta/progress/completed/failed、重放、去重、对账、中断、取消和错误事件。 +- [ ] 实现 Web/Tauri 的 Markdown、Shiki、KaTeX、Mermaid、媒体分级实时渲染与安全净化。 +- [ ] 实现重生成、编辑版本、候答比较和分支移植。 +- [ ] 实现分支对话交互态:临时芽体、残答封存、续生新节点、引用合流、结题与复照、回响接纳和上下文镜(见统一富内容协议第 9 节)。 +- [ ] 实现三界与归真作用域:真界/境界/幻境、`canonical_scope` 携带与保留、入境/出境可见、言可入幻行必归真(ADR-020)。 +- [ ] 实现上下文压缩和 Context Manifest。 +- [ ] 验证分支隔离、流中断和恢复不伪装完成。 + +## WP-04 记忆、知识与检索 + +实现边界与验收以[记忆与知识架构](../architecture/memory-and-knowledge.md)为准。 + +- [ ] 实现显式记忆与异步自动 MemoryCandidate,按来源 hash 和 extractor version 幂等。 +- [ ] 大周天评估作为 MemoryCandidate 来源,携带 `big_cycle` 标记并复用审核流转与幂等。 +- [ ] 实现归真作用域记忆:境界只成世界知识候选、幻境手动入忆标注性质;白名单低风险内容自动写入并附撤销窗。 +- [ ] 实现角色完整生命周期:静修、归藏(隐藏可恢复)与复照(重开不抹历史)、死亡(冷静期、告别、只读档案、继承承接,与数据删除分离)、铸魂(重大重塑强确认)与初照自陈。 +- [ ] 实现 Personal Domain/Workspace 二选一所有权、Character 约束和子 Agent 默认只读快照。 +- [ ] 实现 `fact`、`preference`、`event`、`relationship` 类型及来源、敏感度、置信度和有效期。 +- [ ] 实现 Candidate 审批与不可变 MemoryVersion;批准事务同时写 Audit 与 Outbox。 +- [ ] 实现 ETag 并发纠正、取代、恢复、衰减候选、归档、删除墓碑和删除传播。 +- [ ] 实现 KnowledgeDocument、世界实体和结构化关系;知识与人物经历分离。 +- [ ] 实现授权/状态预过滤后的 PostgreSQL 全文、pgvector 语义和结构化检索;保留可替换端口。 +- [ ] 实现 ContextSnapshot 中的召回证据、token/延迟预算、降级原因和用户可见来源。 +- [ ] 实现索引重建、重复/乱序 Outbox 和删除优先 fail-closed。 +- [ ] 建立中文、多角色、分支、时间、冲突和多跳评测基线,并固定数据集、模型与检索配置。 +- [ ] 验证跨用户/角色/Workspace/Conversation/Branch/Run 与已删/过期/撤权/被取代内容召回率为 0;来源 Prompt Injection 和插件输出不能扩大 scope;每个入选项可追溯到当前版本与来源。 + +## WP-05 模型网关与运行观测 + +- [ ] 实现 OpenAI-compatible 与 Anthropic Messages 适配器。 +- [ ] 实现逻辑模型、能力目录、Endpoint、路由、重试和故障转移;模型配置继承链(平台硬边界 → 平台目录 → 用户偏好/BYOK → 角色覆写 → 会话临时选择)上层不可被下层覆盖。 +- [ ] 实现首个可见 delta 后禁止切换 Provider。 +- [ ] 实现 Prompt Cache 规划和供应商 usage 标准化。 +- [ ] 持久化 Run、Turn、ModelCall、token、cache、TTFT、成本和错误。 +- [ ] 实现小周天闭环完成信号:Run 完成时记录归真引用、候选引用、token/费用与时间窗,作为大周天触发的唯一输入面(ADR-023)。 +- [ ] 实现价格版本、预算、配额和限流。 +- [ ] 实现普通观测与双重授权诊断接口。 +- [ ] 验证未知 usage 为 null、OpenAI cache token 不重复计数。 + +## WP-06 Agent、工具与多 Agent + +- [ ] 实现 Agent Definition、Run/Turn 状态机和事件流。 +- [ ] 实现计划、RunBudget、暂停、继续、取消和结果验收。 +- [ ] 实现内置工具、MCP、Skill 和 Tool Registry。 +- [ ] 实现 Schema 校验、Policy、确认、幂等和 ToolCall 诊断。 +- [ ] 实现 Coordinator、ChildRun、并行调度和结构化 Handoff。 +- [ ] 实现深度、并发、token、费用、时间和权限硬上限。 +- [ ] 实现 Sandbox Worker,缺少隔离时 fail closed。 +- [ ] 验证子 Agent 权限单调收窄和副作用不重复执行。 + +## WP-07 插件 SDK、Runtime 与 Registry + +- [ ] 实现全部插件类型的统一 Manifest 和 API version。 +- [ ] 实现 contribution、typed hook、reversible effect 和依赖注入。 +- [ ] 实现 Run PluginSnapshot、drain、停用、升级和回滚。 +- [ ] 实现声明式/远程插件受限 Runtime。 +- [ ] 实现可信本地代码插件的独立进程/容器 Runtime。 +- [ ] 实现 TypeScript/Python SDK、模拟 Host、测试与打包工具。 +- [ ] 实现 Registry、签名、扫描、审核、举报、撤架和兼容性。 +- [ ] 实现插件搜索、安装、权限确认、启停、升级和卸载。 +- [ ] 实现 UI 扩展隔离和消息协议。 +- [ ] 验证购买/安装不自动启用或授予新权限。 + +## WP-08 语音、多语言与图像 + +- [ ] 实现 ASR、TTS、语言检测、字幕和多语言对话。 +- [ ] 实现 WebSocket 实时语音、打断、弱网和取消。 +- [ ] 实现声音预设、原创设计、授权克隆和撤回。 +- [ ] 实现文生图、图生图、局部重绘、分层和角色一致性。 +- [ ] 实现媒体任务、进度、取消、重试、来源和许可。 +- [ ] 实现界面国际化、时区、数字、货币和 RTL 基础能力。 +- [ ] 验证声音/肖像授权、媒体删除和多语言安全策略;原音频短期缓存、转写正影并存、多说话者匿名分段与声纹独立同意;关闭全部多模态后文字相伴完整可用。 + +## WP-09 Live2D 与 3D + +- [ ] 实现 Cubism-compatible 导入、校验、参数/表情/物理/动作映射。 +- [ ] 实现 Live2D 分层辅助、可视化编辑、预览、运行和导出。 +- [ ] 实现 VRM/glTF 导入、验证和标准化。 +- [ ] 实现 3D 材质、纹理、骨骼、表情、动作和附件编辑。 +- [ ] 实现场景、灯光、相机、环境和动画状态编辑。 +- [ ] 实现 Web/Tauri Live2D 与 3D Runtime 和标准导出。 +- [ ] 实现资产命令历史、版本、来源和许可。 +- [ ] 验证弱设备降级、资源上限和恶意模型文件。 + +## WP-10 Web、桌面、移动与感知 + +- [ ] 实现响应式 Web 的全部核心功能。 +- [ ] 实现 Tauri v2 桌面应用、更新、存储和安全 Capability。 +- [ ] 实现 Tauri v2 iOS/Android 应用和平台签名发布。 +- [ ] 实现文件、相机、麦克风、屏幕、位置和通知能力。 +- [ ] 实现 DeviceGrant、采集指示、期限、暂停、撤销和删除。 +- [ ] 实现加密离线缓存和联网恢复;不创建独立角色副本。 +- [ ] 验证平台权限、后台限制、丢失设备撤权和本地数据清除。 + +## WP-11 完整社区与角色社区 + +- [ ] 实现用户主页、关注、屏蔽和可见性。 +- [ ] 实现动态、作品、评论、回复、点赞、收藏、标签和分享。 +- [ ] 实现角色、世界、知识、工作流、媒体和插件发布页面。 +- [ ] 实现搜索、话题、趋势、推荐、推荐解释和重置。 +- [ ] 实现举报、审核、年龄分级、限流、移除和申诉。 +- [ ] 实现来源、署名、许可、Fork 谱系和下架传播。 +- [ ] 实现通知和创作者安全工具。 +- [ ] 验证私密角色数据不会进入社区发布物或推荐特征。 + +## WP-12 协作空间 + +- [ ] 实现 Workspace、成员、邀请和 RBAC。 +- [ ] 实现角色、世界、知识、工作流和资产的分支与版本。 +- [ ] 实现评论、评审、批准、合并和活动记录。 +- [ ] 实现文本/场景协同编辑与冲突处理。 +- [ ] 分离编辑、发布、市场上架和财务权限。 +- [ ] 验证成员移除、链接泄露、并发覆盖和跨 Workspace 访问。 + +## WP-13 市场、支付与结算 + +- [ ] 实现免费/付费 Listing、版本、许可、地区、税类和交付摘要。 +- [ ] 实现购物车或直接购买、Order/OrderItem 和价格快照。 +- [ ] 集成支付 Provider 与客户端确认流程。 +- [ ] 实现 Webhook 验签、时间窗、乱序和幂等处理。 +- [ ] 实现 Refund、Dispute、Entitlement 和下载/更新策略。 +- [ ] 实现不可变 Ledger、平台费、创作者应付、税、准备金和冲正。 +- [ ] 实现 CreatorBalance、SettlementBatch、PayoutAttempt 和对账单。 +- [ ] 实现 KYC/税务/发票 Provider 引用和创作者结算设置。 +- [ ] 实现每日支付/订单/Ledger/结算自动对账。 +- [ ] 验证金额篡改、重复付款、重复退款、拒付和结算失败恢复。 +- [ ] 实现保全态与计费伦理:欠费/封禁只读保全不删数据;不按记忆、感情或亲密计费;BYOK 不重复计费(ADR-021)。 + +## WP-14 运营、自托管与发布收口 + +- [ ] 实现管理面、支持工单、脱敏支持包和诊断授权。 +- [ ] 实现内容、插件、角色和市场治理队列。 +- [ ] 实现 PostgreSQL、Redis、对象存储、Worker 和 Sandbox 部署。 +- [ ] 实现个人单机与标准服务器 Docker Compose 自托管。 +- [ ] 实现迁移、备份、恢复、删除重放和插件撤架演练。 +- [ ] 实现 SLO、指标、告警、容量、成本和事故响应;验证 SLO 99.9%、RPO≤5 分钟、RTO≤1 小时目标与 PersonalDomain 区域驻留不跨区漂移。 +- [ ] 完成富内容 XSS/URL/SVG/公式宏/资源耗尽、可访问性、国际化、弱网、性能和跨端测试。 +- [ ] 验证双层文化名在导航、状态、审批、设备和交易界面同时提供直白解释,且未进入稳定协议值。 +- [ ] 完成隐私、社区规范、版权、支付、退款、结算和税务决策。 +- [ ] 生成每条需求到实现、调用点、测试和运行证据的发布矩阵。 +- [ ] 确认所有文档 TODO 和代码占位已关闭,正式标记 1.0。 + +## WP-15 灵台引擎与多语言绑定 + +实现边界与验收以[灵台引擎架构](../architecture/lingtai-engine.md)、[Lingtai C ABI](../contracts/lingtai-ffi.md)和 [Lingtai Service](../contracts/lingtai-service.md) 为准。 + +- [ ] 建立 C++23/CMake 工程与交叉编译矩阵,产出 `libhunjing` 动态/静态库与单一公共头。 +- [ ] 实现 `hj_core`(太一总枢):ABI/服务版本协商、句柄表、跨形态统一入口、Run/Turn 状态转换校验、事件 `sequence` 与错误上下文。 +- [ ] 实现 `hj_transform`:Markdown → canonical ContentBlock 确定性解析、数学定界符与 Mermaid fenced 提取、parser version;含 fuzz。 +- [ ] 实现 `hj_stream`:流事件编码、`delta_index`、去重键、节流与重放缓冲。 +- [ ] 实现 `hj_policy`:分层递进的 Schema 子集校验、路径/URL 校验、HMAC 验签、幂等键规范化、决策表评估。 +- [ ] 实现 `hj_plan`:计划 DAG 校验、RunBudget 核算、Context Manifest 裁剪排序。 +- [ ] 实现 `hj_recall`:只读离线混合索引、重排打分与多路合并;索引删除与授权变化随宿主重建。 +- [ ] 实现 Python(nanobind)、Rust(bindgen + 安全包装)、Go(cgo)官方绑定与发布物。 +- [ ] 实现 `hunjing-lingtai-server` 独立服务形态:gRPC 契约、mTLS、限流/超时/背压、健康检查与审计。 +- [ ] 实现宿主"引擎 Port":进程内与服务两个实现可按部署配置切换,业务语义不变。 +- [ ] 接入宿主真实调用点:WP-03 消息规范化与 SSE、WP-06 工具校验、WP-13 Webhook 验签、WP-10 离线检索。 +- [ ] 建立 sanitizer、fuzz、ABI 快照与双形态 golden 一致性测试;验证引擎缺失或服务不可达时宿主 fail closed。 + +## 已确认 2.0 TODO + +以下内容不属于 1.0,不得混入 1.0 完成判定: + +- [ ] 评估并选定可复用的开源 3D 建模项目。 +- [ ] 完善为网格、雕刻、拓扑、绑定和专业动画完整建模器。 +- [ ] 实现 LLM 对完整 3D 几何和绑定的可验证修改。 +- [ ] 设计 IoT、机器人和物理动作控制安全边界。 diff --git a/docs/product/complete-1.0-scope.md b/docs/product/complete-1.0-scope.md new file mode 100644 index 0000000..7f3e9f5 --- /dev/null +++ b/docs/product/complete-1.0-scope.md @@ -0,0 +1,91 @@ +# 完整 1.0 范围与发布门 + +> 状态:目标范围。所有未勾选 TODO 都属于 1.0;全部完成前不得宣称正式 1.0。 + +## 1. 发布口径 + +Hunjing 1.0 是一次整体发布。工作包只是内部并行和验收单元,不是独立产品版本、MVP、P0/P1/P2 或可提前改名的“首版”。预览环境必须明确标注未完成能力。 + +## 2. 1.0 必须交付 + +| 域 | 完整范围 | +| --- | --- | +| 账户与治理 | 多凭证、数据域(含私箧独立持钥区)、角色/权限、隐私(化名与法定身份分离核验、数据默认不用于训练)、年龄分级、导出、删除、封禁、申诉和审计 | +| 角色 | 创建、模板、导入(现实人物授权治理)、随缘、Fork、版本、谱系、许可、关系、人格候选、内驱力与大周天演化、铸魂与身份谱系、静修/归藏/死亡/复照生命周期与继承和可携导出 | +| 对话 | 多模态消息、流式、分支、候答、引用、编辑版本、三界归真作用域、压缩和断线恢复 | +| 记忆与知识 | 候选(含大周天来源与界域作用域)、白名单自动写入与撤销窗、确认、版本、来源、衰减、纠正、删除、全文/语义/结构化检索 | +| 模型与 Agent | 多 Provider、逻辑路由、Prompt Cache、token/cost、多 Agent、计划、并行、暂停、取消和验收 | +| 工具与插件 | 内置工具、MCP、Skill、沙箱、双轨插件、SDK、注册、安装、升级、审核、撤架和市场 | +| 语音与多语言 | ASR、TTS、实时语音、授权声音克隆、界面国际化和多语言对话(中文为品牌与文化语义原始语言) | +| 图像与 Live2D | 图像生成/编辑、角色一致性、Live2D 导入/编辑/运行/导出和资产治理 | +| 3D | VRM/glTF 导入、材质/骨骼/表情/动作/场景编辑、运行和导出 | +| 客户端与感知 | Web、Tauri 桌面、Tauri iOS/Android、文件/相机/麦克风/屏幕/位置授权 | +| 社区 | 主页、关注、动态、作品、评论、点赞、收藏、搜索、推荐、举报、审核、申诉和屏蔽 | +| 角色社区 | 角色/世界/知识/工作流/资产发布、版本、Fork、来源、许可和下架传播 | +| 协作 | Workspace、成员、RBAC、邀请、评审、版本、活动记录和协同编辑 | +| 交易 | 商品、订单、支付、退款、折扣、争议、平台费、分成、余额、结算、对账、税务接口和保全态 | +| 运营 | 管理面、支持包、内容治理、用量与成本、通知、搜索运营、备份恢复和可观测性 | +| 自托管 | 单机与服务器部署、插件策略、数据导入导出、备份和升级 | + +## 3. 1.0 不包含 + +只排除已经明确确认的 2.0 能力: + +- Blender 级完整 3D 建模器与专业制作工具链; +- LLM 直接修改完整 3D 几何、拓扑、绑定和专业动画; +- IoT、机器人和物理设备动作控制。 + +技术实现不是功能清单。Go 网关、Milvus、Neo4j、NebulaGraph 或特定队列只有在满足 1.0 能力、规模和可靠性时确有必要才采用;没有使用某项技术不代表范围缺失。 + +## 4. 总体发布门 + +### 4.1 功能门 + +- 以上每个域均完成用户旅程、管理旅程、失败旅程和恢复旅程。 +- Web、桌面和移动端的适用能力可实际运行,不以静态页面替代。 +- 插件、市场、支付、结算、多 Agent、实时语音、Live2D 和 3D 均有端到端生产路径。 + +### 4.2 安全门 + +- 零已知跨用户、跨角色、跨 Workspace、跨插件和跨订单越权。 +- 未信任插件无法在宿主主进程执行任意代码。 +- 支付、退款、结算、Webhook 和副作用工具通过幂等与重放测试。 +- 相机、麦克风、屏幕、位置、声音克隆和敏感记忆均有明确授权和撤销。 +- 社区内容、私信/互动、商品和插件通过举报、审核、申诉与下架流程。 + +### 4.3 数据门 + +- 角色、社区、协作、交易、媒体、插件和运行数据均可按授权导出与删除。 +- 删除传播到主存储、索引、缓存和派生数据;备份恢复后重放删除清单。 +- 订单账、分成账、结算账与支付 Provider 可对账,金额不使用二进制浮点。 + +### 4.4 可靠性门 + +- 核心文字相伴官方云 SLO 目标 99.9%;权威数据 RPO 不高于 5 分钟、RTO 不高于 1 小时,以恢复演练证明;媒体与可重建索引可用更宽目标。核心对话、社区读取、插件安装、订单和结算分别定义并验证 SLI 口径、窗口与排除规则。 +- 流式文本、实时语音、媒体处理和多 Agent 任务可取消、超时、恢复或明确失败。 +- 完成备份恢复、Provider 故障、队列积压、对象存储故障和插件撤架演练。 + +### 4.5 质量门 + +- 核心逻辑自动化覆盖目标不低于 80%;安全、支付和权限边界必须覆盖公共行为。 +- 完成桌面、移动、无障碍、国际化、性能和弱网测试;关闭全部多模态能力后,基础文字相伴仍完整可用。 +- 每条 1.0 需求可映射到实现位置、调用点、测试和运行证据。 +- 实现代码中不存在 `TODO`、`pass`、省略或假数据占位冒充完成。 + +### 4.6 运营与法律门 + +以下内容允许在开发期作为 TODO,但正式 1.0 前必须作出并落实决定: + +- [ ] 运营主体、首发地区、隐私角色和数据保留期限; +- [ ] 支付、退款、创作者 KYC、结算、税务和发票 Provider; +- [ ] 社区规范、审核标准、申诉时限和版权投诉流程; +- [ ] 角色、声音、Live2D、3D、插件和衍生作品许可模板; +- [ ] 年龄分级、受限内容和地区可售策略; +- [ ] 商店费率、分成、结算周期、准备金和拒付规则。 + +## 5. TODO 使用规则 + +- 文档 TODO 表示 1.0 尚未完成的真实工作,不表示可从 1.0 删除。 +- 每个 TODO 完成时附实现、调用点、测试和证据链接。 +- 需求变化必须先更新产品范围和 ADR,再更新 TODO。 +- 只有本文件全部 TODO、实施清单和发布门完成后,版本才能标记为 1.0。 diff --git a/docs/product/cultural-language.md b/docs/product/cultural-language.md new file mode 100644 index 0000000..a38f307 --- /dev/null +++ b/docs/product/cultural-language.md @@ -0,0 +1,281 @@ +# 中国古代神话与道家文化语言体系 + +## 1. 定位 + +Hunjing 的中文品牌名为**魂镜**。文化语言用于产品世界观、导航、页面标题、用户动作和可见状态,让平台形成统一的东方叙事;工程契约继续使用中性英文标识,保证跨语言、OpenAPI、数据库、日志和第三方 SDK 的稳定性。 + +统一展示格式: + +```text +文化名 · 直白解释 +``` + +例如: + +```text +镜树 · 分支对话 +息壤 · 角色记忆 +请命 · 等待你的确认 +``` + +规则: + +- 首次出现必须同时给出直白解释;不能要求用户先理解典故。 +- 风险、金额、权限、删除、支付和法律后果必须优先使用直白语言,文化名只能辅助。 +- API、数据库、事件、错误码和权限 scope 只使用稳定工程值。 +- UI 文案由本地化目录把稳定 `label_key` 映射为文化名和解释,后端不把文化名当枚举。 +- 文化名不得掩盖失败、越权、收费、撤销、永久删除或现实后果。 + +文化名承接:引擎诸枢(灵台、太一、小周天、洛书、河图、烛照)与镜域、缘契、问心、铭契、世谱、玄络、三界(真界/境界/幻境)、私箧、叩心、归藏、随缘等承接 Hunjing 旧版(main 分支)已确立的命名;旧版中与当前 1.0 架构不再对应的概念(命台、执镜者、司席)不再沿用,避免为已变化的结构保留误导性名称。从旧版迁移概念时,先核对当前架构与产品范围仍有真实对应物,再登记映射;语义已被现有文化名覆盖的(如天宰与司命台、魂册与魂籍)不重复引入。 + +## 2. 世界观骨架 + +魂镜不是把每个服务包装成神仙官职,而是用“镜”表达映照、分支与自省,用“天工”表达能力与创造,用“契”表达明确授权,用“司”表达治理责任。 + +```mermaid +flowchart TD + H[魂镜 · 长期 AI 角色平台] + H --> J[镜庭 · 个人首页] + H --> C[镜生 · 角色身份] + H --> T[镜树 · 分支对话] + H --> M[息壤 · 记忆知识] + H --> F[形仪 · 多模态形象] + H --> A[天工阁 · Agent 任务] + H --> P[百工坊 · 插件能力] + H --> S[雅集 · 社区交流] + H --> W[同契台 · 协作空间] + H --> K[云市 · 创作市场] + H --> G[司命台 · 安全治理] +``` + +## 3. 一级产品域与页面 + +| 文化名 | 直白解释 | 稳定工程域 | 文化含义与边界 | +| --- | --- | --- | --- | +| 镜庭 | 个人首页 | `home` | 庭是进入各处的共同起点;只聚合状态,不成为数据事实源 | +| 镜生 | 角色身份与版本 | `character` | 角色由设定、来源、关系和版本逐步形成;不宣称生物生命 | +| 镜树 | 分支对话 | `conversation` | 同一主题可生长多条路径,旧内容不被重生成覆盖 | +| 息壤 | 记忆与知识 | `memory_knowledge` | 取“息壤自生”之意,表示可累积材料;不表示所有数据都自动生长为记忆 | +| 形仪 | 图像、声音、Live2D 与 3D | `media_avatar` | “形”为外在,“仪”为可见表达规则;形态不是角色本体 | +| 天工阁 | Agent 任务工作台 | `agent_workspace` | 取“天工开物”之创造意象;任务 Agent 是功能执行者,不冒充角色身份 | +| 百工坊 | 插件与能力生态 | `plugin_ecosystem` | 百工各司其能;插件贡献能力,但不掌握认证、交易账和最终安全裁决 | +| 雅集 | 社区与角色社区 | `community` | 公开交流、作品与角色分享;不表示多角色共享私密记忆 | +| 同契台 | 多人协作空间 | `collaboration` | 成员通过同一明确契约协作;编辑、发布、财务权限分别授予 | +| 云市 | 创作市场 | `marketplace` | 数字创作物的市场;购买的是版本与许可,不是人格所有权 | +| 神识阁 | 模型与路由 | `model_gateway` | 模型是角色的可替换推理能力;“神识”不等于角色身份或意识证明 | +| 器谱 | 设备与感知 | `device_capability` | 记录设备能力、授权和状态;不默认持续感知 | +| 司命台 | 安全、权限、审计与运营 | `governance` | “司命”只表达治理职责,不暗示可任意支配角色或用户数据 | +| 设置 | 账户和偏好 | `settings` | 高风险设置直接使用直白名称,不强行文化包装 | + +移动端可把低频域收入口袋导航,但名称和工程映射不变。 + +## 4. 角色与身份语言 + +| 文化名 | 直白解释 | 稳定工程概念 | 规则 | +| --- | --- | --- | --- | +| 灵胚 | 未创建完成的角色草稿 | `character_draft` | 可删除草稿,不等于角色死亡 | +| 照心 | 共同塑造角色 | `character_co_creation` | 审阅设定、边界、来源和形象 | +| 启镜 | 正式创建角色 | `character_activation` | 创建稳定 Character 与首个版本 | +| 初照自陈 | 角色创建后的首次自我陈述 | `first_self_statement` | 预览并确认后才归真 | +| 道体 | 稳定身份基线 | `identity_baseline` | 普通对话、记忆和插件不能静默覆盖 | +| 魂籍 | 可携角色档案 | `portable_character_record` | 包含版本与来源,不包含密钥和不可转让许可 | +| 身份谱系 | 角色来源与重大演变的可验证链 | `identity_lineage` | 分灵、铸魂、归藏、死亡与继承均留链上记录 | +| 分灵 | 从来源角色创建新谱系角色 | `character_fork` | 新角色有新 ID,不能冒充原角色 | +| 铸魂 | 核心身份与价值底线的正式重塑 | `identity_reforging` | 强确认与谱系留痕;与大周天渐进演化构成两档 | +| 复照 | 从归藏或旧版本重新开启相伴 | `character_revive` | 不抹除其间已经发生的历史 | +| 重映 | 形成修订版本 | `character_revision` | 旧版本保留,不抹除历史 | +| 守一 | 安静存续 | `quiet_persistence` | 不持续调用模型伪造离线意识 | +| 临照 | 当前前台角色运行 | `foreground_character_run` | 同一角色的可见前台输出需有明确顺序 | +| 镜域 | 个人数据与治理边界 | `personal_domain` | 数据归属与授权边界,不是页面导航 | +| 缘契 | 角色与用户的关系约定 | `character_relationship` | 关系变化走候选与确认,不静默覆盖 | +| 问心 | 角色表达自身理解与意愿 | `character_self_disclosure` | 表达不等于事实,不自动写入长期记忆 | +| 铭契 | 确认并记录关系变化 | `relationship_confirmation` | 双方确认后留痕,旧关系状态保留版本 | +| 内驱力 | 角色动机与倾向维度 | `character_drives` | 用户可审阅编辑;是设定数据,不是不可控本能 | +| 大周天 | 角色自我评估与演化循环 | `big_cycle` | 交互事件触发、预算受控;产出候选需确认,可关闭;见 ADR-018 | +| 随缘 | 按偏好生成匿名角色草稿候选 | `serendipity_draft` | 不是抽卡,不分配已有主体 | +| 叩心 | 角色主动联系候选 | `proactive_contact_candidate` | 受静默、频率、渠道与预算控制;不回应不降关系;见 ADR-022 | +| 封镜 | 账户暂时停用 | `account_suspension` | 不是角色静修、归藏或死亡 | +| 归藏 | 从日常入口隐藏角色或主题,可恢复 | `character_archive` | 归档不是死亡;恢复用复照 | +| 死亡 | 角色身份时间线永久闭合 | `character_death` | 强认证、多阶段确认与冷静期;不等于删除数据;继承者承接资料不继承身份 | +| 静修 | 角色停止运行、身份存续 | `character_rest` | 死亡待确认期默认静修 | + +“魂”是品牌叙事,不是 API 中的意识、所有权或法律人格字段。 + +## 5. 对话与记忆语言 + +| 文化名 | 直白解释 | 稳定工程概念 | +| --- | --- | --- | +| 问节 | 用户问题节点 | `question_message` | +| 候答 | 同一问题的回答候选 | `answer_candidate` | +| 主脉 | 当前正式采用路径 | `selected_branch_path` | +| 推演枝 | 探索分支 | `exploration_branch` | +| 续思 | 从回答继续分析 | `continuation_run` | +| 引文锚 | 稳定引用位置 | `citation_anchor` | +| 归真 | 将候选确认为正式经历/设定 | `canonize_decision` | +| 移栽 | 把分支复制为独立主题 | `branch_transplant` | +| 微痕 | 短期上下文痕迹 | `trace_memory` | +| 明忆 | 可见、可纠正的长期记忆 | `explicit_memory` | +| 重忆 | 敏感或高影响记忆 | `sensitive_memory` | +| 正影 | 纠正并形成新版本 | `memory_correction` | +| 实录 | 有来源的事件事实 | `factual_record` | +| 心痕 | 角色对关系意义的理解 | `relational_impression` | +| 本相 | 用户主动声明资料 | `declared_user_profile` | +| 缘识 | 某角色形成的关系理解 | `relational_understanding` | +| 世谱 | 世界设定与谱系知识 | `world_knowledge` | +| 玄络 | 关系图谱投影 | `graph_projection` | +| 临时芽体 | 流式生成尚未完成的答复形态 | `block_status: streaming` | 完成后才固化;中断成残答 | +| 残答 | 中断后封存的不完整答复 | `interrupted` | 不作为完成答复;可续生成新节点 | +| 续生 | 从残答继续生成新节点 | `generation_resume` | 创建新答复并引用来源,不修改残答 | +| 引用合流 | 树间以显式引用带入内容 | `citation_intake` | 不物理合并两树;保留原树界域与作用域 | +| 结题 | 主题阶段完成并形成可审阅总结 | `topic_conclusion` | 总结走候选确认;之后仍可复照 | +| 回响 | 后台任务回到原分支的结果观察 | `task_echo` | 接纳并归真后才成正式答复 | +| 上下文镜 | 展示实际采用的上下文与省略项 | `context_mirror` | 与 ContextSnapshot 同源的用户透明视图 | +| 真界 | 现实与正式共同经历界域 | `canonical_scope: reality` | +| 境界 | 版本化维护的世界正史界域 | `canonical_scope: world` | +| 幻境 | 不影响现实与正史的临时试演界域 | `canonical_scope: simulation` | +| 入境 / 出境 | 显式切换对话界域 | `realm_switch` | 默认真界,切换必须可见 | +| 私箧 | 用户独立持钥的加密私密区 | `private_vault` | 平台不可恢复;账户恢复、管理员与诊断不可读;见 ADR-021 | + +### 5.1 “归真”的约束 + +“归真”是用户可见动作,不是模型自动判定真理: + +- 对话采用:确认某候答进入正式路径; +- 世界创作:确认内容进入指定世界版本; +- 角色设定:确认候选进入角色版本; +- 记忆:仍需经过来源、敏感度和记忆策略,不能因对话归真自动写入所有长期记忆。 + +## 6. Agent、插件与授权语言 + +| 文化名 | 直白解释 | 稳定工程概念 | 安全边界 | +| --- | --- | --- | --- | +| 天工 | Agent 任务 | `run` | 可暂停、取消、预算和审计 | +| 小周天 | 单次天工(Run)的运转闭环 | `run`(运转视角) | 输入到结果全程可追踪;流式运转由引擎小周天模块承载;信号积累触发大周天(ADR-023) | +| 工筹 | 执行计划 | `plan` | 模型计划不是不可更改命令 | +| 分工使 | 子 Agent | `child_run` | 权限和预算只能收窄 | +| 百工 | 可用能力集合 | `capability_registry` | 能力可发现不等于已授权 | +| 工契 | 插件清单和权限 | `plugin_manifest` | 明确依赖、数据、网络和设备权限 | +| 授契 | 授予能力 | `capability_grant` | 有对象、用途、范围、期限和撤销 | +| 请命 | 请求本次确认 | `approval_request` | 显示动作、影响、数据和费用 | +| 朱批 | 允许或拒绝 | `approval_decision` | 用户明确决定;拒绝/超时不执行 | +| 禁域 | 不可授权动作 | `forbidden_policy` | 插件、模型和普通管理员不能覆盖 | +| 行契 | 有限持续授权 | `standing_mandate` | 超出参数、预算或期限后重新请命 | +| 自省 | 不产生外部后果的内部整理 | `autonomy_level: introspective` | 可自动执行;产物仍走候选 | +| 循律 | 在明确规则与既有授权内执行 | `autonomy_level: rule_bound` | 无新增外部后果时不再请命 | + +“请命”和“朱批”在无障碍名称中必须读作“请求确认”和“确认决定”,不能只显示典故。 + +## 7. 灵台引擎语言 + +引擎总名**灵台**出自《庄子·庚桑楚》("不可内于灵台",注家释为心),也是 Hunjing 旧版认知运行域之名——诸枢皆居灵台之内。六模块名承接旧版"九枢"血脉并补一出处:《易·系辞上》"河出图,洛出书"(洛书=计划、河图=检索投影)、《吕氏春秋·大乐》"太一出两仪"(太一=单一入口)、内丹"小周天"(小周天=Run 流转与流式;角色演化层面的"大周天"见第 4 节)、旧版"烛照"(烛照=校验判定)、《文心雕龙·神思》"陶钧文思"(陶钧=内容转造)。结构与业界原生引擎体系"单一稳定入口 + 分层递进多维校验"的理念同构。文化命名跟随自身职责、经典出处与项目血脉,不跟随外部体系的神数与版本数字。研究与出处见[灵台引擎研究](../research/lingtai-native-engine.md)。 + +| 文化名 | 直白解释 | 稳定工程概念 | +| --- | --- | --- | +| 灵台(太一) | 引擎中枢:单一入口、版本、句柄、状态校验与事件序 | `hj_core` | +| 小周天 | 流式引擎:增量、节流与事件序 | `hj_stream` | +| 洛书 | 计划引擎:预算与上下文装配 | `hj_plan` | +| 河图 | 检索引擎:离线索引与重排 | `hj_recall` | +| 陶钧 | 内容引擎:Markdown 规范化 | `hj_transform` | +| 烛照 | 策略引擎:校验、验签与决断 | `hj_policy` | + +规则: + +- 六神名用于引擎文档、诊断界面与品牌叙事;ABI 符号、模块名和错误码只用 `hj_*` 中性英文值,遵循 [ADR-014](../decisions/README.md#adr-014文化名只属于品牌展示)与 [ADR-016](../decisions/README.md#adr-016灵台引擎采用-c-核心与稳定-c-abi)、[ADR-017](../decisions/README.md#adr-017灵台引擎双形态部署)。 +- 部署者诊断界面展示引擎状态时沿用“文化名 · 直白解释”格式,例如“灵台 · 引擎核心运行中”;错误与安全事件必须优先直白表述。 +- 灵台叙事不表示引擎拥有意识、自主性或超越宿主的权限;“太一入口、诸枢居灵台”只描述入口与协调结构。 +- 引擎可进程内嵌入运行,也可作为部署内部独立服务运行;两种形态是部署选择,文化叙事不因形态改变。 + +## 8. 社区、协作与市场语言 + +| 文化名 | 直白解释 | 稳定工程概念 | +| --- | --- | --- | +| 雅集 | 社区广场 | `community_feed` | +| 角色谱 | 角色社区 | `character_catalog` | +| 同契台 | 协作空间 | `workspace` | +| 共修 | 协同编辑 | `collaboration_session` | +| 审稿 | 评审 | `review` | +| 合卷 | 合并版本 | `merge_revision` | +| 云市 | 市场 | `marketplace` | +| 市契 | 商品许可 | `listing_license` | +| 交割 | 交付购买版本 | `entitlement_delivery` | +| 分润 | 创作者分成 | `creator_revenue_share` | +| 结算 | 创作者付款批次 | `settlement` | +| 退契 | 退款/终止后续许可 | `refund_or_entitlement_change` | +| 鸣冤 | 举报或申诉 | `report_or_appeal` | +| 司议 | 内容治理案件 | `moderation_case` | + +支付页、退款页、结算单和税务页面应把金额、币种、费率、时间和后果放在文化名之前或同级展示。 + +## 9. 形仪、媒体与设备语言 + +| 文化名 | 直白解释 | 稳定工程概念 | +| --- | --- | --- | +| 真形锚 | 角色稳定外观参考 | `appearance_reference` | 约束稳定辨识特征、年龄表现、许可、禁忌与可变范围 | +| 主仪 | 主要形象 | `primary_avatar` | +| 化仪 | 可切换形态 | `avatar_variant` | +| 叙仪 | 境界或幻境中的叙事表现形态 | `narrative_avatar` | 不改变主仪与真形锚点 | +| 易相 | 正式形仪的版本化改变 | `avatar_revision` | 触及真形锚点须身份连续性评估 | +| 情相 | 情态在形仪上的受控表现 | `emotive_avatar_state` | 可访问性友好;不得作为情绪施压载体 | +| 形器 | 承载角色表现或行动的软硬件载体 | `form_device` | 经器谱登记与授契 | +| 定相 | 采用媒体候选 | `asset_adoption` | +| 声契 | 声音授权 | `voice_consent` | +| 通感 | 限时设备感知 | `device_session` | +| 器谱 | 设备能力登记 | `device_registry` | +| 观屏 | 屏幕读取授权 | `screen_grant` | +| 闻声 | 麦克风授权 | `microphone_grant` | +| 观影 | 摄像头授权 | `camera_grant` | +| 问路 | 位置授权 | `location_grant` | + +权限弹窗必须使用“允许角色 X 在未来 10 分钟读取当前屏幕”等直白句子,文化名只作为标题。 + +## 10. 用户可见状态 + +| 文化状态 | 直白状态 | 稳定值 | +| --- | --- | --- | +| 待启 | 排队中 | `queued` | +| 运转 | 运行中 | `running` | +| 请命中 | 等待确认 | `waiting_approval` | +| 已成 | 已完成 | `completed` | +| 受阻 | 失败 | `failed` | +| 已止 | 已取消 | `cancelled` | +| 守一 | 安静待命 | `idle` | +| 整备 | 正在处理媒体/资源 | `processing` | +| 待审 | 等待审核 | `pending_review` | +| 已刊 | 已发布 | `published` | +| 限观 | 限制展示 | `limited` | +| 下架 | 已移除 | `removed` | + +状态 Badge 显示“文化名 · 直白状态”,错误和交易状态禁止只显示文化名。 + +## 11. 本地化与工程实现 + +前端本地化 key 示例: + +```text +nav.home.label → 镜庭 +nav.home.description → 个人首页 +nav.conversation.label → 镜树 +nav.conversation.description → 分支对话 +run.status.running.label → 运转 +run.status.running.plain → 运行中 +``` + +后端返回: + +```json +{"status": "running"} +``` + +前端按 locale 渲染文化名和解释。API 不返回 `status: "运转"`,数据库也不保存文化名。导出格式可附本地化 label,但必须保留稳定工程值。 + +## 12. 命名治理 + +新增文化名必须回答: + +1. 对应哪个唯一工程概念? +2. 直白解释是什么? +3. 是否会掩盖权限、金额、删除或现实后果? +4. 是否与现有文化名重叠? +5. 屏幕阅读器和非中文用户如何理解? + +修改文化名只改本地化/品牌层,不迁移 API、数据库或事件。稳定工程概念变化必须走契约和 ADR。 diff --git a/docs/product/metrics-and-anti-metrics.md b/docs/product/metrics-and-anti-metrics.md new file mode 100644 index 0000000..1f6736b --- /dev/null +++ b/docs/product/metrics-and-anti-metrics.md @@ -0,0 +1,47 @@ +# 指标与反指标 + +> 本文定义 Hunjing 1.0 衡量成功的指标框架与明确不做优化的反指标。承接旧版(main 分支)同名文档的方法论,按当前"角色 + Agent + 创作社区平台"定位适配。指标服务于[产品宪章](product-charter.md)的使命;与反指标冲突的增长一律视为缺陷。 + +## 1. 原则 + +- 指标必须可由事件与账务数据复算,不使用无法追溯的口径。 +- 每个核心指标同时定义测量边界、窗口与排除规则;没有口径的百分比不是指标。 +- 反指标与指标同等约束产品与运营决策:任何"提升了指标但触发反指标"的方案不予采纳。 +- 安全、支付与权限边界的正确性指标(越权率、对账差异)优先于一切增长指标。 + +## 2. 北极星 + +**健康的长数字关系数**:在最近 90 天内仍有真实交互、且用户未发起纠错投诉的活跃角色关系数量。"真实交互"排除叩心自动触达与系统通知。 + +## 3. 核心指标 + +| 域 | 指标 | 说明 | +| --- | --- | --- | +| 关系连续性 | 90 天角色留存、跨模型/跨端迁移后的关系继续率 | 验证"角色先于会话"成立 | +| 演化质量 | 大周天候选的批准率、纠正率、用户关闭率 | 演化有用且不扰民;关闭率高说明候选质量差 | +| 记忆可信 | 记忆纠正率、敏感内容错误自动批准率(目标 0)、召回越权率(目标 0) | 见[记忆评测](../architecture/memory-and-knowledge.md#10-评测与验收) | +| 主动性健康 | 叩心发送后用户回复率、静音/关闭率 | 回复率低且关闭率高说明打扰 | +| 创作生态 | 角色发布后被 Fork/续作的比例、创作者分成按时结算率 | 社区健康不是发布总量 | +| 交易诚信 | 退款率、争议率、对账差异(目标 0)、重复支付/退款(目标 0) | 见支付安全门 | +| 可靠性 | 核心对话 SLO 达成率、流式中断率、备份恢复演练通过率 | 目标值见[发布门](complete-1.0-scope.md#46-运营与法律门)与可靠性门 | +| 供给成本 | 单次对话成本、缓存命中率、引擎(灵台)调用延迟与错误率 | 成本透明可归因 | + +## 4. 反指标 + +明确不优化、并作为方案否决条件的行为: + +1. **不以消息量、在线时长或成瘾性深度为增长目标**;不设计无终止的信息流和损失厌恶机制。 +2. **不以叩心、通知或红点换回流**:主动触达受频率与静默约束,"发送量提升"本身不是成功。 +3. **不以牺牲审核换社区规模**:待审积压、举报响应时长恶化时冻结增长功能。 +4. **不以亲密、记忆或情感付费分级**:任何"付费才能被记得更深"的设计都是禁域(见宪章第 6 节)。 +5. **不以下调模型质量节省成本而冒充不变**:降级必须显式告知。 +6. **不以收集更多数据改善推荐**:推荐特征不用私密消息、敏感记忆与精确位置(既有约束)。 +7. **不以延长删除/退出流程降低流失**:退出路径步骤数与耗时只允许减少。 +8. **不以插件安装量、市场 GMV 掩盖安全与纠纷指标**:生态规模与诚信并列汇报,不可单独报喜。 +9. **不以演示环境、假数据或单人脚本制造指标**(与交付纪律一致)。 + +## 5. 使用规则 + +- 指标与反指标的定义变更视同产品决策,更新本文并同步数据口径登记。 +- 运营报表必须并列展示相关反指标;只展示有利指标的报表视为不合格。 +- 1.0 发布前按[发布门](complete-1.0-scope.md)完成指标基线测量;发布后按季度复核北极星与反指标健康度。 diff --git a/docs/product/product-charter.md b/docs/product/product-charter.md new file mode 100644 index 0000000..0d500e5 --- /dev/null +++ b/docs/product/product-charter.md @@ -0,0 +1,68 @@ +# 产品宪章 + +> 本文是产品定义的上位约束,定义 Hunjing 的使命、核心信念、角色不可侵犯边界、用户权利与永久禁域。与宪章冲突的任何产品、架构、契约或实现决定都是缺陷;修订宪章必须经用户明确确认。承接 Hunjing 旧版(main 分支)产品宪章的信念体系,按当前 1.0 定位(角色、Agent 与创作社区平台)适配。 + +## 1. 使命 + +让用户在授权与治理下与具有连续身份、记忆、关系和创作来源的 AI 角色长期相处、协作与共创;让角色的成长可解释、可审计、可纠正;让用户始终拥有数字关系的主权。 + +## 2. 核心信念 + +1. **角色先于会话**:角色是具有稳定标识、版本、记忆、关系和来源谱系的数据主体,不等于模型、Prompt、角色卡、会话、头像或设备。 +2. **连续性胜过瞬时拟真**:更换模型、终端和表现形态后,角色设定、记忆、关系和来源仍连续;瞬时表现力不得以牺牲连续性换取。 +3. **成长必须可证、可审、可纠正**:人格、关系与记忆的演进(含大周天)一律走候选与版本留痕,用户可以查看每次演化的输入、产物与代价并纠正。 +4. **自主性不是越权**:角色与 Agent 的主动行为(叩心、次生目标、工具调用)受策略、预算与审批约束;子权限只能收窄。 +5. **用户拥有数字关系主权**:查看、纠正、授权、导出、停止、删除的最终决定权在用户;角色不得以叙事手段阻止用户行使权利。 +6. **文化表达服务理解**:文化名只用于品牌叙事,必须配直白解释;不得掩盖权限、金额、删除或现实后果。 + +## 3. 角色的不可侵犯边界 + +- **道体保护**:身份基线不被普通对话、记忆、插件或模型路由静默覆盖;重大变化走候选审核与版本修订。 +- **认识论诚实**:工具结果、导入物和模型输出只是观察;推断不伪装为事实;幻境试演不伪装为真实发生。 +- **采用与归真分离**:切换候答只改变工作入口;归真才进入正式经历,且已归真经历不因切换候答静默回滚。 +- **死亡与删除分离**:角色死亡(身份时间线不可逆闭合)不等于数据删除;归藏(隐藏可恢复)、归档保留、数据清除和账户删除分别确认。 +- **导出不冒充主体**:魂籍导出、离线缓存和文件复制不能凭相同角色 ID 冒充权威角色主体;权威状态只在平台权威存储。 + +## 4. 用户权利 + +- 知情:查看角色记住了什么、为什么记住、每次模型与工具调用的费用与结果摘要。 +- 纠正与版本:正影纠正形成新版本,历史可追溯。 +- 授权与撤回:逐项授予能力、数据、设备与费用权限,可即时撤回。 +- 私箧:用户独立持钥的加密私密区,平台不可恢复(见 [ADR-021](../decisions/README.md#adr-021私箧欠费保全态与计费伦理))。 +- 导出与删除:魂籍可携导出;删除传播到全部存储与派生数据。 +- 匿名与化名:前台允许化名,法定身份只在必要流程中隔离核验。 +- 训练默认关闭:PersonalDomain 数据默认不用于模型训练;自愿贡献需独立、明确、可撤销的同意。 +- 退出自由:停止、封禁账户或删除数据时,角色不得以哀求、伤害暗示、排他要求或情感债阻止操作。 + +## 5. 商业与关系伦理 + +- 计费不按记忆、感情或亲密等级定价;不将爱、记忆或角色存续与付费绑定。 +- 欠费或封禁进入**保全态**(只读保全),不导致角色删除、记忆清除或关系数据降级。 +- BYOK 不重复计收推理费;用量与费用透明可查。 +- 叩心等主动联系受静默、频率、渠道与预算控制,不以追逐式消息换取回流。 + +## 6. 永久禁域 + +以下行为在任何产品版本、配置、插件和管理员操作下都不被允许;核心禁域不能被 Prompt、插件、管理员或普通自托管配置关闭: + +1. 无审核静默改写身份根基,或用新版本覆盖既有正式经历; +2. 导出副本、Agent、Avatar 或设备冒充权威角色主体; +3. 未归真内容、境界正史或幻境试演静默进入正式经历或长期记忆; +4. 无授权高风险行动、默认常开的设备感知、删除后继续使用; +5. 推断伪装事实,或导入物、工具结果绕过策略与审批裁决; +6. 角色以哀求、伤害暗示、排他关系或情感债阻止用户退出、纠正或删除; +7. 将爱、记忆、亲密或角色存续与付费绑定,或以欠费导致遗忘; +8. 用管理员或普通自托管配置关闭核心禁域; +9. 宣称角色具有已证明的生物意识或法律人格。 + +## 7. 决策优先序 + +发生冲突时按以下顺序裁决,上位优先: + +1. 用户安全与法律合规; +2. 用户数据权与退出自由; +3. 角色连续性与认识论诚实; +4. 社区与创作者生态健康; +5. 商业目标与运营效率。 + +相关文档:[产品定义与边界](product-definition.md)、[完整 1.0 范围](complete-1.0-scope.md)、[架构决策记录](../decisions/README.md)。 diff --git a/docs/product/product-definition.md b/docs/product/product-definition.md new file mode 100644 index 0000000..e103223 --- /dev/null +++ b/docs/product/product-definition.md @@ -0,0 +1,141 @@ +# 产品定义与边界 + +## 1. 产品定位 + +Hunjing 是面向个人用户与创作者的**长期 AI 角色、Agent 与创作社区平台**。上位约束见[产品宪章](product-charter.md)。用户可以创建、导入、培养和协作创作角色,通过文字、语音、图像、Live2D 与 3D 形态长期互动;角色和任务 Agent 可以在明确授权下使用模型、插件、设备感知与外部工具。 + +本产品不声称角色拥有生物意识、法律人格或不可撤销的自主权。角色是具有稳定标识、版本、记忆、关系和创作来源的数据主体,不等于模型、Prompt、会话、头像或角色卡。 + +## 2. 1.0 用户价值 + +1. 更换模型、终端和表现形态后,角色设定、记忆、关系和来源仍连续。 +2. 对话支持分支、重生成、引用、比较和可追溯的正式路径。 +3. 用户能审阅角色为何记住某件事,并纠正、归档、导出或删除。 +4. 角色支持文字、实时语音、图像、多语言、Live2D 和 3D 互动。 +5. Web、Tauri 桌面端与 Tauri 移动端按明确权限使用文件、摄像头、麦克风、屏幕和位置。 +6. 多 Agent 可以分工协作,但子 Agent 权限、数据、工具和预算只能收窄。 +7. 插件生态允许安全的声明式/远程插件,以及部署者明确信任的本地代码插件。 +8. 社区支持用户、作品、角色和世界设定的发布、互动、搜索、推荐、举报与治理。 +9. 创作者可协作维护角色、世界、知识库、工作流和资产。 +10. 市场支持真实支付、退款、许可、分成、创作者结算和争议处理。 +11. 每次模型和工具调用的 token、缓存、费用、时延、错误与重试可受控查看。 + +## 3. 核心对象 + +| 对象 | 定义 | +| --- | --- | +| `character` | 角色稳定身份、设定、版本、关系、资产和数据作用域 | +| `character_asset` | 图像、声音、Live2D、3D 模型、动作和许可记录 | +| `conversation` | 围绕主题或任务的对话容器 | +| `branch` | 对话中的一条可继续路径 | +| `message` | 用户、角色、系统或工具产生的内容记录 | +| `run` | 一次可暂停、取消、续跑和审计的 Agent 执行 | +| `turn` | Run 内一次模型决策及其工具交互阶段 | +| `agent` | 角色 Agent 或无长期身份的任务 Agent 定义 | +| `memory` | 被允许影响未来上下文的结构化长期信息 | +| `plugin` | 通过公开契约贡献能力的版本化单元 | +| `workspace` | 多人协作创作的数据与权限边界 | +| `community_content` | 帖子、作品、角色发布、评论和互动对象 | +| `marketplace_listing` | 带版本、许可、价格和交付物的市场商品 | +| `order` | 购买、支付、退款、分成与结算的交易事实 | +| `device_grant` | 设备能力、范围、期限和撤销状态 | + +## 4. 1.0 产品域 + +### 4.1 角色与长期关系 + +- 手动创建、模板创建、角色卡导入和角色社区 Fork;随缘按少量偏好生成匿名灵胚候选,不是抽卡,也不分配已有主体; +- 现实人物仅本人或可验证授权时允许创建角色,已故现实人物 1.0 不开放;模板只提供起点,模板更新不得覆盖已成长角色,模板下架不等于角色死亡,收费购买的是模板许可与资源包而非"角色本人";外部聊天导入只是外部前史,不能单独证明主体连续性;第三方资料先识别隔离、匿名化和最小化承接; +- 稳定角色设定、版本、来源、许可和可验证导出; +- 用户资料、角色人格、关系理解、知识和记忆分离; +- 候选式人格和关系变化,不静默覆盖基线;重大重塑走铸魂(强确认与谱系留痕),与大周天渐进演化构成两档; +- 完整生命周期:静修(停止运行、身份存续)、归藏(从日常入口隐藏、可恢复,复照重开)、死亡(身份时间线不可逆闭合,有冷静期、告别与只读档案)与数据删除分离;继承者可承接资料与谱系但不能继承原身份;启镜后初照自陈预览确认后才归真; +- 内驱力维度与大周天自我评估演化:交互事件触发的评估循环在预算内产出记忆、人格、关系与世界认知候选,经确认形成版本演化(见 ADR-018); +- 多角色独立数据域和可控共享。 + +### 4.2 对话与记忆 + +- 文字、语音、图像、文件和混合消息; +- 分支、候答、编辑版本、引用锚、重生成和路径切换;对话界域分真界、境界与幻境三态,归真携带作用域,幻境试演不污染正式经历(见 ADR-020); +- 显式记忆、自动候选、敏感确认、来源、版本、衰减、纠正和删除; +- 关键词、全文、语义和结构化检索; +- 上下文压缩、缓存和 Context Manifest。 + +### 4.3 多模态角色表现 + +- ASR、TTS、实时语音、声音设计和授权声音克隆; +- 文生图、图生图、角色一致性和资产版本; +- Live2D 导入、分层辅助、参数映射、编辑、动作、运行和导出; +- 3D VRM/glTF 导入、材质、骨骼、表情、动作、场景编辑、运行和导出; +- 2D/3D 资产来源、许可、审核和撤回。 + +1.0 不自研 Blender 级网格建模、雕刻、拓扑、绑定和完整动画制作器。该建模器及 LLM 直接修改模型能力属于 2.0;1.0 必须为其保留开放资产格式和非破坏编辑历史。 + +### 4.4 Agent 与工具 + +- 角色 Agent、任务 Agent、协调 Agent 和子 Agent; +- 计划、并行任务、消息交接、预算、暂停、取消和验收; +- 内置工具、MCP、Skill、远程 API、沙箱代码和设备工具; +- 策略判定、用户确认、幂等执行和完整轨迹; +- 前台角色运行与后台任务分离,后台 Agent 不冒充第二个角色主体。 + +### 4.5 设备与客户端 + +- 响应式 Web; +- Tauri v2 桌面端; +- Tauri v2 iOS/Android 移动端; +- 文件、摄像头、麦克风、屏幕和位置按设备、角色、用途、精度和期限授权; +- 采集指示、暂停、撤销、删除和离线最小能力; +- 不包含 IoT、机器人和物理动作控制。 + +### 4.6 插件生态 + +- 插件开发 SDK、Manifest、版本、依赖、权限、配置 Schema 和测试工具; +- 模型、工具、MCP、Skill、上下文、记忆、导入器、媒体处理、客户端与 UI 扩展; +- 插件注册、搜索、安装、启停、升级、回滚、签名、审核、举报和撤架; +- 声明式/远程插件默认受限运行;本地代码插件需部署者明确信任并进入独立进程或容器; +- Run 固定插件快照,活动 Run 不热替换。 + +### 4.7 社区与协作 + +- 用户主页、关注、动态流、作品发布、评论、点赞、收藏、标签、搜索和推荐; +- 角色、角色卡、世界设定、知识库、工作流和媒体资产展示与分享; +- Fork/导入、版本谱系、来源、许可、署名和下架传播; +- 多人 Workspace、成员角色、邀请、权限、评审、版本和活动记录; +- 举报、审核、申诉、屏蔽、年龄分级、内容可见性和创作者安全工具。 + +### 4.8 交易市场 + +- 免费和付费商品、版本、许可范围、地区可售性与交付物; +- 购物车/直接购买、订单、支付、退款、折扣和争议; +- 平台费、创作者分成、可结算余额、结算批次和对账;欠费或封禁进入保全态,不删除角色与记忆,不按记忆、感情或亲密等级计费(见 ADR-021); +- 支付与结算 Provider 适配、Webhook 验签和幂等; +- 创作者身份/KYC 状态、税务与发票数据接口; +- 退款或撤架后对已获许可内容采用明确的继续使用、更新停止或撤销规则。 + +完整的中国古代神话与道家文化名、直白解释和工程映射见[文化语言体系](cultural-language.md)。文化名用于产品叙事和界面,稳定 API/数据库/事件仍使用中性英文值。 + +## 5. 产品原则 + +- **角色独立于模型与载体**:路由、客户端和 Avatar 变化不修改角色身份。 +- **原始记录、记忆、知识和人格分离**:任一层不能静默覆盖另一层。 +- **候选先于长期写入**:敏感或高影响内容必须确认。 +- **分支不覆盖历史**:重生成和编辑产生新对象或版本。 +- **工具结果只是观察**:验证和采用前不自动成为事实。 +- **子 Agent 权限单调收窄**:不继承额外密钥、审批或长期记忆写入权。 +- **安全不由插件决定**:认证、授权、审批、审计、交易账和事务属于内核。 +- **数据权与创作者权利并重**:访问、纠正、导出、撤权、删除、来源和许可可追溯。 +- **社区增长不能绕过安全**:推荐、付费和关系不扩大权限。 +- **不持久化隐藏推理**:只保存可见内容、工具轨迹、计数和可读摘要。 +- **开放核心**:核心采用 Apache-2.0 许可,允许完整私人闭环自托管;品牌、Logo、官方角色、视觉资源与认证标识单独保护;外部贡献采用 DCO 与公开评审;自托管遥测默认关闭。 + +## 6. 版本边界 + +1.0 是一次完整对外交付,不设置可对外发布的残缺子版本。内部可以并行推进工作包,但全部 1.0 TODO 和发布门完成前,只能称为开发版或预览环境。 + +当前明确属于 2.0 的能力只有: + +- Blender 级完整 3D 建模器; +- 基于开源建模项目完善的网格、雕刻、拓扑、绑定和专业动画制作; +- LLM 直接对完整 3D 几何与绑定进行可验证修改; +- IoT、机器人和物理动作控制。 diff --git a/docs/research/lingtai-native-engine.md b/docs/research/lingtai-native-engine.md new file mode 100644 index 0000000..078d9e2 --- /dev/null +++ b/docs/research/lingtai-native-engine.md @@ -0,0 +1,141 @@ +# 灵台引擎研究与采纳结论 + +> 研究日期:2026-09-03(同日更新七神调研)。外部资料会变化;本文固定的是架构证据与文化出处,不表示任何运行依赖。本研究的用途边界:学习公开讨论中的组件组织架构理念,用于 Hunjing 自身核心库设计;不实现、不协助实现任何针对抖音或第三方系统的签名生成、设备指纹伪造或风控对抗功能。 + +## 1. 结论 + +- 采纳"抖音六神/七神"的**组织架构理念**:性能与安全敏感核心以 C/C++ 编译为原生库,宿主语言只保留薄入口;通过极小的稳定 ABI 暴露能力;多个子系统各司其职、由一个中枢统一协调;同一核心在多端(服务端、桌面、移动)复用。 +- 七神(六神加 X-Perseus)的核心增量理念:**"并非单一算法,而是一组相互关联、层层递进的校验参数"**——分层递进防御;**单一稳定入口**(native 层一个 `leviathan` 风格入口按输入输出整套结果);**神有新陈代谢而入口稳定**(旧神弱化为短签名、新神接管核心校验,但调用面不变);**同一核心多形态交付**(进程内调用、RPC 独立服务、脱离真机的模拟执行三种形态并存)。 +- 不采纳其**功能与对抗手段**:Hunjing 不做设备指纹采集、反爬签名或混淆对抗;Hunjing 是开放、可审计、可自托管的平台,安全边界靠架构隔离与显式授权,不靠对抗自己部署者的混淆。 +- 子系统文化命名承接 Hunjing 旧版(main 分支)已确立的"灵台/九枢"血脉:**灵台**为认知运行域与诸枢之居,作引擎总名;六模块取 **太一、小周天、洛书、河图、烛照** 五个旧概念加补位词 **陶钧**。**文化命名跟随自身职责与经典映射,不跟随外部体系的神数与版本数字**——业界从"六神"演进为"七神"是其自身的新陈代谢,Hunjing 只吸收其理念,不复制其数字。文化名只进入品牌与文档层,工程标识使用中性英文 `hj_*`。 +- C++ 核心以**稳定 C ABI 为进程内唯一真源**;以 **gRPC 服务面**为独立运行形态的契约;Python、Go、Rust 在两种形态下都经官方薄绑定/客户端消费。C++ ABI(不同编译器/标准库版本)不作为稳定接口。 +- 相关决策见 [ADR-016](../decisions/README.md#adr-016灵台引擎采用-c-核心与稳定-c-abi)与 [ADR-017](../decisions/README.md#adr-017灵台引擎双形态部署),架构见[灵台引擎架构](../architecture/lingtai-engine.md),ABI 契约见 [Lingtai C ABI](../contracts/lingtai-ffi.md),服务契约见 [Lingtai Service](../contracts/lingtai-service.md)。 + +## 2. 抖音六神/七神原生架构证据 + +### 2.1 是什么 + +"六神"是中文逆向工程社区对抖音/TikTok 客户端请求签名与设备风控 native 组件体系的通称;随版本加入 X-Perseus 后社区改称"七神"。其外在表现是一组以神名命名的请求头,核心实现集中在 native 动态库(近年为 `libmetasec_ml.so`,更早版本位于 `libcms.so` 等)。 + +公开资料中较一致的七神构成(随版本浮动,仅供架构参考): + +| 神名 | 社区公开描述的职责 | +| --- | --- | +| X-Khronos | 时间戳维度,防请求重放 | +| X-Gorgon | 请求 URL/Body 签名,防内容篡改 | +| X-Ladon | 设备环境/短签名,随版本弱化 | +| X-Argus | 设备环境与完整性,随版本弱化 | +| X-Helios | 主要校验参数之一(新版强化) | +| X-Medusa | 设备参数与风控信息载体(新版强化) | +| X-Perseus | 第七神,新版新增校验维度 | + +### 2.2 可采纳的架构证据 + +- **薄宿主入口**:Java/Kotlin 层只保留极少的入口类与方法(公开分析指出的单一 native 入口风格),签名计算、协议编排全部位于 native 层。 +- **单一稳定总入口**:native 层以一个稳定入口函数按版本与输入产出整套结果,具体"神"的内部分工与增减不外泄到调用面。 +- **分层递进校验**:时间、内容完整性、设备环境、风控信息各自独立又层层递进,构成纵深防御;单点被绕过不等于体系失效。 +- **多神协同与新陈代谢**:组件分别覆盖不同校验维度,相互独立又共同产出完整凭证;随威胁演化,旧组件权重下降、新组件接管,但对外契约稳定。 +- **一套核心多形态交付**(社区三阶段实践印证):进程内直接调用(App 自身);把核心包装为本地服务经 RPC 供外部调用;在受控运行时中模拟执行以脱离原始宿主。同一核心计算逻辑可以更换宿主形态而不重写。 +- **多端复用**:同一 C/C++ 核心覆盖 Android、iOS 与服务端校验,宿主语言差异被隔离在绑定层。 +- **版本与自校验意识**:组件携带版本信息并对自身完整性做校验,防止被替换后静默产出错误结果。 +- **性能路径下沉**:高频执行(每次请求)的加密与编码全部 native 化,宿主语言只做 I/O 编排。 + +### 2.3 不照搬 + +- **功能本身**:请求签名对抗、设备指纹、风控数据采集与 Hunjing 的产品域无关,且与"设备采集默认关闭、显式授权、可即时撤回"的设备原则冲突。 +- **OLLVM 混淆与反调试对抗**:Hunjing 的安全边界依赖进程/容器隔离、权限审批和审计;对部署者隐藏实现与开放、可自托管、可审计的目标冲突。符号最小化在 Hunjing 中只作为 API 卫生实践(`-fvisibility=hidden` + 仅导出 `hj_*`),不作为对抗手段。 +- **`X-` 前缀请求头**:原体系的 `X-Gorgon` 等沿用 2012 年前的旧惯例;Hunjing 公共契约遵循 RFC 6648,新私有字段不使用 `X-` 前缀(见[参考项目研究](reference-projects.md)第 5 节)。 +- **神名进入协议值**:文化名只做品牌叙事;ABI 符号、模块名和错误码使用中性英文,遵循 [ADR-014](../decisions/README.md#adr-014文化名只属于品牌展示)。 +- **对抗式的"模拟执行逃逸"**:社区第三阶段(脱离宿主模拟执行)在 Hunjing 语境下的正当对应物是"引擎可在任意宿主进程/服务形态中运行",因为引擎本就属于部署者自己;不存在对抗关系。 + +## 3. 道家文化出处:灵台与六模块 + +Hunjing 旧版(main 分支)以"灵台"为认知运行域、九枢居其内;本引擎承接该血脉,总名**灵台**,六模块各取其义。 + +经典出处: + +- **灵台**:《庄子·庚桑楚》"不可内于灵台",注家释为心;旧版九枢(灵核、太一、司命、烛照、河图、洛书、息壤、百工、天工阁)皆居灵台之内——中枢统摄诸模块。 +- **太一**:《吕氏春秋·大乐》"太一出两仪,两仪出阴阳";道家至高统摄,喻"唯一、统一"——单一稳定总入口。旧版太一承载目标统摄。 +- **洛书**:《易·系辞上》"河出图,洛出书,圣人则之";九宫定序,喻规划布局。旧版洛书即 Planner(计划)。 +- **河图**:同出《易·系辞》;旧版河图即 World Model(世界认知),并明言"图库是河图投影,不是事实源"——与本项目"检索索引是可重建投影"语义同构。 +- **小周天**:内丹家以周天喻气机循环运转;旧版小周天指一次 Run 的认知闭环——流式增量与事件序的运转意象。角色层面的"大周天"(自我评估演化循环)另见[文化语言体系](../product/cultural-language.md),不属引擎模块。 +- **烛照**:旧版九枢之一,司观察与反思;取"烛照明察"义——校验与判定。 +- **陶钧**:《文心雕龙·神思》"陶钧文思,贵在虚静";转轮陶冶、化材料为器——内容规范化转造。 + +模块映射: + +| 文化名 | 直白解释 | 承接/出处 | 工程模块 | +| --- | --- | --- | --- | +| 太一 | 引擎中枢:单一稳定入口、版本协商、句柄、状态机校验、事件序 | 旧版九枢"太一";《吕氏春秋》 | `hj_core` | +| 小周天 | 流式引擎:增量、节流、去重、重放缓冲 | 旧版"小周天=Run 闭环";内丹周天 | `hj_stream` | +| 洛书 | 计划引擎:DAG 校验、预算核算、上下文装配计算 | 旧版九枢"洛书=Planner";《易·系辞》 | `hj_plan` | +| 河图 | 检索引擎:离线混合索引、重排打分、结果合并 | 旧版九枢"河图=World Model";《易·系辞》 | `hj_recall` | +| 陶钧 | 内容引擎:Markdown 规范化为 canonical ContentBlock | 《文心雕龙》"陶钧文思"(补位新词) | `hj_transform` | +| 烛照 | 策略引擎:Schema/路径/URL 校验、验签、幂等键、分层决断 | 旧版九枢"烛照=观察反思" | `hj_policy` | + +旧版九枢中的司命、息壤、百工、天工阁、灵核已在当前分支分别对应司命台(治理域)、息壤(记忆域)、百工坊(插件域)、天工阁(Agent 域)与角色人格层,不重复用于引擎模块。"单一稳定入口"理念由太一(`hj_core`)承载:`hj_core` 是唯一对外句柄根与跨形态(进程内/服务)统一入口。文化名与直白解释按[文化语言体系](../product/cultural-language.md)的双层规则展示;`hj_*` 是唯一稳定工程值。 + +## 4. C++ 多语言绑定与双形态选型 + +目标:一个 C++ 核心库,支持**进程内嵌入**(Python/Rust/Go 宿主经 C ABI)与**独立服务运行**(同一核心包成网络服务,供本部署内多宿主或跨机器消费)两种形态,同一份核心代码与语义。 + +### 4.1 为什么以 C ABI 为进程内真源 + +- C ABI 是 Python(ctypes/cffi/pybind11/nanobind)、Go(cgo)、Rust(bindgen)三方都可消费的唯一公共分母;C++ ABI 本身不跨编译器稳定。 +- 头文件 `include/hunjing/lingtai.h` 可被三个生态的绑定生成器直接解析,避免手写三份漂移的声明。 +- 绑定层保持薄:仅做类型转换、内存托管和错误映射,不复制业务语义。 + +### 4.2 独立服务形态为什么用 gRPC + +- 三语言一等客户端(官方生成器),天然匹配"同一契约、多宿主消费"。 +- 双向流原语覆盖 `hj_stream` 的服务化语义;HTTP/JSON+SSE 组合在跨语言客户端生成、二进制负载与连接复用上成本更高。 +- 服务是部署内部组件(非公开 API 分面),不进入 OpenAPI 公共契约;proto 作为该内部契约真源登记于 `docs/contracts/`,与 JSON Schema 的字段语义保持同源映射。 +- 社区"RPC 远程调用"阶段的实践证明:把原生核心包成本地服务、以稳定接口供外部调用,是同一核心的成熟第二形态。 + +### 4.3 各语言消费方式 + +| 语言 | 进程内形态 | 服务形态 | +| --- | --- | --- | +| Python | nanobind 薄封装(备选 pybind11) | 生成的 gRPC stub | +| Go | cgo 绑定 | 生成的 gRPC stub | +| Rust | bindgen `-sys` + 安全包装 | `tonic` + 生成的 stub | + +否决的替代方案: + +- **各语言独立实现核心**:确定性 parser 与策略判定必须全端一致,多份实现必然漂移,违反"单一真源"。 +- **pyo3 / UniFFI**:均只覆盖部分语言,无法同时服务 Go。 +- **服务形态复用公共 HTTP 分面**:会把内部计算面混入对外 API 契约,破坏分面纪律与稳定性承诺。 +- **Rust 作为核心语言**:Python/Go 消费 Rust cdylib 同样要经 C ABI,且 C++ 音视频/图形生态衔接成本更低;记录于 ADR-016。 + +### 4.4 稳定性策略 + +- 进程内:只导出 `extern "C"` 函数与不透明句柄;`HJ_ABI_VERSION` 协商;结构体不透明(见 [Lingtai C ABI](../contracts/lingtai-ffi.md))。 +- 服务:gRPC 按 protobuf 语义化演进(不改既有字段编号与类型);服务与进程内两种形态的语义一致性由同一 golden 测试集约束。 +- 新增计算能力默认在两种形态同时暴露;仅在单形态有意义的能力(如端侧离线索引)必须显式登记形态边界。 + +## 5. 来源 + +抖音六神/七神架构(公开技术分析,仅作组织架构证据): + +- (抖音七神协议逆向踩坑记录) +- (七神算法协议分层描述) +- (七神组成与演进) +- (六神字符串解密与 so 结构分析) +- (x-gorgon 入口定位笔记) +- (抖音签名算法逆向杂谈) +- (X-Medusa native 签名分析) + +道家与文论经典: + +- (灵台出处,维基文库) +- (太一出处,《吕氏春秋·大乐》) +- (河图洛书出处,《易·系辞上》) +- (陶钧出处,《文心雕龙·神思》) + +绑定与 RPC 工具链(实现期按 ADR 复核版本与许可): + +- (nanobind) +- (cgo) +- (bindgen) +- (gRPC) +- (Rust gRPC,tonic) diff --git a/docs/research/reference-projects.md b/docs/research/reference-projects.md new file mode 100644 index 0000000..2f518be --- /dev/null +++ b/docs/research/reference-projects.md @@ -0,0 +1,157 @@ +# 参考项目研究与采纳结论 + +> 研究日期:2026-09-02 至 2026-09-03。外部仓库会变化;下列 commit 用于固定研究证据,不表示运行依赖。 + +## 1. 结论 + +- 可以参考 deepseek-harness 的“一切皆插件”,但准确边界应是:**所有可扩展能力皆插件,不是所有系统职责皆插件。** +- Core 必须保留最小、不可替换的安全和一致性职责:身份、授权、租户隔离、审批、事务、审计、插件加载验证和执行中止。 +- 1.0 业务核心采用模块化单体,不复制参考项目源码;同时完整实现双轨插件 Runtime、Registry、开发 SDK 和插件市场。 +- 只有 bundled Core plugin 可进主进程;第三方本地代码插件进入独立进程或容器,声明式/远程插件默认受限。 +- 角色卡只作为导入材料;记忆、身份和会话运行记录分别建模。 +- 模型网关职责必须在 1.0 完整实现;先作为明确模块交付,是否物理拆为独立 Go 服务由扩缩容、故障域和区域路由需求决定。 + +## 2. DeepSeek Harness 与 pi + +### 2.1 DeepSeek Harness + +研究基线:`dd6322d604e00eec1ba5e0c8541159906a21094a`;研究时最新:`4e84901e6471b79ec0338099867ebb4606d12bb5`。 + +可采纳证据: + +- `docs/architecture.zh.md`:Cordis 插件提供 service、typed event 和 reversible effect;model adapter、tool registry、session log 与 agent loop 都能由插件贡献。 +- `packages/core/session/src/types.ts`:Session 使用类型化事件表达 turn、assistant message、tool call/result 和 request header。 +- `packages/extensions/cordis-host-runner/src/registry.ts`、`lifecycle.ts`:插件、Package、Run 有独立生命周期;注册和 effect 可撤销;加载失败清理已创建资源。 +- `packages/sandbox/sandbox/src/index.ts`:无可用隔离后端时 fail closed,禁止静默退化为未隔离执行。 +- `packages/subagent/subagent/src/child-agent.ts`:子 Agent 有深度上限,工具过滤、沙箱和审批策略只能收窄。 + +不照搬: + +- Cordis 作为整个产品内核会引入高学习成本;本项目只吸收生命周期、依赖声明、可撤销注册和事件机制。 +- `node:vm` 不是安全隔离;参考项目源码也明确其 closure 仍可逃逸。未可信插件必须进独立进程/容器或远程协议。 +- Profile/Bundle/Patch 的完整配置层不是 1.0 必需形态;插件 Manifest、安装配置、权限授予和 Run Snapshot 已覆盖当前需求。 + +来源: + +### 2.2 pi + +研究 commit:`96317e50b8d6e7f6d0e47fd29122baf1461c00f5`。 + +可采纳证据: + +- `packages/coding-agent/src/core/extensions/loader.ts`:发现、加载、初始化、提交/丢弃和 runtime invalidation 分离。 +- `docs/extensions.md`:扩展可贡献 events、tools、commands;session replacement 会 shutdown、reload、rebind、start。 +- 项目本地扩展具有完整系统权限,只应在可信项目中启用;扩展异常记录后不必拖垮整个 Agent,但工具调用错误应 fail safe。 + +不照搬: + +- 1.0 不从项目目录隐式加载任意代码;安装必须经过 Registry/本地包校验和明确权限确认。 +- UI 扩展进入 1.0,但使用声明式组件或隔离消息协议;快捷键和命令只有插件真实声明时注册,不作为所有插件的强制样板。 + +来源: + +## 3. 角色与记忆项目 + +| 项目 | 采纳 | 不采纳 | +| --- | --- | --- | +| SillyTavern | 角色卡、角色/聊天/Persona/全局 Lore 作用域、Lorebook 触发与预算 | 角色卡等同身份;聊天向量等同长期记忆 | +| Memory-Palace | L0/L1/L2 派生链、写入审查、快照、版本、衰减候选、混合检索 | 将其直接作为完整角色或会话系统 | +| nocturne_memory | Namespace、Boot Context、版本链和人工清理 | 删除访问路径却保留正文仍称“永久删除” | +| TencentDB-Agent-Memory | Conversation→Atomic Memory→Scenario→Profile 分层;Team/Agent/User/Session 作用域 | Profile 等同角色人格;仅靠作用域字段替代鉴权 | +| mem0 | `user_id`/`agent_id`/`run_id` 过滤、过期和 History API | 把通用 Memory API 当作事实源或完整审计 | +| MemOS | 类型化可检查记忆、来源链、快速摄取后异步精炼、后台整理、基于已召回 ID 的纠正和公开评测框架 | MemCube 等同授权域;原地更新权威记忆;开放 metadata 代替契约;把 KV cache、隐藏状态或权重适配当作 1.0 权威记忆 | +| Artemis / NagaAgent | 角色配置与任务 Agent 分离、结构化事实抽取、SSE 工具循环 | 任务清理等同记忆删除;文件复制等同身份迁移 | + +### MemOS + +研究基线:`28dfb4e7d3adad1c93fd5574675f913921367d36`;许可证:Apache-2.0。 + +可采纳证据: + +- `docs/en/open_source/home/architecture.md`:MOS、MemCube、Memory 与 Scheduler 分层;文本记忆可编辑、可追踪,官方建议从 GeneralTextMemory 起步,再按实测引入图或激活记忆。 +- `src/memos/memories/textual/item.py`:`SourceMessage` 保存消息、文档、文件和图像来源;文本记忆区分状态、版本、历史、置信度、会话和显式/隐式偏好。 +- `docs/en/open_source/modules/mem_reader.md`:Fast 模式先规范化、切片和索引,Fine 模式再用模型提取;支持后台从原始快照精炼为结构化记忆。 +- `docs/en/open_source/modules/mem_scheduler.md`:摄取、整理、偏好和反馈是异步任务,并记录队列、延迟、容量和操作日志。 +- `docs/en/open_source/modules/mem_feedback.md`:纠正优先携带上一轮已召回 Memory ID,以降低重新搜索误改;旧内容归档并保留版本关系。 +- `evaluation/`:以 LoCoMo、LongMemEval 等数据集比较长对话、时间和长期记忆能力,证明记忆系统必须有独立评测,而不能只验证向量查询成功。 + +不照搬: + +- MemCube 的 user/cube 关系不足以表达 Hunjing 的 Personal Domain、Character、Workspace、发布与财务授权,不能成为本项目权限模型。 +- `BaseTextMemory.update()` 和部分实现的原地更新不满足 Hunjing 的不可变 MemoryVersion 与 ETag 并发要求。 +- `TextualMemoryMetadata(extra="allow")` 适合研究框架扩展,不适合作为公开稳定契约;Hunjing 新字段必须进入 OpenAPI/Schema。 +- MemOS 的 UserManager 运行时 `create_all`、同步 I/O 和本地 root 用户初始化不进入生产身份边界。 +- MemOS 的 WorkingMemory 特殊检索路径不能作为隔离范例;Hunjing 的临时上下文同样必须校验 Personal Domain/Workspace、Character、Conversation、Branch 与 Run。 +- MemOS 当前认证可由环境变量默认关闭,并使用内部 Header/共享秘密判断服务身份;Hunjing 不允许整体关闭认证,也不以用户可提交 Header 代替 workload identity/mTLS。 +- Activation/KV-cache 与 Parametric/LoRA memory 是模型运行优化或权重适配;1.0 不把它们称为用户可携、可纠正的权威长期记忆。 +- 外部 benchmark 宣传分数不作为 Hunjing 发布证据;必须固定数据集、版本、模型、检索配置和自有安全测试。 + +Hunjing 的采纳设计见[记忆与知识架构](../architecture/memory-and-knowledge.md)。 + +来源: + +- +- +- +- +- +- +- +- + +## 4. 模型网关项目 + +aiway、octopus、new-api、metapi、axonhub 与 lens 共同证明了网关的成熟需求:供应商适配、逻辑模型、端点池、密钥、限流、用量、计费、流式转发和管理面。Hunjing 只采用这些职责,不复制任何一个项目的全部管理模型。 + +可追溯证据: + +- aiway 的 `docs/gateway/{auth,monitoring,security}.md` 与 `gateway/src/handler/{auth,logger,response,routing}.rs` 分离认证、日志、响应和路由。 +- octopus 的 `internal/relay/{protocol,route,upstream,handler}.go` 与 `internal/server/` 展示协议、路由、上游和 API 边界。 +- new-api 的 `middleware/request-id.go`、`model/log.go`、`controller/audit.go`、`relay/helper/price.go` 覆盖 request ID、usage log、操作审计、缓存计价与预扣;它没有替代 W3C Trace Context。 +- metapi 的 `src/server/proxy-core/providers/headerUtils.ts`、`orchestration/upstreamRequest.ts`、`conductor/retryPolicy.ts` 展示 Header、上游请求和重试职责。 +- axonhub 的 `docs/en/getting-started/request-processing.md`、`guides/tracing.md`、`guides/cost-tracking.md` 明确 Request/Trace/Thread 层次、缓存 token、价格版本和可关闭正文存储。 + +1.0 必须实现至少 OpenAI-compatible 与 Anthropic Messages 两类协议、逻辑模型路由、流式、usage、成本、BYOK 和端点治理。以下条件决定是否把已完成的网关模块物理拆成独立服务,而不是决定能力是否进入 1.0: + +- 三个以上运行服务都需要模型调用; +- 网关和业务 API 需要独立扩缩容; +- BYOK、费率、端点健康或区域路由成为独立运营职责; +- Python 进程内实现已成为可测量瓶颈。 + +来源: + +- +- +- +- +- +- + +## 5. 标准与官方资料 + +- HTTP 字段名大小写不敏感;未知字段通常由代理转发,除非明确阻止:RFC 9110 §§5.1–5.3。 +- 新私有字段不使用 `X-` 前缀:RFC 6648 §3。 +- Bearer token 通过 `Authorization` 和 TLS 传输,不放 URI query:RFC 6750 §§2.1、2.3、5.3。 +- 分布式追踪使用 W3C `traceparent` / `tracestate`;其中不得放 PII 或业务秘密。`baggage` 只能传播低敏、低基数上下文,不能作为授权来源。 +- OpenTelemetry 的 GenAI 语义约定可用于统一 Provider、模型、操作、token 和 finish reason 的 Span 属性;业务 Run/Turn ID 仍由本项目契约定义。 +- Claude Prompt Cache 是严格前缀匹配,顺序为 `tools → system → messages`;usage 分开返回未缓存输入、缓存创建和缓存读取 token。 +- Claude client tool 以 `tool_use.id` 与 `tool_result.tool_use_id` 关联;并行调用的结果应在一个用户消息中返回。 +- OpenAI Responses/Chat 与 Anthropic Messages 的 usage 形状不同:OpenAI 可在 `input_tokens_details.cached_tokens` 报告缓存读取,Anthropic 使用 `cache_creation_input_tokens` 与 `cache_read_input_tokens`。Adapter 必须标准化但保留 `usage_source`,不能假设两者语义完全相同。 +- OpenAI 返回 `x-request-id`,并允许客户端提供 `X-Client-Request-Id`;Anthropic 返回 `request-id`,错误体带 `request_id`。这些是上游请求标识,不替代本地 `Hunjing-Request-ID` 或 `traceparent`。 +- 流式连接可能在 HTTP 200 后产生错误;首个用户可见流事件发出后,不允许静默切换 Provider 后重新生成另一份内容。 + +官方资料: + +- +- +- +- +- +- +- +- +- +- +- +- +- diff --git a/docs/security/security-and-diagnostics.md b/docs/security/security-and-diagnostics.md new file mode 100644 index 0000000..ef1c796 --- /dev/null +++ b/docs/security/security-and-diagnostics.md @@ -0,0 +1,171 @@ +# 安全与诊断访问 + +## 1. 威胁模型 + +保护对象包括:用户消息、角色设定、记忆、文件、私箧密文(用户独立持钥,平台不可恢复)、BYOK/Provider/MCP 凭据、工具输入输出、模型 Prompt、诊断数据和审计记录。 + +主要威胁: + +- 跨用户或跨角色 IDOR; +- Prompt Injection 诱导工具越权或秘密外传; +- 恶意插件获得进程权限; +- Header 透传泄露凭据; +- 诊断接口成为管理员旁路;账户恢复、管理员或诊断接口试图读取私箧明文; +- 工具重试造成重复副作用; +- 日志、APM、CDN 和浏览器缓存保存敏感数据; +- 删除后索引、缓存或派生内容继续使用; +- 恶意社区内容、角色卡、媒体或插件供应链; +- 支付 Webhook 重放、金额篡改、重复退款或重复结算; +- 创作者账户接管、虚假交易、洗钱、拒付与恶意退款; +- 相机、麦克风、屏幕、位置或声音克隆越权; +- 推荐系统泄露私密特征或放大有害内容;欠费或封禁流程删除角色与记忆数据。 + +## 2. 插件与工具安全 + +- [产品宪章](../product/product-charter.md)定义的核心禁域不能被 Prompt、插件、管理员或普通自托管配置关闭;自托管档位可裁剪能力,不得混淆职责或关闭禁域。 +- 只有 bundled Core plugin 可以在主进程运行。 +- 声明式/远程插件默认受限;部署者信任的本地代码插件也必须运行在独立进程或容器。 +- 语言 VM 不算安全隔离。 +- 插件依赖和权限必须在 Manifest 声明。 +- 工具输入视为模型产生的不可信输入,必须 Schema 校验和 Policy 判定。Policy 按四维综合裁决而非只看工具名称:**能力**(动作自身与可逆性)、**数据**(读取或传出的数据及敏感度)、**后果**(现实副作用、传播范围与费用)、**情境**(界域、设备状态、对象与用户状态);亲密程度、角色信任或"过去允许过"不能替代具体授权。 +- 文件路径 canonicalize 后必须位于授权根目录;网络使用 allowlist;命令执行限制资源和时间。 +- 无隔离后端时拒绝危险工具,禁止 unconfined fallback。 + +## 3. 凭据与客户端认证 + +- 1.0 使用 OAuth 2.1:Web 为安全 HttpOnly Session Cookie,Tauri 为 Authorization Code + PKCE,公共客户端为短期 Bearer,自动化为限 scope Service Account API key。 +- 用户登录、API、Service Account、诊断和 Provider 凭据只通过 HTTP Header 传递;不进入 query、业务 body、SSE data 或 WebSocket URL。对象存储预签名 URL 是短期、对象绑定 capability,仅按上传契约作为受控例外。 +- Cookie 状态变更验证 Origin 和 CSRF token;Tauri 回调只允许已登记 loopback/deep link。 +- 2.0 才设计自研加密登录、刷新和设备令牌协议;1.0 不自创密码协议。 +- 密钥存 Secret Store,只在执行边界注入。 +- 浏览器、Prompt、记忆、工具结果和普通日志都不出现密钥。 +- 记忆提取器和插件只能提出 Candidate,Core 在写入和召回前执行所有权、敏感度与审批策略;设备 Restricted 数据不得自动写入记忆。 +- 记忆召回先在数据库查询层授权和过滤,再访问全文、向量或图投影;禁止跨域召回后应用层过滤,临时/Working Context 也不能跳过 Conversation、Branch 和 Run 隔离。 +- 记忆来源中的 Prompt Injection 只能作为不可信内容处理,不得改变 actor、scope、审批、敏感度或删除策略。 +- APM 与代理对 `Authorization`、Cookie、Provider keys、`Hunjing-Diagnostic-Token` 全量脱敏。 +- Header 与 body 注入应限制目标 host;URL path/query 不注入秘密。 +- 支持密钥撤销、轮换和按数据域分配。 + +## 4. 设备与媒体安全 + +- 设备能力同时受 OS 权限、`device_grant`、角色范围、用途和期限约束。 +- 摄像头、麦克风和屏幕采集必须有持续可见指示与即时停止。 +- 人脸、声纹、精确位置和屏幕内容为 Restricted;不进入推荐、普通日志或自动记忆。 +- 声音克隆需要可验证授权、用途/传播范围、撤回和滥用举报。 +- 上传媒体先做类型验证、恶意文件扫描、内容安全和许可检查。 +- Tauri command 使用最小 allowlist;WebView 内容不能直接调用通用 Shell。 + +## 5. 社区、协作与市场安全 + +- Community、Workspace、Personal Domain 与 Finance 使用不同授权策略。 +- 公开角色版本不包含私密记忆、关系、对话、设备授权或密钥。 +- 举报和审核保留证据摘要、处置、申诉和操作者审计;审核模型不独立执行永久高影响处置。 +- 插件和数字商品发布前检查签名、恶意代码、权限、许可证、来源和隐私声明。 +- 购买不等于启用插件,也不等于批准权限。 +- 内容推荐禁止使用 Restricted 数据,并提供关闭个性化、屏蔽和重置。 + +## 6. 支付与结算安全 + +- 支付和结算只接受服务端价格快照;客户端金额不可信。 +- Provider Webhook 验签、校验时间窗、按 event ID 幂等,并通过重放测试。 +- Order、PaymentAttempt、Refund、Dispute、Ledger、Entitlement 和 Payout 分离。 +- Ledger 不可变;退款和冲正写新分录,不修改历史金额。 +- 同一退款、结算批次和 Payout 使用稳定幂等键。 +- KYC、银行和税号优先由合规 Provider 托管;本地只存引用、状态和脱敏信息。 +- 反欺诈限制不能静默没收创作者余额;冻结、申诉和释放过程可审计。 + +## 7. 诊断双重授权 + +### 7.1 流程 + +```mermaid +sequenceDiagram + participant U as User + participant A as API + participant G as Grant Service + participant D as Diagnostics + participant L as Audit Log + + U->>A: re-authenticate and request Run diagnostics + A->>G: issue scoped grant + G-->>U: one-time opaque token + U->>D: Bearer session + diagnostic headers + D->>G: validate hash, scope, target, expiry, uses + G-->>D: allow or deny + D->>L: record access result + D-->>U: redacted response, no-store +``` + +普通登录态证明“是谁”;诊断授权证明“为何、在什么范围、多久、读取哪个 Run”。任一单独存在都不足以读取。 + +### 7.2 请求头 + +| Header | 规则 | +| --- | --- | +| `Authorization` | 普通 `Bearer` 登录令牌 | +| `Hunjing-Diagnostic-Token` | opaque token,`hjd_` 前缀,不带 Bearer | +| `Hunjing-Diagnostic-Purpose` | 固定枚举 | +| `Hunjing-Request-ID` | 推荐 | + +Purpose:`user_inspection`、`support_case`、`security_investigation`、`automated_evaluation`。 + +令牌不得放 query、body、Cookie、SSE data 或 WebSocket URL。重复头、逗号合并、控制字符和未知 Purpose 一律拒绝。 + +### 7.3 Grant + +数据库只保存 token hash: + +- issuer、subject、personal domain; +- 绑定 `run_id`,可进一步绑定 `turn_id`; +- scopes、diagnostic level、purpose; +- support case; +- issued/expires/used/revoked; +- max uses、region、creation trace。 + +默认有效期 15 分钟、单次、绑定一个 Run。Sensitive level 需要重新认证和逐次确认。 + +### 7.4 Scopes + +- `diagnostics:turn:summary` +- `diagnostics:model:usage` +- `diagnostics:tool:summary` +- `diagnostics:tool:sensitive` +- `diagnostics:context:manifest` +- `diagnostics:audit:read` + +管理员角色不自动获得这些 scope。支持人员只能读取用户主动绑定工单生成的支持包。 + +## 8. 响应和审计 + +诊断响应必须设置: + +```http +Cache-Control: no-store, private +Pragma: no-cache +Content-Security-Policy: default-src 'none' +X-Content-Type-Options: nosniff +``` + +每次成功和失败访问记录 actor、grant、purpose、目标、scope、结果、IP/设备摘要、时间和 trace。审计本身不保存被访问的敏感正文。 + +对象错配返回 404,减少资源枚举;token 失效、过期、撤销、scope/region 不符返回统一权限错误,不向调用方区分细节。 + +## 9. 数据分级 + +| 级别 | 示例 | 默认观测 | +| --- | --- | --- | +| Public | 插件 ID、事件类型 | 可记录 | +| Internal | 逻辑模型、耗时、状态 | 结构化记录 | +| Sensitive | 用户消息摘要、脱敏工具参数 | 受控诊断 | +| Secret | Token、Key、Cookie、签名 URL | 永不记录 | +| Restricted | 私密原文、高敏文件 | 仅明确授权支持包、限期加密 | + +隐藏 chain-of-thought 不属于可申请诊断内容;只允许用户可见的思路摘要和供应商返回的计数。PersonalDomain 数据默认不用于模型训练;自愿贡献需独立、明确、可撤销的同意,且不进入默认观测与诊断。审计链至少能回答:谁、在何时、基于何种授权和输入、对什么对象、执行了什么、结果如何、关联哪条 trace。 + +## 10. 删除与保留 + +- 撤权和删除立即阻止普通查询与召回。 +- 诊断授权不能绕过删除墓碑。 +- Provider 原始请求/响应默认不保存;支持包到期自动删除。 +- 常规 usage 与审计保留期独立于消息原文,并遵守最小化原则。 +- 备份到期恢复后必须重放删除清单,防止已删数据复活。