文档:集成本地构建发布契约

This commit is contained in:
2026-08-12 21:27:51 +08:00
parent 5b44864265
commit 6e822ccf7c
14 changed files with 156 additions and 36 deletions

View File

@@ -6,11 +6,11 @@
|---|---|---|---|
| 登录续期 | Renderer 活动信号 | Main Works Session | 连续 7 天未使用才清除会话 |
| 项目创建 | 新建项目对话框 | Host API → Main 项目初始化 | 创建时固定 `ProjectType`;小游戏/小程序原子生成受控模板,自定义只生成项目空间 |
| 一键提交 | `ProjectPublishAction` | Renderer capability → Host API → loopback preview preflight → Main packager → Works Square 版本上传 | 只对小游戏/小程序开放;本地预检只做 UX fail-fastMain 随后打包、自动版本、幂等重试和脱敏Renderer 轮询云构建 |
| 本地预览检查 | 当前项目内置浏览器 loopback URL | fresh Electron WebContents/CDP桌面、移动 | 检查错误、白屏和外域;不调用 Playwright/Vite,不产生 receipt/provenance不替代服务端门禁 |
| 一键提交 | `ProjectPublishAction` | Renderer capability → Host API → Main 本地 npm/Vite build → built snapshot preflight → source+built+contract 上传 | 只对小游戏/小程序开放Main 自动版本、幂等重试和脱敏Renderer 轮询服务端校验/固化状态 |
| 构建产物预检 | Main-owned built snapshot | 一次性 loopback origin → fresh Electron WebContents/CDP桌面、移动 | 检查错误、白屏和外域;不调用 Playwright检查与上传归档相同字节,但不产生可信 receipt |
| 提交绑定 | 云端成功上传响应 | Main → submission binding v2 | 只持久化成功的 app/version/review/hash落盘失败返回固定告警但不反转提交 |
| 运营发布 | Works Square 审核与交付 | 公共 `play_url` | 客户端只消费服务端发布结果;真实 Builder → OSS/CDN 生产链仍待整链验收 |
| 可信发布门禁 | 上传源码 | 服务端受控构建 → 包体/不可变 Release 校验 → 人工审核 | 唯一不可绕过权威;若未来增加 runtime 强门禁需可信 verifier 绑定精确构建产物 |
| 运营发布 | Works Square 审核与交付 | 公共 `play_url` | 客户端只消费服务端发布结果;真实合同校验 → OSS/CDN 生产链仍待整链验收 |
| 可信发布门禁 | source+built+artifact contract | 服务端逐字节重算/合同校验 → 不可变 Release 固化 → 人工审核 | 服务端不运行项目 Vite仍是不可绕过权威未来 runtime 强门禁需可信 verifier |
| 真机预览 | 项目空间 | Main → Owner preview / `play_url` | 核对 app、version、release 和同源 HTTPS`runtime_url` 仅一版本兼容回退 |
| 设计会话创建/切换 | AI 绘画页面或侧栏 | Renderer API → Main → Workspace Conversation API | 新会话属于现有 Workspace读取独立消息、Brief、Quote 和 `turnRevision` |
| 设计消息与确认 | 当前 Conversation | Main → 持久 Agent Gateway Session → Conversation 快照 | 请求和流式结果同时绑定 Workspace + Conversation |
@@ -18,10 +18,10 @@
## State Ownership
- Main 持有刷新凭据、发布 Token、临时 ZIP、幂等键和 submission binding v2Renderer 不持有归档路径或自动部署状态。
- Main 持有刷新凭据、发布 Token、固定 npm runtime、源码/构建归档、临时目录、幂等键和 submission binding v2Renderer 不持有归档路径、构建 origin 或自动部署状态。
- 项目内 `.niancode/project.json` 保存 `ProjectType`Main 在配置写入和目录复用时保持其不可变,并在打包时重新读取校验。
- Renderer 仅持有短效公开会话状态、提交展示状态和安全投影后的公共播放/短时预览 URL。
- 本地预检临时 WebContents/partition 只属于一次调用,不写 submission binding 或上传字段;其结果不具备 project/digest provenance,也不覆盖生产 opaque-origin。
- 本地构建临时目录、HTTP origin 和预检 WebContents/partition 只属于一次调用;预检读取与 `built_archive` 相同的内存字节,但结果不写为可信上传 receipt,也不覆盖生产 opaque-origin。
- 旧 schema v1 `submitted` 记录迁移并保留;旧 `armed``waiting_for_package``waiting_for_login``uploading``failed` 归一为 `legacy_retired`,不再启动 watcher 或上传任务。
- AI 绘画 Conversation 持有消息、Brief、Quote、`turnRevision` 和服务端 Session 绑定Workspace 持有 Conversation 列表、生成任务和资产。
- 本地开发适配器将旧单会话 schema v2 原子迁移为带默认 Conversation 的 schema v3打包应用不使用该本地适配器作为云端失败回退。

