# CY-01｜Cindy 的文档与软件结构

核验日期：2026-10-10。本章以复制到本版本的 Cindy 文档和源码为依据，学习怎样从需求找到规则，再把规则对应到实现。阅读基线为 `5888d140db4f58af77f154f745ac2a047cb5da69`，采集时工作区状态为空，见 [仓库版本记录](<../../资料记录/仓库版本.json>)。本次只读分析客户端相关模块，没有启动 Cindy 或验证外部服务。

![Cindy 文档与软件结构逻辑架构图](<../../图表/CY-01_架构.svg>)

## 1. 建立项目阅读入口

理解一个大型仓库，首先需要三种不同的入口。项目规则说明改动应遵守什么；规范索引说明哪里有适用规则；仓库地图帮助找到实现位置。它们不能互相替代：地图中的一句话不等于完整接口契约，规则提出的要求也不能证明所有旧代码已经满足要求。

[docs/README.md](<../../sources.html#ref-7d36283eed1214>) 逐项登记文档类型、状态和治理模块。[仓库地图](<../../sources.html#ref-ad87aa7fb2d489>) 明确自己只做定位导航，目录的 `package.json`、README 和实现代码才是具体事实来源。阅读时记下提交、工作区状态和文件位置，避免把旧整理稿的路径当成当前事实。

本章使用的阅读顺序是：先看索引和地图，找到涉及的规则；再看包清单和接口；最后沿一条任务调用链追到代码。源码副本方便离线回查，并不代表复制了整个可运行仓库。

## 2. 文档分类决定适用范围

索引把 `authoritative` 定义为对治理模块有约束力，参考材料则可能是设计、研究或历史记录，需要看正文判断完成状态。权威性来自登记与适用范围，不能只看文件名、篇幅或修改时间。

| 文档类型 | 回答的问题 | 阅读时的判断 |
|---|---|---|
| 产品规则 | 用户看到什么行为、功能边界是什么？ | 核对治理的产品场景 |
| 开发规则 | 依赖、进程、配置、数据和交付怎样组织？ | 核对改动是否命中读取时机 |
| 设计规则 | 界面语言、组件与交互遵守什么？ | 不以源码旧样式代替规则 |
| 技术设计／参考 | 某项方案怎样设想或落地？ | 继续确认实现与当前版本 |
| 研究／历史记录 | 某次问题发现了什么？ | 保留当时条件与未覆盖项 |
| 索引／地图 | 到哪里继续查？ | 不把导航摘要升级为事实合同 |

例如 [Pi 长工具研究](<../../sources.html#ref-73fa23b0a5e810>) 给出了具体取证和旧测试记录，可以支持开发案例；它不自动成为所有 Agent 的统一恢复规范。遇到规则与代码不一致，应登记“规则要求”和“当前观察”两列，再确定维护位置，不能任意选择一项抹掉另一项。

## 3. 从需求定位文档

以“手机发起一项只读资产清单检查，并把执行状态显示回来”为阅读需求。先列出涉及的行为：手机控制桌面、指定工作目录、调用工具、事件返回和持久记录。随后进入 [远程与手机适配规则](<../../sources.html#ref-6c98e874a9f60a>)、[Electron 进程边界](<../../sources.html#ref-2ae4d54d5d5b0d>) 和 [maker-core 行为规则](<../../sources.html#ref-b35bfce00f1f89>)。

这条路线会把三个容易混淆的问题拆开：文件实际在哪里，谁有执行能力，谁展示结果。手机路径不能自然当成本机路径；界面显示“运行中”不能证明执行进程仍存活；提供一个工具说明不能证明本次调用已经被授权。

然后查 Mobile 控制入口、device-link 白名单、被控 Desktop 的发送入口与事件链，最后寻找覆盖对应行为的测试或记录。这是一条静态阅读路线，本章没有实际发起手机调用。

## 4. 多端与共享模块地图

Desktop 使用 Electron，Mobile 使用 Expo／React Native。两者共享部分契约与能力包，但运行位置不同。当前 [Mobile 包清单](<../../sources.html#ref-8513444a514373>) 直接依赖 `device-link`、`maker-shared` 等包，没有直接依赖 `maker-core`；因此不能把手机画成在本地执行同一套 Agent 核心。

| 模块 | 本次确认的职责 | 不能由此推出的结论 |
|---|---|---|
| `apps/desktop` | UI、宿主、IPC、持久化和本地执行适配 | 所有逻辑都应放在 Main |
| `apps/mobile` | 控制端连接、会话展示与设备交互 | 手机上运行完整桌面 Agent |
| `maker-core` | Agent 抽象、Session 与事件编排 | 不需要 Node 或供应商依赖 |
| `maker-shared` | 跨端展示契约 | 负责桌面数据库副作用 |
| `device-link` | 跨设备协议客户端、隧道准入等 | 客户端代码证明服务端鉴权正确 |

[maker-core/package.json](<../../sources.html#ref-27ffac7e144b2b>) 不含 Electron 依赖，但包含 SDK、模型资料包等依赖，部分实现使用 Node。所谓“零 Electron 依赖”是明确的解耦边界，不是“零依赖”或可直接在浏览器运行。

仓库地图和 [device-link 包清单](<../../sources.html#ref-3413df29082900>) 的描述仍写“零依赖”，实际 `dependencies` 已包含 `@cindy/device-link-protocol`。可以保留 WebSocket 由宿主注入的设计认识，依赖图则必须包含协议包。这个差异说明摘要也需要随实现维护。

## 5. 界面与执行之间的边界

Renderer 负责展示、表单、交互状态与无特权纯计算。preload 通过 `contextBridge` 暴露按用途命名的方法；Main 管理持久化、系统能力与相关校验。可复用领域逻辑进入 packages，通过接口接收宿主能力，不能反向导入 Desktop Main 或 Renderer。

当前输入主路径可以在 [makerChatStore.ts](<../../sources.html#ref-6a8e22c24fac78>) 看到 `input.enqueue` 调用；[preload.ts](<../../sources.html#ref-8486ab5d6fa7a7>) 把它映射到 `maker:input:enqueue`。Main 的 [register.ts](<../../sources.html#ref-dad802d99d7e18>) 接入输入协调器，实际派发委托 `sendToAgentAccepted`。

兼容的直接发送入口仍存在：[sessionSendHandler.ts](<../../sources.html#ref-b2890a80e09245>) 校验入口并委托 [makerSendTransaction.ts](<../../sources.html#ref-38135b8d13e5a4>)。因此图中应画“现代入队路径”和“兼容直接入口”汇入同一事务，不能把所有 UI 发送都简化成直接 `maker:send`。

preload 暴露的方法名清楚，并不意味着参数天然可信。规则要求 Main 在产生副作用之前校验来源、结构和归属；规则同时承认存量 handler 仍有未统一部分。本次阅读不能支持“所有 IPC 都已完成审计”的结论。

## 6. Agent、模型与工具的接口位置

[BaseAgent](<../../sources.html#ref-debd299af146f2>) 给不同执行器提供统一抽象，包括能力声明和 `startSession`。不支持的能力可以明确报错，不能因接口名称相同就推定 Claude Code、Codex、Pi 的所有行为相同。

[Maker](<../../sources.html#ref-01bc9befe9e78d>) 组织 Agent 与存储等依赖，创建会话时调用对应 `agent.startSession`，取得执行句柄后建立 [Session](<../../sources.html#ref-01b2959f287d7e>)。供应商／运行器事件经过适配形成共享事件，宿主再消费。模型提出工具动作、执行器运行工具、宿主维护产品状态，职责各有落点。

Ghost 相关能力由 [发现文档](<../../sources.html#ref-ef515727bbe420>)、[MCP 工具入口](<../../sources.html#ref-1dea6aaf5d8734>) 和 [Desktop 适配](<../../sources.html#ref-2973838b2a65f9>) 共同定位。工具发现、手册阅读与实际派发是不同环节，具体调用过程放在 CY-02。

## 7. 状态、数据和配置的归属

至少区分输入队列状态、执行 Session 状态、持久消息记录和界面投影。Renderer 中的缓存可以重建，不能代替持久事实；收到一条广播也不能证明所有异步写入已经完成。

[sessionEventPipeline.ts](<../../sources.html#ref-ae00b7053526c2>) 按顺序调用准备、静默输出投影、流记录、事件交付、终态处理、快照和 usage 记录。源码把它称为同步交付边界，同时说明被接受的异步写入仍保留原轮次；不能把函数同步返回误解为数据库全部 flush。

[数据库规则](<../../sources.html#ref-b9af39ca5c5244>) 只治理 Desktop SQLite，不含服务端数据库。媒体也不是消息正文中的任意路径，本次未追完媒体实现，因此这里只确认其属于宿主受控资源层。

配置还要区分系统默认与用户自定义。[配置契约](<../../sources.html#ref-956e829fccbcc1>) 要求保留 override 的存在性。模型显示开关采用 `override ?? 当前 defaultEnabled`，显式 `false` 有效；恢复默认删除对应 override。该合同与所有消费方已经一致是两项不同结论，后者需要逐项验证。

沿状态追踪时，先给每项事实找归属，再问界面怎样投影它。例如用户点发送、协调器入队、执行器接受、工具返回和消息保存，应分别记录触发者与观察值。发生争议时回查拥有该事实的模块，不能凭界面文字反推全部底层行为。

## 8. 把结构与证据放在一起

| 需求／规则 | 模块或接口 | 可回查证据 | 当前证据边界 |
|---|---|---|---|
| 用户输入进入执行 | preload、输入协调器、发送事务 | 上述三段代码入口 | 静态调用关系，未真实发送 |
| Agent 核心可复用 | BaseAgent、Maker、Session | 包清单与核心源码 | 不证明所有平台可运行 |
| 手机远控准入 | device-link allowlist | [allowlist.ts](<../../sources.html#ref-d9d0cb4160c739>) | 双层准入设计，非服务端审计 |
| 插件实时可见性 | `classifyGhostVisibility` | [ghostVisibility.ts](<../../sources.html#ref-a4a42155ea1d1d>) | 当前源码含下线分支 |
| 默认与覆盖分离 | 配置消费者 | 配置权威文档 | 未遍历全部消费者 |

还有一项细节差异：Ghost 发现文档的部分旧判序没有列出下线状态；当前函数在账号可用之后、工作目录停用之前检查 `retirement`，返回 `GHOST_RETIRED`。判断当前执行关系应以该函数为依据，维护文档时补上遗漏。

## 练习与验收

为“远程读取一份资产清单”写一条阅读路线，使用 [调用与开发交接模板](<../../模板/Cindy调用与开发交接.md>) 登记执行位置、适用规则、入口、参数、返回与未验证项。交付一张调用图和一张证据表。

验收时，读者应能沿链接找到每个关键节点，分清控制端和执行端，并解释“入队接受”“工具完成”“持久记录”“用户目标完成”的区别。图中若出现未经读取的服务端模块，只能标成外部边界，不能填入臆测的内部步骤。

![本章思维导图](<../../图表/CY-01_思维导图.svg>)

## 来源与衔接

来源为上述 V2.0 内 Cindy 文档和源码副本，导航到完整规范见 [规范索引](<../../sources.html#ref-7d36283eed1214>)，结构约束见 [架构不变量](<../../sources.html#ref-963bcda8ceb9f0>)。运行与开发两条线见 [CY-02](<CY-02_Agent使用与开发过程.md>)，工程迁移见 [CY-03](<CY-03_工程原则与迁移.md>)。用户提供的“TapTap CEO 与纯 AI 开发”属于项目背景，本次客户端源码阅读不能证明具体人员身份、贡献比例或开发方式。
