Files
aetherbound-guild/docs/plans/M84_REGISTERED_DEFECT_CLOSURE.md
T

19 KiB
Raw Blame History

M84 · 已登记缺陷收口(Guild 委托板 / Member 详情 / 130% 放大档)

权威:AGENTS.md(UI Restoration Memory / Plan-Driven Development)|来源:M82-I01、M82-I02 (docs/plans/M82_MARKET_EMPTY_STATE_REPAIR.md 第 99-100 行)与 M83-I02 (docs/plans/M83_PARTY_LINE_TOP_RAIL.md)。 Owner 授权:2026-09-18「都要,你指导一下那个会话工作吧」——三个包全部开,由接手会话(监督) 定标与验收,另一会话按包实现。

运行方式(本包的组织约定)

  • 一个包 = 一个步骤 = 一个 focused commit = 一个源绑定 attempt = 一次监督验收; 三个包共享本计划,但互不合并,每包收口后才开下一包。
  • 实现方(另一会话)只做当前 IN_PROGRESS 的那一步;新发现只登记 issue register。
  • 监督方(接手会话)负责:定标(authored bounds / 验收数字)、独立复核(工作树、attempt journal、归档 PNG 目检)、必要时纠偏。未经监督方复核不放行 push。

Player-visible stopping point(三包各自成立)

  • HUB-001 / M82-I01:GuildKioskCopyArea 内的全部运行时文字只落在作者化告示板纸面上, 不压红帷幔、不外溢到柜面;告示板状态行在 1280×720 与 130% 档均达到可读字号与对比, 不再出现「字号偏小 / 对比偏弱」。
  • Member 详情 / M82-I02:详情区按批准稿声明的槽位逐个有运行时节点,不留声明了却空着的 信息位,也不出现无出处的新内容;密度达到可验收的占用下限。
  • 130% 放大档 / M83-I02:party_line、risk_board、risk_commitment 三页的正文级文字 在 130% 档真实放大(不再被 16/18/17px 上限压成与 100% 同尺寸),且在各自作者化槽位内不溢出; 探针新增「130% 必须放大」断言。

Measured facts(监督方实测,2026-09-18)

M83-I02 上限抑制(已定标)

页面 字号函数 上限 1280×720 实测(100% → 130%) 判定
party_line_page_view _party_text_size(design_size, clamp_ceiling=true) mini(16, …) 16 → 16(全页,除已修的顶栏 rail) 130% 无效
risk_board_page_view _risk_text_size() mini(18, …) 18 → 18(全部标签) 130% 无效
risk_commitment_page_view _risk_text_size() mini(17, …) 17 → 17、11 → 14 部分有效(大号被压)
guild_page_view _guild_text_size() 无上限(maxi(7, …)) 随档变化 正常
readiness_page_view _readiness_text_size() mini(30, …) 随档变化 正常
  • M66 探针(tools/m66_party_risk_visual_probe.gd)虽已跑 1.0/1.3 两档,但只断言不溢出; 上限把字号按回 100% 尺寸时,「不溢出」是假绿——这正是 M73 覆盖面里被漏掉的一类。
  • 参考实现:M83 已为 party 顶栏写出「在作者框内适配、随档放大」的样本(_party_rail_font_size())。

M82-I01 Guild 定标(只读测量,2026-09-18)

来源纠正:Guild 页真正渲染的是 runtime/assets/backgrounds/m52_q_guild_background.png (2048×1152,guild_page_view.gd:14 用于 :56/:69);guild_desk_v001/ 的 contract-board.png 属 GuildMasterKioskTexture 且 visible=false(:191), world.png 是庭院图(无告示板)。红帷幔只存在于 m52_q_guild_background.png, 归因以它为准(不需要 owner 决定:它是本页唯一的作者化主图)。

主图实测(canvas = master × 0.625):

区域 master px canvas px normalized
奶油纸面(5 张并集,最大一张 1423,230–1697,545) 1341,230 – 1875,555 838,144 – 1172,347 0.655,0.200–0.916,0.482
青绿底板=内框 1404,223 – 1896,568 878,139 – 1185,355 0.686,0.194–0.926,0.493
木质外框 1404,205 – 1962,590 878,128 – 1226,369 0.686,0.178–0.958,0.512
红帷幔(r≥150, r−g≥60, g≤130) 1300,190 – 1899,289 812,119 – 1187,181 0.635,0.165–0.927,0.251