View File

@@ -7,7 +7,10 @@
| `src/components/works/ProjectPublishAction.tsx` | 可发布项目的一键提交、云构建轮询与用户可理解状态 | 只通过 Renderer API 提交非敏感元数据;绑定告警不终止轮询 |
| `src/lib/works-square.ts` | Renderer 侧 Works Square Host API 契约与安全错误映射 | 不接触 Token、ZIP、本地绝对路径或自动部署状态 |
| `electron/api/routes/works.ts` | Works Host API、Renderer capability 门禁、上游安全投影 | 发布凭据、打包、上传与本地绑定均在 Main 内完成 |
| `electron/agent-browser/module.ts` | 当前项目 loopback preview 的桌面/移动临时 WebContents/CDP 预检 | UX fail-fast不运行 Vite、不生成 receipt、不得升级为可信发布证明 |
| `electron/services/project-release-builder.ts` | Main-owned 安全快照、本地 npm/Vite 构建、source+built 双归档与 v1 contract | 固定 npm 11.6.2;项目 Vite 由 lockfile 决定Vite config/plugins 以桌面用户权限执行 |
| `electron/services/publish-runtime.ts` | 安装包内 npm 闭包定位与 Electron Node 执行 | 不回退全局 npm/PATH缺失或版本不符 fail closed |
| `electron/services/static-release-server.ts` | 用内存 built snapshot 建立一次性 loopback origin | 预检和最终上传归档必须来自相同文件字节;总是清理临时服务 |
| `electron/agent-browser/module.ts` | built artifact 的桌面/移动临时 WebContents/CDP 预检 | UX fail-fast不生成可信 receipt、不得升级为平台证明 |
| `electron/agent-browser/electron-adapter.ts` | Electron WebContents/CDP 设备指标、事件与临时 partition 适配 | probe 不挂载 UI并在结束后销毁视图、清理隔离存储 |
| `electron/services/project-packager.ts` | 受控项目扫描、静态 ZIP 生成和敏感/历史控制文件排除 | 只允许可发布 `ProjectType`,不提供 Compose 或手工 ZIP 路径 |
| `electron/services/works-submission-binding.ts` | submission binding v2 持久化与旧 schema 迁移 | 旧中间态终止为 `legacy_retired`;文件名暂作安装兼容 |
@@ -24,13 +27,14 @@
## Dependency Direction
- Renderer UI → Renderer API contract → Main Host routes → Main services → Works SquareRenderer 不反向读取 Main 凭据、文件系统或归档。
- Project configuration 决定产品分流Main packager 与服务端独立校验决定发布安全本地 `ProjectType` 不是授权结论。
- Local preview preflight 只依赖当前已运行的 loopback 页面并早于打包/网络请求;它不建立源码、摘要、构建产物之间的 provenance服务端仍是受控构建与 Release 安全权威。
- Project configuration 决定产品分流Main release builder 生成 source/built/contract服务端独立重算和校验决定发布安全本地 `ProjectType` 不是授权结论。
- Built artifact preflight 检查最终上传的同字节快照,但客户端可被绕过且不产生可信 receipt服务端仍是合同、摘要和不可变 Release 安全权威。
## Risky Or Sensitive Areas
- `electron/api/routes/works.ts` 同时承担发布 capability、上游安全投影和错误脱敏变更时必须验证未在拒绝前读取凭据或项目文件。
- `electron/agent-browser/module.ts` 的预检必须继续拒绝非 loopback/外域访问、隔离临时 partition 并清理所有 view/listener不能因本地通过而跳过服务端校验。生产 opaque-origin 行为不由该 loopback 检查覆盖
- `project-release-builder.ts` 执行受信本地项目的 Vite config/plugins拥有桌面用户权限必须保持路径、环境、时间、输出、进程树和临时目录限制不得包装为 sandbox
- `electron/agent-browser/module.ts` 的预检必须继续拒绝外域访问、隔离临时 partition 并清理所有 view/listener不能因本地通过而跳过服务端逐字节校验。生产 opaque-origin 行为不由该 loopback 检查覆盖。
- `works-cloud-deploy.json` 是兼容文件名;不得因名称重新引入自动部署协调语义。
- `runtime_url` 是一个客户端版本的迁移回退;删除前必须确认服务端和存量数据稳定提供 `play_url`
- 多 Conversation 事件处理必须区分对话快照与 Workspace 任务更新;不得用任务时间戳推进 Conversation 流水位,也不得让旧会话的迟到流覆盖当前会话。

