Commit 078bdcd
check-half-states self-test: route every nullable predicate row through a wrapper, and delete the 14 literal stray spaces (#12390)
* check-half-states self-test: route every nullable-predicate message assertion through a row-text wrapper
The self-test's message assertions read `predicate(...).includes(needle)` on
predicates that are three-valued by design (null when clean, a string when the
row fires). The moment a change makes such a predicate go clean, that line
throws `TypeError: Cannot read properties of null (reading 'includes')` while
evaluating t()'s arguments — before t() runs — so the suite ABORTS there,
every later case never runs, and the output names a TypeError instead of a row.
Generalizes the per-predicate wrapper PR #12272 established for H34
(`const h34row = (...args) => String(fn(...args) ?? '')`) to the remaining 18
predicates, plus the two local nullable helpers (`halves`, `dead27`) that carry
the same shape. 145 call sites switched; predicates themselves are unchanged and
their `typeof`/`=== null` assertions deliberately stay un-wrapped.
Self-test output is byte-identical to before: 1380 cases pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
* check-half-states self-test: close the variable-mediated half of the nullable-.includes population
The card's table counted only DIRECT call expressions (`pred(...).includes(`).
A second population reaches the same throw through a local const —
`const h9NoLine = h9OnHoldNoRestartWhen(...)` then `h9NoLine.includes(...)` —
which a call-expression scan cannot see. Measured on the pristine base: 108
such sites across 29 variables, spanning four predicates the card never named
(h20, h21, h23, h28).
This half is what actually kept the suite aborting: with population A alone
fixed, the H9 ablation still died at the first `h9NoLine.includes`.
Two shapes, chosen per variable:
- no nullability assertion on the const -> wrap the DECLARATION in place
(19 variables, zero call-site churn)
- `typeof X` / `X === null` asserted -> keep the raw const and add a
`XRow` sibling (10 variables, 56 sites switched), because stringifying
in place would make those assertions trivially true
Audit now reports 0 unsafe receivers in both populations. Self-test output
remains byte-identical: 1380 cases pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
* pm-dispatch corpus: delete the 14 literal stray spaces after a Han-adjacent ASCII mark
#12081 measured a LINE-END event (a soft break after an ASCII , ; : between Han
characters). A faithful re-wrap preserves that space as a literal ", " in
source, where the line-end predicate can no longer see it — so the defect
migrates rather than disappears.
Re-derived on this tree with the card's predicate (literal Han + ASCII ,;: +
space + Han, one line, excluding fenced / front-matter / multi-line ruling
regions via the ratchet's own state machine): 7 + 6 + 1 = 14, reproducing the
card's table exactly. All 14 deleted.
Each site has a same-line sibling using the identical mark with NO space
(实测存在,churn · 判据的,PM · 哈希:空 · 它不是,它), which is what makes the
judgment mechanical rather than stylistic.
The enumeration-marker family (semicolon + space + a circled mark such as
U+2462 / U+2463) is left untouched — measured, it falls OUTSIDE the predicate
by construction (the successor is not Han), so all 6 such sites survive
unchanged. Byte delta is exactly -14; line counts are unchanged, so no CEILINGS
row moves and no table row widens.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RMTpSRF5CjMmQBFfPtPCwJ
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent e18c870 commit 078bdcd
4 files changed
Lines changed: 306 additions & 238 deletions
File tree
- .claude
- agents
- skills/pm-dispatch
- references
- scripts/pm
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
207 | 207 | | |
208 | 208 | | |
209 | 209 | | |
210 | | - | |
| 210 | + | |
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| |||
229 | 229 | | |
230 | 230 | | |
231 | 231 | | |
232 | | - | |
| 232 | + | |
233 | 233 | | |
234 | 234 | | |
235 | 235 | | |
| |||
250 | 250 | | |
251 | 251 | | |
252 | 252 | | |
253 | | - | |
| 253 | + | |
254 | 254 | | |
255 | 255 | | |
256 | 256 | | |
| |||
260 | 260 | | |
261 | 261 | | |
262 | 262 | | |
263 | | - | |
| 263 | + | |
264 | 264 | | |
265 | 265 | | |
266 | 266 | | |
| |||
334 | 334 | | |
335 | 335 | | |
336 | 336 | | |
337 | | - | |
| 337 | + | |
338 | 338 | | |
339 | 339 | | |
340 | 340 | | |
| |||
373 | 373 | | |
374 | 374 | | |
375 | 375 | | |
376 | | - | |
| 376 | + | |
377 | 377 | | |
378 | 378 | | |
379 | 379 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
127 | | - | |
| 127 | + | |
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
| |||
Lines changed: 7 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
55 | | - | |
| 55 | + | |
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
| |||
195 | 195 | | |
196 | 196 | | |
197 | 197 | | |
198 | | - | |
| 198 | + | |
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
| |||
271 | 271 | | |
272 | 272 | | |
273 | 273 | | |
274 | | - | |
| 274 | + | |
275 | 275 | | |
276 | | - | |
| 276 | + | |
277 | 277 | | |
278 | 278 | | |
279 | 279 | | |
| |||
303 | 303 | | |
304 | 304 | | |
305 | 305 | | |
306 | | - | |
| 306 | + | |
307 | 307 | | |
308 | 308 | | |
309 | 309 | | |
310 | 310 | | |
311 | 311 | | |
312 | 312 | | |
313 | | - | |
| 313 | + | |
314 | 314 | | |
0 commit comments