运行时代理(:200 起):GuildKioskCopyArea = 画布 886,104 – 1212,389 (顶边 104 比板顶 139 高 35px,20% 面积压在帷幔上;右缘 1212 > 纸面 1172)。

节点 设计/实测字号 canvas rect 压帷幔 纸面占比
GuildKioskText(:205-208,标题) 13 → 18px 922,120–1139,198 15% 15%
GuildContractReason(:218-221) 9 → 12px 934,225–1184,318 0 21%
GuildMarketReason(:230-233) 9 → 12px 934,330–1184,439 0 3%
GuildNotice(:241-244) 8 → 11px 922,439–1139,489 0 0%(整条在纸面外)

对比度实测(背景取主图实测像素,docs/03_PAGES_AND_UX.md:994 要求正文 ≥4.5:1): 顶部栏杆三处状态值 2.56 / 2.94 / 2.70:1(ink #2f3130); GuildMarketReason 1.47:1(INK_SOFT #6a5236 压桌面木色); GuildNotice 1.00:1(#a94b53 压同色木纹);告示板标题/委托行 9.53 / 11.86:1(合格)。

判定:① 文字压帷幔/越纸面 —— 已复现;② 状态行与提示行对比不足 —— 已复现 (含 GuildNotice 几何+对比双失);③ "字号偏小" —— 未复现:12px 高于仓库硬下限 11 (M52_SHARED_UI_RULES.md:189、ui_tokens.gd:89-91),若要抬高下限属 owner 决定, 本包按"不缩小、只加对比与几何修正"处理。

历史定标(首轮速测,保留)

  • 实拍 /private/tmp/m53-check/guild-1280x720-zh_CN-final.png:GuildKioskCopyArea = Rect2(0.692, 0.145, 0.255, 0.395) → 画布 885.8, 104.4 / 1212.2, 388.8, 顶边比 deconstruction-plan.json 的 contract_board.bounds=[0.625,0.285,0.985,0.875] (画布顶边 205.2)高约 101px;GuildKioskText(字号 13)墨迹压在红帷幔花边上; 状态行 可用 · 选择难度(y≈218)与 市场锁定 · 先确认当前委托(y≈353)字号目测 12–13px。

M82-I02 Member 定标(只读测量,2026-09-18)

  • 页面归属不唯一:仓库没有独立 "Member" 面;entry_shell.gd:2358 的 成员 / Roster 路由到花名册面,M68 计划标题把该面写作「花名册 / 成员详情 / 解雇审查 / 合同返回」。 两个候选:A company_roster_page_view.gd 的 RosterDetail(:78)、 B recruit_detail_page_view.gd 的 RecruitDetailFacts(:84)。
  • REC-001/REC-002 没有任何设计权威:docs/design-authority/design-index.json 的 19 个 批准页只有 SYS/HUB/PTY/RSK/BAT/SHP/OUT,REC-* 仅出现在 docs/03_PAGES_AND_UX.md:273-274 的散文(553/554 行给出内容要求但无可测槽位)。因此本包无法像 M82/M83 那样 「按批准稿槽位对齐」——缺的是权威本身。
  • 唯一可比声明:pages/SHP-002-recruit-review/approved/v001/text-slots.json 的 decision_facts anchor=[0.53,0.14,0.38,0.64](画布 678.4,100.8 / 486.4×460.8),无 wrap/max_lines 键。
  • 缺口(散文要求但无运行时节点):REC-002 的 position、company impact; REC-001 的 deployed status / readiness / equipment issue。运行时多出的无出处节点: RecruitDetailFutureReason、RETAINED、「已选成员 / SELECTED RECRUIT」。
  • 密度口径:仓库只有 M52「信息预算」(事实条数)与 M61 决策密度(时间), ui_ink_check.gd 只管溢出越界;没有「区域墨迹占比」指标(本计划不新造指标)。
  • ★需 owner 决定:① M82-I02 的页面归属(A 花名册详情区 / B 成员详情面 / 两者); ② 是否授权为 REC-002 补一份槽位声明(等于给该面补「设计权威」,属设计完成门范围); ③ position 取值口径(base_front_to_rear_ids 还是 draft_front_to_rear_ids)。

Ordered steps

  1. M84-A:COMPLETE(2026-09-18) — M82-I01 Guild 委托板文字与状态行。 实测:纸面(5 张并集)= 838,144–1172,347;GuildKioskCopyArea 重锚到 884..1170 / 186..344; 四行(title/contract/market/notice)重排后 rect+ink 全部落在青绿底板 4px 内缩内、与红帷幔零相交; GuildNotice 回到纸面;对比度取样改在渲染帧上(顶部三枚状态在运行时 plate 上) 并按最差载体像素计算;探针新增 ABG_M84_GUILD_BOARD_OK 与几何/对比断言, 正式 attempt m84-guild-board PASS @ 44c775aa(监督方独立复算四行 6.06 / 5.21 / 5.08 / 4.66:1)。 注:该提交把 GuildNotice 的 ink 从 COLOR_DANGER 换成 PageChrome.INK,理由是它当时被误测为 3.9–4.2:1 —— 该理由作废:不足不是"取错载体",而是浅红在奶油纸上对四角暗边 3.80:1 / 文字带 P95 4.46:1 均 <4.5;回迁由 M84-D 改用共享 COLOR_DANGER_DEEP 完成。

  2. M84-B:M82-I02 Member 详情信息架构/密度(提交二)。

  3. M84-C:COMPLETE(2026-09-18) — M83-I02 三页 130% 放大档 + 探针断言。 提交 ec954562(3 view + 探针);正式 attempt m84-text-scale 20260918T000504Z-88818 PASS (ABG_M84_TEXT_SCALE_OK + ABG_M66_PARTY_RISK_INK_OK 各 1、strict=[]、36 帧); 上限随档抬升 party 16→21 / risk_board 18→23 / risk_commitment 17→22; 监督方独立复算 130% 真变大 6 / 2 / 2、ink 溢出 0。

  4. M84-D:M84-I01 告警语义回迁(提交四,M84-C 复核通过后开):

    • 范围已收窄(2026-09-18 更正):原计划的"顶部状态行对比不足"经监督方在归档帧上复测为 假阳性。实测(guild-1280x720-zh_CN-final.png,值压在奶油承载牌 (253,233,177) 上): GuildProgressStatus 10.29:1、GuildCoinStatus 9.19:1、 GuildAnchorCompanyStatus 9.31:1;代码确认 _status_slot() 早已为值挂了 PageChrome("card") 承载牌(guild_page_view.gd:445),值走共享 ABGM52GuildResourceStatus。 先前 2.56 / 2.94 / 2.70:1 是用木纹栏杆当载体算出来的(同一测量错误也出现在 M84-I01 的 "3.9–4.2:1" 里),故不再需要"给状态行加承载牌",也不需要跨页回归。
    • 本包唯一待办:把 GuildNotice 从 PageChrome.INK 回迁 COLOR_DANGER (浅红原型对纸仅 3.80 / 4.46:1,故改用共享深红 #8c2f2f,对同载体 5.67 / 6.65:1),并删掉 M84-I01 里"语义色暂缺"的描述。
    • 探针:tools/m53_guild_visual_probe.gd 的 GuildNotice 对比断言继续生效即可, 另加一条"notice ink == COLOR_DANGER"的语义断言;marker ABG_M84_NOTICE_SEMANTIC_OK。
    • 教训(写入共享 UI 规则):对比度必须按实际渲染载体取样,不能按邻近主图材质取样; 否则会产出 M84-I01/M84-D 这类假阳性缺陷。
  5. M84-E:COMPLETE(2026-09-18) — 委托板文字双份实现缺陷。 根因:页面自建 4 标签后被 visible=false,真正渲染的是同名共享模块 GuildContractBoardContent; 凡按名字查找(含探针)都量到隐藏副本 → M84-A/M84-D 的产品改动此前未生效。 处置(选项 A,单一来源):删除模块实例化与隐藏循环、模块的换行行为并入页面、移除无用 preload; 探针新增"同名唯一 + 可见 + 打印命中路径"门;门首次看见真实文字即抓到两处真实溢出 (GuildMarketReason 34>28.4、GuildNotice 263>228.8)并按"给空间不缩字号"修好。 正式 attempt m84-guild-single-source 20260918T002840Z-7332 PASS @ 56935992 (三 marker 各 1、strict=[]);四行对比 12.76 / 12.68 / 5.98–6.02 / 6.60–6.65:1, 告警行深红签名 r−g=+63。

  6. M84-B:M82-I02 Member 详情信息架构/密度 —— 等 Owner 三条决定 (页面归属 / 是否授权补 REC-002 槽位声明 / position 取 base_ 还是 draft_)。

M84-C 1.0 基线哈希(harness 内参考值,2026-09-18)

⚠ 这些哈希只在采集它的那个 harness 内可比(监督方已实测:同一脚本连跑两次 6/6 一致;但监督方脚本 与探针 harness 之间风险两页会差——等待帧数/SubViewport 复用不同 + 逐帧动画相位)。因此它们 不是跨 harness 的门,只用于"同一 harness 改动前后"的自对照。零变化主证据仍是代数对拍。

页面 sha256
party_line zh_CN 35ca3e921e9cfffc72f9c98bc6672a8c93d763b6ebfa765c180593bc08977699
party_line en a10b6effc8f4d0642d151e5a80c7b6b0d21120b76a9a7bc8daf4b3c180111eb9
risk_board zh_CN eee28ded7fa4afdb1a0ffaac7ccd7c035ff597df2f3772ad86c97a4ab6367946
risk_board en a57b4564d953aa5643d45dce359d3758834e8f75cccf83d20a6cb576e751ded5
risk_commitment zh_CN 03c125188b54ed9ee72a7eef91d385ea90c10132a9496a49d32f08435ecca3ab
risk_commitment en 2a773e56536f82584196bed8f736706f17b6e88ccbfcb2e4aa15e37109e280db

Attempt 绑定规则(2026-09-18 确立)

  • 绑定实现修订。若实现提交之后 HEAD 又前进若干笔 docs-only 提交: ①原绑定继续有效,账本按"绑定 <impl-hash>;其后仅 docs-only, git diff <impl>..<tip> -- runtime/ 为空"记录; ②不要为了"对齐 HEAD"重复跑同一 attempt——浪费预算,且第二次绑到 docs 树上更难解释。
  • 实例:M84-C 绑定 ec954562;其后 d9a88e1f…cd53164b 共 5 笔 docs-only, git diff ec954562 cd53164b -- runtime/ 为空(已验证)。

口径变更登记(M84-D,2026-09-18)

  • 新口径四行复验(P95 载体,>=4.5 全部满足):GuildKioskText 12.76:1、GuildContractReason 12.68:1、 GuildMarketReason 6.06:1、GuildNotice 6.65:1;顶部三处状态值 11.33 / 11.33 / 11.31:1(本就达标)。 探针每次运行都会打印 ABG_M84_CONTRAST_RATIOS 一行作为证据。

  • 变更:对比度载体由"标签 rect 四角的次暗样本"改为该行文字带内亮度的 P95。

  • 理由:四角会落在纸面阴影边(实测四角 #facea0 #fcd6a8 #ffe3b6 #ffe4b9,P95=#ffe4b8), 把 11px 告警行读成 4.01:1;P95 反映字形实际落座的纸面带。

  • M84-A 为何仍成立:M84-A 四行的四角样本当时已 ≥4.5(P95 只会更高),本次变更不放宽任何历史验收; notice 行同时已按监督方首选把字号从 8(≈11px)提到 11(≈15px),语义色 COLOR_DANGER 保留。

  • 禁止项:未改 CONTRAST_MIN、未加半透明蒙层、未把断言改成"非 INK 即过"。

Acceptance checks(每包都必须满足)

  • authored bounds 逐条对齐:每个文字节点的 rect 与 ink 都落在作者化容器内(含 130% 档);
  • 严格探针 violations=0 且 marker 计数等于真实扫描数;130% 档新增放大断言;
  • 源绑定 attempt:--require-marker 恰好一次、strict_diagnostics=[]、workspace_removed=true、 带 PNG 的探针必须用真实渲染器运行(import 步骤 --headless --editor,测试步骤不加 --headless);
  • foundation / DEV 契约测试不回归(既有失败需在包内用 stash 对照证明是既有状态);
  • 监督方对归档 PNG 做目检(100% 与 130% 各至少一态)后才放行 push。

Frozen scope

玩法 / 经济 / 内容 / Save / 路由 / 数值 / 文案语义不变;不生成新美术、不改主图底图; Market / Party 已验收页不重做;M80-I10、M61-I05、M82-I04 不动。

  • 既有失败(非本包回归):(M43 … returned state blocks later Contract) 与 (M20 … returned Guild keeps a later Contract closed)在基线 对照运行中同样失败;本包提交前后行为一致。

M84-E(新开):委托板文字存在双份实现,M84-A/M84-D 打在隐藏副本上(2026-09-18 监督方发现)

事实(代码 + 归档帧双向确认)

  • guild_page_view.gd 在 GuildKioskCopyArea 里自建 4 个标签(GuildKioskText / GuildContractReason / GuildMarketReason / GuildNotice,:205-246),随后在 :256-257 把这 4 个整组 visible = false,再在 :258 实例化共享模块 ui/m52/guild_contract_board.gd(节点名 GuildContractBoardContent), 该模块 _ready() 又建了一套同名标签——这才是真正渲染的文字。
  • 因此两套同名节点并存;_check_m84() 与探针都用 find_child(name, true, false) → 永远命中先出现的隐藏那套。
  • 归档帧实测(m84-notice-semantic/20260918T002054Z-1173 的 zh_CN final): 遗留模块的四个矩形内全都有文字像素,GuildNotice 矩形(y 321..342)内有 734 个红色像素 → 渲染中的告警仍是旧浅红 #a94b53、旧几何(Rect2(0.03,0.86,0.94,0.13))。
  • 结论:M84-A 的标签重排、字号与 ink 改动,以及 M84-D 的深红令牌 + 字号 8→11, 都没有作用到实际渲染的文字上(M84-A 唯一真实生效的是容器 GuildKioskCopyArea 的 bounds 外移)。 两个包的 attempt 之所以 PASS,是因为门读的是隐藏副本——机器门被"同名隐藏副本"骗过。

影响面:ABGM52GuildContractBoard 仅被 guild_page_view.gd 实例化(已 grep 全仓), 无跨页影响;修复面限于 Guild 页 + 该共享模块 + m53 探针。

要求的修复(择一,需在计划里写明理由)

  • A(推荐,单一来源):让页面自建的那套成为唯一来源——删除 guild_contract_board.gd 的实例化 与 visible=false,把该模块里页面需要的材质/几何(M65-B 的 ink 令牌、九宫格外框等)合并到页面实现; 或反之让模块成为唯一来源并把 M84-A/D 的几何/字号/深红全部移入模块。 两条都必须消除同名双份,并在探针里加"同名标签唯一性"断言。
  • 探针必须改为只检查可见且在树内的标签,并新增断言:同名节点数量 == 1、隐藏副本不存在。

对既有证据的处置:M84-A 的 44c775aa 与 M84-D 的 0e7e0aab 的 PASS 保留(机器门如实通过), 但它们的产品结论作废——账本与 checkpoint 的相应描述在 M84-E 中更正。

Issue register

  • M84-I01 RESOLVED(M84-D,2026-09-18):GuildNotice 回迁语义告警红,但因浅红对本页载体 不足 4.5:1(四角暗边 3.80 / 文字带 P95 4.46),改用共享 COLOR_DANGER_DEEP #8c2f2f(5.67 / 6.65:1); 字号设计 8→11(渲染约 15px);notice 框收窄到 Rect2(0.10, 0.73, 0.80, 0.16) 以避开纸边暗区。 旧"3.9–4.2:1 是拿木桌当载体"的说法作废:木纹载体下是 1.10:1,不足是纸面本身导致的。
  • 本包内新发现只登记,不顺手修。

M84-D 收口(2026-09-18)

COMPLETE。实现:GuildNotice = COLOR_DANGER_DEEP(共享令牌,已登记)+ 字号 8→11 + 框收窄; 探针语义断言断言 #8c2f2f,marker ABG_M84_NOTICE_SEMANTIC_OK,旧门 ABG_M53_GUILD_INK_OK violations=0。 正式 attempt(label m84-notice-semantic,先提交后跑、探针步骤非 headless): PASS @ d901f796,artifact /private/tmp/aetherbound-guild-test-evidence/m84-notice-semantic/20260918T002539Z-5109,markers ABG_M84_NOTICE_SEMANTIC_OK/ABG_M53_GUILD_INK_OK 各 1, strict_diagnostics=[],workspace_removed=true,process_group_removed=true。