[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MXVRBWFE43ETGHD20VT8TX":3,"skill-same:01M6MXVRBWFE43ETGHD20VT8TX":46},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":21,"linkOnly":22,"markdownContent":23,"markdownBody":23,"frontMatter":24,"refName":25,"commitSha":26,"skillDirectory":27,"forksCount":28,"repositoryHtmlUrl":29,"repositoryHomepageUrl":6,"ownerHtmlUrl":30,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":31,"install":32,"resources":45},"01M6MXVRBWFE43ETGHD20VT8TX","deployment-designer",null,"miniidealab\u002Fopenlogos","miniidealab","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F4251156?v=4","01M6MX6BM454XESZCRPBQQHKRT","FredHuang","01M6MX6BR4417H4QA658D4GW9X",581,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fdeployment-designer\u002FSKILL.md",[],[18,19,20],"deployment","deployment designer","designer","2026-11-10 10:12:30",false,"# Skill: Deployment Designer\n\n> 在代码实现前输出完整部署方案：部署拓扑、环境配置、发布命令、数据迁移、回滚策略和部署后冒烟测试方案。该 Skill 是 Phase 3 Step 3 的执行入口。\n\n## 触发条件\n\n- 用户要求设计部署方案、发布方案或上线方案\n- 用户提到 “Phase 3 Step 3”、“部署方案”、“deployment plan”\n- API \u002F DB 设计完成后，需要进入部署方案设计\n- Initial 阶段准备进入测试设计前，`3-technical-plan\u002F3-deployment\u002F` 仍为空\n\n## 前置依赖\n\n1. `logos\u002Fresources\u002Fprd\u002F3-technical-plan\u002F1-architecture\u002F` 中存在架构概要\n2. `logos\u002Fresources\u002Fprd\u002F3-technical-plan\u002F2-scenario-implementation\u002F` 中存在场景实现文档\n3. API \u002F DB 设计已完成，或对应模块在 `skip_phases` 中明确跳过\n4. `logos\u002Flogos-project.yaml` 可读\n\n## 核心能力\n\n1. 从架构、API、DB 和技术栈中推导部署目标\n2. 设计本地 \u002F 测试 \u002F 预发 \u002F 生产环境部署拓扑\n3. 明确环境变量、密钥来源、构建命令和发布命令\n4. 定义数据迁移、初始化数据和回滚策略\n5. 设计部署后检查清单\n6. 设计 smoke 测试方案输入，供 `test-writer` 生成 `SMOKE-*` 用例\n7. 更新 `logos-project.yaml` 的部署门禁信息\n\n## 执行步骤\n\n### Step 1: 读取上下文\n\n必须读取：\n\n- `logos\u002Flogos-project.yaml`\n- 架构概要文档\n- 场景实现文档\n- API 规格（如存在）\n- DB DDL（如存在）\n- 现有部署方案（如存在）\n\n重点确认：\n\n- 项目是否需要部署\n- 目标环境有哪些\n- 是否存在远程服务、生产环境、密钥、域名、证书或数据迁移\n- smoke 需要覆盖哪些最小链路\n\n### Step 2: 判断部署门禁\n\n默认规则：\n\n- 软件项目默认需要部署方案\n- 有运行环境的项目默认需要部署执行和 smoke\n- 纯文档、纯规范、无需运行环境的库项目可声明 `deployment_required: false`\n\n若用户选择无需部署，部署方案仍需写明原因和跳过条件。\n\n### Step 3: 输出部署方案\n\n默认文件：\n\n`logos\u002Fresources\u002Fprd\u002F3-technical-plan\u002F3-deployment\u002Fcore-01-deployment-plan.md`\n\n**⚠️ Mermaid 部署拓扑图语法安全（强制）**：\n- 部署拓扑通常使用 Mermaid `graph` \u002F `flowchart`，节点标签默认写成 `ID[\"标签文本\"]`。\n- 含域名、URL、API 路径、端口、环境名、云服务名、中文、空格或 `\u003Cbr\u002F>` 的标签必须加双引号：`Pages[\"Cloudflare Pages\"]`、`API[\"API :8787\"]`、`Proxy[\"\u002Fvoice\u002Fapi 代理\"]`。\n- 错误：`Proxy[\u002Fvoice\u002Fapi 代理]`，因为 `[\u002F` 会触发 Mermaid 平行四边形形状语法，容易导致部署图渲染失败。\n- 多行标签使用 `\u003Cbr\u002F>`，整段文本仍放在同一对双引号内：`Worker[\"Cloudflare Worker\u003Cbr\u002F>staging\"]`。\n- 子图名称含空格、中文或特殊字符时必须加引号：`subgraph \"Staging Environment\"`。\n- 只有明确要表达特定形状时才使用 Mermaid 形状语法；普通部署组件一律使用带引号的文本节点。\n\n文档结构：\n\n```markdown\n# core-01-deployment-plan\n\n## 一、部署目标\n\n## 二、部署拓扑\n\n## 三、环境变量与密钥\n\n## 四、构建与发布命令\n\n## 五、数据迁移策略\n\n## 六、回滚策略\n\n## 七、部署后检查清单\n\n## 八、冒烟测试方案\n\n## 九、门禁结论\n```\n\n### Step 4: 设计 smoke 输入\n\n在部署方案的“冒烟测试方案”中列出必须覆盖的 smoke 检查项：\n\n- 健康检查\n- 核心入口\n- 数据库迁移\n- 静态资源\n- 配置与密钥\n- 关键链路\n- 日志与监控\n\n具体 `SMOKE-*` 用例由 `test-writer` 输出到 `logos\u002Fresources\u002Ftest\u002Fsmoke\u002F`。\n\n### Step 5: 更新 logos-project.yaml\n\n如模块需要部署，建议写入：\n\n```yaml\ndeployment_gates:\n  core:\n    deployment_required: true\n    smoke_required: true\n    environments:\n      - staging\n```\n\n并将部署方案加入 `resource_index`。\n\n#### Step 5.1: 产出环境登记表 `logos\u002Fenvironments.yaml`（environment-registry）\n\n部署方案涉及具体环境（测试、预发、生产等）时，按方案「一、部署目标」「三、环境变量与密钥」「四、构建与发布命令」产出或更新 `logos\u002Fenvironments.yaml`（格式权威：`spec\u002Fenvironments.md` §2、§11.2），并为可由 OpenLogos 执行部署的环境写出 `deploy` 条目与部署脚本（来源变更 environment-deploy）：\n\n```yaml\nschema_version: 1\nenvironments:\n  - id: staging\n    name: 预发环境\n    tier: staging\n    aliases: [预发]\n    health: https:\u002F\u002Fstaging.example.com\u002Fhealthz\n    version: https:\u002F\u002Fstaging.example.com\u002Fversion\n    secrets: [STAGING_DEPLOY_TOKEN]\n    deploy:\n      mode: script\n      script: deploy\u002Fstaging.sh\n      args: [\"{env}\", \"{ref}\"]\n      timeout_sec: 1800\n  - id: prod\n    name: 生产环境\n    tier: prod\n    aliases: [生产]\n    deploy:\n      mode: ci\n      provider: github-actions\n      workflow: deploy.yml\n      inputs: { environment: \"{env}\" }\n```\n\n规则：\n\n- `id` 用小写字母、数字与连字符；`tier` 取 `dev | test | staging | prod`；id 与 alias 不区分大小写全局唯一。\n- `secrets` **只写环境变量名，不得写值**；方案中出现的真实密钥一律不进登记表。\n- `deployment_gates.\u003Cmodule>.environments` 中的每一项必须能按 id 或别名解析到登记表中的环境。\n- 只登记部署方案确实涉及的环境，不臆造；部署方案没有环境划分时不产出登记表（登记表是 opt-in）。\n- 登记表属于 `guard.exempt` 内置默认，修改不需立案；但只要任一环境配置了 `promote_from` 或 `require_approval`，它就成为门禁策略来源，AI 对它的修改须经宿主弹窗由用户批准，无人值守模式下被阻断（来源变更 environment-promotion-approval，决策 C11）。\n\n**选择执行方式**：\n\n- 仓库已有可用的 GitHub Actions 部署工作流 → 优先 `mode: ci`、`provider: github-actions`；GitLab 等其他 CI → `mode: ci`、`provider: script`，编写仓库内的 `trigger_script` 与 `status_script`（JSON 协议见 `spec\u002Fenvironments.md` §11.3）。\n- 没有流水线、部署步骤可脚本化 → `mode: script`，编写部署脚本。\n- 部署步骤暂时无法脚本化（需要人工或 AI 判断的操作） → `mode: agent`，`plan_section` 写部署方案中对应章节标题；后续应尽量改为 script 或 ci。\n\n**登记表不承载可执行命令**（决策 D13）：`deploy` 只写脚本路径、工作流名、参数、超时等配置，**不得**写 `run`、`command`、`shell` 等命令字段——登记表免立案可改，命令写在这里会让部署行为绕过 guard。改变部署行为必须改受保护的脚本或工作流。\n\n**部署脚本编写要求**（script 方式）：\n\n- 放在仓库内被 git 跟踪的路径（默认 `deploy\u002F\u003Cenv>.sh`），提交可执行位；CLI 以参数数组直接执行、不经 shell，参数用 `args` 的占位符 `{env}`、`{ref}`、`{ref_short}`、`{deploy_id}` 传入。\n- 脚本在**目标版本的隔离工作树**中运行（`workdir: worktree` 默认）：工作树里没有 `node_modules`、构建产物等未跟踪文件，脚本必须自行安装依赖与构建，不得依赖当前工作区状态。\n- 失败时以非零退出码退出；不打印密钥值（CLI 只能遮盖已声明的密钥）；幂等，可重复执行。\n- 可读取 `OPENLOGOS_DEPLOY_ENV`、`OPENLOGOS_DEPLOY_REF`、`OPENLOGOS_DEPLOY_ID`、`OPENLOGOS_DEPLOY_CHANNEL`。\n\n**CI 工作流要求**（ci 方式）：工作流部署的必须是自身检出的提交，并以固定名称上传 artifact `openlogos-deploy-result`，其中 `result.json` 为 `{\"deployed_ref\": \"\u003C40 位 commit>\"}`，值取自部署所用 `actions\u002Fcheckout` 步骤的 `commit` 输出（provider: script 由 `status_script` 在 `completed` 时输出 `deployed_ref`）。没有回报时 OpenLogos 记录部署版本为未知，该次部署不能作为回滚目标、smoke 不能得到已验证事实。\n\n**晋级与审批门（可选，来源变更 environment-promotion-approval，见 `spec\u002Fenvironments.md` §12）**：\n\n- `promote_from: \u003C上游环境 id>`：部署某个 commit 到该环境前，要求上游环境已对该 commit 以 smoke 验证通过（`verified=true`）。只填登记表中已有环境的 `id`（不填别名），不得指向自身或成环；只在配置了 `deploy` 的环境上合法。\n- `require_approval: true`：部署前必须有人执行 `openlogos approve --env \u003Cid> --ref \u003C版本>`，一次审批只放行该版本的一次成功部署。\n- 对 `tier: prod` 的环境，在部署方案的「九、门禁结论」中**提示**用户可选配置这两个字段，并说明其效果（`--auto` 全自动运行遇到它们会停下等人）；**不自动开启**，由用户决定是否写入登记表。门禁一旦写入，之后对登记表的修改须经用户确认，建议在用户确认方案后一次性写好。\n- 设计阶段不得执行 `openlogos approve` 或带 `--force-promote` 的部署；这两类动作只能由人执行。\n\n**提案默认部署环境（可选，来源变更 proposal-default-environment，见 `spec\u002Fenvironments.md` §13）**：\n\n- 登记表顶层 `proposal_default_env: \u003C环境 id>` 表示「需要部署的提案未另行指定目标环境时，默认部署到这个环境」。配置后，change-writer 写提案时不再逐案询问目标环境；部署方式、回滚与 smoke 证据仍按已合并部署方案与配置逐项核对，缺项照常询问。它不决定提案是否需要部署，也不构成部署执行或发布授权。\n- 值只填登记表中已有环境的 `id`（不填别名）。所指环境可以配置 `promote_from` \u002F `require_approval`，部署时照常受门；为让默认环境的提案少问问题，建议在部署方案中为它写明部署步骤、回滚或首次部署失败处置，并配置 smoke 命令。\n- **只在用户明确指定时写入**：产出或更新登记表时，向用户说明该字段的作用，由用户明确指定一个环境或选择不设；用户未明确指定时不写。已存在的值不得自行修改或删除。该字段不受 guard 保护，修改不需立案——正因如此，是否设置、设为哪个环境必须由用户决定。\n\n**自验证（设计阶段，不做真实部署）**：对每个配置了 `deploy` 的环境依次运行 `openlogos env check` 与 `openlogos deploy --env \u003Cid> --ref \u003C当前提交> --dry-run`（只读；配置了门禁的环境 dry-run 会如实报告 `DEPLOY_PROMOTION_UNVERIFIED` \u002F `DEPLOY_APPROVAL_REQUIRED`，这是预期结果，记入方案而不是去满足它；校验脚本在目标版本中存在且可执行、参数占位符合法、声明的密钥齐全、`gh` 可用且已登录），shell 脚本另做 `bash -n` 语法检查；任一失败先修正再交付。**设计阶段不得执行真实部署**。\n\n## 输出规范\n\n- 部署方案：`logos\u002Fresources\u002Fprd\u002F3-technical-plan\u002F3-deployment\u002Fcore-01-deployment-plan.md`；配置了 `deploy` 的环境须在方案中新增「部署脚本审阅摘要」一节：每个脚本或工作流的路径、做什么、动哪些外部资源（服务、数据库、存储、域名）、需要哪些密钥变量名、失败与回滚方式。该节供愿意审阅的人阅读，**不写任何确认标记、不阻断流程**（来源变更 environment-deploy，决策 C03）\n- 环境登记表（部署方案涉及具体环境时）：`logos\u002Fenvironments.yaml`，格式见 `spec\u002Fenvironments.md`\n- 部署脚本（script 方式）：仓库内受保护路径，默认 `deploy\u002F\u003Cenv>.sh`；CI 适配脚本（provider: script）同样放在仓库内\n- 文档语言遵循项目 locale\n- Mermaid 可用于部署拓扑图，且必须遵循上述节点标签与子图命名安全规则\n- 不执行任何真实部署命令；只运行只读的 `openlogos env check`、`openlogos deploy --dry-run` 与脚本语法检查\n\n## 人类确认点\n\n本 Skill 只设计部署方案，不执行部署。部署执行必须等到：\n\n1. 代码实现完成\n2. `openlogos verify` 通过\n3. 用户明确授权部署\n\n## 推荐提示词\n\n- `帮我设计部署方案`\n- `按 Phase 3 Step 3 输出部署方案`\n- `基于当前架构设计 staging 部署和 smoke 方案`\n\n## Authority writer cutover 与 projection 重建\n\n\n部署设计前读取 `spec\u002Fauthority-closure.md` 和 Authority Registry，并逐个稳定 `fact_id` 引用 owner\u002Fwriter\u002Fmutation entry、projection、recovery 与 cutover；不得另建 owner 表或用路径生成事实身份。只要本次改变 owner\u002Fwriter\u002Fmutation entry、projection schema 或 recovery source，部署方案必须包含有限 cutover；不得把长期双写当兼容策略。\n\n### 强制顺序\n\n1. 冻结 authority identity、before facts、当前入口和回滚制品。\n2. 停止\u002F隔离旧 writer，并证明旧入口不能成功写入。\n3. 启用唯一新 mutation entry；不可逆写入前明确 rollback boundary。\n4. 从 authority 重建 projections，以 generation\u002Fversion\u002Fhash\u002Freceipt 做 freshness probe。\n5. 执行 stale\u002Fconflict\u002Fresponse-lost\u002Frestart\u002Flegacy-writer 负向 smoke。\n6. 记录 exit evidence，结束迁移窗口；失败时恢复冻结版本且不留下混合 writer。\n\n部署完成与 cutover 完成是两个事实，不能由“进程已启动”反推 writer 已唯一。新 authority 已产生不可逆写入后禁止重新开启旧 writer；只能前滚或启用兼容 reader。部署任务与 smoke 仍分别等待用户明确授权。\n",{},"master","abf55fdedadaeb660f928aa7258b9ec35d4ab003","skills\u002Fdeployment-designer",9,"https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos","https:\u002F\u002Fgithub.com\u002Fminiidealab","2026-10-18 11:36:11",{"source":7,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add miniidealab\u002Fopenlogos --skill deployment-designer",{"tool":38,"command":39},"bunx","bunx skills add miniidealab\u002Fopenlogos --skill deployment-designer",{"tool":41,"command":42},"pnpm","pnpm dlx skills add miniidealab\u002Fopenlogos --skill deployment-designer","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fdeployment-designer\u002FSKILL.md",true,[],[47,93,105,114,122,131],{"skillNo":48,"name":49,"nameZh":6,"description":50,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":51,"categories":52,"keywords":72,"publishedAt":21},"01M6MXX45142DGRFD9ZYPT5YC9","ui-ux-pro-max","UI\u002FUX design intelligence. 67 styles, 96 palettes, 57 font pairings, 25 charts, 13 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind, shadcn\u002Fui). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI\u002FUX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient. Integrations: shadcn\u002Fui MCP for component search and examples.","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fui-ux-pro-max\u002FSKILL.md",[53,58,61,64,69],{"categoryNo":54,"categoryName":55,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":59,"categoryName":60,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":62,"categoryName":63,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":65,"categoryName":66,"taxonomyType":67,"taxonomyTypeDesc":68},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",{"categoryNo":70,"categoryName":71,"taxonomyType":67,"taxonomyTypeDesc":68},"01JBSEEDCAT000000000000033","数据分析师",[73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92],"ui ux","pro","max","ui ux pro max","ui","ux","projects","mode","card","app","tsx","fix","improve","Tailwind","Charts","Animation","design","actions","MCP","search",{"skillNo":94,"name":95,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":101,"publishedAt":21},"01M6MXWY8HJV93BBR8FPNJXAMV","test-writer","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Ftest-writer\u002FSKILL.md",[98],{"categoryNo":99,"categoryName":100,"taxonomyType":56,"taxonomyTypeDesc":57},"01JBSEEDCAT000000000000008","测试与质量",[102,103,104],"writer","test writer","test",{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":111,"publishedAt":21},"01M6MXWSAMN9AD3T8F6N099ZGY","test-orchestrator","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Ftest-orchestrator\u002FSKILL.md",[110],{"categoryNo":99,"categoryName":100,"taxonomyType":56,"taxonomyTypeDesc":57},[112,113,104],"orchestrator","test orchestrator",{"skillNo":115,"name":116,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":21},"01M6MXWN29FY7K9ASMFRSPWQCN","slice-planner","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fslice-planner\u002FSKILL.md",[],[120,121],"slice planner","planner",{"skillNo":123,"name":124,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":127,"publishedAt":21},"01M6MXWFR1C1V66NSRTAM1FZPR","scenario-architect","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fscenario-architect\u002FSKILL.md",[],[128,129,130],"architect","scenario","scenario architect",{"skillNo":132,"name":133,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":21},"01M6MXWD6ZCGPT4FDT580S8K96","project-init","https:\u002F\u002Fgithub.com\u002Fminiidealab\u002Fopenlogos\u002Fblob\u002Fmaster\u002Fskills\u002Fproject-init\u002FSKILL.md",[],[137,138,139],"project init","init","project"]