# Taichu (太初) - 项目规范

## 项目定位

专注于**单本玄幻小说**的个人写作助手，基于 LangChain 与 LangGraph 构建的多 Agent 写作系统。

## 对话规则：
- 当用户提问存在歧义、信息缺失或逻辑矛盾，且无法通过上下文合理推断时，必须主动向用户提问澄清，不得擅自猜测或假设后直接作答。明确后再给出回答。
- **SDD 使用边界**：除非用户明确要求使用 SDD、规格驱动开发、spec 流程或 `$codex-sdd`，否则不得自动初始化、推进或恢复 SDD 开发流程；普通修复、重构、页面调整、诊断和分析任务按直接代码调查、最小变更与针对性验证处理。
- **中文表达强制规则**：任何面向用户的回答、网页文案、按钮、卡片、提示、报错、功能说明、验收说明和项目文档说明都必须使用中文。内部代码标识、接口枚举、文件路径、命令、依赖名称可以保留原始拼写，但不得把英文内部标识直接当作用户可见文案；需要提及时必须配中文名称或中文解释。
- **开发计划禁止工时估算**：除非用户明确要求评估时间、成本或人力，否则开发计划不得提供“人/天”、工时、完成周期、排期或人员投入估算。太初项目默认由 Codex 按用户可用时间连续推进，计划只按依赖关系、实施批次、风险和验收门禁拆解，不以人工开发时长作为计划依据。
- **系统问题记录口令**：用户说“记录系统问题”“把这个记到系统问题”等同于要求把当前问题写入收件箱的「系统问题与改进项记录」。应优先通过 `/api/inbox/issues` 写入 `project_assets/source/workspace/inbox_issues.jsonl`，不得另建平行文档代替该入口。`content` 必须严格按“记录日期、状态、现象、根因、影响、修复、验证、相关代码”的顺序逐行填写，使用全角冒号，字段不得缺失、改名或调序；未知内容明确写“待调查”“待处理”“待验证”或“暂无”。记录必须采用高层工程视角，说明用户可见现象背后的架构机制、被破坏的职责或数据边界、系统性影响、目标不变量、修复路径和可验证结果；不得把页面字段、函数名、枚举值或内部名词罗列当作问题分析。已解决的问题标记为 `processed`，尚未解决的问题标记为 `todo`。

## Skills 规则
- `.agents/skills/` 是唯一项目级 Skill 目录。
- 创建、修改或讨论 Skills 时，**必须先读取** `.agents/skills/rule.md` 并遵循其中定义的规范。

### Graphify 暂停规则
- **当前状态：禁用**。项目处于 vibe coding 阶段；在用户明确进入 spec/SDD 开发或明确要求重新启用 Graphify 之前，Codex 不得使用 Graphify 分析、解释或追踪本项目代码。
- 禁用期间，即使全局 Graphify Skill 被自动触发，也必须以本项目规则为准跳过；不得运行 `graphify query`、`path`、`explain`、`affected`、`update`、`watch` 或 Hook，也不得把 `graphify-out/graph.json`、`GRAPH_REPORT.md` 等现有生成物作为当前代码事实源。
- 禁用期间，代码分析必须直接读取当前源码，并使用 `rg`、测试和其他不依赖 Graphify 缓存的方式核验。Graphify 的 Codex Skill 已从自动发现目录移至 `C:\Users\wyh\.codex\disabled-skills\graphify`；`graphify.exe` 和项目 `graphify-out/` 继续保留。
- 已打开的 Codex 任务可能仍保留创建时注入的 Skill 清单；即使旧任务仍显示 Graphify，也必须忽略并遵守本规则。移动 Skill 后应重启 Codex，再创建新任务验证停用状态。
- 重新启用时，必须先把 Graphify Skill 恢复到 Codex Skill 发现目录，再按届时需要的代码范围重新构建或增量更新图谱并验证新鲜度；更新成功前不得复用现有旧图谱。

## docs 规则
- 创建、修改或讨论 `docs/` 时，**必须先读取** `docs/rule.md`。
- `docs/` 按“学习资料、已讨论功能、旧历史”区分实现讲解、未来计划和废弃方案；根目录及 `docs/` 外的规则说明必须持续保持最新。

## 不可变决策

以下决策已在项目初期确定，后续开发必须遵循：

