Skip to content

refactor(scripts): the item-carrier disposition is RULED and says it is not a dialect - #10087

Merged
os-tesla merged 1 commit into
mainfrom
claude/issue-9871-item-carrier-disposition
Sep 20, 2026
Merged

os-tesla merged 1 commit into
mainfrom
claude/issue-9871-item-carrier-disposition

Conversation

@os-tesla

Copy link
Copy Markdown
Collaborator

Fixes #9871

Clause-②: no — an internal scanner's disposition string and the pins that read it. It moves no exported symbol and no key on a published payload.

What this is

The second flight on objectui#9871. The first one's code landed (PR #9940, Part of on purpose, while the family question was still open). The director seat then answered it — summon #25 class-1 item 2, letter C, 2026-09-20:

A body child list on a non-node ITEM (tab item, list item) is ⛔ not inside objectui#6771's ruled family and ⛔ not a second family: it is a producer violating the item's published schema, fixed at the producer (done: objectui#9941). The scanner's unruled:item-carrier disposition is renamed to a ruled, non-dialect disposition … and leaves any pending list; objectui#6771 step 4's landability is judged on the node face only.

This PR is that rename and its pins. ⛔ The scan, the criterion and the census are ⛔ not re-opened.

The spelling, and why it is not neutral

dispositionOf('item') is now ruled:not-a-dialect/item-schema-violation.

The name carries the answer rather than leaving a reader to guess it, and the ruling is cited where a reader MEETS the disposition, not only in the file header:

  • beside the constant (dispositionOf's docblock);
  • in the KNOWN_LIMITS entry — id unruled-item-carrier becomes item-carrier-not-in-ruled-total — which every run emits in both output modes;
  • in the note the text mode prints under the dispositions table.

Each of those three states in one line what the site actually IS: a producer violating the item's own published schema (TabItemSchema declares content and declares no body; ListItem likewise), fixed at the producer.

The behavioural half, which is not a string

  • It leaves every pending list. The header section「The open question this scan REPORTS and ⛔ does not answer」is gone; its replacement states the ruling. The KNOWN_LIMITS entry no longer says「unruled … reports the question rather than answering it」, and the printed note no longer asks it. An item hit awaits no seat.
  • The arithmetic did ⛔ NOT change. An item carrier is still never folded into objectui#6771's ruled total. What changed is the reason — not that family at all, rather than not-yet-judged.
  • Step 4 landability: already right, ⛔ not "fixed". Read before changing, as the order required: the scan does ⛔ not compute or report objectui#6771 step 4's landability. finalVerdict's docblock already disclaimed it in as many words (「It is NOT … the day objectui#6771 step 4 becomes landable」), and item carriers were already out of the ruled bucket. Only the prose moved, to state the node-face-only rule.

⚠️ The hazard this rename introduces, pinned in the same act

Both answers now begin ruled:. A reader that bucketed on that prefix would fold the item carrier straight into the ruled total — the one arithmetic the ruling says must not weaken. The discriminator is the carrier, never the prefix, and a new pin holds the two buckets apart on exactly that (new Set(byDisposition).size is 2 while both rows start ruled:).

Evidence

RED before / GREEN after, file state proved in the SAME command. The pins were written first and run against the byte-identical scanner: worktree blob b51f13aaa == HEAD:scripts/body-dialect-producer-scan.mjs b51f13aaa, and the run failed 4 of 26 — expected 'unruled:item-carrier' to be 'ruled:not-a-dialect/item-schema-viola…', the two-bucket equality, the KNOWN_LIMITS id lookup (expected undefined to be truthy) and the CLI payload's id list. After the scanner change, blob d42f6ac95 != HEAD: 2 files, 48 tests passed.

The scan itself, before and after, both buckets lit. On a planted corpus carrying BOTH carriers in one run, so the split is a discrimination and not an artifact of a one-shaped corpus:

disposition before after
ruled:6771 (node, the control) 1 1
unruled:item-carrier 1 —
ruled:not-a-dialect/item-schema-violation — 1

On the live tree, nothing moved and nothing was supposed to: 0 producers before and after, with the same-subject controls identical in both runs — 5,189 files scanned, 1,067 candidate body spellings, 312 held out by C2, 5 passing C2 with no recognised emission channel. ⭐ Those controls are the point: a zero from a corpus that could not have held the subject would be a broken instrument, and this card exists because a classifier was provably blind in two directions.

Premise re-taken before any edit, on origin/main 0c2eb5eee, each leg with its control in the same command: the criterion header carries C1 — EMISSION / C2 — RESOLUTION / C3 — CARRIER; unruled:item-carrier was present at 8 sites in 3 files while the control spelling ruled:6771 lit 4 sites in the same command (so the instrument distinguishes this spelling from any disposition); the shipped tabs defaultProps spell content, objectui#9941 is closed, and the producer-side repair the ruling rests on really is landed.

Gates, re-run as the last action before the push, at 5d81f6cda with git diff HEAD empty and nothing untracked: check:control-bytes, check:entry-guard, check:new-line-citations, check:comment-mask-corpus, check:unreferenced-sources, check:test-path-roots, check:esm-specifiers, check:changeset-claims, check:pending-changeset-literals, check:changeset-presence, check-hand-rolled-comment-mask, check:vi-mock-specifiers, check:lint-rule-coverage, check:required-check-set --self-test — all exit 0. Tests behind the shared verify lock (VERDICT command-exit 0).

Changeset: decided by the gate, ⛔ not from memory. node scripts/check-changeset-presence.mjs at 5d81f6cda: No source or published contract of a released package changed in this range, so no changeset is owed. (3 files changed, 0 of them published source.)

ESLint narrowing, declared with its three readings at 5d81f6cda: eslint --no-inline-config --format json over the 3 changed files — ② the JSON carries 3 file entries, 0 errors, 0 warnings; ① the population is read from eslint.config.js itself, whose 471 lines configure no type-aware linting (projectService / parserOptions / project: grep exits 1, with languageOptions / rules: lit as the control in the same command); ③ therefore this diff cannot move the verdict on any untouched file. The repo-wide pnpm lint run is CI's.

Acceptance notes

⛔ No third file reads the disposition string. The census pin scripts/__tests__/body-dialect-census.test.ts is one of the scanner's pins under scripts/__tests__/ and is inside the declared surface; package.json and .changeset/9871-body-dialect-producer-scan.md name the script, never the disposition, and are untouched.

⚠️ The census pin's item-carrier assertion stays vacuous on the live tree — the item-carried set has been empty since objectui#9941, so the loop body never runs. It is updated to the new spelling and kept, ⛔ not deleted, exactly as its own comment instructs: it fires the moment an item-carried producer returns. The instrument that actually failed before this change is the producer-scan pin set, which is where the new assertions live.

noted, not filed: packages/components/src/renderers/layout/tabs.tsx still reads item.content || (item as any).body — a lenient consumer fallback for the spelling the producer no longer emits. It is a reader, so the criterion correctly scores it as not a producer, and it is also what keeps C2's item leg resolvable. Retiring it is a consumer-side decision on the item face, ⛔ not this card's rename, and ⛔ not a dialect question under the ruling above. Successor: whoever holds the item face on objectui#9590.


🤖 Generated with Claude Code

https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq


Generated by Claude Code

…is not a dialect

The `body`-dialect producer scan filed an item-carried `body` as
`unruled:item-carrier` and reported the family question rather than
answering it. The director seat answered it — summon #25 class-1 item 2,
letter C, on objectui#9871 (2026-09-20): a `body` child list on a non-node
ITEM is not inside objectui#6771's ruled family and not a second family.
It is a producer violating the item's own published schema (`TabItemSchema`
declares `content` and declares no `body`; `ListItem` likewise), fixed at
the producer — done, objectui#9941.

