Files
crearte-monorepo/docs/ROADMAP.md
T
XingfenD 14d029e61b docs: register P13 dark mode (crearte 0.26.0) + server micro-batch (0.17.2)
Brings the P13 batch into this wrapper's version control: spec and plan enter
the repo, ROADMAP gains the P13 row and its document-index entry, and the four
stale 'C dark mode' backlog mentions carried since P9/P10/P9-B/P12 are marked
cleared in place — following the P12 precedent of annotating the historical row
rather than rewriting it, since those entries were true when written.

Wrapper CHANGELOG 0.3.6 records the crearte-only dark-mode delivery
(983e7c4, merge-base e59a171), the parallel server micro-batch delivered during
the survey phase while the implementer owned crearte exclusively (dbf7fe5,
0.17.2: a real uploads.go error-fallthrough defect with zero prior coverage,
plus a decision-record comment on the bundle-key route after grep overturned the
initial suspicion of a hole), and three lessons:

- max(a,b) >= k is a vacuous-assertion hot zone: when the two sides are
  complementary the max has a non-trivial lower bound (here sqrt(16.50) =
  4.0621), so any threshold below it can never fail. The controller's own first
  correction to the scrim guard shipped exactly that, and the same
  one-directional verification recurred in the alpha fallback. Fixing a guard
  now requires proving both no false-red on legal values and no false-green
  under mutation.
- Tailwind v4 scans every source file including test files, so a class-name
  literal in a test comment burns a dead utility into the artifact.
- A universal claim needs a universal grep: 'accent is the only background use'
  was false because both the spike-0 grep and the new guard covered app/ while
  runtime/ sits beside it. That blind spot cost a false spec fact and hid a real
  pre-existing WCAG violation (paper on accent = 3.2590 in light, since P9-B).

ROADMAP's P13 row cites merge commit 983e7c4 per the P12 convention, with the
bookkeeping commits named separately so the reference cannot be mistaken for
them.
2026-10-03 07:30:12 +08:00

29 KiB
Raw 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。CSP / TLS+HSTS / OG 卡片 / 播放计数 / D4 nav 换行 挂账待启动)

排序理由

  • 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)