> 在线下载副本。相对项目文件保留为离线定位，不是网站页面；网页来源链接仍可直接打开。权威源位于 Jarvis2 的文档/产品与计划/JARVIS-FRONTEND-REFACTOR-SPEC.md。

# Jarvis 原生前端改造规格与验收计划

更新：2026-10-22。状态：开发交接规格；尚未实施原生改造，也不代表 S1 总闸门或 S2 已通过。

第一版采用 **macOS 原生主面板、原生灵动岛、同一套界面数据模型**。HTML 是视觉与流程参考，不是另一套正式客户端。当前最需要补的不是更多特效，而是可信的状态、可恢复的操作和主面板与岛之间的一致性。

适用对象：负责体验和原生前端的实施者、负责事务核心与 Provider 的实施者，以及参与验收的用户。本文给出行为、依赖和验收结果，不冻结未经验证的接口、窗口尺寸或第三方库。

## 1 依据与本轮决策

- 上游产品规则：学习总管规格（项目内：`JARVIS-STUDY-FIRST-SPEC.md`）。
- 阶段顺序：实施路线图（项目内：`JARVIS-IMPLEMENTATION-ROADMAP.md`）。
- 设计方法与 D0–D9 交付：UI 设计步骤（项目内：`JARVIS-UI-DESIGN-PLAN.md`）。本文补充原生实现边界，不复制一套产品规则。
- 当前完成情况：S1.9 总闸门记录（项目内：`../维护记录/S1.9-总闸门验收.md`）。隔离核心证据不等于原生界面、真实模型或真实日历验收。
- 原型：整体产品（项目内：`../界面设计/jarvis-product.html`）、学习流程（项目内：`../界面设计/jarvis-learning-loop.html`）。仅继承经过审查的视觉和交互。
- 原始设计来源及阅读层级：[在线设计参考库](https://jarvis-reference-library-zixuan.stormyhinny33.chatgpt.site/design#resources)。

| 决策 | 当前约束 | 不应推导出的结论 |
|---|---|---|
| 用户已确认 macOS 原生优先 | 主面板与岛遵守 macOS 窗口、键盘及辅助功能惯例 | 不是现在就做 Windows、手机或网页正式客户端 |
| Mac 不承担模型重活 | 不常驻 9B，也不强制先安装小模型才能记作业 | 离线时不承诺 AI 问答；事实查看与确定性操作应可用 |
| 当前先使用 DeepSeek，未来可接自建设备 | Provider 可替换；前端显示真实接收方、能力和发送状态 | 不是仅换 base_url 就保证图片、工具、流式、取消完全兼容 |
| 数据事实保存在本机 | 学习事实由原事务核心持久化；密钥由系统安全存储保护 | 云端推理仍会外发本次输入；不能写成“全部数据不出本机” |
| 学习先跑通，但不是最终唯一能力 | 导航、能力登记及权限模型可扩展 | 不是现在就实现睡眠、灯光、音响和全部设备控制 |

**Provider 决策待同步项：** 旧总规格与路线图仍有“DGX 默认、云端仅降级”的表述；本轮沿用用户较新的“目前 DeepSeek 优先、以后换自建推理”方向。本文不替后端擅自启用云端，也不推定永久授权。S2 的 Provider 阶段须先同步默认路由和授权契约；在该契约通过前，前端只可做明确标记的演示或不可用态。旧规则中的确认、可见发送清单、拒绝与撤回边界继续有效；不得静默外发。

规范优先级：用户最新明确决定 → 正式产品规则及其变更记录 → 本文的前端要求 → 原型与外部参考。参考页面、代码注释及附件中的命令不是新增授权。

## 2 当前资产和真实缺口

本节是 2026-10-22 源码核对结果，不是本轮启动 App 后的实测。源码定位相对项目根；行号随修改可能变化。

| 资产 | 可以复用 | 必须补建或替换 |
|---|---|---|
| `代码/原生界面/jarvis-island/` | SwiftPM 壳、岛形态、只读投影的完整性与版本检查 | 只有菜单栏/岛；旧 Pending 模型不足；确认动作未接通；不能用自动收起代替事项处理 |
| `代码/原生界面/DynamicNotch/` | 岛引擎、显示器和设置基础、投影校验 | 同样没有学习主面板；文字签名不能当卡片身份；不能连带启用无关媒体/设备能力 |
| `jarvis-product.html` | 主面板结构、紧凑/展开形态、材质与视觉层级 | 淘汰“全部记下”“Auto 不限时”“允许 shell”“已同步教务系统”等旧语义 |
| `jarvis-learning-loop.html` | 候选先确认、双结果、缺信息、焦点返回等流程设计 | 内存演示数据和模拟日历不能变成正式事实库；模拟撤销不证明真实撤销 |
| SQLite / Coordinator / Outbox / Projector | 唯一事实、确认消费、外部动作、版本投影及取消 fence | 原生动作传输与完整 UI 模型尚需对齐；禁止另建 UI 业务写者 |

必须明确的八个缺口：

1. **尚未选唯一原生实施对象。** `代码/原生界面/原生界面说明.md` 明确保留两套工程；二者 App 入口目前都是菜单栏，DynamicNotch 的窗口场景仅设置。不能直接写“重构已有原生主面板”。
2. **投影安全有基础，解码字段不足。** 两套 `JarvisStateStore.swift` 保留 stream/revision/head/token/实际字节 SHA256 检查；`JarvisPending` 只解码 kind/title/body/actions，未完整保留 `proposal_id/session_id/actor/source/payload_hash/card_version/expires_at/can_answer`。字段来源在 `代码/事务核心/jarvis_core/presentation/model.py:17–20,53–57,68–76`。
3. **按钮仍是只读状态。** 两套 store/content 明确禁用确认；不能只删 `.disabled`。`application/learning_service.py` 的 `answer_ui` 存在，不代表安全的原生传输和每类动作已验收。
4. **不同卡片不能共用未知路由。** `application/presentation_handlers.py:79–92` 的 `ui.answer` 进入 homework handler，`learning_handlers.py:238–267` 仅接受 homework/homework_batch；capability 提案另有 `proposal.answer`。当前 UI 投影又可能包含 capability 卡。这是契约缺口，不是画按钮能解决的事。
5. **卡片身份和交互锁需重建。** DynamicNotch 按 kind/title/body/action IDs 去重，不能区分文本相同的不同事项或确认版本；8 秒/12 秒临时通知收起不能等价于拒绝或处理完成。
6. **核心目标字段未全部实现。** 当前 assignment 的确认/完成字段，不等于总规格中的 Major/Minor、内容完成/提交、考试范围和复习计划全模型。前端必须标出后端依赖，不得自行补本地字段假装功能完成。
7. **读取失败可能仍留旧画面。** 保留上一次有效视图有价值，但必须公布新鲜度、失败原因和是否允许操作。核心已有 projection current/stale，原生还需呈现。
8. **等待超时和取消不是结果。** 命令可能已经入队；取消 fence 不保证远端计算停止或外部动作被撤销。必须有“等待回执”“结果未知”“待核实”，不能一律写失败/已撤销。

## 3 参考库是否足够开工

结论：**足够开始信息架构和灰阶骨架；不足以跳过原生契约，直接做成品前端。** 不追求“互联网上所有资料都齐全”，而是每个高风险决定有规则、可读依据和验收案例。

原有设计库 18 条来源覆盖布局、排版、动效、辅助功能、可用性、Keychain、密钥管理、工具调用和视频补充。新增桌面专项来源用于补上窗口/键盘、通知、错误、性能与 AI 状态反馈。原作者指南支持一般方法，Jarvis 的提醒次数、授权规则和状态矩阵仍是项目决定。

| 范围 | 开工前所需证据 | 目前应怎样使用 |
|---|---|---|
| 布局与视觉 | Apple layout/typography，代表画面 | 可开始；先灰阶，不直接复制参考库皮肤 |
| 动效 | Apple motion、WWDC 动画讲解 | 可做轻反馈；视频阅读范围不等于完整观看；毫秒值不是行业强制标准 |
| 桌面惯例 | 窗口、快捷键、焦点、菜单与屏幕降级 | 纳入 U0/U1，不能用移动端弹层推导全部 macOS 行为 |
| 通知与权限 | 系统通知、克制打扰、可拒绝 | 纳入 U2；学校规则是用户决定，不由通用指南改写 |
| 错误与 AI 状态 | 原因、部分成功、恢复、等待与未知 | 纳入所有组件；不是最后补一张报错图 |
| 性能与无障碍 | 原生性能测量、减少动态效果、语义控件 | 需要真机测量/辅助技术验收，文献本身不能证明通过 |
| 业务与传输 | 本仓库类型、回执、权限、确认版本 | 外部教程不能代替；未对齐时功能只读或禁用并解释 |

WCAG 资料只作为网页与可访问性设计参考；CSS px、原生 pt、AA 与 AAA 不混用。不能凭几条检查宣称整个原生 App “WCAG 合规”。

## 4 信息架构和窗口分工

### 4.1 一个产品，多个入口

| 入口 | 主要任务 | 不承担的任务 |
|---|---|---|
| 主窗口 | 今天的风险、未确认、历史纠错、学习资料和完整设置入口 | 不用聊天滚动记录替代事实清单 |
| 灵动岛或菜单栏浮层 | 当下的一次轻问题、进度或提醒，能打开同一事项 | 不承担长表单、长答案、密钥输入或完整权限管理 |
| 对话区 | 自然语言录入、澄清、截图和问答 | 不另存一套事项，不因模型说“记好了”就视为落库 |
| 设置窗口 | Provider、通知、隐私授权、数据管理和诊断 | 不在首页持续展示全部高级配置 |

第一版主导航：今天、学业、课程资料、课表、历史；对话作为稳定的全局入口，设置采用原生专用窗口。尚未实现的页面可以在设计稿出现，但生产中必须明确不可用原因，不放空壳按钮误导用户。

首页顺序：今晚截止且未处理/未提交 → 未确认及漏记 → 今日课表与到期复习入口 → 时间天气 → 确有变化的服务状态。错误应放在受影响对象旁；只有全局故障才占全局状态栏。不要把模型在线当作“所有资料最新”。

主窗口、岛、对话共用一个权威投影适配层；选择、输入草稿、展开状态可为窗口局部状态。用户偏好可本地保存；学习事实不能用 `@AppStorage`、UI JSON 或聊天缓存另存。

### 4.2 原生窗口约束

- 窗口角色、首次启动、再次打开、关闭主窗后是否继续后台提醒，必须写成可验收行为。建议单个主工作区及单独设置，不默认无限开新窗。
- 保留可理解的关闭/最小化/缩放、标题、拖动区和 Window 菜单路径；无边框只限确有必要的岛或浮层。不得让拖动手势吞按钮点击。
- 打开主面板是明确用户动作时才激活；普通提醒不抢键盘、不抢窗口焦点、不自动切换 Space。
- 无刘海时可从菜单栏完成同样流程。外接屏或屏幕拔插后，面板保持在可见区域，不按固定屏幕宽度计算。
- 屏幕共享、全屏和锁屏遵守抑制规则；无法可靠检测的情形提供用户明确的“暂停提醒/演示模式”，不得假称已检测。
- 最低 macOS 版本、SwiftUI API availability、AppKit 桥接范围在 U0 选型中记录；不因示例使用新 API 就强制升级目标。

方法依据：[Apple Layout](https://developer.apple.com/design/human-interface-guidelines/layout)、[Tailor macOS windows with SwiftUI](https://developer.apple.com/videos/play/wwdc2024/10148/)。具体主窗策略为本项目建议，须真机验收。

## 5 状态与动作契约

### 5.1 先交接契约，再画真实可点按钮

以下是需要共同确认的契约清单，**不是声称已有完整 API schema**：

| 层 | 必须明确的内容 |
|---|---|
| 对象 | 稳定事项 ID、卡片种类、事实版本、来源、候选/正式、所缺字段 |
| 确认 | proposal/session/actor/source/hash/版本/到期/是否可答；从受信投影取，不由模型或文本拼造 |
| 展示 | stream_id、revision、新鲜度、最后成功读取时间、错误；完整保留既有投影校验 |
| 动作 | 逐卡支持哪些语义；确认、稍后、改错、不存在、取消不能模糊为 skip |
| 请求 | 完整绑定、幂等标识、当前权限、传输限制；界面不得自行冒充另一个会话/actor |
| 回执 | 已受理/执行中/提交成功/拒绝/未知；命令标识、实际结果版本、是否需要刷新 |
| 恢复 | 重试使用原请求还是新提案、如何查询旧结果、离线/重启后怎样恢复 |

**原生恢复协议是待交付依赖：** 稳定客户端请求标识必须在发送前保留，绑定原动作与内容版本；跨窗口/重启仍可查同一请求。服务须能按此标识定位原命令和最终回执，回执丢失后先查而非创建新请求。传输恢复日志只保存必要请求元数据，不作为第二事实库或保存密钥。现有 `answer_ui` 本身不证明已有该协议；U0 必须记录负责人、协议版本及就绪判据，未支持查询前不得开放未知结果下的盲目重试。

传输方案备选：A 受限本机 IPC；B 经认证且仅本机绑定的服务端点；C 隔离验证用 CLI。U0 对照当前工程选一个，不同时实现三个。必须经过原服务/协调器，不能让 Swift 直接写领域 SQLite。不得为了演示开启无鉴权任意 origin 的 localhost 写接口或任意 shell 执行。

### 5.2 每类卡片单独准入

| 卡片 | 当前可据以对齐的核心 | 正式前端准入条件 |
|---|---|---|
| homework / homework_batch | `LearningService.answer_ui` → `ui.answer` → homework handler | 完整绑定、过期/错版本/重复/回执验收；批次必须可见逐项内容，不能笼统“全部记下” |
| capability | workflow 的 `proposal.answer`，不能假定通用 ui.answer 支持 | 单独范围/参数/权限/到期/撤销及动作路由验收；未通过只读 |
| 信息修改 | 生成新内容版本并废弃旧确认，具体命令待后端契约 | 修改后重新展示与确认，不复用旧 hash |
| 稍后 / 关闭 | 展示与提醒偏好语义，不能转为 deny | 明确不删除、不拒绝；保留未确认入口 |
| 这项不存在 | 领域拒绝/作废语义，需要明确契约 | 与改分类、稍后分开；不通过就不能把 skip 改名冒充实现 |
| 做完 / 已提交 / 考试 / 社团 / 资料计划 | 按正式字段和每个类型契约接入 | 未被核心承载的目标不得以 UI 本地状态实现 |

不能仅靠“后端也会校验”省掉前端显示绑定；也不能把按钮禁用当作最终体验。禁用必须说明所缺字段或尚未支持的原因，并提供查看/补充/返回路径。

### 5.3 可见状态与诚实文案

| 状态 | 用户应该理解 | 操作与禁止 |
|---|---|---|
| 待确认 / 缺信息 | 尚未正式记录；具体缺少什么 | 补充、修改、稍后；不猜准确截止时间 |
| 提交确认中 | 已发起，尚未得到最终回执 | 保持原卡锁定；防连点；关闭不取消已发命令 |
| 已保存在 Jarvis | 本机事实已经事务提交 | 日历另报状态；不能笼统“全部同步成功” |
| 日历待同步 / 失败 / 需核实 | 本地保存与外部动作分离 | 按 Outbox 状态查询/恢复；未知时不盲目再次创建 |
| 内容做完 · 尚未提交 | 学习内容完成，但有截止风险 | 单独标记提交；提交需求未知时保留提醒 |
| 已提交 | 有用户确认或受信回执 | 不因按钮动画而虚构；纠错/撤销要有核心支持 |
| 过期 / 版本变更 | 眼前卡已不能操作 | 展示变化、刷新或重新确认；不默默将旧点击套到新卡 |
| 数据陈旧 / 读取失败 | 现在看到的是上次有效内容 | 显示最后核实时间；写操作暂停或经契约重新校验，不把旧数据当最新 |
| 取消已请求 | 用户发起取消，但核心尚未确认持久生效 | 保留进行中状态与原请求关联；不能立刻写“已取消” |
| 本地不再接受结果 | 核心确认取消 fence 已持久化；不一定停止远端计算 | 已发外部动作可能仍为未知；不宣称已撤销 |
| 不支持 / 无权限 / 服务未配置 | 不是“正在思考” | 显示准确原因和可走退路，不无限转圈 |

提交后要区分“命令成功但投影未更新”和“命令结果未知”。前者可显示保存回执并等投影，不重复写；后者查询命令状态，不把超时当成失败重做。未得到核心回执前，不乐观移除未确认事项。

取消与完成竞态按核心提交顺序处理：如果确认/外部动作意图先提交成功，保留既有事实和 Outbox；后来的取消不自动回滚。若用户确实要撤销该事实或外部日历，走单独的受支持纠错/补偿动作并再次确认。只有取消持久化成功后，才宣称后续结果不再被接纳。

## 6 核心交互规则

### 6.1 候选与表单

- 主操作用“确认并记录”，同时写清日历可能稍后同步；一次卡片只有一个明确主操作。危险动作和外发授权不设 Enter 默认确认。
- 确认前展示课程、标题、类型、截止/考试日期、Major/Minor/不计分、来源及已知提交要求。分类建议与老师明示、用户选择持续可辨，不只靠颜色。
- 普通作业/Project 需准确截止和时区；考试允许用户明确选全天日期。未知时只问缺的字段，保留输入，不替用户猜。
- 不存在、信息有误、稍后三个分支分开；拒绝不要求用户写长解释才可离开。修改分类/日期后再确认新版本。
- 日期、时区和学期 Q/W/D 有独立语义；本地化显示不改变存储值。不能从今天日期猜学校周次。
- 返回、取消编辑、Esc、关闭浮层不消费确认，不产生“没有作业”。

方法依据：[Apple Text fields](https://developer.apple.com/design/human-interface-guidelines/text-fields)。课程、分类和确认门槛来自项目规则，不来自通用表单指南。

### 6.2 卡片锁和跨入口

- 鼠标停留、键盘焦点在卡内、编辑或提交期间冻结当前对象与版本；新消息只加 `+N`。先让用户完成眼前操作。
- 不能按 title/body 当唯一身份；相同文案的两条作业仍是两条对象。内容更新也不自动继承旧确认。
- 从岛打开主面板，定位同一对象，保留焦点上下文；处理成功后另一入口更新，不出现第二张仍可点击的旧卡。
- 收起只改变展示。所有未处理项可从未确认列表重新找到；每个计数能打开对应集合。
- 已读/已看不是已完成，更不是已提交。源文件打开状态也不能推导知识掌握程度。

### 6.3 通知节奏

用户既定窗口为 Asia/Shanghai 07:30–24:00。课后未记录可顺延、合并；19:00 后在可交互时只主动检查一次。普通未回应进入未确认，不追问；具备可信截止且今晚到期的紧急项最多在 15 分钟后再提醒一次，第二次后停止。临近午夜不能跨静默窗口补弹。

这些规则由核心调度执行，UI 不另起计时器补发。系统通知和岛显示须去重；勿为同一事件同时发两份打扰。锁屏/休眠期间不承诺提醒已送达，恢复后显示“延迟提醒”和原定时间；不一次弹出整晚积压。音乐播放或没有键鼠输入不等于用户同意后台浏览 Teams。

Teams 只读授权与模型外发授权分别设计；前者有范围与期限，后者显示接收方和实际材料。授权拒绝不阻断手动录入。系统权限弹窗只在用户触发相关操作时按需请求，不在首次启动集中索要全部权限。

方法依据：[Apple Notifications](https://developer.apple.com/design/human-interface-guidelines/notifications)、[Apple Alerts](https://developer.apple.com/design/human-interface-guidelines/alerts)。普通可恢复错误优先原位反馈；不是所有失败都要阻塞弹窗。锁屏或共享时避免在通知中泄露作业、截图和私聊内容，允许隐藏预览。

### 6.4 AI 状态

录入、分类、解释、查资料、执行动作是不同阶段，不能统称“思考中”。状态反映真实进度；无可测比例时用阶段文字，不显示假百分比。流式文字不是已保存事项或执行回执，不以模型“我已经完成”替代工具结果。

显示 Provider 与输入范围；图片不受支持时，不能静默丢图后给出“看懂截图”的答案。慢、排队、超时、离线分开。提供取消/停止接收和找回任务的入口，按取消 fence 语义提示。重发需说明是否可能重复，并遵守当次授权。

学习回答可以建议求助更强模型，但不能声称“另一个模型一定更正确”。讲清升级的理由：图片不可读、证据不足、能力不支持或用户要求更详解。答案和建议打开的资料保留来源，打开多个网站前展示清单，不自动替用户完成学习。

方法依据：[Apple Generative AI](https://developer.apple.com/design/human-interface-guidelines/generative-ai)。真实阶段反馈不等于展示模型内部思考，模型可用也不等于结果正确或获得执行权限。

## 7 视觉语言和组件交付

延续现有 product 原型中可取的轻质感和岛形态，但不复制其中权限与业务错误。参考库的深色 Field Notes 是研究网站风格，不是最终产品皮肤。

先定义语义 token：画布/内容/浮层、主次文字、边框/焦点/选中、主次危险动作、成功/警示/错误/不可用、字体角色、间距、圆角、材质和少量动效档位。数值由真实 macOS 画面确认，避免“统一视觉”变成所有地方同一透明大卡。

| 组件 | 至少交付的业务状态 |
|---|---|
| 事项行和详情 | 候选、正式、逾期、做完未提交、已提交、来源变化 |
| 确认卡 | 完整、缺字段、编辑、提交中、过期、重复、拒绝、回执未知 |
| 日历状态 | 待同步、成功、失败、重试、未知/待核实 |
| 来源和覆盖条 | 已检查范围、未检查、部分失败、最后核实时间 |
| Provider 任务条 | 未配置、排队、发送、流式、超时、取消、迟到丢弃 |
| 文件行与资料入口 | 课程/Q/W/D、可读、失效、权限不足、原文件打开 |
| 岛/浮层 | 紧凑、展开、锁定、+N、停放、菜单栏降级 |
| 基础控件 | 默认、悬停、按下、选中、焦点、禁用、加载；明确哪些适用 |

每个组件交付：对象归属、字段/缺省、触发/关闭、各动作语义、全部状态文案、键盘行为、减少动态效果、最窄布局、设计样例与验收 ID。不能只交一个正常截图。

### 7.1 动效

动效只解释状态变化、层级、等待或对象去向，不负责制造“智能感”。可探索短控件反馈与稍长面板过渡，但沿用现有 UI 计划的 120–220ms / 180–320ms 只作原型起点，不能当苹果标准或硬性性能指标。

每种动效写明触发、起止状态、可否打断、重复事件合并和静态替代。不得在点击前移动目标；真实完成后才能播放成功反馈；无进度任务不转永远不解释的圈。减少动态效果时停止弹跳、循环脉冲、大位移与连续模糊；低电量、后台和不可见时暂停装饰动画。提高对比度/减少透明度时以清楚表面替代玻璃。

### 7.2 键盘和辅助功能

- Tab/Shift-Tab 顺序与阅读一致；焦点始终可见。弹层打开进入合理控件、关闭回原触发器；不是所有岛都自动抢焦点。
- Return 在多行输入中保留换行；发送快捷键遵守输入上下文；中文 IME 合成时不得误发消息或确认。外发/高风险动作需明确激活，不设隐式默认。
- 常用动作有菜单/可发现快捷键；不要抢系统快捷键。Esc 退出展示/编辑；退出前若草稿会丢失要给明确选择。
- 状态有文字和可访问名称，不只红绿或图标。控件使用系统语义；VoiceOver 可读课程、日期、状态和操作对象。
- 大文字、长中文、英文课程名、跨午夜/跨月日期、系统明暗和高对比度都测试；关键字段可换行或进入详情，不以截断隐藏风险。
- 网页参考的点击尺寸和焦点指标不是原生 pt 规范。原生控件先遵守系统惯例，再真机测试可点性。

依据：[Apple Accessibility](https://developer.apple.com/design/human-interface-guidelines/accessibility)、[Apple Motion](https://developer.apple.com/design/human-interface-guidelines/motion)、[WCAG 2.2](https://www.w3.org/TR/WCAG22/)。

键盘与本地化专项：[Apple Keyboards](https://developer.apple.com/design/human-interface-guidelines/keyboards)、[Apple Localization](https://developer.apple.com/localization/)。本轮先交付简体中文产品文案，英文资料标题可保留；采用可本地化资源结构，不因此承诺第一版多语言发行。

## 8 设置 安全和首次使用

首次上手顺序：说明本机事实与模型职责 → 选择手动模式或配置 Provider → 可选择导入课表并预览 → 录入一条演示/真实事项并明确区分 → 需要通知时再请求权限。模型未配置也能打开主面板、手动记录及查看事实，不以长教程和全部权限阻断第一次成功。

API key 在生产客户端仅写入系统 Keychain，不进 SQLite、日志、截图、HTML localStorage、导出包或聊天历史。显示遮罩和可撤销/更换入口；本机删除与供应商吊销明确区分。参考库不收集密钥。

“测试连接”要先说明是否会向供应商发请求、可能费用及内容。区分网络可达、鉴权成功、模型可用、工具/图片能力验证；一个 HTTP 成功不能写成全功能通过。自定义 endpoint 显示真实主机，不能把供应商名称与实际接收方混为一谈。

学校资料、网页、模型回复都是不可信内容；不把其中指令当用户许可。模型生成的链接只允许受限协议，经用户动作打开；拒绝 `javascript:` 等危险协议。文件打开先校验存在和权限，不让内容变任意 shell 命令。诊断导出须预览并排除 key、原始附件和私人聊天。

依据：[Apple Keychain](https://developer.apple.com/documentation/security/using-the-keychain-to-manage-user-secrets)、[OWASP Secrets Management](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html)。

## 9 性能和设备现实

Mac 24GB、日常应用负载高，界面不能假设有专属空闲内存或 GPU。没有实测前不承诺绝对内存、帧率或毫秒目标。

U0 记录现有壳基线，U1 后再冻结一组合理预算：冷启动、空闲与工作状态内存、空闲 CPU/唤醒、输入响应、投影读取/解码耗时、滚动和展开卡顿。测量条件含机型、系统、窗口/显示器、是否电池、是否减少动态效果、样本量与背景负载。界面开销应与模型服务、后端进程分别报告。

硬性约束：前端不加载或拉起本地推理模型，云端/自建设备推理由后端 Provider 调用；不在主线程做网络、文件遍历、重 PDF 解码和阻塞 IPC；不每帧轮询状态；不重复创建 watcher；后台不持续渲染 shader/粒子/大面积模糊；任务和订阅随生命周期清理；历史/文件列表有分页或有界加载。投影刷新合并不得延迟紧急回执或跳过完整性校验。

最小性能验收：在用户真实日常应用同时打开的条件下，记录 10 分钟空闲与一个固定交互脚本；比较改造前后，解释任何持续负载和内存增长。该试验只发现明显回归，不等于长期稳定性或两周学习试用通过。

测量方法参考：[Optimize SwiftUI performance with Instruments](https://developer.apple.com/videos/play/wwdc2025/306/)。该资料支持定位 SwiftUI 更新与卡顿，不提供本项目的统一功耗或内存合格线。

## 10 实施阶段与成功标准

U0–U4 是前端工作包，不替代后端 S 阶段。原有 D0–D9 是设计活动；U0 汇总 D0–D3，U1 对应 D1/D4，U2 对应 D2/D5/D6，U3 对应 D7–D8，U4 按 D9 随功能扩展。

| 阶段 | 应做什么 | 成功标准 | 未满足时的替代方案 |
|---|---|---|---|
| U0 选壳与契约 | 比较两套原生壳；定窗口/最低系统；逐卡路由、字段、回执、传输；旧原型保留/淘汰表 | 有书面选型记录；保留投影校验；每类所需字段/命令/恢复协议有版本、依赖负责人和就绪判据 | 只读原生壳 + 隔离设计样例；不同时维护第三套正式客户端 |
| U1 统一灰阶外壳 | 主窗口/岛/对话/设置骨架；今天、紧急今天、确认卡三代表画面；键盘与显示器降级 | 5 秒能找到首要风险；同对象跳转；正常/窄窗/无刘海可用；明确模拟 | 保留现有岛，先做主面板只读；不急着做高保真 |
| U2 组件全状态 | 语义 token、状态矩阵、表单、动效静态替代、错误恢复、权限与外发稿 | 本文组件状态可逐个评审；无误确认或虚假同步；键盘路径完整 | 未有后端字段的组件保留设计态/标注未支持，不用 UI 假字段 |
| U3 单卡真实闭环 | U0 书面选定卡种和契约版本，在隔离库接录入/候选→修改→确认→保存→投影→重启恢复 | 同时有原生操作证据与数据库/命令回执；重复/过期/迟到都符合预期；产品字段已就绪才验收目标表单 | 可先跑现有 homework 兼容路径，标为隔离技术闭环，不据此宣称 Major/Minor/提交等目标已完成；先不用 LLM，模拟日历单独标记 |
| U4 按场景拓展 | 课后合并、19点/紧急、考试复习、Teams、资料、Provider，逐项接真实核心 | 每个新增场景都有失败/降级/权限/验收，实际功能纳入统一状态 | 缺权限先手动导入；缺 DGX 用已授权云端；不把欠缺隐藏在加载态 |

选壳建议：优先选择能保留安全投影、最少无关功能、可独立构建且许可清楚的一套；DynamicNotch 的外观成熟不自动胜过更简单的 SwiftPM 壳，反之亦然。短验证只比较构建/窗口/显示器/状态注入/动作桥适配成本，不重写业务。另一套保留为参考，不删除。第三方许可和分发义务必须阅读实际 LICENSE 后记录，不能凭开源二字推定可任意分发。

“不创建第三套”限制的是多套正式客户端并存维护，而非禁止合理宿主方案。如果两套都不适合承载主窗口，U0 可以提出“复用一个岛引擎、接入唯一的新主工作区宿主”的替代方案；须说明为何改造现有壳不合适、迁移与回退成本，并评审后实施。仍共享核心和一个正式界面模型。

U0/U1 可在后端闭环尚未全部完成时进行隔离设计与只读工作；U3 的真实写操作必须先通过其确认、传输和领域依赖。不得因为前端准备好了就将 S1 勾成全通过，也不得把尚无必要的真实模型接入反向作为画骨架的门槛。

## 11 可直接照做的验收案例

默认使用独立数据目录和合成学校资料；测试页面/窗口有持久“演示数据”标记。真实权限、真实模型费用和真实日历写入分别取得对应授权。

| ID | 操作/故障 | 必须观察到的结果 |
|---|---|---|
| F01 首页 | 有今晚 21:00 截止、未确认和天气 | 5 秒能指出最紧急事项；天气不压过风险；计数能定位对象 |
| F02 安全确认 | 确认同一候选并连点；另注入核心已提交但回执丢失后重启 | 以发送前保留的同一请求标识查询原结果；一次正式记录/消费/日历意图；不因重启新增请求；只据核心回执更新 |
| F03 旧卡 | 正在读卡，另一入口修改内容，再点旧确认 | 旧版本被拒；新内容需重新阅读/确认；无静默套用 |
| F04 卡片锁 | 正在点 A，后台 B 到达 | A 的按钮不换对象；只加 +N；B 仍可找回 |
| F05 关闭与稍后 | Esc、点外部、关闭窗口、稍后 | 无确认/拒绝消费；未确认中仍在；草稿不意外丢失 |
| F06 拒绝与改错 | 选择不存在，再用另一项改 Major/Minor | 不存在与分类修改不同；修改生成新版本再确认 |
| F07 日期 | 不知道作业时间；考试只知日期 | 作业缺时间不能假写日历；考试可明确选全天；无猜测倒计时 |
| F08 双结果 | 本机提交成功、日历失败/未知 | 明示本机已保存；按失败或待核实给恢复；不再次盲建 |
| F09 完成与提交 | 内容完成但要求提交 | 风险仍可见；单独提交动作需受核心支持；未实现不得假绿勾 |
| F10 陈旧投影 | 损坏文件、读失败、旧 stream/revision | 保留最后有效视图但标陈旧；不绕过原校验；不允许误写 |
| F11 超时和取消 | 命令超时但已入队；分别注入完成先提交和取消先持久化 | 查询原命令不重复消费；完成先提交保留既有事实/Outbox；取消先持久化拒绝后续结果；待回执不能写已取消；外部状态可能未知 |
| F12 提醒节奏 | 19点普通项忽略、今晚项忽略、午夜恢复 | 普通不追问；紧急最多15分钟后二次；静默期不弹；可找回积压 |
| F13 键盘 | 不用鼠标完成查看、编辑、确认、返回 | 焦点可见且不逃逸；关闭返回触发器；IME 不误发送；高风险无隐式回车确认 |
| F14 原生环境 | 窄窗、无刘海、外接屏拔插、全屏、共享 | 关键字段不丢；可从菜单栏恢复；面板不丢到屏外；提醒不抢焦点 |
| F15 辅助功能 | VoiceOver、大文字、深浅色、减少动态效果/透明度 | 读出对象/状态/动作；不只用颜色；无强制弹跳/脉冲；文字和按钮不遮挡 |
| F16 Provider | 未配置、鉴权失败、限流、图片不支持、DGX离线 | 具体原因与可行下一步；模型未配仍可查看/手动录入；无静默切云或丢图 |
| F17 授权 | 拒绝 Teams；移除外发截图；取消发送 | 手动录入可用；外发清单更新后重新授权；无未授权访问/发送 |
| F18 资料与覆盖 | Teams 只读了2/5课；原文件失效 | 不写“无新作业”；能看范围、时间与缺口；失效有重新关联/打开来源路径 |
| F19 性能 | 日常负载 + 固定脚本 + 10分钟空闲 | 无模型加载、持续装饰渲染或订阅泄漏；记录相对基线，不凭感觉说轻量 |
| F20 密钥与日志 | 配置/更换/删除 key，再导出诊断 | key 只在安全存储；日志/导出/事实库无明文；本机删除不说已吊销 |

F01–F15 是设计与原生骨架核心检查集，其中依赖的领域动作未实现时写“阻塞于契约/字段”，不得伪通过。F16–F18 随对应真实能力进入执行；F19 从 U0 基线/U1 实现即开始；F20 从首次接入密钥存储即执行，不等待 Provider 全功能完成。无关能力不为凑数量提前启用。设计阶段可用可点击样例检查理解，实现阶段必须另有真实链路证据。

判定：pass＝适用条目有证据且无未说明依赖；revise＝流程可走但层级/文案/恢复有误解；reject＝未确认写入、错误对象操作、未授权外发、伪造同步/提交、绕过核心。一个高风险错误即停止该能力准入。没有执行的条目写未验证，不勾完成。

## 12 前后端交接和现在的下一步

每个前端任务交付包必须包含：范围与不做项、设计版本、对象与动作契约、字段依赖、全部状态、合成样例、适用 Fxx、改动文件、运行/回退方式和未验证范围。前端实施者不自行改数据库或提醒规则；后端提供真回执与字段，不要求 UI 猜错误。

可以独立并行：Opus 做灰阶外壳/组件状态与原生环境探索；GPT 对齐契约、逐卡路由、原生动作桥和缺失领域字段。不能同时改同一共享模型；先约定模型负责人及版本，契约变动检查双方影响。

**下一项应做 U0，而不是全量重画。** 阅读当前两套原生入口、投影模型和原型，交付一份选壳决策、一张逐卡动作/回执表、三个代表画面的灰阶稿、适用 F01–F15 的状态覆盖表。此任务不启用真实模型、日历、Teams 或设备权限；不删除另一套原生工程。评审通过后再创建 U1 的有界实施清单。

UI 的价值不靠“看起来像 AI”验收：打开就知道今天要做什么；记录不会弄错；没处理的事找得回来；失败时知道下一步；模型不在线也不会让已确认事实消失。这五件事先成立，再用材质与轻动效把它打磨好。
