test(console,components): pin the last four one-key member blocks (objectui#8071 slice 7) - #8942
Conversation
…jectui#8071 slice 7) Converts every remaining `MEMBER_PIN_EXEMPTIONS` block whose remainder was exactly one key into a real per-block member pin, deletes those four exemptions, and lowers `MEMBER_PIN_EXEMPTION_CEILING` 41 -> 37 in the same commit. element:button.action -> elementButtonActionMembers-8071.test.tsx (new) element:number.filter -> elementNumberFilterMembers-8071.test.tsx (new) page:accordion.items -> pageAccordionItemMembers-8071.test.tsx (new) page:tabs.items -> pageTabsItemMembers-8071.test.tsx (new) All four blocks now carry zero exemptions. The batch is coherent on slice 6's terms: one package (`packages/components`) registers all four, and the selection rule is stateable in a sentence. Two one-key blocks were deliberately left. `record:related_list.actions` is the `NO_READ_SITE_TO_PIN` sentinel and the reading was re-measured rather than inherited: `record-related-list.tsx` still holds zero case-sensitive occurrences of `actions` (control: `import` reads 9 in the same file). `object-kanban`'s `columns` / `dataSource` are held by the unruled contract question in objectui#8913, so `NEWLY_JUDGED_UNPINNED_MEMBERS` is unchanged. No pre-existing file covered any of the four keys' member SET; each candidate was read end to end before being rejected. `action-bodyShape-forward.test.tsx` had to be refused rather than passed over — it names both the block and the key, so it would satisfy the locator, while what it says is that `element:button` is deliberately out of its scope. Its boundary is pinned as behaviour in the new file instead. Ledger (TypeScript AST walk, object boundaries from node spans): exemptions 41 -> 37, ceiling 41 -> 37, pins 49 -> 53, prefixes 10 -> 6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
⛔ The enqueue is not taking from this seat — this PR needs a human "Merge when ready" click
What is measured
⇒ Two calls, an idle queue, and no state change. The first call did nothing; the second has had ~19 minutes against an empty queue and also shows nothing. Why I cannot tell you more than that
⛔ What I am deliberately not doing⛔ Not calling ⛔ Not calling ⛔ Not pushing an "update branch" commit to shake the state loose: that would move the head, discard 33 green checks and cost a full CI cycle to fix a problem that is not in the PR. ⇒ The unblockA human "Merge when ready" click on this PR. It is green on every check, the base is only one commit behind (
Generated by Claude Code |
⛔ RETRACTION — my previous comment was wrong. The enqueue worked; nothing was broken.
This PR merged at What I got wrong, and whyI concluded "no-op" from three readings:
⭐ The actual mistake is a calibration error. Every merge I had observed this shift landed ~16–18 minutes after its enqueue, and I treated that as the queue's ceiling rather than as four samples from a distribution whose upper tail I had never measured. The true latency here was ~54 minutes from the second call. "Elapsed time exceeds every latency I have seen" is not evidence of a no-op — it is evidence that my sample was small. What stands from that commentOnly the tooling limitation, which is unchanged and was already stated as such: ⛔ No human click was needed. Sorry for the noise on this thread. Generated by Claude Code |
Refs #8071 — slice 7. The card stays open, and 37 exemptions remain.
What this lands, in one commit
Every remaining
MEMBER_PIN_EXEMPTIONSblock whose remainder was exactly one key becomes a real per-block member pin. The four exemptions are deleted andMEMBER_PIN_EXEMPTION_CEILINGmoves 41 to 37 in the same commit, so the ceiling never holds an unused slot.element:button.actionpackages/components/src/__tests__/elementButtonActionMembers-8071.test.tsxelement:number.filterpackages/components/src/renderers/basic/__tests__/elementNumberFilterMembers-8071.test.tsxpage:accordion.itemspackages/components/src/__tests__/pageAccordionItemMembers-8071.test.tsxpage:tabs.itemspackages/components/src/__tests__/pageTabsItemMembers-8071.test.tsxAll four blocks now carry zero exemptions. The batch is coherent on slice 6's terms: one package (
packages/components) registers all four — the twoelement:keys sharerenderers/basic/elements.tsx, the twopage:keys sharerenderers/layout/containers.tsx— and the selection rule is stateable in a sentence.AST ledger — measured, not inherited
TypeScript AST walk (
ts.createSourceFile,VariableDeclaration, initializer unwrapped through as / satisfies / parens,PropertyAssignment), object boundaries from AST node spans. Re-derived on this branch's own head rather than taken from the dispatch.The delta balances on one instrument: minus 4 exemptions, minus 4 ceiling, plus 4 pins, with the parent holding exactly one key under each of the four prefixes taken. Parser guards clean:
parseDiagnostics0; exactly oneVariableDeclarationper name, so no shadowed node was picked up; 0 non-PropertyAssignmentmembers and 0 computed keys in either object; 0 non-string array elements.Instrument cross-check, reported rather than smoothed
A key-anchored regex bounded to top-level indentation inside the AST span AGREES on both objects: 37 = 37 and 53 = 53, with an empty only-in-AST and an empty only-in-regex set.
The depth-blind key anchor slice 6 caught still reads
MEMBER_PINSas 159 against the AST's 53. Fully accounted for: values are objects of shape file-plus-pins, so 53 entries carry 106 nested sub-keys, and 53 + 106 = 159 matches to the unit. That is the same failure mode for the fourth time on this file, on new content — recorded, not smoothed.The two one-key blocks deliberately NOT taken
record:related_list.actionsis theNO_READ_SITE_TO_PINsentinel, and the reading was re-measured here rather than inherited: on this treepackages/plugin-detail/src/renderers/record-related-list.tsxcontains zero case-sensitive occurrences ofactions(control on the same file, same run:importreads 9), and the only near-matches areuseRelatedRecordActions/relatedActions— the host bridge the constant already names. Nothing to pin, still. It is not "one easy key left".object-kanban.columns/object-kanban.dataSourceare theNEWLY_JUDGED_UNPINNED_MEMBERSpair, held by the unruled contract question in objectui#8913 and by the live branch overpackages/plugin-kanban/**. Pinning a shape a pending ruling may delete would be worse than leaving it exempt, soNEWLY_JUDGED_UNPINNED_MEMBERSis unchanged — no block it names was touched, and no file this PR edits is owned by that branch.Why four new files rather than promotions
Every candidate was read end to end before being rejected, not dismissed on its greps. None covered its key's member set:
element-button-action.test.tsxdrives onlytypeandtoon one navigation action;action-bodyExtra-forward.test.tsxpins one member across four renderers;page-accordion-icon.test.tsxpinsiconalone; the fivepage:tabssuites pin one member each; andelement-number.contractEnvelope-6726.test.tsxdrives the samefind()fallback branch but never authors afilter, so the locator itself would refuse it.One had to be refused rather than merely passed over.
action-bodyShape-forward.test.tsxNAMESelement:buttonand the keyaction, so it would satisfy the locator — while what it actually says is thatelement:buttonis deliberately out of its scope. Crediting it would have been a pin asserting the opposite of its claim, which is the false-negative shape objectui#8068 exists to end. Its boundary is instead pinned as behaviour in the new file, which authors a non-whitelisted key and asserts it is dropped.Ablations — every mutation proven on disk BEFORE any result was read
Each run anchors grep counts on both the injected and the removed text, requires
git hash-objectto differ from the HEAD blob, restores withgit checkout HEAD -- ABSOLUTE_PATHfrom atrap ... EXIT INT TERM, and proves restoration by blob hash — never by an exit code.Family 1 — the gate mechanism. One deleted exemption re-added, ceiling untouched. Blob
c5497f50toc7e10387and back toc5497f50.Exactly three rows red, each for its own reason, 195 green:
Family 2 — one per new pin, each failing for its own reason. All four pin files run together each time, so "its own reason" is observable rather than asserted.
element:button.actionbodyExtrafrom the forward whitelistelement:number.filterfind()wrapper key to the flat spellingpage:accordion.itemsit.collapsed === falsebecomes!it.collapsedpage:tabs.itemsBlob hashes:
elements.tsx498cbdeftoe0e1ebbdand to7fcb7bfc, restored to498cbdefboth times;containers.tsx0ba09c75to072638f8and to8fecfe8a, restored to0ba09c75both times.⭐ Worth one line for the next reader: the accordion ablation reds the two rows written as controls — "every panel stays shut when no item declares it" and the
allowMultiplerow — and not the row that namescollapseddirectly. In single modedefaultOpen[0]masks the difference between the two readings, so the controls are the only thing that catches it. They are load-bearing, not decoration.Verification
Exit codes captured into a variable before any pipe; readings taken from each tool's own verdict line.
registry-inputs-spec-parity.test.ts@object-ui/consolefull suite@object-ui/componentsfull suite (two shards)type-check, both packageserror TSrows, both echoed their script and printed Donelint, both packagesNotes that keep those readings honest:
lintwas read for the literal worderror, not merely a zero exit. Every hit is awarning Error: ...rule message or a source line containing the word; zero severity-ERROR rows in either package. Both packages emitted real eslint summaries (1535 and 621 output lines), so "the filter matched no script, nothing ran, exit 0" is excluded.type-checkgenuinely covers the changed files rather than skipping them:packages/componentschainstsc -p tsconfig.test.json, whose include globs aresrc/test patterns, andapps/consoleincludessrcwith no exclude.type-checkattempt failed withTS2307on unbuilt workspace siblings. The dependency closure was built and it was re-run; the table reports the run on the built tree..changeset/member-pins-slice-7.mdcarries an empty frontmatter — declared as releasing nothing, whichscripts/check-changeset-presence.mjsaccepts as a complete answer (exit 0).scripts/check-governed-queue-guard.mjs --teston all six paths reports NOT GOVERNED (exit 0).After this slice
Every remaining exemption sits on one of four multi-key blocks —
object-grid15,object-form7,object-master-detail-form6,object-metric6 — plus the two held keys. The "close a block outright by taking its last key" shape is now exhausted: the next slice is the first that has to take a partial block or close a multi-key one whole. That is stated in the ceiling docblock too, so the next reader does not spend the search rediscovering it.⛔ Draft on purpose — the PM lands it.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Jmxdo7bmeqCQHLSfmLVX9w
Generated by Claude Code