docs: re-pin both P15 specs after task-level review adjudication

Twenty-four pinned corrections across the two specs and their plans, every one
traced to a measured finding. Both task-level reviewers overturned claims I had
written into the specs, and I reproduced each against the base tree before
accepting it (git show, never the working tree, which already carries the fix).

P15-A spec gains two sections. T1.4 records the reviewer's candidate guard for
phase-independence: the spec called "do not merge phases four and six" the most
important constraint in the batch, yet its only stated mitigation was the
byte-level comparison, which is one-shot evidence — after the report is filed,
nothing reddens when someone merges them. The reviewer built CG1/CG2/CG3 and
verified them both ways: green on the legal tree, red on four distinct merge and
degeneration forms, all assertion-red rather than compile-red, while the three
shipped guards stayed green throughout. T4 records the adjudication of nine
findings, including two that undercut the guard the batch itself added: a
half-finished dir parameter that redirects which files are counted but not which
are read, so a scan pointed elsewhere can satisfy its own precondition while the
169-line function it exists to catch stays invisible; and a span scanner keyed to
line-initial func, which means a 125-line package-level closure passes all four
gates and all three guards. Also pinned: the gofmt gate in the four-gate recipe.
gofmt -l lists unformatted files and still exits zero, so the recipe everyone ran
reported gofmt_exit=0 as evidence of formatting cleanliness. Implementer and I
shared that recipe, which is why the same blind spot was computed twice and
caught by neither.

Phase intervals are corrected to the real base-tree line numbers. The prior text
told the implementer to move lines 212-213 into a helper; 213 is the slog.Info
the same spec requires to stay in the caller, so following it would have swapped
what moves with what stays. Phases six and seven also overlapped, each claiming
the transaction error mapping. The skeleton now passes a pointer where its own
note eighteen lines later demanded a pointer receiver, and the transaction
helper's signature carries submissionID, which removes the batch's dependence on
a cross-repository equality argument for the only acceptance criterion it has.

P15-B spec corrects the artifact criterion I had backwards. I wrote that deleting
a token should change the var(--color-*) count; that count measures usage, the
token had zero usage across seven utility suffixes, and it stayed at 75. Had it
moved, that would have meant something referenced the token, contradicting the
dead-token premise. Definition-side and usage-side are separate measures and the
spec now says so.

Leg five is re-pinned as critical. It was the sole enforcement point for the
non-reactive injection decision, and it only pinned literal form: two
type-legal variants that establish the dependency elsewhere in the computed body
pass all ten legs with vue-tsc clean, and the reviewer proved by effectScope
evaluation counting that both really do make the iframe src flip on a theme
change, reloading a running game. The narrowing was introduced by the
implementer's own fix, to avoid a trap comment that spells out the forbidden
literal; but comment masking already neutralizes that comment, so the narrowing
was unnecessary and the second line of defense created the gap. Same shape as
the P14 final review finding a hole in the first round's fix.

Also pinned: the rejected deviation five, with the corrected root cause (all four
freeze attempts used page.route, which does not intercept service worker
registration, worker-issued requests, or navigations synthesized by respondWith;
context.route holds the loading screen past 25 seconds); the missing
dark-system-times-light-hash grid that one mutation slipped past all ten source
legs and all five e2e legs simultaneously; the fourth tautology class the spec's
three warnings omitted, where emptying a loop's driving collection makes it
vacuously true; legs seven and eight, which respectively substring-searched a
hex that occurs three times in the file and matched only double-quoted style
attributes; the copyable code block's comment, which now avoids the three
literals that would false-redden a correct implementation, with the annotation
moved outside the block; and three new discipline entries covering untested
method scope, measurement units, and retaining one-off verification scripts.

