You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
test(scripts): floor check-skill-line-ratchet's self-test on all 155 table rows
Recipe A per the pilot PR #15271: every row label is a declared battery with a
floor of 1, `registerCase(name)` is the first statement of the driving loop,
the roster is a LITERAL cross-checked against the table, size pinned at 155.
The only deleted line is the red-run verdict, reworded to the recipe's
`N failure(s) (cases and floor)`; the green line stays byte-identical.
The batch-8 census flagged this table's four `...(() => { ... })()` spreads as an
IIFE-produced block whose rows could not take a literal roster key. Measured, that
premise does not hold here: each IIFE is a SCOPING device that declares local
fixture consts and then returns an array of LITERAL [label, actual, expected]
rows. No label is a template string or computed, and no row comes from a
map/push/loop. Three independent readings agree on 155 -- labels extracted from
source, literal row starts, and the `cases.length` the green line prints on a run
-- so ALL 155 rows are floored with no residue, rather than the partition the row
anticipated.
Part of #13799
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Copy file name to clipboardExpand all lines: scripts/pm/check-skill-line-ratchet.mjs
+267-1Lines changed: 267 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -1488,6 +1488,209 @@ function run() {
1488
1488
if(failed)process.exit(1);
1489
1489
}
1490
1490
1491
+
// -- The self-test's own battery roster and floor (#13489) ------------------
1492
+
//
1493
+
// `--self-test` reaching its verdict used to be this self-test's ONLY success
1494
+
// condition, so "every case held" and "the cases never ran" printed the same
1495
+
// line. Closed the PR #13487 way: what is pinned is the registered NAMES, not a
1496
+
// number.
1497
+
//
1498
+
// This self-test is TABLE-DRIVEN -- one `cases` table, one loop over it, and a
1499
+
// sink (`failed++`) that writes only when a case FAILS. Routing THAT sink
1500
+
// through `registerCase()` would register a case only when it fails: a fully
1501
+
// green run would register 0 and every battery would read DID NOT RUN, the
1502
+
// floor inverted rather than installed. So the roster is the table's own rows.
1503
+
// Each row LABEL is a declared battery, verbatim, with a floor of 1, and
1504
+
// `registerCase(name)` is the first statement of the driving loop body -- so the
1505
+
// case is attributed to the row actually being run. There is no `battery()`
1506
+
// opener: for a table-driven self-test the ROW is the battery.
1507
+
//
1508
+
// ⭐ ALL 155 rows are floored, the four `...(() => { ... })()` spreads included.
1509
+
// Those spreads were flagged in the batch-8 census as an IIFE-produced block
1510
+
// whose rows could not take a literal roster key. Measured here, that premise
1511
+
// does not hold for this file: each IIFE is a SCOPING device that declares
1512
+
// local fixture consts and then `return [...]`s an array of LITERAL
1513
+
// `[label, actual, expected]` rows. No row label is a template string, none is
1514
+
// computed, and no row is produced by a `map`/`push`/loop. Three independent
1515
+
// readings agree on 155 -- the source labels extracted by indentation, the
1516
+
// literal row starts, and the `cases.length` the green line prints on a run --
1517
+
// so nothing here is the `extra`-call residue of PR #15286, and leaving any row
1518
+
// outside the roster would have been the lossy reading.
1519
+
//
1520
+
// A pinned TOTAL is not the repair, and neither is a roster DERIVED from the
1521
+
// table: `cases.length` moves with the table, so a deleted row would delete its
1522
+
// own floor. The roster below is a LITERAL the table is checked against, which
1523
+
// is what lets a deleted or renamed row name ITSELF in the refusal.
1524
+
//
1525
+
// The counts are a FLOOR, not an equality -- a row that grows into several
1526
+
// registrations must not red. 1 is the honest floor for a table row: the loop
1527
+
// reaches it exactly once per run.
1528
+
constSELF_TEST_BATTERIES=Object.freeze({
1529
+
'under the ceiling -> green': 1,
1530
+
'at the ceiling -> green': 1,
1531
+
'over the ceiling -> red': 1,
1532
+
'red message names the file': 1,
1533
+
'red message names the remedy': 1,
1534
+
'red message names the authoring rule': 1,
1535
+
'empty read -> red, not a skip': 1,
1536
+
'every covered file has a positive ceiling': 1,
1537
+
'SKILL.md is covered': 1,
1538
+
'the dev-agent definition is covered': 1,
1539
+
'all five compressed references are covered': 1,
1540
+
'all eight lane/seat job descriptions are covered': 1,
1541
+
'the other four skills are covered (#9473)': 1,
1542
+
'root AGENTS.md is covered (#9792)': 1,
1543
+
'root CLAUDE.md is covered (#9965)': 1,
1544
+
'references/compile-surfaces.md is covered (#12098)': 1,
1545
+
'every separator-less ceiling declares a root-file watch hint': 1,
1546
+
'and the declaration names no file the map does not cover': 1,
1547
+
'both root instruction files are declared': 1,
1548
+
'the declared form is NOT a CEILINGS key': 1,
1549
+
'the published skills/ catalog is deliberately uncovered': 1,
1550
+
'budget is 120 bytes': 1,
1551
+
'a short ASCII line -> green': 1,
1552
+
'a long ASCII line -> RED': 1,
1553
+
'a short CJK line -> green': 1,
1554
+
'a long CJK line -> RED': 1,
1555
+
'the RED message names the budget': 1,
1556
+
'the RED message names the line number': 1,
1557
+
'the RED message offers NO allowlist to add a line to': 1,
1558
+
'no offenders -> green verdict': 1,
1559
+
'a long line inside a fence is exempt': 1,
1560
+
'...and the SAME line outside one is RED': 1,
1561
+
'scan: a fenced long line yields no offender': 1,
1562
+
'scan: the fence closes again': 1,
1563
+
'a long table row is exempt': 1,
1564
+
'...and the same cells as prose are RED': 1,
1565
+
'a long heading is exempt': 1,
1566
+
'...and the same text as a paragraph is RED': 1,
1567
+
'front matter is exempt': 1,
1568
+
'scan: front matter closes at the second ---': 1,
1569
+
'an anchored Blocked-by: line is exempt': 1,
1570
+
'Restart-when: too': 1,
1571
+
'Restart-touch: too': 1,
1572
+
'but a MID-PROSE mention is not exempt — the escape hatch is line-anchored only': 1,
1573
+
'a long blockquote line is exempt': 1,
1574
+
'...including one indented inside a list': 1,
1575
+
'...and the same quotation unquoted is RED': 1,
1576
+
'a bare over-long URL is exempt': 1,
1577
+
'a single over-long code span is exempt': 1,
1578
+
'...but prose LEADING to that URL is RED (wrap first, URL lands alone)': 1,
1579
+
'wrapLine splits a long CJK line': 1,
1580
+
'every wrapped CJK segment is within budget': 1,
1581
+
'wrapping a CJK line changes NOTHING but whitespace': 1,
1582
+
'wrapping an ASCII line changes NOTHING but whitespace': 1,
1583
+
'a list continuation is indented under the marker': 1,
1584
+
'no continuation line opens a new markdown block': 1,
1585
+
'wrapLine is idempotent — its output is the canonical form': 1,
1586
+
'wrapLine leaves a short line untouched': 1,
1587
+
'wrapLine never breaks inside a code span': 1,
1588
+
'wrapLine never breaks inside a 「…」 ruling quote': 1,
1589
+
'...nor inside a 『…』 one': 1,
1590
+
'a quote longer than the budget makes its line unbreakable, not RED': 1,
1591
+
'a line OPENING an unterminated 「 is exempt': 1,
1592
+
'a line INSIDE an open quote is exempt': 1,
1593
+
'...and the same line outside one is RED — the exemption is the quote, not the text': 1,
1594
+
'a SHORT line inside a quote is simply green, not counted exempt': 1,
1595
+
'advanceState opens on an unmatched 「': 1,
1596
+
'advanceState closes on the matching 」': 1,
1597
+
'a quote opened and closed on ONE line does not open the state': 1,
1598
+
'advanceState does not track quotes inside a fence': 1,
1599
+
'scan: a two-line quote yields quotation exemptions, not offenders': 1,
1600
+
'wrapLine never strands a closing 。 at a line head': 1,
1601
+
'an ASCII , after a Han character is a no-break-after mark': 1,
1602
+
'...and ; and : are the same mark class': 1,
1603
+
'...but after a LATIN word it stays an ordinary break point': 1,
1604
+
'...and a mark with a space before it follows nothing': 1,
1605
+
'...and an atom not ending in one is never the mark': 1,
1606
+
'breakLegal refuses the break after a Han+ASCII mark': 1,
1607
+
'...a mark with no following space was never a break point to begin with': 1,
1608
+
'...still allows the CJK-to-CJK break one atom earlier': 1,
1609
+
'...and still allows an ordinary ASCII space break': 1,
1610
+
'wrapLine splits the trap line': 1,
1611
+
'no wrapped line ends on a Han+ASCII mark — the break is no longer OFFERED': 1,
1612
+
'...the line it took instead is still within budget': 1,
1613
+
'...and it moved only whitespace, as every wrap must': 1,
1614
+
'the SAME shape with a Latin word before the mark still breaks there': 1,
1615
+
'wrapLine is still idempotent under the new rule': 1,
1616
+
'a long table row is EXEMPT from the 120-byte line rule': 1,
1617
+
'...and the same row is METERED by its file pin': 1,
1618
+
'at exactly the pin -> green': 1,
1619
+
'one byte wider -> RED (widening a cell is the measured defect)': 1,
1620
+
'narrower than the pin -> green': 1,
1621
+
'a pin of 0 is a measurement — a file with no table row passes it': 1,
1622
+
'...and the FIRST table row in such a file is RED': 1,
1623
+
'a missing pin is RED, not a skip (#4690)': 1,
1624
+
'...and says so rather than naming a width': 1,
1625
+
'the RED message names the width': 1,
1626
+
'the RED message names the line': 1,
1627
+
'the RED message names the remedy': 1,
1628
+
'the RED message names consolidation as the way to pay it down': 1,
1629
+
'the RED message offers NO allowlist': 1,
1630
+
'the RED message says raising needs a maintainer ruling': 1,
1631
+
'scanTableRows finds the widest row': 1,
1632
+
'...and reports its line number': 1,
1633
+
'a `|` line inside a FENCE is not a table row': 1,
1634
+
'a `|` line in FRONT MATTER is not a table row': 1,
1635
+
'a file with no table row measures 0': 1,
1636
+
'every ceilinged file carries a pin': 1,
1637
+
'and the pin map names no file the ceiling map does not cover': 1,
1638
+
'every pin is a non-negative integer': 1,
1639
+
'the published skills/ catalog is uncovered here too': 1,
1640
+
'the citation is the ruling this file was given': 1,
1641
+
'cross-file move — a raise covered by its sources\' net decrease PASSES': 1,
1642
+
'...and the green verdict states the arithmetic it read': 1,
1643
+
'cross-file move — a raise whose sources did NOT shrink is RED (the whole defect: a `move` that licenses an ordinary raise would run green forever)': 1,
1644
+
'...and the RED verdict names the raise and the net decrease it fell short of': 1,
1645
+
'...and sends the author to the ordinary path rather than to a bigger declaration': 1,
1646
+
'cross-file move — a raise EXCEEDING the net decrease is RED, even by one line': 1,
1647
+
'...while a raise exactly equal to it is legal': 1,
1648
+
'cross-file move — a declaration citing no ruling is RED, however sound its arithmetic': 1,
1649
+
'...and the RED verdict spells the citation it wanted': 1,
1650
+
'cross-file move — declarations whose net movement is 0 leave the map total unchanged': 1,
1651
+
'cross-file move — a declaration whose participants net POSITIVE fails the total (+2 here)': 1,
1652
+
'...and the RED total names the lines it grew by': 1,
1653
+
'...and a net-negative move reports the corpus shrinking': 1,
1654
+
'cross-file move — one source may not pay for two destinations': 1,
1655
+
'cross-file move — a destination lowered back to or below its pre-move ceiling reads as PAID DOWN, never as red (lowering is always legitimate)': 1,
1656
+
'...and says so rather than reporting an arithmetic it can no longer measure': 1,
1657
+
'cross-file move — a SOURCE grown back past what it paid re-opens the move (the loophole: the destination keeps the lines while the payers grow back)': 1,
1658
+
'cross-file move — an unknown destination is RED, not a skip (#4690)': 1,
1659
+
'cross-file move — an unknown source is RED, not a skip (#4690)': 1,
1660
+
'cross-file move — a file may not pay its own raise': 1,
1661
+
'cross-file move — a declaration naming no source at all is RED': 1,
1662
+
'every live declaration cites the ruling': 1,
1663
+
'every live declaration names its destination\'s pre-move ceiling and at least one source': 1,
1664
+
'every live participant is a file this map covers': 1,
1665
+
'ruled raise — a destination that later took an ordinary ruled raise PASSES with `was` at its literal pre-move value': 1,
1666
+
'...and the verdict prices the MOVE, not the ruling: +10 against the sources\' net 11': 1,
1667
+
'...and names the ruled lines it took out, so the arithmetic can be read back': 1,
1668
+
'...while the SAME tree with the raise unrecorded is the double red this record ends': 1,
1669
+
'...whose first half reads the ruling as the move\'s: +44 against 11': 1,
1670
+
'...and which now sends the author to the record rather than to `was`': 1,
1671
+
'ruled raise — the map-wide total subtracts it too, and reads the corpus DOWN 1': 1,
1672
+
'...where the unrecorded twin reports the corpus growing by 33': 1,
1673
+
'ruled raise — a record quoting NO ruling is RED (the licence is the maintainer\'s or it does not exist)': 1,
1674
+
'...and the RED verdict says what it wanted': 1,
1675
+
'...while an ENGLISH ruling quoted the way this map already quotes one passes': 1,
1676
+
'ruled raise — a record with no line count is RED': 1,
1677
+
'ruled raise — a NEGATIVE line count is RED: lowering is always legitimate and is never recorded here': 1,
1678
+
'ruled raise — a record with no ruling DATE is RED': 1,
1679
+
'ruled raise — records claiming MORE lines than the ceiling stands above `was` are RED': 1,
1680
+
'...which is the loophole that closes: an inflated record would otherwise read the move as paid down and pass forever': 1,
1681
+
'ruled raise — a destination whose whole rise is ruled keeps none of it for the move, and reads as paid down': 1,
1682
+
'ruled raise — a declaration carrying no record behaves exactly as before (every case above this group is one)': 1,
1683
+
'every live ruled-raise record quotes its ruling, dates it, and names a positive line count': 1,
1684
+
});
1685
+
1686
+
// DELETING an entry silences that battery's floor exactly as effectively as
1687
+
// zeroing it, so the roster's own size is pinned too. This pin is also half of
1688
+
// the duplicate-label refusal: two rows sharing a label collapse to ONE key in
1689
+
// the literal above, so the roster falls below this number; the table
1690
+
// cross-check in the floor block is the other half, and names WHICH label
1691
+
// collided.
1692
+
constSELF_TEST_BATTERY_FLOOR=155;
1693
+
1491
1694
// Returned by `selfTest()` only after its verdict is printed. The dispatch
1492
1695
// refuses anything else: a `return` that leaves the function above that line
1493
1696
// prints nothing and still exits 0 — a self-test that never finished, reported
0 commit comments