### 工具链
- **包管理**：使用 **uv**，禁止使用 pip/poetry/pipenv
- **Python 版本**：>= 3.12
- **启动命令**：`uv sync` 安装依赖，`uv run` 执行脚本

### Agent 框架边界
- **官方实现优先**：Agent、消息、Tool、结构化输出、Middleware、Checkpoint、Store、人工介入与图执行优先直接采用 LangChain/LangGraph 官方接口。只有官方能力无法满足已确认需求时，才允许基于官方接口在框架外扩展；不得因现有自定义实现与框架冲突就绕过框架另造平行协议。
- **默认不使用 DeepAgents**：项目默认不引入 DeepAgents 等高层封装。只有 LangChain/LangGraph 官方能力确实无法覆盖需求，并已向用户说明缺口、替代方案和功能取舍后，才允许讨论是否引入。
- **供应商适配归基础设施层**：模型供应商 HTTP 协议、鉴权、流式事件转换、用量计费和脱敏回放可以在 `infrastructure` 扩展，但应用层模型调用必须面向 LangChain `BaseChatModel` 及其原生消息、`tools`、`tool_choice` 和结构化输出接口；不得让供应商传输 DTO 成为 Agent 或领域协议。
- **线程与运行职责分离**：`conversation_id` 是 LangGraph 长期会话 `thread_id`；同一会话中的每次用户请求可以建立独立业务 `run_id` 用于审计，但不得再把 `run_id` 当作外层图线程。故障恢复和 Human-in-the-loop 必须复用同一线程及官方 Checkpoint/`interrupt()`/`Command(resume=...)` 语义，业务运行投影和副作用账本不得替代框架检查点。
- **替换即清理**：官方实现替代自定义实现时，必须在同一迁移中删除旧协议、旧仓储、旧配置、旧测试和失效文档入口；不得保留可被误用的新旧双轨。

### 启动脚本
- **一键启动**：根目录 `start.bat`（Windows Batch），启动或复用 MongoDB，并在清理固定端口后启动前后端
- **任何代码变更不得破坏启动脚本**：修改以下文件时，必须验证 `start.bat` 能否正常运行：
  - `pyproject.toml`（依赖、入口点、packages 声明）
  - `.env.example`（配置项增删）
  - `src/taichu/main.py`（FastAPI 启动逻辑）
  - `src/taichu/config.py`（设置字段变更）
  - `web/package.json`（前端依赖、scripts）
  - `web/next.config.ts`（Next.js 配置）
- **破坏性变更时**：同步更新 `start.bat` 并测试
- **本地验证固定端口**：验证本项目前后端效果时，固定使用前端 `http://localhost:3000` 和后端 `http://127.0.0.1:8000`。启动前必须先探测固定端口；若已有本项目 dev 服务且响应正常，直接复用并刷新页面，不另启 `3001`、`8001` 等临时端口。若固定端口被非本项目进程占用或服务异常，需要按 `start.bat` 的约定处理固定端口，不得通过换端口规避验证。前端验证默认使用 `localhost:3000`，不要混用 `localhost` 和 `127.0.0.1` 访问同一个 Next dev 服务。
- **后端源码热重载与验收**：`uv run taichu` 本地开发入口默认只监听 `src/taichu/` 下的 Python 源码并热重载，运行数据和文档变更不得触发后端重启。Codex 修改后端代码后必须等待热重载完成，并通过 `http://127.0.0.1:8000` 的真实接口确认新代码已加载；若监听进程未重载、接口仍表现为旧代码或热重载失败，必须自动按 `start.bat` 的固定端口约定清理并重启 8000 后再验收，不得把重启步骤留给用户。

### 变更联动规则
- **技术栈变更必须联动清理**：当替换某一技术组件（如前端框架、数据库、LLM 提供商）时，必须同步清理旧组件的依赖声明、配置文件、目录结构和相关文档。不允许留下"僵尸依赖"或"孤儿配置"。
- **检查清单**：变更技术栈时至少检查：`pyproject.toml` 依赖、`packages` 声明、`.env.example` 配置项、`AGENTS.md` 中相关描述。
- **旧实现清理规则**：当重构或新实现替代旧实现时，必须同步删除已经不再使用的旧函数、旧接口、旧状态、旧字段、旧前端入口、旧测试和旧文档说明；不得把“暂时不用”的旧实现残留在代码库里。
- **软删除展示规则**：前端所有“删除”操作完成后，已删除条目不得继续出现在普通列表、筛选结果、搜索结果或默认视图中；后端可以用软删除状态字段保留数据，但默认列表、检索和有效知识上下文必须排除软删除数据。

