Files
XingfenD d70991b0ad docs: book P15-B as delivered (wrapper 0.3.9, ROADMAP ledger section)
P15-B merged to crearte master as 7f91fa3 (0.27.0, merge-base f823195, thirteen
commits across two fix-forward rounds). P15 is now fully landed.

Three things this entry records that a routine booking would omit.

The whole-branch review blocked the batch - the second time it has done so after
P11 - and its critical finding was in the guard layer rather than the product:
maskSourceComments() compared a two-character slice against the four-character
'<!--', so its HTML-comment branch never ran, producing two false greens and
three false reds and making two already-committed claims false. Product code
needed no change; one added line and one changed comparison closed it.

The second round was executed by the controller rather than the dispatched
subagent, which ran 1h25s and failed with no output, leaving nothing to salvage.
The controller produced one false green of its own on the way - a mutation round
whose anchor failed to match was scored as meeting an expectation that happened
to be an empty list, the same defect the reviewer had caught in itself.

The e2e suite carries a pre-existing flaky leg at roughly one run in three
(core.spec.ts's worker leg: helpers.ts reads an async-postMessage attribute with
a bare getAttribute and no retry). Every file involved has zero diff against the
batch base and all four legs this batch added were green in all three review
runs. Recorded so the next red CI run is not attributed to this release.

ROADMAP also gains a standing ledger section, which the roadmap never had: the
cross-batch items accumulated by P15's two review rounds and the branch review,
each with its measured basis rather than an aspirational note. It includes the
revival of feat/submission-preview - the inline play-test preview for the submit
form and the review page, which the user asked about and which turns out to be
delivered work sitting unmerged in two paired remote branches (crearte a3cb5e3,
crearte-server 6b072d6, 27 tests, zero residue on master), together with the two
hard collisions that make reviving it a real batch rather than a rebase.
2026-10-04 04:14:09 +08:00

46 KiB
Raw Permalink Blame History

crearte 路线图 / Roadmap

跨三个仓库(crearte 前端 / crearte-server 后端 / crearte-deploy 编排)的子项目路线图与索引,维护在 monorepo wrapper(本仓库)。

  • 版本 v0:2026-09-29 与维护者确认的分解与顺序。
  • 现状基线:crearte 0.13.0 / crearte-server 0.11.0 / crearte-deploy 0.3.1。

分解原则

  • 按「依赖关系 + 是否阻塞上线」排序;每个子项目的规模控制在一份 spec 能装下。
  • 每个子项目独立走 spec → 实现计划 → 实现 → 验证 的循环。
  • 隐藏复杂度出现时升级路径(拆出新子项目),不硬塞进当前子项目。

第一波:上线底座(运维 / 可靠性,顺序敏感)

# 子项目 内容 涉及仓库 依赖 状态
P0 已知缺陷清理 ① CORS Access-Control-Allow-Headers 补 If-None-Match(解锁 e2e:stack Step5:revoke 410 + 降级)② 清理 compose 配置漂移(BUNDLE_KEY_STORE 环境变量、bundle-keys-* 卷——密钥自 server 0.6.0 起在 Postgres)③ crearte-deploy CHANGELOG 补账 server, deploy 无 完成(server a8ea755 / deploy 27044be,2026-09-29 合并推送)
P1 prod 写侧可用 prod 栈补对象存储(prod MinIO 或外部 S3)+ api-prod 配 STORAGE_S3_* / GAMES_BASE_DOMAIN / CORS_ALLOWED_ORIGINS;密码默认值、TLS 起步。现状:prod 无对象存储时写侧路由(上传/投稿/审核/预览)不注册,生产只读 deploy(少量 server) P0 完成(crearte 63bb96d / deploy 4d53d58,2026-09-29 合并推送;TLS 与真域名留清单,见 spec §6)
P2 CI + 测试基线 后端 / 部署仓建 CI(gofmt/vet/test + TEST_DATABASE_URL 集成层 + e2e:stack 全链路);与前端已有 validate.yml 对齐。现状:后端/部署仓无 CI,Postgres 集成测试无 TEST_DATABASE_URL 时静默 skip 三仓 P0(e2e 依赖其修复) 完成(server 7b97108 / crearte 711b6de / deploy 522545d,2026-09-30 合并推送;e2e-stack 宿主仓修订见 spec §2.2;首跑拓出 serve-runtime 子域缺陷已修(5e0fb2e);Actions 启用与分支保护为 owner 手动尾巴,见 spec §2.4)
P3 备份 + 可观测 pg_dump 定时备份 + MinIO 数据保护 + 恢复演练 runbook;结构化 / 请求日志 + /metrics;限流器单实例问题记录权衡 server, deploy P1(拓扑定型) 完成(2026-10-01 历史重放合并推送:deploy 12f7c10 0.6.0(backup.sh/restore-drill.sh/BACKUP-RUNBOOK/CI dry-run 腿/LOG_FORMAT-LOG_LEVEL 透传)+ server d627e12 0.16.0(slog 机械迁移 30 处含 P7/P8b2 新面、RequestLogger 中间件、手写 /metrics http+go+pgpool 三族、限流单实例权衡文档)。P3M 合流后终验全绿:容器四连+真库 -p 1 -count=1(skip 守卫 0,含注销链集成)+实栈 metrics 冒烟(计数族/nomatch/双跳过/slog JSON/pgpool 族/go 族全中)。原 P3 提交 7fcfe0e/6ffd1ee/93a3c70 在回滚窗口脱离 master,经 cherry-pick 重放字节级回归,P7/P8b2 新面补入同规则迁移。本机实栈备份演练腿未跑(prod 栈未起),留 owner 按 runbook 执行)

第二波:产品价值(可与第一波部分并行)

