diff --git a/scripts/pm/check-widening-tells.mjs b/scripts/pm/check-widening-tells.mjs index 6d2ba5a70f..076cf6b5f6 100644 --- a/scripts/pm/check-widening-tells.mjs +++ b/scripts/pm/check-widening-tells.mjs @@ -47,7 +47,11 @@ * accept set gains a spelling an author may now write. * T2 a new member of a closed set: `z.enum([…])`, `z.union([…])`, * `z.discriminatedUnion(…)`, or a `CORE_PLUGIN_TYPES`-shaped `as const` - * array — the accept set gains a VALUE. + * array — the accept set gains a VALUE. ⚠️ That is what the tell is a + * tell OF, ⛔ never what every row SAYS: a member line carries no set, so + * since #19384 the row asserts this form only when the hunk shows one of + * the four above the line, and says what it did not measure when it does + * not. Its section is below. * T3 a new row in a published entry point's export listing * (`packages/spec/api-surface/*.json` and its signatures sibling) — the * PUBLIC SURFACE grows, which ADR-0059's backward-compatibility gate @@ -99,12 +103,16 @@ * * Both refinements read bytes the hunk already contains: the added line's * NEIGHBOURS on the new-file side, and the lines the same hunk REMOVED. ⛔ - * Neither recovers block state. This file still cannot tell an array element - * from a call argument, still does not know whether a property sits inside - * `z.object({`, and ⛔ still has no notion of DIRECTION — a tell, never a - * proof, exactly as before. (#17618 later added the ONE bracket fact a hunk - * does carry — which delimiter is innermost, over that hunk's own lines — and - * nothing more: still no shape, still no direction. Its section is below.) + * Neither recovers block state. This file still does not know whether a + * property sits inside `z.object({`, and ⛔ still has no notion of DIRECTION — + * a tell, never a proof, exactly as before. (#17618 later added the ONE bracket + * fact a hunk does carry — which delimiter is innermost, over that hunk's own + * lines — and nothing more: still no shape, still no direction. Its section is + * below. ⭐ #19384 then read that same fact on the other side of the question, + * so the sentence "this file cannot tell an array element from a call argument" + * that stood here is now bounded rather than absolute: it CAN, exactly when the + * hunk shows the bracket, and where it cannot the row says so in its own words. + * Its section is below too.) * * **A fragment of a multi-line string concatenation is not a set member.** * #16822's filing left the instrument that proves the variable was accidental: @@ -1124,10 +1132,360 @@ * • a closer whose type does not match the opener it popped — **0 rows**. * • a `*\/` this walk cannot explain — **0 rows**. * - * ⇒ Nothing is silenced by any of them today: no reader suppresses on the flag. - * The number a future suppressing reader needs is the 0.7%, and it should be - * re-measured on that day rather than quoted from here — on the gate's own read - * path, with its blob resolution asserted first. + * ⇒ Nothing is silenced by any of them. That sentence used to read "no reader + * suppresses on the flag"; #19384 wrote the first one that does, and it refuses + * to decline while the flag is up, so the direction is unchanged — a guessed + * stack buys a false tell (loud) and never a swallowed one. The number a future + * suppressing reader needs is the 0.7%, and it should be re-measured on that + * day rather than quoted from here — on the gate's own read path, with its blob + * resolution asserted first. + * + * ## The thirteenth accidental variable #19384 removed — a member with NO SET + * above it + * + * T2's sentence is "a new member of a CLOSED SET", and the row rendered it over + * any lone quoted string on a contract-source line. `BARE_STRING_ELEMENT` is a + * quoted string, an optional comma and an optional trailing comment — nothing + * in it asks whether one of the four forms the doctrine names stands above the + * line. So the row asserted a fact the instrument never measured, which is NOT + * the "a tell, never a proof" allowance this file grants everywhere else: that + * allowance covers a tell that is right about its own SHAPE and silent about + * direction. Here the shape itself was unverified while the row stated it as + * read. ⭐ T1's own docblock had DECLARED the equivalent limit since #16822 and + * bounded it at #17618; T2 declared none. + * + * The filing measured it as three legs, one instrument, both controls lit — and + * they are the battery below, case for case: + * + * A four members added to a `new Set([`, the opener standing in the hunk as + * context ⇒ 4× T2, exit 4. `new Set(` is none of the four forms and no + * authored document is ever parsed against such a set. + * B the FALSIFIER: the identical four members, same construct, same file, + * re-spelled on ONE line ⇒ 0 tells, exit 0. + * C the lit control: a genuine new `z.enum([` member ⇒ T2, exit 4. + * + * ⇒ A and B are the same change with the same semantics and opposite verdicts, + * so the rows were keyed on LINE LAYOUT. ⛔ And B is EVIDENCE, never the + * remedy: re-spelling source to dodge a gate corrupts every later reading the + * instrument takes. The live carrier was PR #19314 — seven `_zod.def.type` + * discriminants added to a `new Set([…])` in `stack.zod.ts`, read only by a + * wrapper-peeling walk — seven T2 rows against a `Clause-②: no` an at-tier + * review had already ruled correct. + * + * What the hunk DOES carry is the bracket fact #17618 established and #18721 + * and #19099 made reliable: which delimiter is innermost, over the line's own + * hunk. Every one of the four forms puts its members inside a `[`, so + * {@link closedSetMembership} asks that `[`'s head which construct opened it + * and answers in three states — `declared` (one of the closed-set + * constructors, BY NAME and under any receiver, with a TRANSPARENT wrapper such + * as `Object.freeze(` read through to the head left of it), `refused` (a call + * whose name is one of a CLOSED vocabulary positively known to close no set) + * and `unread` (everything else, an unknown callee included). ⛔ Only `refused` + * takes a row away, and only on positive, hunk-local evidence, which is the + * shape of every decline in this file — so a name the reader does not know + * leaves the tell where it was, the direction {@link PARAMETER_LIST_HEAD} takes + * for the same reason. + * + * ⭐ `unread` is the answer that keeps this repair honest, and it is the COMMON + * one. An opener above the hunk, a `CORE_PLUGIN_TYPES`-shaped `as const` array + * — whose `as const` sits BELOW its members where no upward reader reaches it — + * a property-valued array, a `(` or `{` frame, a walk that stopped being a + * reading: all of them keep their row. ⛔ What changes is the SENTENCE, to one + * that names the half that was not measured. A row that says less is not a row + * that fires less, and the loud direction is untouched. + * + * The price, measured over the 283 commits touching these surfaces in this + * tree's available history (objectstack-ai/objectstack at `c27e16059d`, 1,441 + * commits deep, the graft-boundary commit `d83d079b` excluded for the reason + * #19099's section gives), 1,051 file diffs: of the 944 tell rows the previous + * reading raises, 12 now decline and 932 stand. All 12 are T2 and all 12 are + * bare elements the hunk shows inside ANOTHER call's argument list — nine in an + * `Object.freeze([…])` of near-miss key spellings a schema REFUSES, three in + * `new Set([…])` value-class ledgers — checked row by row, 0 exceptions. No T1, + * T3 or T4 row moves. Of the 133 T2 rows in that window, 121 stand: 104 change + * their sentence (10 to the measured one, 94 to the NOT-MEASURED one) and 17 + * are OPENER rows, which carry their constructor in their own bytes and are not + * touched by this round at all. + * + * ⭐ And NO row anywhere in that window begins firing. The removed side is read + * the way #17618 reads a deleted parameter — an element the OLD side shows + * inside another call buys no replacement budget, so a genuine member added + * beside it still reports — and that leg has zero historical population here, + * exactly as #17955's un-retiring leg did: a sensitivity guarantee this tree + * has not yet had occasion to exercise, not a refusal aimed at work already + * done. + * + * ## ⛔ THE CENSUS ABOVE COULD NOT HAVE SEEN THE HOLE IT WAS QUOTED AGAINST + * + * The first cut of this reading asked the bracket head for a LITERAL `z.enum(`, + * while the refusal arm matched `.enum(` as an ordinary call. So Prettier's + * chain wrap — `z` on one line, ` .enum([` on the next — read `refused`, and a + * member added under it raised NO row: not a member row, and not an opener row + * either, because the opener test wants `z.` and the wrap does not carry it. + * The set went fully dark. Measured on a synthetic member under that spelling: + * exit 4 on the previous instrument, exit 0 on the first cut. The same hole + * swallowed `z.enum([`, `zod.enum([` and `Full.extract([`. + * + * ⚠️ AND THE CENSUS READ 0 BEGIN-FIRING OVER A POPULATION THE DEFECT DOES NOT + * LIVE IN. Every chain-wrapped constructor site in this tree — 13 line-initial + * `.enum([` against a control of 741 one-line `z.enum([`, and 16 against 906 + * across all four forms — carries a ONE-LINE member list: checked site by site, + * 0 of the 16 is followed by a bare element. So no commit in that window ever + * added a member under the spelling, and a tree census cannot reach it either. + * A population in which the failure cannot occur is not evidence of its + * absence, and a count taken over one says nothing it can be quoted for. The + * second round therefore measures THREE populations, and the containing one is + * synthetic by construction: + * + * ① the same commit window, both instruments — every commit reachable from + * `origin/main` at `57ceb9d6d2` touching `packages/spec` less the graft + * boundary, 349 commits, 3,850 file diffs, `git show --unified=3` split per + * file: 774 rows on EACH side, 0 declined, 0 begun, 0 row changing CLASS, + * 166 changing only their sentence's wording. The repair moves no + * historical verdict, which is the same fact as "this census cannot contain + * it" said from the other end. + * ② the tree, both instruments — identical, for the same reason. + * ③ ⭐ THE CONTAINING ONE. Every bare element the reader calls a member today + * (1,354 in `packages/spec/src/**` at `57ceb9d6d2`, each rebuilt as a + * one-member addition with a 40-line context window), with its constructor + * RE-SPELLED the way a formatter or an author may spell it. Per spelling, + * on the first cut: 1,179 of 1,354 went SILENT and not one read as measured. + * On this reading: 1,354 rows, 1,223 measured, 0 silent — the same answer as + * the un-re-spelled control, for chain-wrapped, generic (``) and + * aliased (`zod.`) alike. A sub-enum (`Full.extract([`) fires all 1,354, all + * as NOT MEASURED, which is the honest verdict for a form the doctrine does + * not name. ⛔ And the lit controls that make the census a reading rather + * than a hope: re-spelt to `z.tuple([` or `new Set([`, the same 1,179 stay + * silent on BOTH instruments — the silence is bought by the construct, never + * by the harness. + * + * ## ⛔ AND EVERY CENSUS ABOVE WAS BOUNDED BY A CLONE HORIZON NOBODY STATED + * + * ⚠️ Read the three counts above as WINDOWED, never as history. The first two + * were taken in a container cloned 1,441 commits deep (oldest commit + * 2026-09-06) and the third in one 2,169 deep — and that third reading called + * its oldest commit `3c1bbd2a87` "the root". It is not a root: it is a SHALLOW + * GRAFT BOUNDARY, `.git/shallow` names it, and 12,310 commits lay beyond it. + * Every "0 exceptions, checked row by row" any of them printed is a statement + * about its window. The count moved 12 → 14 on the second deepening alone, and + * the two commits it gained are the two ACCEPT SETS this round had to name. + * + * ⇒ So this round unshallowed first (`git fetch --unshallow`; no `.git/shallow` + * remains) and re-took both censuses over the whole history: 14,479 commits + * reachable from `origin/main` at `8e368dc3b9`, root `1598cabe4a`, 2026-01-18. + * ⛔ A census that cannot contain the failure is not evidence of its absence, + * and a depth nobody states is a census nobody can re-take. + * + * ① THE LANDED POPULATION — 2,640 non-merge commits touching the four + * surfaces this file declares in this repo, 10,364 file diffs, + * `git show --unified=3` split per file by this file's own + * `splitUnifiedDiff`, all three instruments over the SAME rows + * (`readSource` stubbed to `null` on all three alike, so #18702's factory + * resolution is out of every reading rather than out of one). + * ⭐ THE JUDGING UNIT, which every figure below is only re-takeable + * against: EACH COMMIT'S FILE LIST IS JUDGED TOGETHER, in one + * `wideningTells(files)` call. That is the instrument's own unit — it + * mints {@link ledgerRowLicences} over the list it is handed, so a #17300 + * licence added in one file reaches its siblings exactly as it does on the + * real PR the gate judges. Per commit, then: base 29,580 rows + * (T1 16,498 · T2 5,993 · T3 6,141 · T4 948); the failed head 29,480; this + * reading 29,552. ⭐ Base → here: 29,552 stand, **28 decline, 0 begin**, + * 5,164 change only their sentence. + * ⛔ THE SAME HARNESS JUDGING EACH FILE ALONE reads 452 rows higher on T2 + * and identical on T1, T3 and T4 — base 30,032 (T2 6,445), the failed head + * 29,932, this reading 30,004, base → here 28 decline / 0 begin / 5,616 + * sentence-only, failed head → here 0 / 72 — and that second figure is the + * one three records on this PR quoted. Neither harness erred and the + * difference is not a disagreement of method: the 452 are 452 T2 rows, + * every one in `packages/spec/src/migrations/registry.ts`, falling in 105 + * of the 275 non-merge commits that touch it, each row's #17300 licence + * minted by a SIBLING file of the same commit — so the row declines when + * the commit is read whole and stands when that file is read alone. + * Re-measured here as a set difference of the two key dumps over those 275 + * commits: 452 per-file-only, **0 per-commit-only**, and 0 of the 452 + * outside that file or outside T2. ⇒ A census that does not state its unit + * lands the next reader 452 rows away in one direction or the other, which + * is the same defect as a census that does not state its population. + * All 28 declines are T2 and all 28 were re-read + * THROUGH THIS READER rather than by eye: callee `Set` on 28 of 28, 0 + * exceptions, across eleven bindings — the three `field-value.zod.ts` value + * classes, `VALUE_DOMAIN_FIELD_TYPES`, `TEXT_OPERATOR_DOOR_PASSING_TYPES`, + * `IMPORT_REFERENCE_TYPES`, `PUBLIC_FORM_SERVER_MANAGED_FIELDS`, + * `CONTAINER_ISSUE_CODES`, `VIEW_WRITE_PATH_IDENTITY_KEYS`, + * `TITLE_INELIGIBLE_TYPES` and `VALID_AST_OPERATORS`. ⭐ Failed head → + * here: 0 decline and **72 BEGIN**, every one of them `Object.freeze(`, + * over five bindings (`PLATFORM_CAPABILITY_TOKENS` 28, + * `REGISTRY_DECLARED_META_TYPES` 27, `SCHEDULE_ORGANIZATION_NEAR_MISSES` 9, + * `FLOW_TRIGGER_KINDS` 4, `PLATFORM_ALWAYS_ON_CAPABILITIES` 4). ⛔ The + * earlier record's "the 9 declines it protects" was one binding seen + * through a window; the freeze silence cost 72 rows, not 9. T1, T3 and T4 + * are identical on all three instruments across all 10,364 diffs. + * ② THE CONTAINING POPULATION, synthetic by construction because the landed + * one cannot hold the failure — the tree has no bare element under a + * `makeEnum([` at all. Every bare-element line in `packages/spec/src` + * (6,553 over 1,014 files) rebuilt as a one-member addition with three + * lines of REAL context; the 716 whose opener stands in that context are + * the ones whose callee decides the verdict, and each was re-spelled. Per + * spelling, failed head → this reading, counted as SILENT: `makeEnum([` + * 710 → 0, `stringEnum([` 710 → 0, `Object.freeze([` 710 → 0, `z.tuple([` + * 710 → 0, and `new Set([` 710 → 710, which is the residual stated below + * and the only one. The lit control that makes it a reading rather than a + * hope: re-spelt to `z.enum([` the same sites read MEASURED on both, 710 of + * 716, and the 6 that never move are hunks the walk reports it could not + * read. ⛔ As written, this tree has 19 sites where the base instrument + * fires and this reading does not — `Set` 11, `default` 8 — and they are + * named one by one below. + * + * ## ⛔ THE REFUSAL WAS OPEN-VOCABULARY, AND AN OPEN VOCABULARY IS NOT EVIDENCE + * + * The reading above answered `refused` for EVERY callee that was not one of the + * four — which is a decline drawn from the absence of a name rather than from + * the presence of one, the exact inversion of "positive, hunk-local evidence". + * Measured on the shape a real PR carries (three lines of context), base + * instrument → that reading: `makeEnum([` 4 → 0, `stringEnum([` 4 → 0, a fifth + * `FLOW_TRIGGER_KINDS` kind under `Object.freeze([` 4 → 0, a whole freeze array + * added in one diff 2 rows → 0, a member under `z.enum(Object.freeze([` 4 → 0, + * a frozen array fed to `z.enum(KINDS)` on the next line 4 → 0. Any helper + * nobody had enumerated silenced a genuine set, and `Object.freeze` silenced + * the FOURTH FORM ITSELF. + * + * ⛔ The mitigation this header used to claim for the freeze case — "the enum's + * own opener line, which fires as an opener row" — is FALSE BY TEST: a + * member-adding diff carries no opener line at all, and a frozen array handed + * to `z.enum(KINDS)` on the next line raises 0 rows. It was a documented + * defect, not an honest stated silence, and it is repaired rather than + * disclosed: {@link TRANSPARENT_ARRAY_CALLEE_NAMES} reads `freeze` THROUGH to + * the head left of it, and {@link NON_SET_CALLEE_NAMES} is now the whole, + * CLOSED list of names that buy a silence. + * + * ⚠️ THE ONE RESIDUAL, NAMED COMPLETELY RATHER THAN CHARACTERISED. `new Set([` + * still declines, because PR #19314's seven `_zod.def.type` discriminants are + * one and an at-tier review ruled all seven false positives — and the same + * spelling carries REAL ACCEPT SETS in this tree, which is a known wrong answer + * rather than a risk. Measured on this tree, every site where the previous + * reading fires and this one does not: NINETEEN, `new Set(` 11 and `.default(` + * 8, and here they all are — + * + * `new Set([`: `CALENDAR_DATE_TYPES`, `INSTANT_TYPES`, `CLOCK_TIME_TYPES` + * (`data/field-value.zod.ts`), `VALUE_DOMAIN_FIELD_TYPES` + * (`data/field.zod.ts`, read by `.has(field.type)` in a `superRefine` that + * REFUSES what an author wrote, and again on the write path in + * `record-validator.ts`), `TEXT_OPERATOR_DOOR_PASSING_TYPES` + * (`data/filter-text-operator-declared-type.ts`), `IMPORT_REFERENCE_TYPES` + * (`data/import-coercion.ts`, read by `rest`'s import coercion), + * `PUBLIC_FORM_SERVER_MANAGED_FIELDS` (`security/public-form.ts`, read by + * four seams of `rest-server.ts` to refuse a visitor's value), + * `CONTAINER_ISSUE_CODES` (`shared/union-branch-policy.ts`) and + * `VIEW_WRITE_PATH_IDENTITY_KEYS` (`ui/view.zod.ts`). + * + * ⚠️ AND ONE SHAPE THE SITE LIST ABOVE CANNOT REACH — RESTORED, because the + * round-3 head named it and this reading dropped the sentence while the shape + * stayed dark. A `new Set([` literal spelled INSIDE one of the four + * constructors puts the member's innermost `[` on the SET, so the head this + * reader asks answers `Set` and the member is `refused`: `z.enum([...new Set([`, + * `z.enum(Array.from(new Set([`, `z.enum([...KNOWN, ...new Set([` and + * `z.union([...new Set([` all go fully dark, with no opener row to compensate + * because the opener test reads the LINE and that line's own constructor is + * `new Set(`. Measured on the shape a real PR carries, base instrument → this + * reading: a member added under each of the four spellings 1 row → 0, and + * through the CLI `--declaration no --diff` the first is base exit 4 / here + * exit 0. ⭐ ZERO tree sites (`packages/spec/src`, non-test, at `57ceb9d6d2`) + * and ZERO landed rows carry it, so it costs nothing today and neither census + * below can contain it — which is exactly why it is DISCLOSED here rather than + * counted there. ⛔ A residual that claims to be named COMPLETELY owes the + * shapes with no population as well as the sites with one; completeness is the + * claim under test, and this shape is pinned in `--self-test` beside leg A. + * + * ⛔ Which of them the silence actually costs, measured by reading the + * consumers rather than the names: `VALUE_DOMAIN_FIELD_TYPES` refuses an + * authored `valueDomain` at parse time and again at write time, and + * `PUBLIC_FORM_SERVER_MANAGED_FIELDS` decides what an anonymous visitor may + * send — those TWO are accept sets in the doctrine's sense, and they are the + * whole of what this silence costs on this tree. + * + * ⚠️ Two corrections to the record this round was dispatched against, both + * re-measured rather than recalled. FIRST: `TEXT_OPERATOR_DOOR_PASSING_TYPES` + * has NO non-test consumer — `textOperatorDoorVerdict` reads the REFUSED set, + * not this one — so it is a published derived constant whose own parity test + * reds on a change, not a live accept set. SECOND, and it is the one every + * earlier record got wrong in the same direction: `VALID_AST_OPERATORS` is NOT + * A SITE OF THIS SILENCE AT ALL. On this tree it is + * `export const VALID_AST_OPERATORS = new Set(Object.keys(AST_OPERATOR_MAP));` + * (`data/filter.zod.ts:2139`) — one line, DERIVED, with no member line under + * it, so this reader never classifies anything for it and the site list above + * rightly omits it. It IS an accept set (`isFilterAST` reads it to judge a + * filter) and it IS dark, but not to this decline: a widening of it today is a + * new key on the `AST_OPERATOR_MAP` object literal it derives from + * (`data/filter.zod.ts:2036`), and measured on the shape a real PR carries + * that diff raises 0 rows on the base instrument, on the failed head and HERE + * alike, against `VALUE_DOMAIN_FIELD_TYPES`'s real member line as the firing + * control (base 1 row / here 0). ⇒ a PRE-EXISTING SHAPE GAP in the T2 member + * reading, and ranging it under this silence charges this round for a hole it + * neither opened nor widened while hiding the hole that is really there. Its + * one landed `new Set([` row is `ee6d064db9` (2026-02-24), the day the binding + * was last spelled with members, and the census below counts that row and no + * other. + * + * ⛔ AND THE MECHANISM IS THE SHAPE, NOT THE FRAME — the sentence three + * records carried ("a `{` frame this file leaves loud and unclassified") is + * FALSE and is deleted rather than softened. Measured against the shape + * itself: `memberTellKind(" 'newop': '$eq',", { onContractSource: true })` + * answers `null`, because a string-valued KEYED entry matches neither + * `BARE_STRING_ELEMENT` nor `SCHEMA_PROPERTY` — so the line never reaches T2's + * member reading, never reaches {@link closedSetMembership}, and never reaches + * a frame at all. The same reader on the same hunk, as the controls that tell + * the two causes apart: ` 'between',` and ` "quoted",` both answer T2, a + * BARE element added inside that identical `{` frame raises 1 T2 row (the + * NOT-MEASURED sentence), and a zod-valued key added inside one raises T1. + * ⛔ "Loud and unclassified" cannot be a cause of silence in the first place: + * *loud* means the row FIRES, which is exactly what every `(` and `{` frame + * does here — {@link closedSetMembership} says so in its own words, "keeps its + * row". A future repairer sent after the frame reader would rebuild the one + * limb that is already firing — the 442 `(` and 1,791 `{` bare-element lines + * {@link closedSetMembership}'s own tree census counts — and leave this limb + * dark. The shape is pinned by its own case beside the constructor-wrapped set + * literal, so the 0 rows cannot move unnoticed. + * `.default([`: `allowedLicenses` and `prohibitedLicenses` + * (`kernel/plugin-security.zod.ts`) and `redact` (`system/logging.zod.ts`) + * — a default VALUE list, which is the one member of this vocabulary whose + * silence is sound. + * + * ⛔ And the rationale this file used to give for the `Set` half — "a set of + * internal discriminants is not an accept set, no author's document is ever + * parsed against it" — is FALSE of the sets above. The honest statement is + * that `new Set([` and a `z.enum([` are byte-indistinguishable INSIDE A HUNK + * once the head is the same (`ReadonlySet = new Set([` carries both an + * accept set and #19314's private walk vocabulary), so what separates them is + * CONSUMPTION — a FILE-level fact this hunk-shaped reader cannot reach and must + * not pretend to. + * + * ⛔ AND THE SILENCE IS PERMANENT, not pending a successor — a ruling, not a + * shrug. Ruling #202 B (charter #19457, stock cleanup #19458) makes the dev + * queue product-only: a tooling card closes at FIRST grading, and reopening one + * needs a named product PR it blocks or a customer-visible contract it + * protects. A file-scoped consumption reading is a tooling card by that text, + * so ⛔ no card is owed for it and ⛔ none may be promised here. A sentence + * that defers to a successor nobody will open is the same false disclosure as a + * census quoted from a different reader — it reads as "not yet" where the + * truth is "not ever, on present policy". ⇒ THE DISPOSITION: this file STATES + * the silence, names every site it covers and every shape it hides, and pins + * both directions, and that is the whole of it. The day a real PR is held by + * one of these declines, that PR is the reopen reading the ruling names, and + * the card is filed then — by the author it holds, against evidence, never in + * advance. + * + * ⛔ What is NOT in that list any more, because the vocabulary is read by NAME: + * the receiver, and ONE NON-NESTED type-argument group. `z.enum(`, `zod.enum(`, + * a chain-wrapped ` .enum(` and `z.enum(` are one form spelled four + * ways, and the formatter decides which one tomorrow's file carries. ⛔ A + * NESTED type argument is deliberately NOT read and the sentence says so: + * `z.enum>([`, `new Set>([` and + * `Object.freeze>([` all answer `unread` and KEEP their row, + * because both heads spell the group as one pair of angle brackets with no + * angle bracket inside and a regex does not balance them. That is the loud + * direction, so the bound is STATED rather than widened; widening it means a + * balanced-bracket reader, which is a different instrument and not a + * docblock's promise. * * ## The shape this gate keeps firing on, and what to do about it — ruling D′ * @@ -1413,8 +1771,17 @@ const ROOT = fileURLToPath(new URL('../..', import.meta.url)); // // The counts are a FLOOR, not an equality — adding cases is ordinary work and // must not red. A battery BELOW its floor means cases stopped running. +// +// ⛔ AND EVERY FLOOR SITS AT ITS BATTERY'S OWN REGISTERED COUNT, never below it. +// A floor with slack is not a pin: the at-tier record on #19384 deleted a +// registered case outright and the suite stayed GREEN at 572, because 45 was +// pinned against 48 registered. Slack is indistinguishable from a battery that +// has quietly stopped running that many cases, so the only honest reading of +// "this case is pinned" is a floor that the deletion of ONE case breaches. +// Measured when this was written: three other batteries carried the same slack +// (4, 9 and 2 cases) and are seated at their counts here too. const SELF_TEST_BATTERIES = Object.freeze({ - 'the patch reader: added lines, and the line numbers they carry': 17, + 'the patch reader: added lines, and the line numbers they carry': 21, 'the unified-diff splitter, for the local `git diff` path': 15, 'the local path composed: an unread diff is not a narrow diff': 7, 'the surfaces, imported rather than restated': 11, @@ -1437,16 +1804,17 @@ const SELF_TEST_BATTERIES = Object.freeze({ 'the declared registry rows still exist in this tree': 4, '#17112 — the count is split: examined is not examinable': 23, '#17217 — the CLI can be told which board it judges': 22, - '#18560 — the declaring vocabulary is a NAMED list, every form pinned by a counterfactual fixture': 32, - '#18640 — an inline closed set RE-SPELLED at the same binding is not a set that gained a value': 20, + '#18560 — the declaring vocabulary is a NAMED list, every form pinned by a counterfactual fixture': 41, + '#18640 — an inline closed set RE-SPELLED at the same binding is not a set that gained a value': 22, '#18702 — a declaring factory PRIVATE to one file, resolved through its own DEFINITION': 54, "#18721 — a hunk's LEADING CONTEXT is not a reason to abandon the parameter reading": 14, '#19099 — the enclosing-delimiter walk says when it STOPPED READING and started guessing': 15, + '#19384 — a bare element is not a member until the hunk shows one of the four forms above it': 77, }); // DELETING an entry silences that battery's floor exactly as effectively as // zeroing it, so the roster's own size is pinned too. -const SELF_TEST_BATTERY_FLOOR = 16; +const SELF_TEST_BATTERY_FLOOR = 29; // The key an assertion is filed under when no battery is open. It is not a // declared battery, so it reds by the same set difference rather than silently @@ -2104,13 +2472,62 @@ const SCHEMA_PROPERTY = new RegExp( `${KEY_HEAD_SOURCE}(?:${SCHEMA_PROPERTY_FORMS.map((f) => f.pattern).join('|')})`, ); +/** + * The callee NAMES that CLOSE a set — T2's doctrine's four forms, held ONCE as + * names rather than twice as spellings of them. + * + * ⛔ One vocabulary, two readers whose reach is deliberately different, and the + * difference is the EVIDENCE each one stands on. {@link CLOSED_SET_OPENER} + * tests a whole LINE, which may be prose, a comment or a string literal, so it + * keeps the `z.` receiver that has always bounded it. {@link closedSetMembership} + * tests a bracket HEAD the delimiter walk reached AS CODE — strings and + * comments skipped by construction — so it asks for the name alone and admits + * ANY receiver and ONE NON-NESTED type-argument group. ⛔ Not "any type + * argument": the group is one pair of angle brackets with no angle bracket + * inside, so `z.enum>(` is not matched and its member keeps its row + * — loud, bounded and pinned, never widened by a sentence. + * + * ⭐ That asymmetry is the repair. Requiring the receiver on the HEAD side is + * what made Prettier's chain wrap — `z` on one line, ` .enum([` on the next — + * read as another call's argument list, and a member added under it went + * SILENT on both rows at once: no opener row either, because the opener test + * does want `z.` and the wrap does not carry it. Measured: exit 4 before this + * reading existed, exit 0 after, with the whole set dark. The same hole + * swallowed `z.enum([`, `zod.enum([` and `Full.extract([`. + */ +const CLOSED_SET_CONSTRUCTOR_NAMES = Object.freeze(['enum', 'union', 'discriminatedUnion', 'literal']); + /** T2 — a closed set DECLARED or re-written on one line. */ -const CLOSED_SET_OPENER = /z\.(?:enum|union|discriminatedUnion|literal)\(/; +const CLOSED_SET_OPENER = new RegExp(`z\\.(?:${CLOSED_SET_CONSTRUCTOR_NAMES.join('|')})\\(`); -/** T2 — a bare string element of a multi-line `z.enum([…])` or `as const` array. */ +/** + * T2 — a bare string element of a multi-line `z.enum([…])` or `as const` array. + * + * ⛔ It does NOT verify that one of the four closed-set forms stands above the + * line. A hunk is a fragment and block state cannot be recovered from one + * honestly, exactly as {@link SCHEMA_PROPERTY} says for T1 — and until #19384 + * T2 said it nowhere, while the row it rendered asserted "a new member of a + * closed set" as read. The shape above matches a lone quoted string on ANY + * contract-source line: an element of a `new Set([…])`, of a plain `string[]`, + * of an argument list. + * + * What DOES bound it is the same one bracket fact T1 reads (#17618), asked of + * the element instead of the key: {@link closedSetMembership} in `tellsInFile`. + * Positive evidence in three directions and no other — the hunk shows the + * enclosing delimiter opening one of the four forms (the row says so), it shows + * the delimiter opening some OTHER call's argument list (the row DECLINES), or + * it shows neither and the row fires with a weaker sentence that says what was + * not measured. + */ const BARE_STRING_ELEMENT = /^[ \t]*(?:'[^']*'|"[^"]*")[ \t]*,?[ \t]*(?:\/\/.*)?$/; -/** T2 — a bare schema arm of a multi-line `z.union([…])`. */ +/** + * T2 — a bare schema arm of a multi-line `z.union([…])`. + * + * ⛔ Bounded exactly as {@link BARE_STRING_ELEMENT} is, and by the same reader: + * `ArmSchema,` on its own line is a union arm, an array element or an argument, + * and this shape cannot tell them apart on its own. + */ const BARE_SCHEMA_ARM = /^[ \t]*[A-Za-z_$][\w$]*Schema[ \t]*,[ \t]*(?:\/\/.*)?$/; /** @@ -2136,8 +2553,17 @@ const CONTINUATION_TAIL = /(?(` are ONE form spelled four ways; the formatter decides + * which one tomorrow's file carries, so the reading may not depend on it. + * `(?:<[^<>]*>)?` — ONE explicit type-argument group, which a call may carry + * and which says nothing about which construct it is. ⛔ Its own bound is + * in its bytes: no angle bracket inside, so a NESTED group + * (`z.enum>(`) does not match and the member falls to `unread` + * and keeps its row. That is the loud direction, and it is the SAME bound + * the refusal head carries in {@link CALL_HEAD_CALLEE} — two copies of one + * group, each pinned by its own case, because deleting either one moves + * rows in opposite directions. + * `[^()[\]{}]*$` — what makes it the delimiter's OWN call and not one + * anywhere to its left. `z.discriminatedUnion('type', [` leaves only + * `'type', ` between the two and matches; `z.enum(['a']).or(fn([` leaves a + * bracket pair and does NOT, so that head falls through to the refusal + * reading and is judged on `fn`. + * + * @param {readonly string[]} names + */ +const constructorArgumentHead = (names) => new RegExp( + `(?:^|[^\\w$])(?:[A-Za-z_$][\\w$]*[ \\t]*\\.[ \\t]*)*(?:${names.join('|')})[ \\t]*(?:<[^<>]*>)?[ \\t]*\\([^()\\[\\]{}]*$`, +); + +/** T2 — the head of a `[` one of the FOUR closed-set forms opened. */ +const CLOSED_SET_ARGUMENT_HEAD = constructorArgumentHead(CLOSED_SET_CONSTRUCTOR_NAMES); + +/** + * The CALLEE NAME of the call a `[`-frame head ends in, or `null` when the head + * is not a call at all — the reading the REFUSAL stands on. + * + * A frame's `head` is the text LEFT OF the delimiter, so an array passed to a + * call carries that call's own open paren at the END of its head: `new Set(`, + * `Object.freeze(`, `z.array(z.string()).default(`. + * + * ⛔ Deliberately NOT "any head ending in `(`": a grouping paren (`const X = (`), + * an array bound to a name (`export const CORE_PLUGIN_TYPES = `) and a + * property's array value (`kinds: `) answer `null` — NOT a call — which leaves + * the tell FIRING. That is the loud direction, and two of those three are where + * the fourth closed-set form lives, one of them wrapped in a paren that reads + * as a call to anything cruder than this. + * + * ⭐ `(?:<[^<>]*>)?` is the SECOND copy of the type-argument group + * {@link constructorArgumentHead} carries, and it is load-bearing in the + * OPPOSITE direction: on the declared head a missing group loses a `declared` + * (loud), here it loses a `refused` (also loud, and a genuine `new Set([` + * silence returns). ⛔ Both copies are pinned by their own cases — the group + * stood here unpinned until the round that added them, and a piece whose + * deletion moves no case is a piece no case is pinning. Its bound is the same + * and is stated rather than widened: no angle bracket inside, so a NESTED group + * (`new Set>(`, `Object.freeze>(`) answers + * `null` and the member keeps its row. + */ +const CALL_HEAD_CALLEE = /(?:\bnew[ \t]+)?(?:[A-Za-z_$][\w$]*[ \t]*\.[ \t]*)*([A-Za-z_$][\w$]*)[ \t]*(?:<[^<>]*>)?[ \t]*\($/; + +/** + * The call a frame head ends in — its callee NAME and the text LEFT OF the + * whole call expression — or `null` when the head is not a call. + * + * ⭐ `before` is what makes a TRANSPARENT wrapper readable: the slice starts at + * the `new` keyword when there is one, so `const S = new Set(` answers + * `{ callee: 'Set', before: 'const S = ' }` and never a `before` still carrying + * `new `. That is the whole job of the `(?:\bnew[ \t]+)?` prefix in + * {@link CALL_HEAD_CALLEE} — the NAME is found either way, because the pattern + * is unanchored at its start, so the prefix is load-bearing here and nowhere + * else. + * + * @param {string} head — a frame's `head`, the text left of its delimiter + * @returns {{ callee: string, before: string }|null} + */ +export function callHeadOfFrame(head) { + const s = String(head ?? ''); + const m = CALL_HEAD_CALLEE.exec(s); + return m === null ? null : { callee: m[1], before: s.slice(0, m.index) }; +} + +/** + * The callee name a frame head ends in, or `null` when the head is not a call. + * + * @param {string} head — a frame's `head`, the text left of its delimiter + * @returns {string|null} + */ +export function calleeOfFrameHead(head) { + return callHeadOfFrame(head)?.callee ?? null; +} + +/** + * The callee names that say NOTHING about what the array they receive IS — + * read THROUGH, never as evidence. + * + * `Object.freeze` is the measured instance and the ruling that put this list + * here: freeze takes an array and answers that same array, so every one of the + * four forms survives it. `z.enum(Object.freeze([…]))` IS a `z.enum`, and + * `Object.freeze([… ] as const)` bound to a name IS the fourth form — the + * construct stands one slice to the LEFT of the wrapper, and a reader that + * stopped at `freeze` was refusing on the wrapper's own name while the thing it + * wraps went unread. Measured before this reading existed, each on the shape a + * real PR carries: a fifth `FLOW_TRIGGER_KINDS` kind base exit 4 / exit 0, a + * whole freeze array added in one diff base 2 rows / 0, a member under + * `z.enum(Object.freeze([` base 4 / 0, and a frozen array fed to `z.enum(KINDS)` + * on the next line base 4 / 0. + * + * ⛔ TRANSPARENT is not UNKNOWN, and the difference is the direction each one + * fails in: an unknown callee leaves the row FIRING, while a transparent one is + * stripped off the head and the head is judged again — so a wrapper can only + * ever reveal a construct, never hide one. + */ +const TRANSPARENT_ARRAY_CALLEE_NAMES = Object.freeze(['freeze']); + +/** + * The CLOSED vocabulary of callee names a `[` frame may be REFUSED on — the + * whole of it, and the only silence T2 buys from a frame head. + * + * ⛔ NOT "every name that is not one of the four". That open-vocabulary refusal + * is the defect this list replaces: it silenced a genuine set under every + * helper nobody had enumerated — `makeEnum([`, `stringEnum([`, both measured + * base exit 4 / exit 0 — while the file's own doctrine says the opposite, in + * {@link PARAMETER_LIST_HEAD}'s words: a prefix the reader does not know + * "leaves the tell where it was". A name earns a place here only by being + * positive evidence that the delimiter's list is not an accept set: + * + * `Set` — a `new Set([…])` of internal discriminants. PR #19314's seven + * `_zod.def.type` names are the measured carrier and an at-tier review + * ruled all seven false positives. ⚠️ This one keeps a KNOWN WRONG ANSWER; + * {@link closedSetMembership} states it and names its two carriers. + * `default` — a `.default([…])` argument is a default VALUE, so its elements + * are values the accept set already admits, never members of it. + * + * ⛔ TWO NAMES THAT MUST NEVER JOIN THIS LIST, and the reason is the direction + * each one fails in: zod's sub-enum builders `extract` and `exclude`. An + * `extract` list gains a value exactly as an `enum` list does; an `exclude` + * list gaining one is the same edit in the opposite DIRECTION, which this file + * has never claimed to read — and a reader with no notion of direction may not + * spend that ignorance on a silence. Their absence here IS the reading (they + * had a branch of their own until this round, and it decided nothing once the + * vocabulary closed), and it is pinned by its own cases. + * + * ⛔ A name is added here only with the evidence written beside it, and ⛔ never + * to quieten a row somebody found noisy: the loud direction is the one this + * family takes everywhere. + */ +const NON_SET_CALLEE_NAMES = Object.freeze(['Set', 'default']); + +/** + * Is this side-line a MEMBER OF ONE OF THE FOUR CLOSED-SET FORMS? (instance 3) + * + * The third reading built on the one bracket fact a hunk carries (#17618), and + * the first of the three that has to answer in more than two states — because + * T2's row asserts a FORM and the evidence for a form comes in three strengths: + * + * `'declared'` — the hunk shows the innermost open delimiter where the + * element sits, and the CALLEE NAME its head ends in is one of the four + * ({@link CLOSED_SET_CONSTRUCTOR_NAMES}). The doctrine's row is then true + * as written. ⭐ Any receiver, and ONE NON-NESTED type-argument group: + * `z.enum(`, `zod.enum(`, a chain-wrapped ` .enum(` and `z.enum(` + * are one form spelled four ways, and the formatter picks which one + * tomorrow's file carries. ⛔ A NESTED type argument is not read and the + * claim is bounded to say so: `z.enum>([` answers `'unread'` + * and keeps its row — the loud direction, pinned by its own case. + * `'refused'` — the hunk shows that delimiter and the callee name its head + * ends in is one of a CLOSED vocabulary of names positively known to close + * no set and derive none ({@link NON_SET_CALLEE_NAMES}). ⛔ Never "any name + * that is not one of the four": that open-vocabulary refusal silenced a + * genuine set under every helper nobody had enumerated. ⇒ NO ROW. + * + * ⚠️ AND ITS ONE RESIDUAL IS A KNOWN WRONG ANSWER, named here rather than + * reasoned away. `new Set([…])` is refused because PR #19314's seven + * `_zod.def.type` discriminants are one and an at-tier review ruled all + * seven false positives — and this tree spells two real ACCEPT sets exactly + * the same way: `VALUE_DOMAIN_FIELD_TYPES` in `data/field.zod.ts`, whose + * `.has(field.type)` inside a `superRefine` REFUSES what an author wrote + * (its own docblock calls a member addition "a widening of this set"), and + * `PUBLIC_FORM_SERVER_MANAGED_FIELDS` in `security/public-form.ts`, which + * four seams of `rest-server.ts` read to refuse a visitor's value. TWO, and + * the header lists every site the decline reaches. Measured on the shape a + * real PR carries: adding `'email',` to the first is base exit 4 / this + * reading exit 0. ⛔ `VALID_AST_OPERATORS` is NOT a third — it is + * `new Set(Object.keys(AST_OPERATOR_MAP))` on one line + * (`data/filter.zod.ts:2139`) with no member line under it, so nothing here + * ever classifies it; it is an accept set and it IS dark, on the base + * instrument exactly as here — but to a SHAPE, never to a frame. Widening + * it means a new string-valued KEYED entry on the object literal it + * derives from, and `memberTellKind` answers `null` for that shape: + * ` 'newop': '$eq',` matches neither `BARE_STRING_ELEMENT` nor + * `SCHEMA_PROPERTY`, so the line never reaches T2's member reading, this + * function, or any frame. ⛔ The earlier sentence — "a `{` frame this file + * leaves loud and unclassified" — is deleted as FALSE: *loud* means the + * row fires, which is what every `(` and `{` frame does here (see below, + * "keeps its row"), so a frame can never be the cause of 0 rows. The + * controls that separate the two, on that same hunk: a BARE element added + * inside the identical `{` frame raises 1 T2 row with the NOT-MEASURED + * sentence, and a zod-valued key inside one raises T1. The header says + * which hole this is and measures it, and a case pins the 0 rows. + * + * ⚠️ AND THE OTHER HALF OF THE SAME RESIDUAL, which no site list can + * reach: a `new Set([` literal spelled INSIDE one of the four + * constructors — `z.enum([...new Set([`, `z.enum(Array.from(new Set([`, + * `z.union([...new Set([` — puts the member's innermost `[` on the SET, so + * the head answers `Set` and a GENUINE four-form set goes fully dark, with + * no opener row to compensate. Zero tree sites and zero landed rows carry + * it, so only a case can hold it and one does. ⛔ The rationale + * this bullet used to carry — "a set of internal discriminants is not an + * accept set, no author's document is ever parsed against it" — is FALSE of + * both. The two constructs are byte-indistinguishable INSIDE A HUNK: same + * `ReadonlySet = new Set([` head, same element shape, same tail. + * What separates them is CONSUMPTION — one is read by a `superRefine`, the + * other by a wrapper-peeling walk — a FILE-level fact no hunk-shaped reader + * reaches. ⛔ And the silence is PERMANENT rather than pending: ruling + * #202 B (#19457) makes a tooling card close at first grading, so no + * successor card is owed and none is promised here — reopening needs one + * of that ruling's TWO readings, a product PR the defect blocks or a + * customer-visible contract it protects, and the header states the + * disposition in full. Both directions are pinned below, so this silence + * cannot move unnoticed and cannot spread: every other callee is loud. + * `'unread'` — everything else, and it is the common answer: no delimiter + * shown where the line sits, a walk that stopped being a reading, or a + * delimiter this reader cannot classify — an array literal BOUND to a name, + * which is exactly where the fourth form (`CORE_PLUGIN_TYPES`-shaped + * `as const`) lives, since the `as const` sits BELOW the members and no + * line-shaped reader looking upward ever reaches it. ⇒ the row still fires, + * with the weaker sentence that says which half was not measured. + * + * ⭐ ONLY a `[` frame is classified, and the bound is declared rather than + * discovered. All four forms put their members inside a `[` — `z.enum([…])`, + * `z.union([…])`, `z.discriminatedUnion(d, […])`, `[…] as const` — so a `(` or + * `{` frame is never one of them. ⛔ The guard is NOT redundant with the head + * reading and the difference is a measured row: a `{` frame opened inside a + * call carries that call's paren at the end of its head (`defineRegistry({`), + * so without the guard a shorthand `FooSchema,` property would be REFUSED — + * swallowed, in the quiet direction. A `(` frame's head stops one character + * short of its own callee's paren and answers `null` instead, which is the same + * `'unread'` by a different route. ⇒ every `(` and `{` frame answers `'unread'` + * and keeps its row. + * + * ⚠️ The population that leaves loud, RE-MEASURED THROUGH THIS READER — the + * number below was quoted from an earlier one for two rounds, under a + * paragraph that says "this reader", which is the same class of false + * disclosure as a silence that is not named. + * + * The window, stated so the reading can be re-taken: repository + * `objectstack-ai/objectstack`, COMPLETE clone (no `.git/shallow`), subtree + * `packages/spec/src` at `57ceb9d6d2` (= `origin/main` at this branch's merge + * base; `git diff 57ceb9d6d2 HEAD -- packages/spec/src` is empty, so the + * reading is taken in the head worktree over those same bytes), 1,014 non-test + * files scanned and 441 of them carrying one, every line `memberTellKind` calls + * T2 on the contract source surface fed back through `closedSetMembership` with + * its own 60 PRECEDING LINES as the hunk — 6,553 lines. THIS reader answers: 1,354 `declared`, 27 `refused` + * (`new Set(` 20, `.default(` 7, `Object.freeze(` ZERO) and 5,172 `unread`. + * Inside that `unread`: 1,791 in a `{`, 1,484 with no frame shown at all, 865 + * where the walk reported it stopped reading, 590 in a `[` this reader cannot + * classify, and 442 in a `(` — `.describe(` prose and `retiredKey(` + * prescriptions, no closed-set member among the heads. + * + * ⭐ THE LIT CONTROL that makes it a reading and not a re-type: the round-3 + * blob of this file, run over the SAME bytes with the SAME window, answers + * 1,354 / 92 / 5,107 with `Object.freeze` 65 — reproducing the quoted number + * exactly. So the 65 that moved are the freeze sites the PREVIOUS round made + * TRANSPARENT — this round changes no verdict at all — they moved `refused` → + * `unread` (the `[` bucket, 525 → 590) and nowhere else, and the shift is the + * reader's rather than the harness's. ⛔ The + * `(` and `{` counts did not move at all, which is the other half of the same + * evidence. + * + * ⛔ Reaching the `(` and `{` populations needs the callee NAME rather than the + * bracket — a different reading, and under ruling #202 B (#19457, #19458) not + * a card anybody opens in advance. ⭐ That ruling names TWO reopen readings and + * this paragraph used to name one: a product PR the defect blocks, OR a + * customer-visible contract it protects. The FIRST is the one a card here is + * filed under, on the day a real PR is held by one of these rows. ⛔ The + * SECOND is not this docblock's to answer — whether a reader guarding + * `@objectstack/spec`'s accept sets "protects a customer-visible contract" is + * the maintainer's weighing, and an instrument that decided it in its own + * comments would be ruling on the charter that governs it. Both are named so + * that neither is lost to a sentence carrying only the first. This file buys + * no silence it cannot pay for with evidence. + * + * ⛔ AND THAT CENSUS CANNOT CONTAIN THE FAILURE THIS READER WAS REPAIRED FOR, + * which is why it is quoted for what it bounds and never as a clearance. Every + * chain-wrapped constructor site in this tree — 13 line-initial `.enum([` — and + * the one `.extract([` carry ONE-LINE member lists today, so no bare-element + * line sits under any of them and no count over this tree moves when the + * chained, generic and aliased spellings change verdict. The reading that CAN + * contain it is synthetic by construction: take each multi-line closed set the + * tree really has and re-spell its opener the way a formatter would. A + * population in which the defect cannot occur is not evidence of its absence. + * + * ⭐ This reader SUPPRESSES on the frames, which {@link enclosingDelimiters} + * imposes two obligations for, and both are discharged here. FIRST: it refuses + * when the `unreadable` flag is set — a guessed stack must never buy a silence. + * SECOND: its triggers are stated where the reader describes itself, all of + * them — a `/` with another `/` left on its line (the only shape a single-line + * regex literal can have, which this scan does not lex; ⛔ a LONE `/` is + * arithmetic and raises nothing), a closer whose type does not match the opener + * it popped, a string literal that never closes on its line, and a `*\/` the + * walk cannot explain — a second one, or one after the flag is already up (⛔ + * the FIRST `*\/` on a clean walk is not a trigger: it says the hunk began + * inside a comment, and the walk restarts after it). + * + * ⛔ It is NOT a shape reader and must never be grown into one. It asks which + * bracket is innermost and what stands immediately left of it, and nothing + * about what the construct IS — so, like its two siblings, it has no truncating + * failure: a state it cannot read is reported as one, never as "not a member". + * + * @param {{ text: string, hunk: number }[]} side — one SIDE of `patchLines` + * @param {number} index — the line's index into that side + * @returns {'declared'|'refused'|'unread'} + */ +export function closedSetMembership(side, index) { + const { frames, unreadable } = enclosingDelimiters(side, index); + if (unreadable || frames.length === 0) return 'unread'; + const open = frames[frames.length - 1]; + if (open.opener !== '[') return 'unread'; + return arrayHeadMembership(open.head); +} + +/** + * The same three states, read off a `[` frame's HEAD alone — and the loop is + * the transparent wrapper. + * + * Each pass asks the head two questions in this order, and the order is the + * evidence: is this one of the four forms, and is it a call whose NAME this + * file has positively classified. A call whose name is TRANSPARENT + * ({@link TRANSPARENT_ARRAY_CALLEE_NAMES}) is stripped off the head and the + * shortened head is asked again, so `z.enum(Object.freeze([` reads `declared` + * and `const KINDS = Object.freeze([` reads `unread` — the wrapper reveals the + * construct instead of standing in for it. + * + * ⭐ A sub-enum BUILDER (`Full.extract([`, `Full.exclude([`) needs no arm of its + * own any more and no longer has one: it is simply a name the closed refusal + * vocabulary does not carry, so it falls to `unread` and the row fires with the + * NOT-MEASURED sentence. ⛔ That arm was DELETED rather than kept as defence in + * depth, because a branch whose deletion changes no verdict is a branch no case + * can pin — and this round is the one that learned what an unpinnable guard is + * worth. The behaviour is pinned where it is now decided: by `extract` and + * `exclude` being absent from {@link NON_SET_CALLEE_NAMES}. + * + * ⛔ The loop terminates STRUCTURALLY, and it is written that way on purpose. A + * transparent step replaces the head with `before`, the slice ending where a + * match begins that runs to the head's LAST character and spans at least a + * callee and its paren — so every pass drops two characters or more, and an + * empty head matches nothing and answers `unread`. ⛔ A length guard here would + * be a line no head can reach and no case can pin, which is the shape this + * round exists to stop adding. + * + * @param {string} head — a `[` frame's `head`, the text left of the delimiter + * @returns {'declared'|'refused'|'unread'} + */ +function arrayHeadMembership(head) { + let text = String(head ?? ''); + for (;;) { + if (CLOSED_SET_ARGUMENT_HEAD.test(text)) return 'declared'; + const call = callHeadOfFrame(text); + // ⛔ A head that is not a call at all buys no silence — an array literal + // bound to a name, a property's array value, a grouping paren. The fourth + // form lives in two of those three. + if (call === null) return 'unread'; + if (!TRANSPARENT_ARRAY_CALLEE_NAMES.includes(call.callee)) { + // ⛔ The CLOSED vocabulary, and the only silence this reader buys: a name + // it does not know leaves the tell where it was. + return NON_SET_CALLEE_NAMES.includes(call.callee) ? 'refused' : 'unread'; + } + text = call.before; + } +} + /** A property NAME at the head of a line, in the four spellings `SCHEMA_PROPERTY` admits. */ const KEYED_PROPERTY_NAME = /^[ \t]*(?:'([^']+)'|"([^"]+)"|(\[[^\]]+\])|([A-Za-z_$][\w$]*))[ \t]*\??[ \t]*:/; -/** The closed-set constructor a property's value opens with, if it opens with one. */ -const CLOSED_SET_CONSTRUCTOR = /z\.(enum|union|discriminatedUnion|literal)\(/; +/** + * The closed-set constructor a property's value opens with, if it opens with + * one. ⛔ Built from {@link CLOSED_SET_CONSTRUCTOR_NAMES} like + * {@link CLOSED_SET_OPENER}: one vocabulary, so no two of these three readings + * can drift apart the day a fifth form is admitted. + */ +const CLOSED_SET_CONSTRUCTOR = new RegExp(`z\\.(${CLOSED_SET_CONSTRUCTOR_NAMES.join('|')})\\(`); /** * The KEY a T1-shaped line names, or `null` when the line names none. @@ -2638,7 +3446,7 @@ export function respellsExistingClosedSetKey(text, removedTexts) { * ③ the member list closes ON THIS LINE. A list that opens here and closes * later is unreadable, exactly as it is for a keyed value. */ -const CLOSED_SET_BINDING_HEAD = /^(.*?)z\.(?:enum|union|discriminatedUnion|literal)\(/; +const CLOSED_SET_BINDING_HEAD = new RegExp(`^(.*?)z\\.(?:${CLOSED_SET_CONSTRUCTOR_NAMES.join('|')})\\(`); export function closedSetBindingMembers(text) { const s = String(text ?? ''); @@ -3794,6 +4602,11 @@ export function tellsInFile( // failure for a silent one on the only diff shape that re-opens an accept // set the tree had already closed. if (kind === 'T1' && declaresUnwritableKey(r.text)) continue; + // #19384 — read on the OLD side too, the way #16822's fragment rule and + // #17618's parameter are: an element the hunk shows inside some other + // call's argument list was never a member of a closed set, so it must not + // buy an added member of a real one the right to go unreported. + if (kind === 'T2' && closedSetMembership(oldFile, oldAt.get(i)) === 'refused') continue; if (kind !== null) budget.set(kind, (budget.get(kind) ?? 0) + 1); } for (const i of block) { @@ -3935,10 +4748,56 @@ export function tellsInFile( CLOSED_SET_OPENER.test(text) && !rewritesExistingOpener(text, removedByHunk.get(hunk)) && !respellsExistingClosedSetBinding(text, removedHere); - if (onContractSource && (opener || kind === 'T2')) { + // An OPENER carries its constructor in its own bytes, so the row it + // renders asserts only what the line shows. It is read FIRST and unchanged + // by #19384, which is a repair to the MEMBER reading alone. + if (onContractSource && opener) { rows.push({ tell: 'T2', ...at, why: 'a new member of a closed set (z.enum / union / an `as const` array) — the accept set gains a value' }); continue; } + // #19384 — a MEMBER line carries no set. Until this reading T2 fired on any + // lone quoted string (or `…Schema,` arm) on the contract source surface, + // with no requirement that one of the four closed-set forms stood above it, + // and rendered "a new member of a closed set" over an element of a + // `new Set([…])`, a plain `string[]` or an argument list — a fact the + // instrument never measured. The three verdicts, and what each one costs: + // + // `refused` — the hunk SHOWS the element inside another call's argument + // list. Positive evidence, hunk-local, absent by default, exactly like + // every other decline in this file. NO ROW. + // `declared` — the hunk shows one of the closed-set constructors opening + // the delimiter the element sits in. The doctrine's sentence, true as + // written. + // `unread` — no evidence either way. The row STILL FIRES; only its + // sentence changes, to one that names the half that was not measured. + // ⛔ That is the loud direction and it is not negotiable: a member of a + // `z.enum([` whose opener sits above the hunk lands here, and so does a + // `CORE_PLUGIN_TYPES`-shaped `as const` array, whose `as const` is + // BELOW its members where no upward reader reaches it. + // + // ⛔ AND THIS READING SITS BELOW THE #16943 BUDGET DELIBERATELY — the + // ordering decides a row, so it is stated here and pinned by its own case. + // A refused element is still a T2-kind line, so it SPENDS the unit its + // block's removal earned, exactly as any other added member does. Hoist the + // refusal above the spend and that unit survives for the next added line, + // so a GENUINE member beside it goes silent — one report bought at the price + // of another, the same inversion #18629's spend note refuses on the other + // side of the question. Measured: a block whose removal buys one T2, whose + // first added member is refused and whose second is `declared`, reports 1 + // row here and 0 with the refusal hoisted. + if (onContractSource && kind === 'T2') { + const membership = closedSetMembership(newFile, newAt.get(i)); + if (membership === 'refused') continue; + rows.push({ + tell: 'T2', + ...at, + why: + membership === 'declared' + ? 'a new member of a closed set — this hunk shows the element inside an `enum` / `union` / `discriminatedUnion` / `literal` argument list, so the accept set gains a value' + : 'a new bare element on the contract source surface — ⚠️ this hunk does not show it inside one of the four closed-set forms, so whether the accept set gains a value is NOT MEASURED here (an `as const` array declares itself BELOW its members)', + }); + continue; + } if (kind === 'T3') { rows.push({ tell: 'T3', ...at, why: 'a new row in a published entry point\'s export listing — the public surface grows (ADR-0059)' }); continue; @@ -4371,6 +5230,46 @@ const FILE_ENUM_MEMBER = { status: 'modified', patch: patchOf(95, "+ 'workflow', // Business: long-running orchestration"), }; +// The live carrier of #19384, in the bytes PR #19314 actually pushed: seven +// zod `_zod.def.type` discriminants added to a `new Set([…])` in +// `stack.zod.ts`, read only by `pipeAuthorableSide` while peeling a pipe's IN +// side. ⭐ The opener is an ADDED line of the same hunk, which is what makes +// the evidence hunk-local — and the set is a list of internal wrapper labels, +// never an accept set any authored document is parsed against. +const FILE_INTERNAL_SET_MEMBERS = { + filename: 'packages/spec/src/stack.zod.ts', + status: 'modified', + patch: patchOf( + 3411, + '+const COLLECTION_WALK_WRAPPERS: ReadonlySet = new Set([', + "+ 'optional',", + "+ 'nullable',", + "+ 'default',", + "+ 'prefault',", + "+ 'readonly',", + "+ 'nonoptional',", + "+ 'catch',", + '+]);', + ), +}; +// ⛔ The control that is the whole finding: the SAME seven names, the same +// file, the same hunk shape — under a closed-set opener instead. +const FILE_CLOSED_SET_MEMBERS = { + filename: 'packages/spec/src/stack.zod.ts', + status: 'modified', + patch: patchOf( + 3411, + '+export const CollectionWalkWrapperSchema = z.enum([', + "+ 'optional',", + "+ 'nullable',", + "+ 'default',", + "+ 'prefault',", + "+ 'readonly',", + "+ 'nonoptional',", + "+ 'catch',", + '+]);', + ), +}; const FILE_API_SURFACE = { filename: 'packages/spec/api-surface/kernel.json', status: 'modified', @@ -5199,6 +6098,357 @@ export function selfTest() { t('⭐ THE RESET REACHES `inParameterList` — an arrow in an `@example` block would otherwise read as a real parameter list and SWALLOW the key line behind it; discarded frames make it fire', inParameterList(JSDOC_ARROW, 2) === false); t('⛔ CONTROL — the identical head on a line the walk really reads as code still declines, so the case above measures the comment and not the head', inParameterList([CTX('const check = ('), CTX(' extra: z.string(),')], 1) === true); + // -- #19384: a bare element is not a member until the hunk shows the set ---- + // + // The card's three legs first, each its own diff, because they are the + // INSTRUMENT: A and B are the same change with the same semantics, and a + // matcher that answered them differently was keyed on line layout. + battery('#19384 — a bare element is not a member until the hunk shows one of the four forms above it'); + const LEG_A = { + filename: 'packages/spec/src/probe.ts', + status: 'modified', + patch: [ + '@@ -1,3 +1,7 @@', + ' const PIPE_WRAPPERS: ReadonlySet = new Set([', + " 'optional',", + "+ 'nullable',", + "+ 'default',", + "+ 'prefault',", + "+ 'catch',", + ' ]);', + ].join('\n'), + }; + const LEG_B = { + filename: 'packages/spec/src/probe.ts', + status: 'modified', + patch: [ + '@@ -1,3 +1,4 @@', + ' const PIPE_WRAPPERS: ReadonlySet = new Set([', + " 'optional',", + "+ 'nullable', 'default', 'prefault', 'catch',", + ' ]);', + ].join('\n'), + }; + const LEG_C = { + filename: 'packages/spec/src/probe.ts', + status: 'modified', + patch: [ + '@@ -1,3 +1,4 @@', + ' export const ModeSchema = z.enum([', + " 'read',", + "+ 'write',", + ' ]);', + ].join('\n'), + }; + t('⭐ LEG A — four members added to a `new Set([`: the opener is CONTEXT the hunk shows, and `new Set(` is none of the four forms, so NO row fires', tells(LEG_A).length === 0); + t('⭐ LEG B — the falsifier: the IDENTICAL four members re-spelled on ONE line reads the same, so the verdict is no longer keyed on line LAYOUT', tells(LEG_B).length === tells(LEG_A).length && tells(LEG_B).length === 0); + t('⛔ LEG C — the lit control: a genuine new `z.enum([` member still fires, and still as T2', tells(LEG_C).length === 1 && tells(LEG_C)[0]?.tell === 'T2'); + t('…and ONLY leg C says the set was shown — the row asserts what was measured and the legs disagree about that, which is the whole repair', says(tells(LEG_C)[0]?.why, 'this hunk shows the element inside')); + // -- the live carrier, and the control that is the finding ------------------ + t('⭐ THE LIVE CARRIER — PR #19314\'s seven `_zod.def.type` discriminants added to a `new Set([…])` in `stack.zod.ts` raise NO row', tells(FILE_INTERNAL_SET_MEMBERS).length === 0); + t('⛔ CONTROL — the SAME seven names in the SAME file under a `z.enum([` opener raise seven, so the silence above is bought by the construct and never by the names', tells(FILE_CLOSED_SET_MEMBERS).filter((r) => r.tell === 'T2' && BARE_STRING_ELEMENT.test(` ${r.text}`)).length === 7); + // -- the loud direction: what must NOT go quiet ---------------------------- + // + // ⚠️ These five are the card's own prohibition — "the repair has to be + // written so it does not go silently quiet on real closed sets". Every one of + // them keeps its row; only the SENTENCE weakens, and it weakens to one that + // names the half that was not measured. + t('⛔ an element whose opener sits ABOVE its hunk STILL fires — absence of evidence is not evidence, exactly as #16822 reads a missing neighbour', tells(FILE_ENUM_MEMBER)[0]?.tell === 'T2'); + t('…and its row says so rather than asserting a set it never saw', says(tells(FILE_ENUM_MEMBER)[0]?.why, 'NOT MEASURED')); + t('⛔ a `CORE_PLUGIN_TYPES`-shaped `as const` array STILL fires — its `as const` sits BELOW the members, where no upward reader reaches it', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const CORE_PLUGIN_TYPES = [', "+ 'workflow',") }).some((r) => r.line === 4 && r.tell === 'T2')); + t('⛔ …and so does an array literal on a PROPERTY, which this reader also cannot classify', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+ kinds: [', "+ 'workflow',") }).some((r) => r.line === 4 && r.tell === 'T2')); + t('⛔ an arm inside a `z.union([` the hunk shows fires AND reads as measured', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+const U = z.union([', '+ WorkflowSchema,') }).some((r) => r.line === 4 && says(r.why, 'this hunk shows the element inside'))); + t('⛔ …and so does one inside a `z.discriminatedUnion(\'type\', [`, whose discriminator argument stands between the constructor and the bracket', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, "+const D = z.discriminatedUnion('type', [", '+ WorkflowSchema,') }).some((r) => r.line === 4 && says(r.why, 'this hunk shows the element inside'))); + t('⛔ the OPENER row is untouched by this round — it carries its constructor in its own bytes, so it never needed the frames', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+const U = z.union([') })[0]?.tell === 'T2'); + // -- the vocabulary is the FOUR constructors, not "any z. call" ------------- + t('⭐ `z.tuple([` is not one of the four forms AND not in the refusal vocabulary, so it KEEPS ITS ROW — the reader asks which constructor it is rather than whether the head says `z.`, and a name it has not classified buys no silence', closedSetMembership([CTX('const T = z.tuple(['), CTX(" 'a',")], 1) === 'unread'); + t('⛔ …while `z.literal([` is one of the four and reads as declared', closedSetMembership([CTX('const L = z.literal(['), CTX(" 'a',")], 1) === 'declared'); + // -- the flag: a reader that SUPPRESSES must refuse a guessed stack --------- + const REGEX_ABOVE = [CTX('const S = new Set(['), CTX(' ...SEEDS.filter((s) => /^x/.test(s)),'), CTX(" 'workflow',")]; + t('⭐ a hunk the walk could not READ refuses the decline — `unreadable` costs a false tell (loud) and never a swallowed one', enclosingDelimiters(REGEX_ABOVE, 2).unreadable === true && closedSetMembership(REGEX_ABOVE, 2) === 'unread'); + t('⛔ CONTROL — the identical hunk with the regex spelled away reads cleanly and DOES decline, so the case above measures the flag and not the `new Set(`', closedSetMembership([CTX('const S = new Set(['), CTX(' ...SEEDS.filter(isLive),'), CTX(" 'workflow',")], 2) === 'refused'); + // -- the removed side, read the way #17618's parameter is ------------------- + // + // ⚠️ THE REMOVED AND ADDED LINES SIT IN ONE CHANGE BLOCK, and that is the + // whole case rather than a detail of it. `changeBlocks` splits on a CONTEXT + // line, so a fixture that puts context between the two hands them to + // different budgets and the old-side reading is never consulted at all: the + // first cut of this battery did exactly that and stayed green with the leg + // DELETED. A pin that survives the deletion of what it pins is not a test. + const CROSS_PAID = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -10,5 +10,6 @@', + ' const INTERNAL = new Set([', + "- 'peeled',", + '+]);', + '+export const ModeSchema = z.enum([', + "+ 'write',", + ' ]);', + ].join('\n'), + }; + // The same block with the REMOVAL inside a real closed set. It buys its unit, + // the added member spends it, and only the opener row is left — so the case + // above measures the construct the removed element sat in and not the + // arithmetic, and the two differ by exactly that one line of fixture. + const CROSS_PAID_CONTROL = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -10,5 +10,6 @@', + ' const LEGACY = z.enum([', + "- 'peeled',", + '+]);', + '+export const ModeSchema = z.enum([', + "+ 'write',", + ' ]);', + ].join('\n'), + }; + t('⭐ a REMOVED element the old side shows inside another call buys NO budget, so a genuine member added in the SAME BLOCK still fires — the opener row plus the member row', tells(CROSS_PAID).length === 2 && tells(CROSS_PAID).every((r) => r.tell === 'T2')); + t('…and the second row IS the member, reading as measured — ⛔ not the opener row twice, which is what "2 rows" would also mean', says(tells(CROSS_PAID)[1]?.why, 'this hunk shows the element inside') && tells(CROSS_PAID)[1]?.line === 13); + t('⛔ CONTROL — the identical block with the removal inside a REAL closed set buys its unit, the member spends it, and only the OPENER row is left', tells(CROSS_PAID_CONTROL).length === 1 && says(tells(CROSS_PAID_CONTROL)[0]?.why, 'z.enum / union')); + t('⛔ CONTROL — a removed element of a REAL closed set still buys its unit, so the case above measures the construct and not the arithmetic', tells({ filename: 'packages/spec/src/a.zod.ts', patch: "@@ -10,3 +10,3 @@\n export const ModeSchema = z.enum([\n- 'read',\n+ 'write',\n ]);" }).length === 0); + // -- the reading itself, in the three states it answers in ----------------- + t('`closedSetMembership` answers `declared` on a constructor the hunk shows', closedSetMembership([CTX('export const M = z.enum(['), CTX(" 'read',")], 1) === 'declared'); + t('…`refused` on another call\'s argument list', closedSetMembership([CTX('const S = new Set(['), CTX(" 'read',")], 1) === 'refused'); + t('…and `unread` when the hunk shows no open delimiter at all', closedSetMembership([CTX(" 'read',")], 0) === 'unread'); + t('⛔ an array literal BOUND TO A NAME is `unread`, never `refused` — the fourth form lives there and must not be silenced', closedSetMembership([CTX('export const CORE_PLUGIN_TYPES = ['), CTX(" 'read',")], 1) === 'unread'); + t('⛔ …and so is EVERY `(` frame — all four forms put their members inside a `[`, and a `(` frame\'s head stops one character short of the callee\'s paren, so this reader declines to classify one', closedSetMembership([CTX(' note: z.string().describe('), CTX(" 'prose',")], 1) === 'unread' && closedSetMembership([CTX('const wrapped = ('), CTX(" 'read',")], 1) === 'unread'); + t('⛔ CONTROL — the same call with an ARRAY argument DOES carry its paren in the head and is refused, so the case above measures the frame and not the callee', closedSetMembership([CTX('const F = new Set(['), CTX(" 'read',")], 1) === 'refused'); + t('⛔ …and a `{` frame, which this reader classifies not at all', closedSetMembership([CTX('const shape = {'), CTX(" 'read',")], 1) === 'unread'); + t('⭐ the vocabulary is INTACT — `memberTellKind` still classifies a refused element as a member of kind T2, so both sides of the budget keep reading one question', memberTellKind(" 'workflow',", { onContractSource: true }) === 'T2'); + // -- ONE FORM, FOUR SPELLINGS: the hole the first cut of this reading left -- + // + // ⚠️ The first cut asked the head for a literal `z.enum(`, and the refusal + // arm matched `.enum(` as an ordinary call — so Prettier's chain wrap read + // `refused` and a member added under it went SILENT, with no opener row to + // compensate because the opener test wants `z.` too. Measured then: exit 4 + // before that reading existed, exit 0 after. ⛔ The census that missed it read + // 0 begin-firing over a population the defect does not live in — every + // chained site in the tree carries a ONE-LINE member list — so these cases + // are SYNTHETIC on purpose: the formatter decides tomorrow's spelling, and a + // population that cannot contain the failure is not evidence of its absence. + const CHAIN_WRAPPED = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -3,3 +3,4 @@', + ' export const ModeSchema = z', + ' .enum([', + "+ 'write',", + ' ]);', + ].join('\n'), + }; + t("⭐ PRETTIER'S CHAIN WRAP — `z` on one line, ` .enum([` on the next: the member FIRES and reads as measured, because the receiver is admitted and discarded", tells(CHAIN_WRAPPED).length === 1 && says(tells(CHAIN_WRAPPED)[0]?.why, 'this hunk shows the element inside')); + t('…and the reader says so on its own', closedSetMembership([CTX('export const ModeSchema = z'), CTX(' .enum(['), CTX(" 'read',")], 2) === 'declared'); + t('…the same wrap on a `z.union([` too, which is where the arms live', closedSetMembership([CTX('export const AnySchema = z'), CTX(' .union(['), CTX(' ReadSchema,')], 2) === 'declared'); + t('⭐ EXPLICIT TYPE ARGUMENTS — `z.enum([` is the same form and reads declared', closedSetMembership([CTX('export const M = z.enum(['), CTX(" 'read',")], 1) === 'declared'); + t('⭐ AN ALIASED NAMESPACE — `zod.enum([` is the same form and reads declared', closedSetMembership([CTX('export const M = zod.enum(['), CTX(" 'read',")], 1) === 'declared'); + t('⛔ CONTROL — the name is a whole TOKEN, so `parseenum([` never reads `declared`: the receiver is discarded, the word never is — and being a name the vocabulary does not carry, it keeps its row', closedSetMembership([CTX('const X = parseenum(['), CTX(" 'read',")], 1) === 'unread'); + // -- a set DERIVED from another one: never `refused`, never `declared` ------ + t('⭐ `Full.extract([` builds a SUB-ENUM and gains a value exactly as an enum does — it FIRES, and ⛔ never reads `refused`', closedSetMembership([CTX('export const Sub = Full.extract(['), CTX(" 'read',")], 1) === 'unread'); + t('⛔ …and `Full.exclude([`, whose added member moves the set the OTHER way — a direction this file has never claimed to read, so it fires rather than declines', closedSetMembership([CTX('export const Sub = Full.exclude(['), CTX(" 'read',")], 1) === 'unread'); + t('⛔ CONTROL — the NAME is what decides under one receiver: `Full.enum([` reads declared while `Full.omit([` reads `unread`, so the two above are bought by the name and never by the dot', closedSetMembership([CTX('export const Sub = Full.enum(['), CTX(" 'read',")], 1) === 'declared' && closedSetMembership([CTX('export const Sub = Full.omit(['), CTX(" 'read',")], 1) === 'unread'); + // -- the `[`-only guard, which a `{` a CALL opened is the case for --------- + // + // ⛔ NOT redundant with the head reading: a `{` opened inside a call carries + // that call's paren at the END of its head, so without the guard a shorthand + // property arm would be REFUSED — swallowed, in the quiet direction. A `(` + // frame cannot reach that state (its head stops one character short), which + // is why the `(` cases alone left this guard unpinned. + const BRACE_IN_CALL = [CTX('export const registry = defineRegistry({'), CTX(' UserSchema,')]; + t('⭐ a `{` frame a CALL opened carries that call\'s paren in its head — the `[`-only guard is what keeps the arm inside it `unread` instead of refused', enclosingDelimiters(BRACE_IN_CALL, 1).frames.at(-1)?.opener === '{' && enclosingDelimiters(BRACE_IN_CALL, 1).frames.at(-1)?.head.endsWith('(') && closedSetMembership(BRACE_IN_CALL, 1) === 'unread'); + t('…and the ROW survives it, which is the half a reader-only case cannot pin', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const registry = defineRegistry({', '+ UserSchema,') }).some((r) => r.line === 4 && r.tell === 'T2')); + // ⛔ …and the case that actually PINS the guard once the refusal is a closed + // vocabulary: `defineRegistry` is a name the vocabulary does not carry, so + // dropping the guard leaves that arm `unread` either way and the two cases + // above go quiet about it. The `{` has to be opened by a call this file DOES + // refuse on, and then the guard is the only thing between the arm and a + // silence. + const BRACE_IN_REFUSING_CALL = [CTX('export const S = z.object({}).default({'), CTX(' UserSchema,')]; + t('⭐ a `{` frame opened by a REFUSING call is what the `[`-only guard exists for — without it the arm inside `.default({` would be swallowed, in the quiet direction', enclosingDelimiters(BRACE_IN_REFUSING_CALL, 1).frames.at(-1)?.opener === '{' && calleeOfFrameHead(enclosingDelimiters(BRACE_IN_REFUSING_CALL, 1).frames.at(-1)?.head) === 'default' && closedSetMembership(BRACE_IN_REFUSING_CALL, 1) === 'unread'); + t('…and its ROW survives too', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const S = z.object({}).default({', '+ UserSchema,') }).some((r) => r.line === 4 && r.tell === 'T2')); + // -- the refusal is a CALL, never "any head ending in `(`" ----------------- + t('⭐ a GROUPING paren is not a call — `const X = ([` … `] as const)` is the fourth form wrapped, and it keeps its row', closedSetMembership([CTX('const X = (['), CTX(" 'read',")], 1) === 'unread'); + t('…and the ROW survives it too', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+const X = ([', "+ 'read',") }).some((r) => r.line === 4 && r.tell === 'T2')); + // -- the constructor must be the delimiter's OWN -------------------------- + t("⭐ `z.enum(['a']).or(fn([` is judged on `fn`, never on the `enum` to its left — a reader that searched the whole head would answer `declared` here, and this one keeps the row", closedSetMembership([CTX("const X = z.enum(['a']).or(fn(["), CTX(" 'read',")], 1) === 'unread'); + t("⛔ …and the same shape ending in a REFUSING call answers `refused`, not `declared` — two different answers off one head prove which call was read", closedSetMembership([CTX("const X = z.enum(['a']).or(new Set(["), CTX(" 'read',")], 1) === 'refused'); + t("⛔ CONTROL — the constructor's OWN earlier arguments still count: `z.discriminatedUnion('type', [` leaves only `'type', ` between the two and reads declared", closedSetMembership([CTX("const D = z.discriminatedUnion('type', ["), CTX(' WorkflowSchema,')], 1) === 'declared'); + // -- the sentence says only what was MEASURED ----------------------------- + const PAREN_FRAME_ROW = tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+ note: z.string().describe(', "+ 'prose',") }).find((r) => r.line === 4); + t('⛔ the NOT-MEASURED sentence claims only that — on a `(` frame the hunk DOES show the enclosing construct, and a row saying otherwise asserts a second thing it never measured', says(PAREN_FRAME_ROW?.why, 'does not show it inside one of the four closed-set forms') && !says(PAREN_FRAME_ROW?.why, 'which construct encloses it')); + t("⭐ `calleeOfFrameHead` is the refusal's whole evidence, read on its own — the call answers its name", calleeOfFrameHead('const S = new Set(') === 'Set' && calleeOfFrameHead(' note: z.string().describe(') === 'describe'); + t('⛔ …and a head that is NOT a call answers `null`, which is what leaves the tell firing', calleeOfFrameHead('export const CORE_PLUGIN_TYPES = ') === null && calleeOfFrameHead('const X = (') === null && calleeOfFrameHead(' kinds: ') === null); + // -- the residual quiet direction, PINNED so it cannot move unnoticed ------ + // -- `Object.freeze` is TRANSPARENT, and that is a RULING ------------------ + // + // ⚠️ It used to read `refused`, disclosed in the header as a stated silence. + // The at-tier record ruled that disposition a documented DEFECT rather than + // an honest silence, on the evidence and not on taste: freeze is transparent + // to what its array is, so refusing on it is refusing with no evidence about + // the construct at all — and the mitigation the header claimed ("the enum's + // own opener line fires as an opener row") is false by test, because a + // member-adding diff carries no opener line. Measured on the shape a real PR + // carries, base instrument → the previous cut: a fifth `FLOW_TRIGGER_KINDS` + // kind 4 → 0, a whole freeze array added in one diff 2 rows → 0, a member + // under `z.enum(Object.freeze([` 4 → 0, a frozen array fed to `z.enum(KINDS)` + // on the next line 4 → 0. + t('⭐ `Object.freeze([… ] as const)` is read THROUGH — the fourth form wrapped KEEPS ITS ROW, because freeze says nothing about what its array is and the head left of it declares nothing', closedSetMembership([CTX('export const CORE_PLUGIN_TYPES = Object.freeze(['), CTX(" 'workflow',")], 1) === 'unread'); + t('…and the ROW survives it, which is the half a reader-only case cannot pin', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const CORE_PLUGIN_TYPES = Object.freeze([', "+ 'workflow',") }).some((r) => r.line === 4 && r.tell === 'T2')); + t('⭐ …and the strip REACHES the constructor — `z.enum(Object.freeze([` is a `z.enum`, so its member reads as MEASURED rather than merely firing', closedSetMembership([CTX('export const M = z.enum(Object.freeze(['), CTX(" 'read',")], 1) === 'declared'); + t('…however many wrappers stand between, because the head is asked again after every strip', closedSetMembership([CTX('export const M = z.enum(Object.freeze(Object.freeze(['), CTX(" 'read',")], 1) === 'declared'); + t('⛔ CONTROL — the strip is bought by the NAME `freeze` and never by "a call inside a call": `z.enum(buildList([` is judged on `buildList` and keeps its row', closedSetMembership([CTX('export const M = z.enum(buildList(['), CTX(" 'read',")], 1) === 'unread'); + // -- the refusal is a CLOSED vocabulary, which is the other half ----------- + t('⭐ AN UNKNOWN CALLEE KEEPS ITS ROW — `makeEnum([` closes a set to whoever wrote it, and an open-vocabulary refusal silenced every helper nobody had enumerated', closedSetMembership([CTX('export const MADE = makeEnum(['), CTX(" 'read',")], 1) === 'unread'); + t('…and it is not one spelling — `stringEnum([` reads the same, because the vocabulary is a LIST and not the complement of the four forms', closedSetMembership([CTX('export const MADE = stringEnum(['), CTX(" 'read',")], 1) === 'unread'); + t('…and the ROW survives, so an unknown helper is loud rather than merely unclassified', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const MADE = makeEnum([', "+ 'read',") }).some((r) => r.line === 4 && r.tell === 'T2')); + t('⭐ the vocabulary READ AS A LIST — the two names that buy silence, and the three that must never', NON_SET_CALLEE_NAMES.length === 2 && NON_SET_CALLEE_NAMES.includes('Set') && NON_SET_CALLEE_NAMES.includes('default') && !NON_SET_CALLEE_NAMES.includes('freeze') && !NON_SET_CALLEE_NAMES.includes('extract') && !NON_SET_CALLEE_NAMES.includes('exclude')); + t('⛔ …and `default` is read on a real keyed head — a `.default([…])` list is a default VALUE, never the accept set', closedSetMembership([CTX(' kinds: z.array(z.string()).default(['), CTX(" 'read',")], 1) === 'refused'); + // -- the residual, NAMED rather than reasoned away ------------------------- + // + // ⚠️ `new Set([` keeps its silence and the silence is WRONG on two live + // accept sets. Both are named here so the day one of them moves, a case + // moves with it — and so that nobody re-derives the false rationale this + // reading used to carry ("no author's document is ever parsed against it"). + t('⚠️ THE RESIDUAL — `VALUE_DOMAIN_FIELD_TYPES` is a real ACCEPT set spelled `new Set([`, refused by a `superRefine` that reads it, and this reader silences it', closedSetMembership([CTX('export const VALUE_DOMAIN_FIELD_TYPES: ReadonlySet = new Set(['), CTX(" 'text',")], 1) === 'refused'); + t('…so is `PUBLIC_FORM_SERVER_MANAGED_FIELDS`, which decides what an anonymous visitor may send — and PR #19314\'s internal discriminant set is BYTE-INDISTINGUISHABLE from both inside a hunk — same head, same element shape — which is why only CONSUMPTION separates them and no hunk-shaped reader can', closedSetMembership([CTX('export const PUBLIC_FORM_SERVER_MANAGED_FIELDS: ReadonlySet = new Set(['), CTX(" 'owner_id',")], 1) === 'refused' && closedSetMembership([CTX('const COLLECTION_WALK_WRAPPERS: ReadonlySet = new Set(['), CTX(" 'pipe',")], 1) === 'refused'); + // -- the readings the vocabulary is derived from, pinned as ONE ------------ + // -- the OTHER half of the residual: a `new Set([` INSIDE a constructor ---- + // + // ⚠️ RESTORED. The round-3 head named this shape in its header and the next + // head dropped the sentence while the shape stayed dark. It has ZERO tree + // sites and ZERO landed rows, so neither census can contain it and only a + // case can hold it — which is the whole reason a residual that claims to be + // named COMPLETELY owes the shapes with no population too. + const ENUM_OVER_SET = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -3,3 +3,4 @@', + ' export const ModeSchema = z.enum([...new Set([', + " 'read',", + "+ 'write',", + ' ])]);', + ].join('\n'), + }; + const ENUM_OVER_SET_CONTROL = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -3,3 +3,4 @@', + ' export const ModeSchema = z.enum([', + " 'read',", + "+ 'write',", + ' ]);', + ].join('\n'), + }; + t("⚠️ THE RESIDUAL'S OTHER HALF — a `new Set([` literal spelled INSIDE one of the four constructors puts the member's innermost `[` on the SET, so the head answers `Set` and a GENUINE four-form set is refused: the spread, the `Array.from` and the union spelling alike", closedSetMembership([CTX('export const M = z.enum([...new Set(['), CTX(" 'read',")], 1) === 'refused' && closedSetMembership([CTX('export const M = z.enum(Array.from(new Set(['), CTX(" 'read',")], 1) === 'refused' && closedSetMembership([CTX('export const A = z.union([...new Set(['), CTX(' ReadSchema,')], 1) === 'refused'); + t('…and the ROW is gone with it — no member row and no opener row either, because the opener test reads the LINE and that line\'s own constructor is `new Set(`', tells(ENUM_OVER_SET).length === 0); + t('⛔ CONTROL — the identical member with the inner set spelled away FIRES and reads as measured, so the silence above is bought by the `new Set(` and never by the spread or by the fixture', tells(ENUM_OVER_SET_CONTROL).length === 1 && says(tells(ENUM_OVER_SET_CONTROL)[0]?.why, 'this hunk shows the element inside')); + // -- the accept set that is dark to a SHAPE, not to a frame ---------------- + // + // ⚠️ `VALID_AST_OPERATORS` is widened by a new KEY on the object literal it + // derives from, and that diff raises NOTHING — on the base instrument, on + // every head of this branch and here. Three records on this PR named the + // cause as "a `{` frame this file leaves loud and unclassified"; that is + // false, and the control below is what tells the two apart: a frame this + // reader cannot classify is LOUD, so it fires inside the identical `{`. + // The cause is that NO TELL MATCHES the shape — a string-valued keyed entry + // is neither a `BARE_STRING_ELEMENT` nor a `SCHEMA_PROPERTY` — so the line + // never reaches T2's member reading, `closedSetMembership`, or any frame. + // ⛔ An unpinned 0 is indistinguishable from a 0 that moved: the disclosure + // in the header is a measurement, so it gets a case like every other one. + const MAP_KEY_ENTRY = { + filename: 'packages/spec/src/data/filter.zod.ts', + status: 'modified', + patch: [ + '@@ -2036,4 +2036,5 @@', + ' const AST_OPERATOR_MAP = {', + " '=': '$eq',", + "+ 'newop': '$eq',", + " 'equals': '$eq',", + ' };', + ].join('\n'), + }; + const MAP_BARE_ELEMENT = { + filename: 'packages/spec/src/data/filter.zod.ts', + status: 'modified', + patch: [ + '@@ -2036,4 +2036,5 @@', + ' const AST_OPERATOR_MAP = {', + " '=': '$eq',", + "+ 'newop',", + " 'equals': '$eq',", + ' };', + ].join('\n'), + }; + t("⚠️ THE OTHER DARK WIDENING IS A SHAPE GAP — a string-valued KEYED entry on an object literal answers `null` from `memberTellKind`, in both key spellings, so a new `AST_OPERATOR_MAP` key (the only way `VALID_AST_OPERATORS` widens today) raises 0 rows and never reaches a frame at all", tells(MAP_KEY_ENTRY).length === 0 && memberTellKind(" 'newop': '$eq',", { onContractSource: true }) === null && memberTellKind(" newop: '$eq',", { onContractSource: true }) === null); + const MAP_ZOD_VALUED_KEY = { + filename: 'packages/spec/src/data/filter.zod.ts', + status: 'modified', + patch: [ + '@@ -2036,4 +2036,5 @@', + ' const Shape = z.object({', + ' a: z.string(),', + '+ newop: z.string(),', + ' });', + ].join('\n'), + }; + t('⛔ CONTROL — the identical `{` frame is LOUD, which is why it can never be the cause of that silence: a BARE element added inside it raises its T2 row with the NOT-MEASURED sentence, a zod-valued key added inside one raises T1, and the two bare spellings both answer T2 on their own', tells(MAP_BARE_ELEMENT).length === 1 && tells(MAP_BARE_ELEMENT)[0]?.tell === 'T2' && says(tells(MAP_BARE_ELEMENT)[0]?.why, 'does not show it inside one of the four closed-set forms') && tells(MAP_ZOD_VALUED_KEY).length === 1 && tells(MAP_ZOD_VALUED_KEY)[0]?.tell === 'T1' && memberTellKind(" 'between',", { onContractSource: true }) === 'T2' && memberTellKind(' "quoted",', { onContractSource: true }) === 'T2'); + // -- the type-argument group, pinned on the head that READS it ------------- + // + // ⛔ Two heads carry the group and only the DECLARED one had a case: deleting + // it from `CALL_HEAD_CALLEE` left the whole suite green while + // `new Set([` silently became `unread`. A piece whose deletion moves + // no case is a piece no case is pinning. + t('⭐ THE TYPE-ARGUMENT GROUP ON THE REFUSAL HEAD — `new Set([` is the same call as `new Set([` and is refused, which pins the group in `CALL_HEAD_CALLEE` rather than only the copy in the declared head', closedSetMembership([CTX('const S: ReadonlySet = new Set(['), CTX(" 'read',")], 1) === 'refused' && calleeOfFrameHead('const S: ReadonlySet = new Set(') === 'Set'); + t('…and on a REFUSING METHOD head too, so the pin is not one callee\'s spelling', closedSetMembership([CTX(' kinds: z.array(z.string()).default(['), CTX(" 'read',")], 1) === 'refused'); + t('⛔ THE BOUND, stated rather than widened — ONE non-nested group is read and a NESTED one is not, on BOTH heads at once: the declared head, the refusal head and the transparent wrapper all answer `unread` and KEEP their row', closedSetMembership([CTX('export const M = z.enum>(['), CTX(" 'read',")], 1) === 'unread' && closedSetMembership([CTX('const S = new Set>(['), CTX(" 'read',")], 1) === 'unread' && closedSetMembership([CTX('export const K = Object.freeze>(['), CTX(" 'read',")], 1) === 'unread'); + t('…and the ROW survives the nested case, so the docblock sentence is repaired in the direction that costs nothing', tells({ filename: 'packages/spec/src/a.zod.ts', patch: patchOf(3, '+export const M = z.enum>([', "+ 'read',") }).some((r) => r.line === 4 && r.tell === 'T2')); + // -- a REFUSED element still SPENDS, and the ordering is the case ---------- + // + // ⛔ The new-side refusal is read AFTER the #16943 budget. Hoist it above the + // spend and a refused element stops consuming the block's unit, which then + // pays for the GENUINE member beside it — quieter than here, and unpinned + // until this case. The removal earns one T2, the refused `...new Set([` + // member consumes it, and the real member has nothing left to pay with. + const REFUSED_SPENDS = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -10,4 +10,7 @@', + ' export const M = z.enum([', + " 'read',", + "- 'legacy',", + '+ ...new Set([', + "+ 'x',", + '+ ]),', + "+ 'write',", + ' ]);', + ].join('\n'), + }; + const REFUSED_SPENDS_CONTROL = { + filename: 'packages/spec/src/a.zod.ts', + status: 'modified', + patch: [ + '@@ -10,4 +10,4 @@', + ' export const M = z.enum([', + " 'read',", + "- 'legacy',", + "+ 'write',", + ' ]);', + ].join('\n'), + }; + t("⭐ A REFUSED ELEMENT STILL SPENDS THE BLOCK'S UNIT — the removal buys one T2, the refused member inside the nested `new Set([` consumes it, and the genuine member beside it has nothing left to pay with and FIRES", tells(REFUSED_SPENDS).length === 1 && tells(REFUSED_SPENDS)[0]?.line === 15 && says(tells(REFUSED_SPENDS)[0]?.why, 'this hunk shows the element inside')); + t('⛔ CONTROL — the identical block WITHOUT the refused element spends that same unit on the genuine member and goes silent, so the case above measures the ORDERING and not the fixture', tells(REFUSED_SPENDS_CONTROL).length === 0); + // -- the readings the vocabulary is derived from, pinned as ONE ------------ + t('⭐ the `new` prefix is LOAD-BEARING on `before` and nowhere else — the NAME is found either way because the pattern is unanchored at its start, but the slice must begin AT `new` or a transparent strip leaves one behind', callHeadOfFrame('const S = new Set(')?.before === 'const S = ' && callHeadOfFrame('const S = new Set(')?.callee === 'Set'); + t('…and `before` is the text left of the WHOLE call, its receiver chain included', callHeadOfFrame('export const X = Object.freeze(')?.before === 'export const X = ' && callHeadOfFrame('export const X = Object.freeze(')?.callee === 'freeze'); + t('⭐ the four names are spelled ONCE in this file — ⛔ no reading hand-copies the alternation, which is the drift one vocabulary exists to prevent (two copies stood until this round: the opener-binding head and the opener head)', !readFileSync(fileURLToPath(import.meta.url), 'utf8').includes(CLOSED_SET_CONSTRUCTOR_NAMES.join('|'))); + t('…and every name in it is read by the opener reader, while one outside it is not', CLOSED_SET_CONSTRUCTOR_NAMES.every((n) => closedSetOpenerBinding(`export const X = z.${n}([`) === 'export const X =') && closedSetOpenerBinding('export const X = z.tuple([') === null); + // -- T3 -------------------------------------------------------------------- battery('T3 — a new row in a published entry point'); t('a new export row is a tell', tells(FILE_API_SURFACE)[0]?.tell === 'T3'); @@ -6090,6 +7340,10 @@ export function selfTest() { "#18702's FILE-LOCAL declaring factory, resolved through its own definition at the head BLOB and classified by what its body returns — every factory the filing card names pinned against its own arm, the refusal arm read off a `z.never` definition rather than a name with its chained-arm control, the counterfactual bracketed by the same fixture with the resolver blind, and both boundaries (an imported factory, an unclassifiable body) pinned as a STATED silence the reader prints, " + "#18721's hunk LEADING CONTEXT — an underflowing closer drops and the walk goes on, so #17618's parameter decline reaches a real diff: PR #18720's own hunk silent at its reported line, bracketed by the same file's true-positive control that fires, by a new key behind the same underflowing context, by a key added after the parameter list closes, and by the removed side where a phantom budget disappearing makes a genuine key fire, " + "#19099's walk saying when it STOPPED READING — the whole shown stack beside a flag raised on a possible regex literal, a type-blind pop and an unterminated string, with a lone slash read as the division it is, a hunk that BEGINS inside a JSDoc read rather than guessed at, each of the reset's three guards pinned against the frames it protects, the apostrophe residual pinned in the direction it fails, and the reset reaching `inParameterList` so an `@example` arrow cannot swallow the key line behind it, " + + "#19384's bare element that is not a member until the hunk shows one of the four forms above it — the card's three legs, where A and B now agree because the verdict is no longer keyed on line layout and C still fires, PR #19314's own seven discriminants silent beside the control that is the finding, and the loud direction pinned: an opener above the hunk, a `CORE_PLUGIN_TYPES`-shaped `as const` array, a property-valued array, a guessed stack, and the removed element that buys no budget with its removal and its addition in ONE change block beside the control that DOES pay — the four spellings of one form (chain-wrapped, generic, aliased, plain) each reading as measured under any receiver with `parseenum(` as the whole-token control, a sub-enum builder firing rather than declining while a sibling method is still refused, the `[`-only guard pinned on the `{` a call opened where alone it can be swallowed, the grouping paren that is not a call, the constructor that must be the delimiter's OWN, the NOT-MEASURED sentence claiming only what was not measured, `Object.freeze([` read THROUGH to the head left of it so the fourth form wrapped keeps its row while `z.enum(Object.freeze([` reads as measured, the refusal closed to a NAMED vocabulary so an unknown helper is loud, `new Set([` pinned as the residual silence with the TWO accept sets it covers named " + + "and with the constructor-wrapped set literal that goes dark beside them, the type-argument group pinned on the REFUSAL head with its non-nested bound stated rather than widened, " + + "and a refused element still spending its block's unit so the genuine member beside it fires, " + + 'the other dark widening pinned as the SHAPE GAP it is — a string-valued keyed entry on an object literal that no tell matches, so it never reaches a frame — bracketed by the LOUD `{` frame that fires on a bare element and on a zod-valued key inside the very same hunk, ' + "#16448's four positive controls each with its file:line, its negative controls — " + 'the same diffs with `yes`, and a removal-only diff with `no` — the local path composed end ' + 'to end so a binary change to a tell surface cannot read as clean, #17112\'s split count with ' +