So `dispositionOf('item')` is now `ruled:not-a-dialect/item-schema-violation`.
The name carries the answer instead of leaving a reader to guess it, and the
ruling is cited where a reader MEETS the disposition: beside the constant, in
the `KNOWN_LIMITS` entry every run emits in both modes, and in the note the
text mode prints under the dispositions table.

The behavioural half, which is not a string: the site leaves every pending
list — it awaits no seat — while the arithmetic is unchanged. An item carrier
is still never folded into objectui#6771's ruled total, and step 4's
landability is judged on the node face only. The scan never computed that
landability and still does not; `finalVerdict` already disclaimed it.

The rename introduces one hazard and pins it in the same act: both answers now
begin `ruled:`, so a prefix match would fold the item carrier straight into
the ruled total. The discriminator is the CARRIER, and a new pin holds the two
buckets apart on exactly that.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
@github-actions github-actions Bot added the tests label Sep 20, 2026
@os-tesla
os-tesla marked this pull request as ready for review September 20, 2026 11:30
@os-tesla
os-tesla enabled auto-merge September 20, 2026 11:30
@os-tesla
os-tesla added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit 205b973 Sep 20, 2026
35 checks passed
@os-tesla
os-tesla deleted the claude/issue-9871-item-carrier-disposition branch September 20, 2026 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

make the body-dialect producer table come from a SCAN, not an enumeration — the first deliverable is the CRITERION, not another count

2 participants