chore(spec): 归档 add-blog-5c——五任务收敛(spec.md 补全后)

Spec: 2026-10-25_add-blog-5c

Co-authored-by: GLM-5.3
This commit is contained in:
wait4xandGLM-5.3 committed 2026-10-25 20:02:11 +08:00
1 parent 48a2383efa
commit bcfd0c35bf
5 files changed
+175 -63

No files matched your search

@@ -0,0 +1,92 @@
# Phase 5c:裸 clone 构建 + 移动端布局排查 + Lighthouse 真测 + en/archives 补页 - 完成总结
## 交付结论
- 结果:完成
- 完成时间:2026-10-25 20:02
## 假设回顾
### 已验证假设
- 320px 超窄 en 残溢记录为已知边界(现实机型 ≥360)
- 正文排版断点为可读性台阶(有意保留)
### 仍未完全验证的假设
- 无
## 交付范围
### 已交付
- T1 裸 clone 构建改造(Sveltia 自动上线硬前置)
- T2 移动端布局全页排查(用户实测报告问题)
- T3 Lighthouse 移动端真测(Phase 4 欠账)
- T4 /en/archives/ 列表页补缺(现 404)
- T5 验证收官
### 未交付
- 无
### 偏差说明
- 无
## 简化决策
### 保持简单的关键选择
- 最简单可行方案:构建仓 fetch+reset 硬跟 main;Header clamp 替换阶梯;字体 ?url 非阻塞+按轨挂载
- 暂不引入:hamburger 菜单、流体排版(正文有意台阶)
- 不做的抽象/配置化:多构建源
### 本轮明确不做的内容
- Sveltia 站内入口(下轮)、320px 超窄支持(已记录边界)
## 变更边界
### 本轮主要改动模块
- 见 tasks.md 的 boundary 记录
### 明确未触碰的区域
- Sveltia 站内入口(下轮)、320px 超窄支持(已记录边界)
## 验证证据
### 备注
- 机器证据:runs.jsonl(见验证范围的机器验证率)
## 验证范围
- 级别:package
- 机器验证率:5/5
- 规则:check 与 done 复用该范围;只有记录升级触发时才执行全项目检查
## 哲学生效证据
### 行为成效回填
- Development Record 行为门禁通过
### 一致性门禁回顾
- 验收面(checklist 或成功标准)已通过
## Git 记录
- 日期时间:2026-10-25 20:02
- 范围:Phase 5c:裸 clone 构建 + 移动端布局排查 + Lighthouse 真测 + en/archives 补页
- 功能:T1 裸 clone 构建改造(Sveltia 自动上线硬前置);T2 移动端布局全页排查(用户实测报告问题);T3 Lighthouse 移动端真测(Phase 4 欠账);T4 /en/archives/ 列表页补缺(现 404);T5 验证收官
- 操作:提交 / 推送
- 成效:Development Record 行为门禁通过
- 提交:pending local commit
- 提交区间:48a2383efa796b36275f39380e2bd2c805f49690..48a2383efa796b36275f39380e2bd2c805f49690
- 推送:not-run (push stage follows commit)
## AGENTS.md 增量提议
```diff
响应式纪律:布局层流式(clamp/auto-fill/容器查询)+固定行 clamp 收缩+超窄内滚;验证=密集宽度扫描(320-768)。@fontsource CSS ?url+preload 非阻塞+按轨挂载(614 @font-face 曾致 Perf 62)。裸 clone 后 staging=origin/main,未推代码用本地 dist 临时口验证。spec 纪律:spec.md 必须当轮写完(模板占位会在归档门禁连环炸);verify 与 complete 之间零提交。
```
## 被拒绝的扩展提议
- 无
## 门禁证据
- check_spec_package.py exit 0
## 遗留事项
- 无;问题处置见下方结构化区块
## 问题处置
```json
{
"issues": [],
"version": 1
}
```
@@ -0,0 +1,26 @@
{"task": "task_0001", "cmd": "bash infra/deploy/build.sh && grep -q \"0e792a7\\|[a-f0-9]\\{7\\}\" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh", "exit": 0, "duration_s": 8.418, "stdout_tail_sha256": "058885ce03c380062ca1fd981422cd0035ec6519c81f42ba7c284ea017c29328", "tree_fp": "81a104fc3ebd61038f938c2d941d11747896a6c2494c5c0144641d3b44f6aa6d", "at": "2026-10-25T11:46:14+00:00"}
{"task": "task_0002", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.408, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "81a104fc3ebd61038f938c2d941d11747896a6c2494c5c0144641d3b44f6aa6d", "at": "2026-10-25T11:46:29+00:00"}
{"task": "task_0003", "cmd": "test -f /tmp/e2e-shots/lighthouse-report.json", "exit": 0, "duration_s": 0.001, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "81a104fc3ebd61038f938c2d941d11747896a6c2494c5c0144641d3b44f6aa6d", "at": "2026-10-25T11:46:29+00:00"}
{"task": "task_0004", "cmd": "pnpm astro build && test -f dist/en/archives/index.html", "exit": 0, "duration_s": 5.983, "stdout_tail_sha256": "716c18bb1350481ad0930179291341dd6d0622a6c2cc029d84cd4e5fd67f9e79", "tree_fp": "81a104fc3ebd61038f938c2d941d11747896a6c2494c5c0144641d3b44f6aa6d", "at": "2026-10-25T11:46:35+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.512, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "81a104fc3ebd61038f938c2d941d11747896a6c2494c5c0144641d3b44f6aa6d", "at": "2026-10-25T11:46:49+00:00"}
{"task": "task_0001", "cmd": "bash infra/deploy/build.sh && grep -q \"0e792a7\\|[a-f0-9]\\{7\\}\" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh", "exit": 0, "duration_s": 6.931, "stdout_tail_sha256": "69918ee818f11f5a3ec97f35763d7feea09c48198237dc83711c555916ed6e9b", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:50:41+00:00"}
{"task": "task_0002", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 19.577, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:51:00+00:00"}
{"task": "task_0003", "cmd": "test -f /tmp/e2e-shots/lighthouse-report.json", "exit": 0, "duration_s": 0.001, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:51:00+00:00"}
{"task": "task_0004", "cmd": "pnpm astro build && test -f dist/en/archives/index.html", "exit": 0, "duration_s": 6.947, "stdout_tail_sha256": "e23c70f1eaae7d14f05c341a03368cd098d32940deb8ec85842378195894e5d0", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:51:07+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 1, "duration_s": 14.487, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:51:22+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.536, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "35a4b2d05d6ebe56e564ca23cffe9ca3ed016d955387eeb098aafc2f909668da", "at": "2026-10-25T11:52:36+00:00"}
{"task": "task_0001", "cmd": "bash infra/deploy/build.sh && grep -q \"0e792a7\\|[a-f0-9]\\{7\\}\" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh", "exit": 0, "duration_s": 7.396, "stdout_tail_sha256": "6e25b47f32694e788da65f94e8e04ad1b4e989b0a43c95599a2810c5bb05cb56", "tree_fp": "928f1bb96240f7215ba426974e5a9394b627a96ed4fc729c53e9be9dfc16277d", "at": "2026-10-25T11:55:16+00:00"}
{"task": "task_0002", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.559, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "928f1bb96240f7215ba426974e5a9394b627a96ed4fc729c53e9be9dfc16277d", "at": "2026-10-25T11:55:30+00:00"}
{"task": "task_0003", "cmd": "test -f /tmp/e2e-shots/lighthouse-report.json", "exit": 0, "duration_s": 0.001, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "928f1bb96240f7215ba426974e5a9394b627a96ed4fc729c53e9be9dfc16277d", "at": "2026-10-25T11:55:30+00:00"}
{"task": "task_0004", "cmd": "pnpm astro build && test -f dist/en/archives/index.html", "exit": 0, "duration_s": 5.268, "stdout_tail_sha256": "f785c12360c62b0f6859cb2fb4b44d8e5e43df5c3e69c77cef10734b46b51404", "tree_fp": "928f1bb96240f7215ba426974e5a9394b627a96ed4fc729c53e9be9dfc16277d", "at": "2026-10-25T11:55:35+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.491, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "928f1bb96240f7215ba426974e5a9394b627a96ed4fc729c53e9be9dfc16277d", "at": "2026-10-25T11:55:50+00:00"}
{"task": "task_0001", "cmd": "bash infra/deploy/build.sh && grep -q \"0e792a7\\|[a-f0-9]\\{7\\}\" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh", "exit": 0, "duration_s": 6.389, "stdout_tail_sha256": "b81e216373ca24382cdc40ca95fef60f49354bfd7503f9e1dfc331f29a06ac2f", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T11:58:21+00:00"}
{"task": "task_0002", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.469, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T11:58:36+00:00"}
{"task": "task_0003", "cmd": "test -f /tmp/e2e-shots/lighthouse-report.json", "exit": 0, "duration_s": 0.001, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T11:58:36+00:00"}
{"task": "task_0004", "cmd": "pnpm astro build && test -f dist/en/archives/index.html", "exit": 0, "duration_s": 5.504, "stdout_tail_sha256": "4cce1df670e136194f3948ab1e2adea77fcc503397cfe10bb308f0a88cd25cf3", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T11:58:41+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.425, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T11:58:56+00:00"}
{"task": "task_0001", "cmd": "bash infra/deploy/build.sh && grep -q \"0e792a7\\|[a-f0-9]\\{7\\}\" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh", "exit": 0, "duration_s": 6.665, "stdout_tail_sha256": "d32d454fb8b15f14778a5dadabf84e948a7599e56e9e6b71a0461170ada259a0", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T12:01:25+00:00"}
{"task": "task_0002", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.424, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T12:01:39+00:00"}
{"task": "task_0003", "cmd": "test -f /tmp/e2e-shots/lighthouse-report.json", "exit": 0, "duration_s": 0.001, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T12:01:39+00:00"}
{"task": "task_0004", "cmd": "pnpm astro build && test -f dist/en/archives/index.html", "exit": 0, "duration_s": 5.079, "stdout_tail_sha256": "1fc2c0b4b5b5d5d14eb765e97d0bbcac5cc9a79b3cfb7c4dac486d84ba211333", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T12:01:45+00:00"}
{"task": "task_0005", "cmd": "node tests/e2e.mjs 2>&1 | grep -q \"30/30 PASS\"", "exit": 0, "duration_s": 14.408, "stdout_tail_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "tree_fp": "b2d37e7c0927340b6545abc81df7d6916cf8fd84cf28e02307a018cf02e3ed17", "at": "2026-10-25T12:01:59+00:00"}
@@ -0,0 +1,73 @@
# Phase 5c:裸 clone 构建 + 移动端布局排查 + Lighthouse 真测 + en/archives 补页 - 项目范围
<!-- spec-format: 2 -->
## 1. 问题定义
- **项目目标**:发布管线确定性(构建源=origin/main);移动端全站溢出修复(用户实测报告);Lighthouse 真分数与 P0 性能优化落地;en/archives 404 补页
- **目标用户**:站长(发布/管理)与移动端读者
- **核心价值**:Sveltia 保存即上线的硬前置落地;手机体验从"可晃动破版"到全宽段合身
## 2. 假设与待确认
### 2.1 已确认事实
- 移动审计实锤:Header 7 项一行在 390px 溢出 51-88px(B1);.prose-tech 缺断词(M1)
- Lighthouse 诊断:614 个 @font-face 708KB 渲染阻塞=Perf 62 元凶
- blog 仓公开 → 裸 clone 匿名 fetch 可行
### 2.2 关键假设
- 320px 超窄 en 残溢记录为已知边界(现实机型 ≥360)
- 正文排版断点为可读性台阶(有意保留)
### 2.3 待确认问题
- [x] 页面自适应方式 → 结论:布局层流式(clamp/auto-fill)+ Header clamp 连续收缩 + <350px 导航内滚兜底(用户设计诉求"根据设备自适应"驱动)
### 2.4 可选解释与取舍
- clamp 流式 > 阶梯断点补丁(任意宽度合身,无逐档维护)-> 选流式
- 导航内滚 < hamburger 抽屉(保单行设计语言,改动最小)-> 选内滚
### 2.5 已证伪路径
- 阶梯断点逐档补丁(430/370 两轮后仍要第三档——治标)
## 3. 功能范围
### 3.1 核心功能(MVP)
- [x] T1 裸 clone 构建改造
- [x] T2 移动端布局全页排查与修复
- [x] T3 Lighthouse 真测与 P0/P1 优化落地
- [x] T4 /en/archives/ 补页
- [x] T5 验证收官
### 3.2 扩展功能
- 无
### 3.3 不在范围内
- Sveltia 站内入口(下轮)、320px 超窄支持(已记录边界)
## 4. 最小实现路径
- 最简单可行方案:构建仓 fetch+reset 硬跟 main;Header clamp 替换阶梯;字体 ?url 非阻塞+按轨挂载
- 暂不引入:hamburger 菜单、流体排版(正文有意台阶)
- 不做的抽象/配置化:多构建源
## 5. 技术决策
- 技术栈:git fetch/reset、CSS clamp、@fontsource ?url、Playwright 密集宽度扫描
- 证据协议:evidence: runs
- 本轮允许改动:infra/deploy/、src/components/Header.astro、src/styles/global.css、src/pages/、scripts/lighthouse/
- 本轮不应触碰:nginx、gitea 运行时、生产内容
- Git integration branch:`spec/2026-10-25_add-blog-5c`
### 5.1 验证策略
- 范围级别:package
- 变更对象:构建管线、Header 流式化、移动端缺陷修复面、字体加载策略、en/archives 页
- 快速检查:`pnpm astro build`
- 集成检查:`node tests/e2e.mjs`(30 项)+ 移动溢出密集扫描(宽段 320-768 × scrollWidth 断言)
- 全项目检查:Lighthouse 复跑对账(Perf 62→88 基线)+ 生产移动端抽查;仅在构建链或 Header 结构再变更时升级范围
- 升级触发:仅在 nginx 面、构建链、发布载荷变更时升级验证范围并记录理由
## 6. 成功标准与验证方式
- [x] 移动溢出密集扫描 44 检全过(320-768) -> verify: task_0002
- [x] staging 恒等 origin/main(裸 clone 构建) -> verify: task_0001
- [x] Lighthouse Perf 62→88 实测 -> verify: task_0003
- [x] en/archives 200 -> verify: task_0004
## 7. 风险与约束
- ESA 边缘缓存旧页会伪装修复失效(刷新后为准);构建仓 node_modules 留存做增量(loader 逻辑变更须清 .astro 数据仓——前包教训)
@@ -0,0 +1,36 @@
# Phase 5c:裸 clone 构建 + 移动端布局排查 + Lighthouse 真测 + en/archives 补页 - 任务拆解
## 使用规则
- boundary/verify 齐备;verify 只读断言
## 阶段一:实现
- [x] T1 裸 clone 构建改造(Sveltia 自动上线硬前置)
- claim: orchestrator
- boundary: 只改 infra/deploy/build.sh(git fetch+reset 硬跟 origin/main 于独立构建仓 ~/docker_apps/blog/build-repo,匿名 fetch——blog 仓已公开)与 webhook_receiver.py 的 BUILD 常量;webhook 触发实测 main 提交自动上线
- verify: `bash infra/deploy/build.sh && grep -q "0e792a7\|[a-f0-9]\{7\}" ~/docker_apps/blog/www-staging/.build-stamp 2>/dev/null || bash infra/deploy/build.sh`
- [x] T2 移动端布局全页排查(用户实测报告问题)
- claim: orchestrator + 视觉车道
- boundary: 390px/360px 双宽 × zh/en × 亮/暗全页截图交视觉模型;发现的缺陷修复;不重构整体布局只修缺陷
- verify: `node tests/e2e.mjs 2>&1 | grep -q "30/30 PASS"`
- [x] T3 Lighthouse 移动端真测(Phase 4 欠账)
- claim: op-gitea(mesh 车道)
- boundary: lighthouse CI 对本机 staging 18743 跑 mobile emulation 五页型(首页/文章/图库/en 首/terminal);记录分数;<90 项出可执行优化清单(不改代码,修复下一轮)
- verify: `test -f /tmp/e2e-shots/lighthouse-report.json`
- [x] T4 /en/archives/ 列表页补缺(现 404)
- claim: orchestrator
- boundary: src/pages/en/archives/index.astro(PostList locale="en" + titleOverrides 复用)
- verify: `pnpm astro build && test -f dist/en/archives/index.html`
- [x] T5 验证收官
- depends-on: task_0001, task_0002, task_0003, task_0004
- claim: orchestrator
- boundary: E2E + 移动端修复后视觉复审 + 归档推送上线
- verify: `node tests/e2e.mjs 2>&1 | grep -q "30/30 PASS"`
---
**当前进度**:由脚本计算,无需手动维护