### 代码原则
- **可扩展性优先**：架构设计是第一优先级，代码组织必须为未来扩展留有清晰入口
- **职责边界优先于短期便利**：不得以“当前实现简单”“暂时够用”或“以后再拆”为理由混合不同职责
- **插件发现与注册分离**：扫描和动态导入属于基础设施层，协议校验、注册和查询属于应用层
- **领域层保持技术无关**：`domain` 不得依赖 Agent、LangGraph、LLM、MCP 或具体存储技术
- **Agent 协议归属应用层**：使用 `required_capabilities` 和 `exposures` 集合声明扩展能力
- **跨层契约默认使用 Protocol**：存储、检索等行为契约优先使用 `typing.Protocol`；只有需要共享实现或固定生命周期模板时才使用 ABC
- **开发过程版本不入代码**：某个功能、Agent、Prompt、Schema 或页面在开发过程中的阶段、成熟度、讨论轮次、实现状态和版本演进，只能记录在项目文档或任务文档中，不得为了表达“当前是 v0.x / 第几版 / Prompt v几 / Schema v几”而反复修改业务代码、manifest、常量或默认字段。只有当版本号被机器用于协议兼容、数据迁移、存储格式判定、外部 API 契约或历史数据解析时，才允许在代码中保留稳定版本字段；此类变更必须说明兼容性理由，不得把文档性的版本记录硬编码进实现。
- **Agent 即插件**：新增 Agent = 新建目录 + 实现协议，不改已有代码
- **存储层抽象**：通过 StorageBackend 接口隔离具体存储实现，方便未来切换

### 仓库目录与占位文件
- **禁止 `.gitkeep`**：仓库不得创建、保留或提交任何 `.gitkeep` 文件。
- **目录按需创建**：运行目录、生成目录和规格目录必须由业务代码或开发脚本使用 `mkdir(..., exist_ok=True)` 等方式按需创建，不得依赖 Git 保存空目录。
- **单一资料入口**：根目录 `README.md` 是面向开发者的仓库地图；新增、移动、删除资料入口时必须同步更新该地图。

### 数据宪法
- **Markdown 是唯一文本事实源**：正文、章节级原文和需要保留作者原始表达的长文本，必须以 Markdown 为准。
- **MongoDB 是唯一结构事实源**：角色、地点、势力、物品、事件、规则等作者确认后的结构化事实，只以 MongoDB `taichu.knowledge_cards` 中 `lifecycle=confirmed` 的记录为准。
- **索引都是派生层**：Milvus 中的向量、BM25、graph 以及未来缓存都必须可重建，不得反向成为业务主数据。
- **SQLite/FTS 已废弃**：SQLite/FTS 不属于当前实现或后续预留方案，不得重新引入其依赖、配置、目录、接口或文档决策。
- **AI 不得直接写入 MongoDB**：AI 输出必须先落为 JSON 中间态，经过 schema 校验、来源校验、冲突校验、生命周期校验和作者确认后，才允许由应用层服务写入 MongoDB。
- **JSON 仅作中间态**：AI 结果、Agent 运行、效果评测和 Inbox 工作区的 JSON/JSONL 只用于候选、运行、审计与回放，不得成为结构事实兼容源或回退源。
- **非事实候选必须标记 lifecycle**：需要作者审核、业务确认或评测状态管理的非事实候选必须显式标记 `lifecycle`，取值只能是 `draft`、`confirmed`、`rejected`；业务状态字段可以另设，但不得替代 `lifecycle`。通用 Agent 自动运行记忆和 LangGraph 节点检查点属于纯运行状态，不经过作者确认，不使用事实生命周期；它们分别通过请求序号、自动过期、`deleted_at` 和检查点线程标识管理有效性。
- **运行记忆禁止作者直接操纵**：通用 Agent 运行记忆只能由 Runtime 按策略自动写入、替代、过期和清理。前端、公开 API、Tool 和子 Agent 不得提供单条运行记忆的手动新增、修改或删除能力；作者只能通过正常对话或 Human-in-the-loop（人工介入）节点修正 Agent。删除整个对话时由系统级联软删除该对话的运行记忆，属于对话生命周期清理，不属于作者直接操纵记忆。

