# Phase 4:极客层 P1 + 发布链闭环 + 上线准备 - 任务拆解 ## 使用规则 - boundary/verify 齐备;verify 只读断言(Phase 2 教训);上线脚本绝不自动执行 ## 阶段一:实现 - [x] T1 命令面板 - claim: op-gitea(mesh 车道,预约 src/components/CommandPalette.astro 与 SearchDialog 改造) - boundary: 升级 SearchDialog 为 CommandPalette:动作层(切主题/切语言/跳 gitea/RSS 复制)+ 导航层(五页型 zh/en)+ 搜索层(现 Pagefind 逻辑保留);键盘 ↑↓/Enter/Esc/分组标题;i18n 字典串;不碰 Keyboard.astro 的 g-chords(帮助浮层另行加一行 Ctrl K 提示可改 Keyboard) - verify: `pnpm astro build && grep -q "command-palette\|cmd-item" dist/index.html` - [x] T2 gitea 贡献热力图 - claim: op-artalk(mesh 车道,预约 src/lib/heatmap.ts 与 src/components/geek/Heatmap.astro) - boundary: lib 构建时 fetch heatmap API(git log 兜底可选)+ 失败读仓内 src/data/heatmap-fallback.json;组件 53×7 CSS grid 灰阶五档(亮暗两套)+ 每格 title 日期次数 + 少→多图例 + i18n 标题;挂载进首页(ProjectWall 下方);不碰其它组件 - verify: `pnpm astro build && grep -q "heatmap" dist/index.html` - [x] T3 webhook HMAC 闭环 - depends-on: 无 - claim: orchestrator - boundary: infra/deploy/webhook-receive.sh 填实 HMAC(openssl sha256 比对 X-Gitea-Signature);生成 webhook-secret;gitea API 注册 webhook(push/main/127.0.0.1 接收端点);接收端常驻方式用 python http.server 微型包装(监听 127.0.0.1:13021,仅 HMAC 通过触发 build.sh);实测一次 push→build→staging 戳更新 - verify: `curl -sf http://127.0.0.1:13021/healthz && grep -q "built at" ~/docker_apps/blog/www-staging/.build-stamp` - [x] T4 预发布全端验收 - depends-on: task_0001, task_0002 - claim: orchestrator - boundary: scripts/preflight.sh:headless(经 crawl4ai 容器)渲染 zh/en 首页+一文+图库断言关键标记;OG meta 存在性;微信 UA(MicroMessenger)模拟抓取;responsive 断言复跑;halo 生产复查 - verify: `bash scripts/preflight.sh` - [x] T5 上线脚本与检查单 - claim: orchestrator - boundary: infra/deploy/launch.sh(root 执行):备份 vhost→wait4x.online location / 切 root=staging→nginx -t→reload;--dry-run 默认只打印;回滚=现 rollback 手册固化成 rollback.sh;docs/上线检查单.md(含 ESA 刷新步骤) - verify: `bash infra/deploy/launch.sh --dry-run` - [x] T6 验收归档 - depends-on: task_0003, task_0004, task_0005 - claim: orchestrator - boundary: 全 verify 复跑 + 板房汇报 + 归档提交 - verify: `bash scripts/preflight.sh && bash infra/deploy/launch.sh --dry-run` --- **当前进度**:由脚本计算,无需手动维护