View File

@@ -11,12 +11,12 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
| Renderer | 项目配置、一键提交状态、真机二维码 | 不接触账号 Token、ZIP、幂等键或本地绝对路径 |
| Host API | 校验本地项目请求并投影安全响应 | 发布 mutation 还必须通过 Renderer capabilityHost token/base 不能单独触发发布 |
| Project Configuration & Template | 保存不可变 `ProjectType`,原子生成新项目骨架 | 小游戏/小程序生成受控 Vite 模板;自定义保持最小项目空间 |
| Project Packager | 确定性扫描、敏感文件排除与 ZIP 生成 | 限制文件数、包体和目录替换 |
| Project Release Builder | Main-owned 安全快照、本地 npm/Vite 构建、双归档与 artifact contract | 固定 npm 11.6.2Vite 由项目 lockfile 锁定;产物与预检使用同一内存字节 |
| Works Session | 七天真实活动滑动续期 | 刷新凭据由 Main 安全持有 |
| Submission Binding | 保存云端已接受的精确 app/version/review/hash 绑定 | schema v2 只记录成功提交;旧中间态迁移为 `legacy_retired`,不恢复后台任务 |
| Play URL Projection | 校验服务端公共播放地址 | 只接受同源 HTTPS 和精确 `/apps/{app_id}/`;优先 `play_url``runtime_url` 仅一版本回退 |
| Device Preview | 核对本地绑定、远端版本和 Release | 待审使用短时 Owner preview已发布使用安全投影后的 `play_url` |
| Local Preview Preflight | 在上传前复用当前项目 loopback preview 做桌面/移动 UX fail-fast | Main 使用 Electron WebContents/CDP不使用 Playwright、不执行 Vite、不生成可信证明 |
| Built Artifact Preflight | 在上传前对最终 built snapshot 做桌面/移动 UX fail-fast | Main 使用临时 loopback origin 与 Electron WebContents/CDP不使用 Playwright、不生成可信证明 |
| AI Design Workspace | 保存项目身份、Conversation 列表、生成任务和资产 | 任务和资产在切换 Conversation 后继续可见 |
| AI Design Conversation | 保存消息、Brief、Quote、`turnRevision` 与服务端 Agent Session 绑定 | 同一 Workspace 内互相隔离Session 由服务端持久化 |
| AI Design Event Routing | Main 云端适配器 → Host API/SSE → Renderer store | Conversation 更新按 Workspace + Conversation 路由;任务更新按 Workspace 归并 |
@@ -24,12 +24,13 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
## Important Boundaries
- 发布只有现有项目配置底部的一个入口,不新增发布工作台、侧栏或资源卡。
- 创建者发布唯一调用链是 `ProjectPublishAction → publishWorksProjectSource → preflightCurrentProject → createStaticProjectPackage → 版本上传 → 状态轮询`;客户端不再提供 Compose runner、deploy-check、watcher/arm/upload 协调或手工 ZIP 上传入口。
- `preflightCurrentProject` 只检查当前项目已附着的受信 HTTP loopback preview。它用 fresh 非持久、未挂载的 Electron WebContents 和 CDP 检查桌面/移动视口、错误、白屏及外域访问,不安装/调用 Playwright不在本地执行项目 Vite/config/plugin。
- 客户端预检是可绕过的 UX fail-fast没有 receipt、project/digest provenance 或生产 opaque-origin parity不能证明随后上传源码或服务端构建产物安全。服务端受控构建、包体校验、不可变 Release 门禁及人工审核仍是唯一不可绕过权威;未来若要求 runtime 强门禁,需由可信 verifier 绑定精确构建产物
- 创建者发布唯一调用链是 `ProjectPublishAction → publishWorksProjectSource → Main-owned release build → preflightStaticArtifact → source+built+artifact_contract 上传 → 状态轮询`;客户端不再提供 Compose runner、deploy-check、watcher/arm/upload 协调或手工 ZIP 上传入口。
- release builder 对 Main-owned 安全快照运行安装包内固定 npm 11.6.2 的 `ci --ignore-scripts`,并显式调用项目 `package-lock.json` 锁定的 Vite。不得使用全局 PATH、预存 `node_modules` 或 Renderer 提供的路径/origin。项目 Vite config/plugins 以桌面用户权限执行,该边界不是 sandbox
- `preflightStaticArtifact` 以临时 HTTP loopback origin 提供最终 `built_archive` 的同一内存文件快照,并用 fresh 非持久、未挂载的 Electron WebContents/CDP 检查桌面/移动视口、错误、白屏及外域访问;不安装/调用 Playwright
- 客户端预检是可绕过的 UX fail-fast没有可信 receipt也不复刻生产 opaque-origin。服务端不执行项目 Vite而是独立重算和校验 source/built/contract 字节、固化不可变 Release人工审核仍不可绕过。未来若要求 runtime 强门禁,需由可信 verifier 绑定精确构建产物。
- `ProjectType` 由创建请求写入项目配置UI 与 Host API 不提供类型变更;缺少类型的旧配置归一为 `custom`
- 本地 `projectType` 只选择产品路径和内部构建 preset不是可信授权声明Main 仍需安全打包,服务端仍需独立校验清单和包体。
- 云端确认上传成功后,本机 submission binding 失败只能产生固定、无路径的 `binding_warning`不能把请求改判为失败Renderer 仍继续轮询云构建
- 云端确认上传成功后,本机 submission binding 失败只能产生固定、无路径的 `binding_warning`不能把请求改判为失败Renderer 仍继续轮询服务端校验与 Release 固化状态
- 公共播放投影只有在上游 `playable === true`、版本名非空且 URL 通过同源 HTTPS、无 userinfo/loopback、长度、精确路径和无 query/fragment 校验时才可播放;不可信数据 fail closed。
- Renderer 只能获得安全状态字段和可展示的播放/短时预览 URL不得持有发布凭据、归档路径或自动部署状态。
- 落盘文件名 `works-cloud-deploy.json` 仅为已安装客户端的数据兼容;领域模型和代码接口是 submission binding不表示仍存在 cloud deployment coordinator。
@@ -39,7 +40,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
## Related Decisions
- 当前长期边界记录于 README、ADR-001、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c` 及本次 Integration Gate后续如改变唯一入口、凭据所有权、Conversation 状态归属或重新引入客户端部署协调器,应新增 ADR。
- 当前长期边界记录于 README、ADR-001、集成任务 `20260807-integrate-login-client-a4f8`、源任务 `20260810-static-release-only-a91c``20260812-client-built-release-makelore-7e5b` 及本次 Integration Gate后续如改变唯一入口、凭据所有权、构建执行边界、Conversation 状态归属或重新引入客户端部署协调器,应新增 ADR。
## Last Updated