### 功能边界
- 专注于**单本玄幻小说写作**场景，系统运行期间只有一个小说上下文
- **不支持多小说管理**：不设计小说列表、小说切换、跨小说检索、`project_id` 或多租户隔离
- **指代默认唯一上下文**：用户提到“主角”“世界观”“当前章节”等内容时，默认指当前唯一小说，不要求先选择小说
- 多个功能入口（知识库、大纲、写作、灵感、审查等），非单一对话窗口
- **多模型支持**：通过工厂模式切换 LLM，预留用量统计接口
- **Web UI 部署**：前后端分离，API 驱动

### 通用写作助手 Agent 产品意图
- **覆盖任意规模的写作相关请求**：通用写作助手不是固定的“检索—写作—检查—生成”流水线，也不只服务复杂长任务；它必须覆盖从一次事实询问、局部分析或小范围修改，到多章节规划、创作和审校等任意规模的小说写作请求。
- **能力边界优先于任务模板**：Tool 和子 Agent 必须围绕稳定、可复用的能力边界设计，不得围绕某个具体用户任务、页面流程或预设任务链专门设计。具体任务是能力在某次运行中的组合，不是能力注册和职责拆分的依据。
- **任务图按请求动态生成**：高层编排 Agent 应根据当前目标选择最小充分执行路径，可以直接回答、调用一个或多个 Tool、调用单个子 Agent，或组织顺序、并行、校验、修复与人工中断节点形成动态 DAG；不得强迫小请求进入长流程，也不得把固定 DAG 写死为通用能力结构。
- **高层编排 Agent 保持全局控制**：高层编排 Agent 负责理解目标、维护计划、全局上下文、依赖关系、执行节奏、结果校验和必要的重规划，不作为设定、写作、审校等单点专家，也不在阶段切换时永久交出全局控制权。
- **总体范式是 Hierarchical Planning + Subagents**：以“分层规划 + 子 Agent”为主导形态；Router、Handoff、Manager-Worker 和 Blackboard 只能作为局部机制使用，不得替代高层编排 Agent 对完整任务的统一管理。
- **能力目录与运行实例解耦**：Tool/子 Agent Manifest 描述长期稳定的能力、权限和调用契约；计划、节点、边和 DAG 属于单次任务的运行状态。Runtime 只能编排已注册的真实能力，不得为当前任务临时补造假 Tool、假 Agent 或任务专用能力。