Every correction was checked by a script asserting both directions — the pinned
text present and the superseded text gone — plus table column integrity, fence
pairing, and code-block cleanliness. Three earlier attempts at this re-pin failed
on my own errors and were fixed before commit; the working tree was never left in
a half-edited state.
This commit is contained in:
2026-10-03 19:48:48 +08:00
parent 82f0a6d360
commit 02188eb3e0
4 changed files with 87 additions and 36 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
| **T1** | `app/lib/bootstrapTheme.test.ts`(**新增**) | **RED 先行**(spec §5-T1)。**10 腿**:①pre-paint 脚本在 `<style>` 与 `<body>` 之前 ②判定序 hash→prefers→light(`indexOf` 比较,**先断言三者都 `> -1`**)③白名单校验 hash theme(只接受 `light`/`dark`)④IIFE 且只用 `var` ⑤**`GameHost.vue` 注入的是 `effectiveTheme()` 而非 `useTheme().theme.value`** ⑥bootstrap 暗色块六个 hex 与 `main.css` 暗色调色板**逐值一致**(字符串相等,**不得写成 `max(a,b) ≥ k`**)⑦bootstrap 亮色六个 hex **未被改动** ⑧`bootstrap/index.html` 内**不存在 inline `style` 里的 `color:`** ⑨**前提检查**(读到 ≥3 个文件且 bootstrap html 长度 >500)⑩`AA_PAIRS` 含 `['ink','surface']` 且 `REQUIRED_KEYS` 不含 `info`、长度 `toBe(11)` | RED 输出**逐字存证** `.superpowers/sdd-p15b/impl-evidence/t1-red.txt`,并**逐腿标注红/绿**:腿 1/2/5/6/8/10 须红,**腿 7/9 应当已绿**(它们是"不得回退"钉桩,不是新功能断言——spec §5-T1 明写这是有意的) |
| **T2** | `app/lib/contrast.test.ts`(改)+ `app/styles/main.css`(改) | 按 spec §3.2/§3.3:`AA_PAIRS` 插入 `['ink','surface','卡片/表格/表单底(bg-surface 62 处,58 靠 body 继承 text-ink)亮18.42/暗14.85']`(**不得改其它 10 对**);删 `main.css:12`(亮)与`:53`(暗) 两行 `--color-info`;`REQUIRED_KEYS` 删 `'info',`;四处 "12 令牌" 文案改 "11 令牌"(`:47,74,119,121`)。⚠️ **`LEGACY_KEYS`(`:197`)不动**(九键不含 `info`,已实测) | `npx vitest run` **80 文件 / 688+N 全绿**(N = T1 腿数 ≥10);`--color-info` 全仓命中 **0**;`AA_PAIRS` **11** 对;`REQUIRED_KEYS` **11** 项;`LEGACY_KEYS` **9** 项不动 |
| **T3** | `bootstrap/index.html`(改)+ `runtime/host/adapters.ts`(改)+ `runtime/host/GameHost.vue`(改) | 按 spec §3.1(a)–(e):head 内 `<style>` **之前**插 pre-paint 脚本(**逐字对齐 spec 给的代码块**,含 CSP 注释与 `catch` 兜底);`<style>` 加 `html[data-theme="dark"]` 覆盖块(**亮色值逐字不变**,`color-scheme: dark` 随块声明一次);**删两处 inline `color`**(`:25` 的 `#a3a3a3`、`:27` 的 `#f87171`,各保留 `font-size`);`resolveRuntimeTargets` 的 `opts` 加**可选**键 `theme?: 'light' \| 'dark'`,**仅当存在时**才写 `fragment.theme`;`GameHost.vue` 注入 **`effectiveTheme()`** 并写明陷阱注释 | `npx vitest run` 全绿;`npm run typecheck`(`vue-tsc --noEmit`)**零错**;**`adapters.test.ts` 4 处既有调用零修改仍绿**(验证 `theme` 是可选键);既有 `*.test.ts` 修改数 = **1**(仅 `contrast.test.ts`,须在报告显式声明) |
| **T4** | e2e / 产物验证 + mutation 自查 | 按 spec §5-T4:`npm run build` exit 0(⚠️ 它会类型检查 `e2e/*.spec.ts`,P13 spike 6 曾因此 `BUILD_EXIT=2`);`npm run e2e` **≥102+1skip** 不回退(`dark.spec.ts` 10 腿全绿);**新增一腿覆盖 hash 注入**(e2e 断言 iframe `src` hash 含 `theme=dark`;**若 fixture 无虚拟游戏可跑,改为 vitest 腿**用 `@vue/test-utils` 挂 `GameHost` 断言 `targets[0].url` 含 `theme=dark`——**必须有一腿覆盖**,不接受"fixture 不支持所以不测");**产物验证**:`dist/` 里 bootstrap HTML 含暗色块、**不含** `#a3a3a3` 与 `#f87171`,主应用 CSS 里 `--color-info` 零命中、`var(--color-*)` 计数与 P13 交付值 **75** 比对并**解释差异**;**mutation (a)–(j) 逐条**附输出 | 全部输出存证 `.superpowers/sdd-p15b/impl-evidence/`;产物 grep **用 `grep -F`**(spec §8-6:手写转义与带引号模式对 minified 产物假阴性) |
| **T4** | e2e / 产物验证 + mutation 自查 | ⚠️ **RE-PIN 2026-10-03(审查裁定后)**:**偏离 5 已驳回**——端到端腿**可**确定性化,用 **`context.route`(不是 `page.route`)** + inert sw.js(`page.route` 拦不到 SW 注册请求 / SW 发起的请求 / 被 SW `respondWith` 合成的导航,实测命中 0);断言须含 **`snap.url === 父侧 iframe src`**(因果链闭合);另加**行为腿**(游戏页切主题 → iframe `src` 不变,D-B 的唯一行为级防线)与**反方向格**(子侧 `[系统暗色] × [hash=light]` → 期望 `light`,H1/H3 的唯一鉴别格)。产物验证**必须在 e2e 之后重跑生产 `npm run build`** 之上做,并用 `grep -c -F 'localhost:4173'` = **0** 证明量的是生产构建(控制者当日量了 e2e 残留 → 7069 vs 7056 的假矛盾)。计数须**同时给 raw 与屏蔽注释后两个数**、字节用 `wc -c`(详见 spec §5-T4.3/§5-T4.4 与 `adjudication.md` §三) | **端到端腿 + 行为腿 + 反方向格三类都跑绿**;mutation 复验须跑审查者自设的 **G1/G2/H1/H3/F1/F2/H4 七条**(spec 的 (a)–(j) 对这七条**全部无牙**)+ 全部对照组 + 合法树 |
---