# 子项目 内容 涉及仓库 依赖 状态
P4 作者主页 /users/:user 聚合页(该作者全部已上架作品,前端按命名空间过滤,零后端改动),按最新上架排序;顺带 /games/:user/:slug 面包屑与作者名互链。spec:docs/specs/2026-09-29-author-page-design.md crearte(前端) 无强依赖,可提前并行 完成(crearte f12cbf1,2026-09-29 合并推送)
P5 收藏 / 评分 新数据表 + 用户态 API + 目录/详情页 UI;产品线里最大的一块 三仓 建议 P2 先落地 完成(server e3da246 / crearte eb5fbed,2026-09-30 合并推送;范围修订 deploy 零改动,见 spec)
P6 hosted 作品投稿(方案 A 自托管内嵌) 作者把游戏部署在别处,投稿填 https URL,站内沙箱 iframe 播放;播放端机件已全存在,打通的是入口:后端 D-B runtime 不可变 + D-C hosted 禁 bundle 两护栏,前端表单第三档+预填解锁 三仓 owner 已拍 A 完成(owner 拍板方案 A:只存 URL、站内沙箱 iframe 播;server 3e11446 0.13.0 / crearte fee5f3b 0.19.0,2026-09-30 合并推送。勘查正误:Approve 落库映射本就全(PayloadToWork import.go:39),无需动;真实缺口只在校验两处——D-B metadata_change 禁改 runtime(根治前端拒预填的降级风险)+ D-C hosted 禁带 bundle。前端:类型三档/表单第三 radio「自托管内嵌」/hostedUrl https+fallback 默认 external 镜像校验/预填解锁;播放端零改动(GameHost/useGameFrame 既有)。双路审查 PASS with notes;六腿全绿:容器四连、空库 -count=1 集成 151 PASS 零 FAIL(含 TestHostedPublishChainOnPostgres 真 HTTP 全链)、真栈 full-loop 分支后端 1 passed、vitest 492/typecheck/admin-flow 6(首轮 1 passed 系栈腿争用假警报,复跑坐实)/主套件 69。T5:deploy 模板层无主站 frame-src 下发(仅两处属运行时子域页 CSP),零改动记录在案。遗留仅剩:new_version 对 hosted 仅 server 拦(前端无硬校验,spec 决策)。D-D(审核面 hostedUrl/fallback 展示行)当日补交:控制者直改维护者小补丁,分支 feat/p6-dd-adminrow(Task 2 任务书漏列该条;审查按任务书对照未扯出——教训:审查依据应是 spec §3 全量),纯文本无锚点+降级中文标签,四腿复跑 vitest 492/typecheck/admin-flow 7/主套件 70 全 RC=0,crearte 合主 9bd9372(0.19.1)

第三波:治理与长尾(随时可插队)

# 子项目 内容 状态
P7 管理后台增强 用户列表 / 角色管理 UI(替代 CLI user set-role)+ 审计日志 完成(server ca24805 0.12.0 / crearte 900f13a 0.18.0,2026-09-30 合并推送。audit_log 表 0010 + 组中间件统一记录(owner 定稿:admin 路由收敛为组,Full-Path 模板入史,GET 也记,失败尝试照记,未遂 401/403 不记);用户列表/PATCH 角色/审计查询三端点;唯一 admin 降级 409 护栏 CLI/API 双覆盖;前端 /admin/users + /admin/audit 两页,降级确认双要点文案;本机六腿验收全绿:容器四连+fresh-DB -count=1 10 ok 零 FAIL 零 skip、废 token 端到端 401、护栏矩阵(非唯一降 OK/唯一降 CLI 拒+API 409)、审计流水含 409 失败尝试、真栈 full-loop 分支后端 1 passed×2、vitest 488/typecheck/admin-flow 6/主套件 68)
P8 长尾打包 权限开关 UI 全量(inlineStyle/wasm/coop/fullscreen/gamepad)、后端 triage 小项(games.Detail 400 细分、admin 路由 slug 校验、approve 同名竞态测试)、账号注销、静态兜底目录、CHANGELOG 模板文案 第一批完成(②⑤①,2026-10-01 合并推送:server 921443a 0.14.0 / crearte 70ba10c 0.20.0。容器四连+空库 -count=1 集成全绿(新竞态测试含,skip 守卫 0)+-race 竞态腿 PASS;curl 冒烟全中:detail 400 细分 user:/slug: 且双非法 user 优先、admin 四路非法 400 invalid work id、合法格式不存在仍 404;FE vitest 499/typecheck/admin-flow 7/主套件 70+1skip;双审 PASS(server PASS with notes—唯一 note 双非法优先级缺钉桩,已以 ee5b960 测试断言补上);deploy 零改动。第二批完成(③账号注销+④静态兜底目录)(2026-10-01 合并推送:server 12b8ffb 0.15.0(迁移 0011 墓碑化删行、DELETE /api/auth/account 对密码注销、唯一 admin 409、user delete CLI、catalog export 出 schemaVersion=2 目录)+ crearte 7d5f338 0.21.0(/account 危险区+deleteAccount 客户端+AdminUsersView 三码中文化钉桩)+。真库注销链集成+分支真产物 curl 冒烟 14 项全 PASS(墓碑行/邮箱复用/409/旧 token 作废/CLI delete/export schema);FE vitest 512/typecheck/主套件 71+1skip/noauth 4,双审 PASS with notes(前端 2 条次要已钉桩 7a54152,server 裁决项:LOG_LEVEL 大小写不一致—deferred)。余 ④的 render 消费端接入按需(feed 已交付)**,CHANGELOG 头部去模板腔两仓已随第一批完成、wrapper 头部不在 spec 范围
P9 UX 增强(第一批:浏览器反馈包) 路由级 document.title 两段式(router afterEach 按 19 个 name 全表设静态基线 + 四个数据页 watch 数据后精化)+ 作品页 meta description(截 120 码点、默认回落)+ StatePanel 骨架对齐(cards 3→6 张、新增 lines 变体六页八实例)。零后端/部署改动 第一批完成(2026-10-01 合并推送:crearte 26cd625 0.22.0(a196603+3f1de38+审查补钉 e9e4c56)。五腿全绿:vitest 551(基线 512+新增 39)/ vue-tsc 零错 / build OK / 主套件 72+1skip(含新增标题 e2e 腿,landing.spec.ts 首条兼容钉一字未动)/ noauth 4。独立审查 PASS with notes:ISSUE-1(离开作品页 description 未回落默认,spec D-C 子项)与 ISSUE-2(「七页」实为六页文案)均已在合主前补钉+补测。B 效率可访问(已于 P9-B 交付)/ C 暗色模式(已于 P13 交付)两批挂账已清偿)
P10 UX 增强(第一批:日常交互包) toast 体系(useToast 单例 store + ToastHost 挂 App.vue)+ 投稿表单脏数据离开守卫(onBeforeRouteLeave confirm + beforeunload)+ 作品标签可点(GameView/GameCard tags → /games?tag= RouterLink)+ 作品页复制链接分享(clipboard + toast)+ 最近玩过条带(recent.ts localStorage + GameHost ready 记录 + LandingView 条带)+ 页头下拉外点/Esc 关闭。零后端/部署改动 第一批完成(2026-10-01 合并推送:crearte ee4edf7 0.23.0,merge-base 26cd625。六任务各经实现→任务级审查→裁定,另加全分支终审(spec §3/§4/§5 全量对照)。五腿全绿:vitest 601(基线 551+新增 50)/ vue-tsc 零错 / build OK / 主套件 77+1skip(基线 72+1skip)/ noauth 4。审查补钉四处:fc0270e(AppHeader 卸载清理 spy)、dbf4bf0(hosted 重开 sync-flush 再记,spec D-H re-pin)、bb9bb35(e2e 夹具修正——spec 测试计划自身误选 external-runtime 夹具 2048/a-dark-room,换 abs-paths/storage)、836b2fb(AppHeader 路由收起回归,spec §5 明列项)。终审裁定「需修复后合并」两条件均已闭合。B 效率可访问(已于 P9-B)/ C 暗色模式(已于 P13)已清偿;OG 卡片 / 播放计数等后续批挂账待启动)
P9-B UX 增强(第二批:可访问与键盘效率包) WCAG AA 色彩对比达标(--color-success 加深 + error toast 换 bg-accent-ink)+ toast 播报区重构(常驻 sr-only 播报层与视觉层解耦,收口 P10 终审转办项 T1(d)「实时区嵌交互按钮」)+ skip-link(App.vue 根首子,focus:z-[80])+ SPA 导航后焦点管理(focusMain(),仅路径变化触发、preventScroll)+ 管理端表格 24 个 <th> 补 scope="col"(两处空表头补 sr-only「操作」)+ 五星评分可访问名(逐星「评 N 星」+ 分组 role="group" 动态标签 + 字形 aria-hidden)。另加两个源码级守卫(contrast.test.ts 十一配对对比度、tableScope.test.ts 全仓 <th 必带 scope)与 e2e/a11y.spec.ts。零后端/部署改动 第二批完成(2026-10-01 合并推送:crearte 338acbf 0.24.0,merge-base ee4edf7。五任务(T1-T4 派发 + T5 控制者本人)各经实现→任务级审查→裁定,四次任务级审查全 PASS,另加全分支终审(spec §1-§6 全量对照 + 跨任务集成缝隙 + mutation 抽查)。五腿全绿:vitest 626(基线 601+新增 25)/ vue-tsc 零错 / build+build-runtime OK / 主套件 80+1skip(基线 77+1skip)/ noauth 4。终审独立实跑六腿与控制者数字逐条一致,裁定 APPROVE with notes(零关键/零重要)。波次内两次 spec 层修正:① T1 实现者抓出 spec 初稿 D-I 缺陷(per-toast role=status 与文字同时创建,部分读屏不播报首条)→ re-pin D-I′ 为常驻播报区,控制者直修 f01baae 并附带钉死饱和态 watch 陷阱(源必须是末尾 id 而非长度,MAX_VISIBLE=3 时 3→3 不触发);② 控制者简报两处数量笔误(对比度 3.16 应为 2.83、「19 个 th」是行计数、元素实为 24)均由实现者以 spec/实测为准纠正,spec §1 已同步。打磨批挂账四条(router 升级复看弱断言、撤评语义进可访问名、手动关最新 toast 的播报重念、spec 口径已修)。C 暗色模式已于 P13 交付清偿;OG 卡片 / 播放计数等后续批挂账待启动(「移动端页头」已于 P12 实测证伪删除:nav 内容宽仅 74–158px,320/360/375/412/768/1280px 零横向溢出))
P11 服务端安全硬化 限流表硬上界(maxEntries 失败关闭:满时先过期清理、仍满则对新面孔 429 且不插入,既有键语义逐字不变;闭合缺陷 B「同窗口 map 无界增长」)+ LOG_LEVEL/LOG_FORMAT 入口层小写化与 trim(闭合 P8 deferred 缺陷 C)+ TrustedProxies 空时启动 slog.Warn(D-C 大声留痕)+ 两个 compose-SNAT 网关陷阱反面钉桩 + deploy TRUSTED_PROXIES 空默认与 README 专节(真实 prod 按实际反代 IP/网段配)+ nginx X-Real-IP 与九处 nosniff/Referrer-Policy(always)。CSP 与 HSTS 有意不做(前者需独立设计批,后者待 TLS 批) 完成(2026-10-02 合并推送:server 9da39b6 0.17.0(merge-base d627e12)/ deploy 740958a 0.7.0(12f7c10)/ crearte d25c497 0.24.1(338acbf)。五任务各经实现→任务级审查→裁定全 PASS(零关键零重要,9 条次要转打磨批),另加全分支终审(qwen3.8-max)裁定「需修复后合并」——N1(WARN hint 竟建议 subnet 信任,即 D-A′ 判定的绕过配置)/N2(spec 五处 subnet 线未随 re-pin 更新)/N3-N5 均已闭合,N6(validate.yml 加 TRUSTED_PROXIES 空默认机器守卫)转打磨批。本批最重要事件:端到端验收抓出设计级错误并 re-pin D-A→D-A′——原 D-A 信任整个 compose 子网,但真实 prod 栈实测:docker 对发布端口做 SNAT,nginx 看到的源恒为网桥网关且网关也在子网内,gin 跳过可信网关后采纳客户端预置 XFF(X-Forwarded-For: 8.8.8.8 → ip=8.8.8.8,限流可自选桶绕过);而真实浏览器(无 XFF)在 compose 下恒塔缩到网关——缺陷 A 对合法流量根本修不了(SNAT 固有)。spike_snat 六用例信任矩阵钉死后改为:空信任默认(XFF 整体忽略、无绕过、D-C 告警如实提示单桶)+ subnet 固定回退 + README 重写真实 prod 配法 + server 两个反面钉桩。修正后 prod 真实栈回归五项全中(告警在位、伪造 XFF 解析为 nginx 容器 IP 绝非 8.8.8.8、单桶 429 正常、404 上安全头完好、卷全留存)。验收全链:server gofmt/vet/build 净 + test 11 包 ok + -race 12 包 ok(Debian 镜像 CGO=1)+ 真库 db-test 集成 ok(skip 守卫 0);crearte vitest 626/typecheck 零错/build OK/主 e2e 80+1skip/noauth 4;终审独立复跑六腿与控制者数字逐条一致。教训入账:隔离 spike 证明组件语义、不证明配置在真实拓扑下正确——安全/网络类修复合并前必须走真实流量路径的端到端验证;验收测错路径(用伪造 XFF 当回归)比不测更危险。CSP / TLS+HSTS 挂账待启动(打磨批已于 P12 部分清偿:P9-B 四条中三条(路由弱断言 / 撤评语义 / 播报重念)与 P11-N5/N6 已闭合;P9-B 第四条「spec 口径」在 P9-B 波次内已修;P11 其余九条次要为纯留档、无可动手改动)
P12 窄屏溢出修复与打磨批 四个实测窄屏溢出缺陷 + 途中发现的一个:缺口 A 页头长 display_name(60 字为合法上限,非敌意构造)撑破全站每个路由(320px +380px / 375px +325px);缺口 B 账号页昵称 dd 逃逸(ddRight=592);缺口 C 目录排序 select 的 shrink-0(/games 320px +3px,短名短数据也复现);缺口 D 五个 admin 表格零 overflow 包裹层(/admin/users 320px +76px,短数据也复现);缺口 E 用户下拉菜单逃逸视口(menu right=485,由页头修复一并闭合)。另加两层机器守卫(e2e/responsive.spec.ts 12 测试零配置改动进 CI 主腿 + app/lib/tableOverflow.test.ts 源码级逐表格父元素判定)与三项打磨(P9B-1 路由弱断言 / P9B-2 撤评语义进可访问名 / P9B-4 播报重念)。零新功能、零后端行为变更 完成(2026-10-02 合并推送:crearte e59a171 0.25.0(merge-base d25c497)/ server d56c593 0.17.1(9da39b6)/ deploy 529a988 0.7.1(740958a)。派发遵循一仓一写者:T1/T2/T3/T5 同动 crearte 单一工作树,故交一个子代理而非四路争用 .git/index.lock;T6(server)/T7(deploy)由控制者本人写。守卫任务提前为 TDD 第一步而非第二波:先写守卫看它变红并逐字复现 spec 实测数字(+380/+325/+3px/五处缺失包裹层),再实现到绿——这个顺序使 RED 输出本身成为「有牙」证明,免去事后 revert 自证。任务级审查三份(前端 PASS with 8 notes、server PASS、deploy PASS with 3 notes + 1 条 spec 勘误)+ 全分支终审裁定 APPROVE with notes(零关键零重要),全部 notes 合并前逐条裁定(FE-1/2/6 fix-forward 20215e7、SD-N1 fa39d27、N-F1/2/4 改 spec/FINDINGS/注释,余为 accepted-with-reason)。终审独立复现三处 mutation(不采信控制者与审查者结果):回退 T1 → 6 腿 e2e 变红;注释掉表格包裹层 → 源码守卫变红;错误文案回显原始 env → server 两条断言同时变红。两个挂账项由实测定夺:①「移动端页头 / 汉堡菜单」证伪删除——nav 内容宽仅 74–158px,320/360/375/412/768/1280px 实测零溢出;② nav 链接逐字换行(375px = iPhone 12/13/14 同样如此)park 待设计决策——纯外观(无溢出无裁剪无功能损失),whitespace-nowrap 在 320px 引入 +11px,七种 gap 收缩组合在「320px + 长名」下全灭(+19~+75px),因 logo(77px)+nowrap nav(138–158px)+截断名(96px) 物理放不下、与页头修复争同一份像素。诊断关键:八种一行修法全停在残差 +32px(含 overflow:hidden)→ 改用烧蚀法定位到 P9-B 自己那个 1px sr-only span(absolute 无 top/left,static 包裹层不构成包含块故逃出滚动裁剪)→ 包裹层必须 relative。归因冲突用运行时注入 2×2 消融定案:768px /account 的 +40px 实由缺口 A(页头)驱动而非 dd——回退 dd @768 仍 over=+0、回退页头 → over=+50;dd 固有右缘恒 592px 故牙口在 <592px 视口。两个修复独立必要、缺一不可,但不是同一视口的同一症状;spec 已 re-pin 五处下游。验收:crearte vitest 635/74(基线 626/73)/ vue-tsc 零错 / build+build-runtime OK / 主 e2e 92+1skip(基线 80+1skip)/ noauth 4——控制者复跑两次 + 任务级审查者与终审者各复跑一次,四方零偏差;server gofmt/vet 净 11 包 ok;deploy 四 profile config -q 绿 + 守卫三态验证(正向绿 / 注入 CIDR 红 / 删注入行红)。教训入账:① 挂账项实现前必须先证伪或证实;② 所有候选修法失败在同一残差上说明诊断错了(换烧蚀法比再加候选有效);③ 运行时样式注入无法验证模板级修法(Vue 把插值编译成单文本节点);④ 源码级 mutation 可能读到 stale dist/(reuseExistingServer: !CI)而产生假 GREEN,关键归因须改用运行时注入;⑤ 守卫自身要受与被守卫代码同等的审视——审查发现注释掉包裹层会使新守卫假绿,与 deploy 守卫里那个恒不匹配的死 CIDR 断言同属假信心类,两者均合并前修掉。CSP / TLS+HSTS / OG 卡片 / 播放计数 / D4 nav 换行设计决策 挂账待启动(UX C 暗色模式已于 P13 交付清偿)
P13 暗色模式 两态主题(light ↔ dark)全站落地:首次访问跟随 prefers-color-scheme,显式点击后持久化到 localStorage['crearte.theme.v1'] 并从此压过系统偏好(无第三态——有意不做)。每主题 12 个设计令牌;暗色在 html[data-theme="dark"](特异性 (0,1,1),无 !important/@apply)下整体覆盖亮色 @theme 块 = 方案 B,故只需 3 处 usage 迁移(方案 A 需 32+ 处)。index.html 内联 pre-paint 脚本(IIFE + 仅 var,在任何 CSS 与 Vue module 之前)设 data-theme 防闪白,判定优先级与 useTheme.effectiveTheme() 逐字一致;页头 32px 开关(登出态可用)同步翻转 data-theme + theme-color meta + localStorage;color-scheme 由 data-theme 驱动使原生控件跟随。五个 --shadow-hard* 改 var() 传导;新增 --color-skeleton 与 --color-scrim(两主题同值不翻转——暗色 color-mix(…ink 60%) 实测 oklab(L=0.962) 近白会毁遮罩)。零生产逻辑变更 完成(2026-10-03 合并推送:crearte 983e7c4 0.26.0(merge-base e59a171;记账 commit 4cfabdd+d1aa8c0)。一仓一写者:T1–T5 交一个实现者子代理(同动 crearte 单一工作树),守卫任务 TDD 先行看红。任务级审查 PASS with notes(自设 10 条 mutation 挖出 5 条 findings)+ 全分支终审 APPROVE with notes(零关键 / 2 重要 / 5 次要 / 3 建议),10 条 note 合并前逐条裁定:4 条 fix-forward(2433ec7/481574c/6ec6170)+ 4 条(bb2cb42)+ 5 条 spec 文档纠正 + 1 条 pre-existing 延后 + 2 条 accepted-with-reason。本批最重要事件:审查阶梯抓出控制者自己写错两次的守卫——scrim 分离断言两次反转:spec 原文「ink vs scrim ≥3 两主题」会让亮色腿误红(亮色实测仅 1.07,两个深色互不分离);控制者第一次改成 max(填充侧,边框侧) ≥3 数学恒真(两侧互补 → 下界 = √cr(paper,ink) = 4.0621 > 3,50653 采样暴力验证),故把亮色 scrim 改纯白(正是该令牌要防的泛白)时填充侧 1.1165 而 max() 读 18.42、守卫仍绿(任务级审查 M1 抓到);交付形态改为按主题钉实际分离侧(亮=填充侧 paper、暗=边框侧 ink),mutation 现能变红。两条教训入 spec:① max(a,b) ≥ k 是恒真断言高发区(互补时下界非平凡),且修守卫必须两方向都验(对合法值不误红 + mutation 下不误绿)——同一错误在 alpha 兜底分支重演(只对当前 Chromium 输出验,漏了 CSS Color 4 百分比/指数 alpha 被解析成 80/1);② Tailwind v4 扫描全部源文件含 .test.ts/.spec.ts——测试注释里的类名字面量会被当候选、烧死 utility 进产物(实现者用拼接修对一处,控制者八分钟后在自己裁定 commit 里重新引入,靠重建抓出 → spec §8-5b)。终审另暴露一处 pre-existing 缺陷并延后不忽视:runtime/host/GameHost.vue:39 降级外链徽标(bg-accent text-paper,11px bold)实测亮色 paper on accent = 3.2590 < 4.5 FAIL(暗色 7.1218 过),根因是 spike-0 的 grep 与 noHardcodedColor 守卫都只覆盖 app/、漏了与 app 同级的 runtime/;该违规自 P9-B 就在、P13 未使其变差且不属 P13 范围 → 三方面处置(守卫扫描根已含 runtime/、spec §3.2「accent 全仓唯一/纯非文本令牌」的假声明已纠正、违规本身登记可访问性打磨批)。守卫体系:contrast.test.ts 重构为按主题分块解析(旧单 Map 解析器逐字保留为 legacySingleMapParse 反面钉桩,防后人「简化」回去——旧解析器在暗色块存在后会把九个旧键静默解析成暗色值而断言标签仍写 light palette = 守卫悄悄变只守暗色)+ 新增 noHardcodedColor.test.ts(沿用 P12 tableOverflow 屏蔽范式,扫 app/+runtime/,含 2 positive + 1 negative control 防「扫 0 文件也报 0 违规」的假信心)+ themeBootstrap.test.ts(钉双写:同键名、两侧 stored 白名单、判定序、IIFE+var、theme-color、color-scheme meta)+ dark.spec.ts 10 腿(含 pre-paint 归因腿:拦 JS 包后 data-theme 仍 dark,证明是内联脚本而非挂载后设置;反方向 stored 压过 system 腿;垃圾 stored 被忽略腿——后两条是 finding #2/N2 的行为解药,因文本位置守卫不鉴别语义重排)。验收:crearte vitest 688/79(基线 635/74)/ vue-tsc 零错 / build+build-runtime OK / 主 e2e 102+1skip(基线 92+1skip,P12 的 12 条 responsive 腿未动全绿)/ noauth 4——控制者与两位审查者各自独立复跑;产物 main-C7966Gm-.css:var(--color-*)=75、内联 #141414=2、暗色块在位、死 utility 双双归零、--tw-shadow 含 var(--color-ink)。挂账新增:第三态「恢复跟随系统」(spike 3 证明 header 在 @320px 最坏格无像素容纳带标签控件)、CSP 落地时内联 pre-paint 脚本需 nonce、死令牌 --color-info(bg-info/text-info 零实例)、SFC <style> 块内硬编码 hex(守卫不覆盖,accepted——app/ 无 <style> 块)、GameHost 亮色徽标 WCAG 3.26——修时须避开与「加载失败」状态点撞色(亮色 accent vs accent-ink 仅 1.4943,徽标与状态点同屏共存于展柜标题栏,改成 bg-accent-ink 会把「已降级外链」与「加载失败」两个语义压成一个视觉信号),属设计决策而非一行改(已实测证伪显而易见修法)。CSP / TLS+HSTS / OG 卡片 / 播放计数 / D4 nav 换行 挂账待启动)
P14 拆分 ContentService god object internal/service/content.go 从 856 行、承载五条互不相干职责线(目录读 / 反应 / 上传 / 投稿 CRUD / 审核发布)的单一 ContentService,拆成五个子 service 文件 + 一个组合根:catalog.go(110) · reaction.go(102) · upload.go(99) · submission.go(291) · moderation.go(298),content.go 缩到 82 行(只留组合根与真正被两三条线共用的 11 个声明)。五个 handler 各改为声明消费方定义的窄接口(可见方法 22 → 4/5/2/5/6,审计确认零过声明、零孤儿);cmd/catalog.go 不再为 god object 交税(依赖槽 4→2、nil bundle 占位消失、不再构造从不读取的 PostgresUserStore);顺手删掉死字段 ContentService.now(构造器赋 time.Now 而包内零读取、无 test seam)。纯结构重构、零行为变更 完成(2026-10-03 合并推送:crearte-server fe810dd 0.18.0,merge-base dbf7fe5;记账 commit e50d08e;spec 两次 re-pin 在 wrapper 11fa1e2+33c2d8d)。一仓一写者:T1–T3 交一个实现者子代理(同动 crearte-server 单一工作树),守卫任务 TDD 先行看红。任务级审查 PASS with notes(1 important + 6 advisory,自设 10 条 mutation)+ 全分支终审 APPROVE with notes(零关键 / 1 重要 / 2 次要 / 3 建议,16 轮 mutation/spike 全在 HEAD 导出副本上跑、以 140 个 blob hash 证明与 HEAD 一致),13 条 note 合并前逐条裁定:3 条 fix-forward(e195be0)+ 1 条 fix-forward(e04694b)+ 5 条 accepted-with-reason + 2 条 spec 措辞纠正 + 1 条挂账 + 1 条「审查者对我错」。本批最重要事件:审查阶梯两轮都抓到了控制者自己的错误——① 任务级审查发现 spec D-J 自述的守卫目的「防方法迁回组合根」没有任何断言覆盖(组合根新增方法后三断言 PASS + build/vet 绿 + 全量 11 包测试全绿 → god object 可静默回潮),并发现 spec 里 mutation (a) 这个 positive control 自身有绕行路径(它红是因为把方法从子 service 拿走,不是侦测到组合根多出方法;改成「复制」即遮蔽形态就会误绿);② 全分支终审在第一轮修复自身里找到洞:源码扫描正则把接收者名写成必需分组,而 Go 允许省略不用的接收者名——遮蔽体恰好常不需要它(func (*ContentService) CoverURL(k string) string),该形态下 build/vet/七断言全绿而遮蔽确实生效(经组合根调用返被接管值、直调子 service 返原值)。一个 token 修好:接收者名改可选分组 (?:\w+\s+)?。③ 终审另推翻我两处已入库的全称声明(「断言 5 是唯一能抓遮蔽的手段」在修前为假;「F4 两层覆盖完整」被孤儿私有方法反例推翻)——两条我都独立复现成立后才动手,均已 re-pin 进 spec 并写明范围。控制者 spike 否决了审查者建议的两条修法(终审在真仓复核,两条驳回都正确):断言值类型 NumMethod()==0 不可满足(嵌入 *T 使方法进值+指针两个方法集,合法树上已是 22 → 恒假断言,正是 P13 恒真断言的镜像形态);比 Method.Func 同一性无法侦测遮蔽(提升方法是 forwarding wrapper,真仓实测合法 9683808≠9511104、遮蔽 9515680≠9511104,两侧都不等)。两条教训入 spec:① 恒假与恒真同样无价值,且恒假更容易被当成「守卫很严」而通过审查;② 写「唯一手段」这类全称声明时必须先枚举形态(有名/匿名接收者、值/指针、导出/未导出),否则它成为下一个审查者的反例靶子。守卫终态:architecture_test.go 253 行 / 七条 reflect 断言(组合根形态 · 各线导出方法名集 · 无 now 字段 · 组合根指针方法集=五线之并 22 · 源码不得声明组合根方法 · 各线字段名集=依赖面 · 构造器不漏装),经两轮审查驱动补强、对 14 条 mutation 双向验证(合法树 7/7 绿、每条 mutation 精确红且非编译红)。副产品发现:reflect.Type.NumMethod() 只暴露导出方法 → 断言 4 看不见未导出的组合根方法,那部分只有源码扫描能抓(四轮仅变方法名大小写的诊断坐实),故断言 5 的作用比原设计更宽。Route C 两条 spec 未记的性质已入 §7:组合根零具名字段 → s.store/s.objects 等在其上是 ambiguous selector(实测编译红 ambiguous selector s.objects),这是比守卫更早的编译期屏障,也解释了为何字段数断言是防「加具体字段」的唯一防线(加具体字段在 Go 里合法);go vet 不报告遮蔽(实测 vet_exit=0)。验收:wc -l 口径 content.go 856→82、六文件最大 298(moderation.go)、service/ 内 >400 行生产文件 1→0、handler 里 service.ContentService 10→0、catalog.go nil 占位与 NewPostgresUserStore →0、组合根自身方法 25→0、cmd/serve.go diff 0 行、既有 *_test.go 修改数 0(--diff-filter=M 空,唯一新增 architecture_test.go);字节级保真 base 39 声明 → 37 逐字一致 + 恰 2 处刻意变更(struct 五具体字段→五嵌入指针、ctor 体改组装而4 参数签名逐字不变)+ 0 缺失 + 零重复声明、接收者分布 4/6/2/7/6/0 匹配归属映射;四门 -count=1 禁缓存全绿 11 包 ok(api ~11s 真库集成、service ~3.7s)+ 七断言 -v 全 PASS——控制者与两位审查者各自独立复跑。13 文件 src diff +1239/−805(含记账 14 文件 +1283/−805)。挂账新增:Approve 169 行(moderation.go:47-215,7 阶段边界已测绘;拆分后行号已重新定位,base 树的 606–772 作废)、memory_content.go 814 行测试替身规模、handler 错误映射去重(92 处 WriteError 但仅 2 处 errors.Is,重复度不足以证明收益)、AccountService/CleanupService 的 now 字段使用复核(本批只确证 ContentService.now 死)、断言 6 只钉字段名不钉类型(低危,有编译器/既有测试兜底)、断言 5 词法扫描对块注释内部行过严(刻意保留:假红比静默遮蔽便宜)、孤儿私有方法归属无守卫(产物只能是死代码,accepted)。CSP / TLS+HSTS / OG 卡片 / 播放计数 / D4 nav 换行 / GameHost 撞色 / 第三态恢复跟随系统 / --color-info 死令牌 / bootstrap 加载屏暗色白闪 挂账待启动)
P15-A 拆分 Approve 七阶段 internal/service/moderation.go 的 Approve 从 169 行函数体拆成 24 行编排体 + 八个具名 helper(loadApprovePlan 47 / precheckApprove 17 / copyApprovalObjects 22 / applyApprovalInTx 27 + 三个 kind 分支 22/22/24 / cleanupApprovalUploads 7)。唯一验收判据是零行为变更,用语句级证据支撑(162 条中 149 逐字 / 13 有登记理由 / 0 缺失 / 0 乱序)。事务边界一行未动。两个新守卫:函数长度(阈值 100 有 78 函数普查依据)+ 阶段独立性(钉住乐观预检与事务内悲观重检不合并,那是长度守卫结构上看不见的性质)。 完成(server e70e99b 0.19.0 / wrapper 0.3.8;任务级审查 PASS with notes + 全分支终审 APPROVE with notes,11 条 findings 全部合并前裁定)
P15-B bootstrap 暗色 + 守卫补钉 + 死令牌清理 游戏加载屏跟随主题(hash → 系统偏好 → light 的判定序,pre-paint 脚本在 <head> 内任何样式表之前),消除暗色用户启动游戏时的白闪;AA_PAIRS 补 ink/surface;删死令牌 --color-info(REQUIRED_KEYS 12→11、LEGACY_KEYS 9 不动、usage 侧 75 不变)。源码守卫 10 腿 + e2e 9 腿(含 snap.url === 父侧 src 因果链闭合与切主题不重载的行为腿)。 完成(crearte 7f91fa3 0.27.0 / wrapper 0.3.9;全分支终审曾裁 🔴 需修复后合并:maskSourceComments() 的 HTML 注释分支是死代码,2 字符切片与 4 字符 <!-- 比较 → 恒 false,造成 2 处假绿 + 3 处假红;第二轮 fix 由控制者直接执行——子代理 1h25s failed 零产出、wreckage 盘点无物可救;十一轮验牙全对 + 四门全绿后合并)

挂账(跨批累积,随时可插队)

P15 两轮审查与终审累积的、不阻塞已交付批次的条目。每条都给了实测依据,不做愿望式登记。

条目 依据与修法 来源
helpers.ts 的 frameDataset() 改用 expect(locator).toHaveAttribute(...) 它用裸 getAttribute(无自动重试)读 worker 异步 postMessage 落地的属性,而 openGame() 只等同步的 data-ready → e2e 有 1/3 级别的既有 flaky(core.spec.ts:14 worker 腿)。相关文件对 P15-B base 0 行 diff,故与本批无关 P15-B 终审 §8.1
腿3 与腿5 一并改成语义化断言 两者都是双向都不精确的字面量钉桩:腿5 漏 5 类类型合法的有害形态(方括号取值 / unref / 跨文件 adapters.ts / provide-inject / 事后改写 url,均由 e2e 行为腿兜住)、误红 2 类无害形态;腿3 对语义等价的换序与 .includes() 改写假红。两处必须同步,否则风格永远分叉 P15-B 终审 §2 + §5.2
两个 expect.poll 的 timeout 20s → 10s 端到端腿最坏路径 = poll(20s) + domcontentloaded + poll(20s) + waitForTimeout(8s) = 48s+ > playwright.config.ts 的 45s;实测正常路径 <1s,10s 已极宽松 P15-B 终审 §8.5
SW 自愈重装路径补 theme 键 RuntimeMeta 无该字段;bootstrapRedirect 重建 8 键而 adapters.ts 是 9 键 → 缓存回收后自愈时,显式选择与系统偏好相反的用户会看到一次错误主题的加载屏。修法:RuntimeMeta 加 theme?、writeMeta 带入、bootstrapRedirect 条件 hash.set P15-B 终审 F-10
noHardcodedColor.test.ts:7 的三条死 utility(另开 chore/ 批) 产物里 .bg-\[\#…\] / .text-\[\#…\] / .border-\[\#…\] 各 1 条,值是省略号 U+2026 而非真 hex(浏览器不生效,约 100 B)。讽刺点:该文件 :17-21 自己写着「本文件里的注释不得写出完整的硬编码色 utility 字面量」而 :7 正犯着。修它会变产物哈希 → 与「三次构建哈希相同」证据链冲突,故须独立批 P15-B 终审 F-11
maskSourceComments() 的 /* 分支会吃掉含 /* 的字符串字面量 实测 const marker = "/*" 会让后续真代码被误屏蔽(P14 审查者第一版脚本的同族假阳性面)。当前四个被扫文件都无此形态 → 潜在风险而非现存缺陷 P15-B 终审 §1.2
CSP 落地需先定反向代理落点(独立设计批) crearte-deploy 现有安全头/CSP/HSTS 命中 0、没有 nginx/traefik/caddy 配置文件(只有 docker-compose.yml 与 .github/workflows/validate.yml)。需要 nonce 的内联脚本共 2 处(src/index.html 1 + P15-B 新增的 src/bootstrap/index.html 1) P11 判定 + P15-B 取证
六个 >60 行的 Go 函数 deleteAccountLocked 83 · UpdateSubmission 76 · ValidateWorkFields 75 · ImportDir 70 · CleanupService.Run 70 · checkSubmissionRules 66 P15-A 终审 §10
长度守卫阈值 100 的盲区 + 三条同族 ①「≤100 行的任何合并形态」不红(合并阶段四与阶段六实测 91 行)② TestApproveIsSmall 的镜像盲区(内联一个阶段时所有守卫全绿)③ 任意长度的非 func 形态逃逸(125 行的包级闭包通过全部四门与三条长度守卫,现由 TestNoPackageLevelFuncClosures 部分覆盖,但空格缩进与分行 var 条目仍逃逸、靠 gofmt 门兜)④ 三个守卫常量的自证钉挡不住「同步改值 + 同步改钉」(固有上限,靠 review 兜) P15-A 终审 §10
P14 断言五被类型别名接收者绕过 type X = ContentService + *X 上的方法 → 遮蔽确实经组合根生效,而与既有断言逐字相同的正则报零命中、十条守卫加 vet 与 build 全绿。最小修法一条正则 ^type\s+\w+\s*=\s*\*?ContentService\b;更强修法改 go/ast,一次性解决 F2/F5/F7 三条词法根因。HEAD 上此类别名 0 处,故洞未被利用 P15-A 终审 F5
CG3 名字级检测被包级函数值别名绕过 var f = applyApprovalInTx 再委托 → 5 条守卫全绿,但全量套件 10 个测试 FAIL 兜底(非静默逃逸)。与上一条同族根因:词法级扫描看不见语义别名,宜一并处理 P15-A 终审 M1
合并前验证清单须含 DB-enabled 对照 spec 点名的 5 个真库守卫(含 2 个并发/TOCTOU 测试)在实现者、任务级审查者、fix-forward 与控制者的所有跑批里全部 SKIP(无人设 TEST_DATABASE_URL),而被报成「含真库集成」的 internal/api ~11s 其实是 mock 路径。全仓受该变量门控的 Test 函数 11 个(cmd 2 / api 4 / repository 2 / service 3) P15-A 终审 §5
crearte-server/AGENTS.md:8 的 gofmt 配方仍是退出码盲形态 该行写 run gofmt -l ., go vet ./..., ...,而 gofmt -l 列出未格式化文件时仍 exit 0 → 应改为 test -z "$(gofmt -l .)"。inner repo 改 AGENTS.md 须开 chore/ 分支(约定类改动按仓内先例 4f9de39 不带 CHANGELOG)。workspace 级 AGENTS.md 已补 P15-A 终审 F3
wrapper docs/CHANGELOG.md 的历史版本乱序 0.3.0(行 69) 排在 0.3.1(行 76) 之前,由 d6e08e1 / 3eec675 引入,在 re-pin 前的 82f0a6d 上已存在 = pre-existing。头部 6 项仍降序,不影响新条目插入 P15-A 记账期实测
memory_content.go 814 行测试替身 · handler 错误映射去重(重复度不足)· AccountService/CleanupService 的 now 字段复核 · D4 nav 换行 · OG 卡片 · 播放计数(server 侧 play_count/og: 均 0 命中 = 全新功能非改造)· 第三态「恢复跟随系统」(spike 3 已证伪:header 在 @320px 无像素容纳带标签控件) 各自的前轮挂账,未变 P12–P14
🔴 复活 feat/submission-preview(用户 2026-10-04 问起,已实测取证) 提交表单侧与审核侧的内联试玩预览,两仓成对:crearte a3cb5e3(19 文件 +680/−36,落后 master 87 commit)· crearte-server 6b072d6(17 文件 +727/−17,落后 47)。含 SubmissionPreview.vue(复用 GameHost 全链路)、content/preview.ts、两条带鉴权路由 /api/uploads/:id/bundle 与 /bundle-key(仅 owner/admin,越权一律 404,响应形状与公开端点一致 → SW 解密逻辑零改动)、27 个测试(server 6+5、前端 3+9+4 e2e)。master 上零残留(RouteUploadBundle 命中 0)。复活不是 rebase:① 撞 P14 的 TestNoContentServiceMethodDeclarations(分支给 ContentService 加了 3 个方法,须迁到 upload 职责线)② 会复现 P15-B 刚修的白闪(分支 preview.ts 里 theme 命中 0,且它改了 adapters.ts +89/−26 与 GameHost.vue 的 props,正压在 D-B 陷阱上)。冲突面:crearte 8 文件双向(9 标记)、server 8 文件(8 标记),分支独有新增 11+9 个不冲突 用户提问 + 控制者实测

排序理由

  • P0 最先:几十行的修复,却解锁整条 e2e 回归链路——后面每一波都靠它做验证保障。
  • P1 紧随:不做则生产环境投稿 / 审核根本不可用,产品功能再丰富也上不了线。
  • P4 可提前:无依赖且范围清晰,若想先看到用户可感知的产品变化,可与第一波并行。

文档与提交约定

  • 所有 spec / 实现计划 / 跨仓库协作文档统一放在本仓库 docs/(docs/specs/、docs/plans/、docs/ROADMAP.md),并在下表登记;内层仓库只保留各自的 docs/CHANGELOG.md 与 docs/README.md。此约定取代 crearte-deploy 0.3.0 确立的「crearte-deploy 为跨仓库文档 canonical home」。
  • monorepo(本仓库)可直接在 master 提交;内层三仓仍遵循各自 AGENTS.md 的分支与合并规范。

子项目文档索引

子项目 spec 实现计划
P4 作者主页 docs/specs/2026-09-29-author-page-design.md docs/plans/2026-09-29-author-page.md(已执行,2026-09-29)
P1 prod 写侧可用 docs/specs/2026-09-29-prod-write-side-design.md docs/plans/2026-09-29-prod-write-side.md(已执行,2026-09-29)
P5 收藏/评分 docs/specs/2026-09-30-favorites-ratings-design.md docs/plans/2026-09-30-favorites-ratings.md(已执行,2026-09-30)
P6 hosted 投稿(方案 A) docs/specs/2026-09-30-hosted-submission-design.md docs/plans/2026-09-30-hosted-submission.md(已执行,2026-09-30)
创作者中心 /creator(维护者直接需求) docs/specs/2026-09-30-creator-center-design.md docs/plans/2026-09-30-creator-center.md(已执行,2026-09-30)
P2 CI+测试基线 docs/specs/2026-09-30-ci-test-baseline-design.md docs/plans/2026-09-30-ci-test-baseline.md(已执行,2026-09-30)
P3 备份+可观测 docs/specs/2026-09-30-backup-observability-design.md docs/plans/2026-09-30-backup-observability.md(已执行——回滚窗口脱离 master,2026-10-01 历史重放回归:deploy 0.6.0 / server 0.16.0)
P7 管理后台增强 docs/specs/2026-09-30-admin-console-design.md docs/plans/2026-09-30-admin-console.md(已执行,2026-09-30)
P8 长尾打包(第一批:②⑤①) docs/specs/2026-10-01-p8-long-tail-design.md docs/plans/2026-10-01-p8-long-tail.md(第一批已执行,2026-10-01)
P8 长尾打包(第二批:③④) docs/specs/2026-10-01-p8b2-deletion-catalog-design.md docs/plans/2026-10-01-p8b2-account-catalog.md(已执行,2026-10-01:server 0.15.0 / crearte 0.21.0)
P9 UX 第一批(浏览器反馈包) docs/specs/2026-10-01-p9-ux-browser-feedback-design.md docs/plans/2026-10-01-p9-ux-browser-feedback.md(第一批已执行,2026-10-01:crearte 0.22.0)
P10 UX 第一批(日常交互包) docs/specs/2026-10-01-p10-ux-daily-interaction-design.md docs/plans/2026-10-01-p10-ux-daily-interaction.md(第一批已执行,2026-10-01:crearte 0.23.0)
P9-B UX 第二批(可访问与键盘效率包) docs/specs/2026-10-01-p9b-a11y-keyboard-design.md docs/plans/2026-10-01-p9b-a11y-keyboard.md(第二批已执行,2026-10-01:crearte 0.24.0)
P11 服务端安全硬化 docs/specs/2026-10-02-p11-server-hardening-design.md docs/plans/2026-10-02-p11-server-hardening.md(已执行,2026-10-02:server 0.17.0 / deploy 0.7.0 / crearte 0.24.1)
P12 窄屏溢出修复与打磨批 docs/specs/2026-10-02-p12-narrow-viewport-overflow-design.md docs/plans/2026-10-02-p12-narrow-viewport-overflow.md(已执行,2026-10-02:crearte 0.25.0 / server 0.17.1 / deploy 0.7.1)
P13 暗色模式 docs/specs/2026-10-03-p13-dark-mode-design.md docs/plans/2026-10-03-p13-dark-mode.md(已执行,2026-10-03:crearte 0.26.0)
P14 拆分 ContentService god object docs/specs/2026-10-03-p14-content-service-split-design.md docs/plans/2026-10-03-p14-content-service-split.md(已执行,2026-10-03:crearte-server fe810dd 0.18.0)
P15-A 拆分 Approve 七阶段 docs/specs/2026-10-03-p15a-approve-phases-design.md docs/plans/2026-10-03-p15a-approve-phases.md(已执行,2026-10-04:crearte-server 0.19.0,merge e70e99b)
P15-B bootstrap 暗色 + 守卫补钉 + 死令牌清理 docs/specs/2026-10-03-p15b-bootstrap-dark-design.md docs/plans/2026-10-03-p15b-bootstrap-dark.md(已执行,2026-10-04:crearte 0.27.0,merge 7f91fa3;经两轮 fix-forward,第二轮由控制者直接执行)