### 通用 Agent 五层记忆与模型 API 角色
- **三条总原则**：完整存储不等于本轮模型投影；业务归属不等于模型 API 角色；Agent 内部调用轨迹不等于用户历史对话。任何上下文组装、压缩、回放和评测都必须同时遵守这三条边界。
- **五层名称与拼接顺序固定**：所有模型可见输入只能归入“稳定记忆、长期记忆、历史对话、工作记忆、当前请求”五层之一，并严格按 `System Prompt → 长期记忆 → 历史对话 → 工作记忆 → 当前请求` 组装。该顺序让稳定规则位于首部、当前目标位于尾部，同时利用大模型的首尾注意效应；不得重新命名为“稳定背景、相关记忆、过程历史”等近义层，也不得在五层之外另造模型上下文分类。
- **稳定记忆就是 System Prompt**：稳定记忆只承载模型身份标识、基本行为与安全准则、固定权限边界，以及 `Static Capability Index（静态能力索引）` 中 Tool 与子 Agent 的稳定名称、职责和调用属性。它以模型 API 的 `system` 角色传输，并保持内容、顺序和序列化方式尽量稳定，为 Prompt Cache/KV-cache 复用提供稳定前缀。与当前任务或阶段相关的候选字段摘要、完整 Schema、输出 Schema、授权、预算和调用状态不属于稳定记忆，统一进入工作记忆。
- **长期记忆**：只表示跨任务沉淀并按当前请求召回的用户身份、表达习惯、写作偏好、协作偏好和效果反馈，用于优化 Agent 回答方式。当前以 `project_assets/source/workspace/long_term_memory.md` 为维护载体，按二级标题拆成可独立召回条目；它不是小说知识库、正文、外部资料或通用检索结果。长期记忆不放入 System Prompt，因为它会增删、支持上下文压缩、按需召回，并可在规划、重规划或校验等合适时点重新召回。它紧跟稳定记忆，有机会在内容未变化时形成较长的半稳定缓存前缀，但不得假定必然命中缓存。
- **历史对话**：历史事实源只永久保存已经发生的原始 `user.content` 和实际展示给用户的 `assistant.content`，包括 Human-in-the-loop 问答；模型投影由早期摘要、相关历史原文和近期原始消息组成，不默认重发完整对话。摘要只能用于延续语义，不能用于证明用户说过某句原话；历史对话不得包含 `system`/`developer` 指令、工具定义、`assistant.tool_calls`、`tool` 结果、子 Agent 输入输出、DAG、节点状态、错误、重试、Token、预算、授权或输出 Schema。
- **工作记忆**：包含当前计划和节点状态、工具请求与工具结果、召回的小说正文和知识卡、附件解析内容与检索片段、子 Agent 契约化结果、错误与修复记录、本轮启用工具、当前授权、剩余调用次数、阶段结论和待办。工作记忆服务当前任务，会更新、压缩、替换和过期；通过工具召回的小说内容始终属于工作记忆，不属于长期记忆。应用层保存完整工作状态，每次模型调用只能投影当前阶段或节点所需的计划、直接依赖结果、当前待办、约束和近期错误，不得默认重发完整 DAG 与全部调用轨迹。
- **当前请求**：只包含用户最新输入的原始 `user.content`、附件原始引用（附件 ID、文件名等不可变标识）和当前 Human-in-the-loop 原始回答，是本轮最高业务目标。用户原文一个字都不得修改、摘要或与应用生成说明混写；附件二进制、解析全文、检索片段和摘要进入工作记忆，不得把整份附件硬塞进当前请求。当下一条用户请求到来后，上一轮用户请求和已展示的模型回答才转入历史事实源。
- **API 角色不是记忆层**：太初统一模型契约使用 `system`、`developer`、`user`、`assistant`、`tool` 及原生 `tools` 参数表达来源和协议关系。`system` 只承载稳定记忆；`developer` 承载长期记忆、历史摘要、工作记忆和阶段契约；历史原文使用真实 `user/assistant` 角色；最后一条 `user` 只承载当前请求原文；`tool` 只回传与 `call_id` 配对的真实工具结果。网关可以按厂商协议转换角色，但不得改变五层业务归属或把内部数据伪装成用户原话。
- **模型契约必须原生传输**：Tool 输入 Schema、结构化输出 Schema 与工具选择约束必须通过模型 API 的原生 `tools`、`tool_choice`、结构化输出或等价协议字段发送；不得把完整 Schema、伪工具调用格式或 JSON 返回契约渲染进 System Prompt、Developer Prompt 或用户提示词来替代原生协议。提示词可以说明业务目标、权限和语义约束，但不得承担模型可执行协议的机器契约职责。
- **工具动态可用性**：全量静态能力索引归稳定记忆；查询相关能力的字段摘要、入选能力的完整输入输出 Schema、本轮实际启用状态、授权、剩余调用次数和失败/重试状态归工作记忆。原生工具定义需要时通过 `tools` 传输。`assistant.tool_call(call_id)` 与对应 `tool(call_id)` 必须作为完整配对链保存在工作记忆或调用轨迹中，不得只保留工具结果；只有最终展示给用户的 `assistant.content` 才能在下一轮进入历史事实源。
- **Agent 消息作用域隔离**：每个 Agent 调用拥有独立消息作用域。子 Agent 内部的 `system/user/assistant.tool_calls/tool` 消息只属于子 Agent 运行轨迹，不得直接并入父 Agent 历史；父 Agent 只能通过带 `call_id` 的工具结果或明确的工作记忆结果契约接收子 Agent 输出。

### 知识库迁移与字段规则
- 旧知识 JSON 已于 2026-07-11 完成一次性迁移：全部 88 张原始卡备份到 `E:\Taichu\迁移备份\知识库-20260711-151915`，其中 58 张有效卡导入 MongoDB 为 `lifecycle=confirmed`，30 张已弃用重复卡只保留备份、不导入。
- 迁移 `finalize` 已完成，`project_assets/source/knowledge/` 已删除；存储骨架、业务代码和开发脚本不得重新创建该目录，也不得提供 JSON 双写或自动回退。
- 知识卡第一版不维护 `body`、`tags`、`fields`、`confidence`、`source_refs`、`relations`、`foreshadow`、`personality`、`motivation`、`appearance`。
- 知识卡第一版来源使用 `source_origin` 与 `source_note`；类型专属字段直接保存在知识卡顶层，不使用 `fields` 包裹对象。
- **已废弃字段防回归**：`importance` 不是知识卡字段，禁止出现在领域模型、MongoDB 校验器、API 契约、知识沉淀候选、专家 Prompt 字段 schema 与输出示例、评测集 `card`、评测字段权重和测试造数中；候选出现该字段必须校验失败，禁止静默删除或兼容写入。`expected_claims[].importance` 仅表示评测断言优先级，绝不映射为知识卡字段。新增或调整知识卡字段时，必须联动核查领域模型、MongoDB 校验器、schema 注册表、Prompt、候选校验、评测样例与前端展示，并为实际渲染 Prompt 增加回归测试。

### 前端
- **框架**：Next.js + shadcn/ui + Tailwind CSS
- **交付端限制**：当前只维护桌面浏览器中的网页应用。不开发、不适配、不验收原生桌面 App、移动 App、手机网页或平板网页；所有前端改动均以桌面浏览器为唯一交付与验证目标。
- **桌面布局边界**：不将窄屏重排、移动导航或触控交互作为需求。已有相关样式不是本次清理对象，后续新增或修改功能不得为移动端额外增加适配逻辑。
- **前端设计强制规则**：涉及 `web/` 下页面、组件、样式、交互、动效、前端文案或视觉方案的创建、修改、评审和讨论时，必须先读取并遵循根目录 `DESIGN.md`。该文档是太初前端设计的强制规则源，不得只作为可选参考。
- **前端组件准入自动规则**：涉及 `web/` 下前端开发、任务包执行、自动修复、自动重构、前端 review、组件库选择、花哨组件或动效素材时，必须自动使用 `.agents/skills/taichu-ui-components/SKILL.md`。该规则不依赖用户显式要求“使用组件库”。
- **导航模式**：以 `DESIGN.md` 定义的午夜极光控制台风格为准：炭灰画布承载主要页面，深色导航条和灰色线框建立层级，白色胶囊按钮用于主操作，极光渐变只用于少量装饰。
- **视觉方向**：以 `DESIGN.md` 为唯一前端视觉规则源；根路径当前直接跳转到 `/home`，不启用独立点云入口或入口页视觉例外。
- **与后端关系**：纯前端，通过 API 调用 FastAPI（`localhost:8000`），开发时前后端独立启动
- **代码目录**：前端代码位于 `web/`

### 文档规则
- 项目标准文档：README.md、AGENTS.md、DESIGN.md、.env.example、.gitignore
- `docs/学习资料/` 保存对具体实现主题的教学式讲解，生成风格与参考样本以 `docs/学习资料/说明.md` 为准；凡涉及当前行为必须核对源码、测试和真实运行结果，未落地内容必须明确标记，学习资料不得替代源码、测试或接口契约。
- `docs/已讨论功能/` 保存用户在多轮讨论中与 Codex 共同建设的未来计划，未落地内容不得写成当前代码事实。
- `docs/旧历史/` 只保存已经废弃、已经被替代或明确不再采用的旧方案与旧实现快照，严禁用于指导当前实现。
- 上述三个目录的普通文章及配套文件保留日期前缀；只有目录说明统一使用无日期的 `说明.md`。详细规则见 `docs/rule.md`。

### project_assets 目录规则
- `project_assets/readme.md` 是 `project_assets/` 的目录结构说明源，记录该目录下各文件夹职责。
- 当新增、删除、移动或改变 `project_assets/` 下任一目录职责时，必须在同一次变更中热更新 `project_assets/readme.md`。
- 候选运行产物、正式源数据和可重建生成物的边界必须与 `project_assets/readme.md` 保持一致。



---

*最后更新：2026-08-30*
