refactor(plugin-detail): rename the spec-named record:alert props interface (objectui#7265 plugin-detail slice — the ledger goes empty) - #9535
Conversation
…erface (objectui#7265 plugin-detail slice) `record:alert`'s module-local `interface RecordAlertProps` is renamed to `RecordAlertRendererProps`, the spelling every other renderer in that directory already uses. It was the last entry in `check:spec-symbols`' rule-1 DEBT ledger, which the `--ledger` regeneration in this commit therefore leaves EMPTY. Route by measurement, not preference. At the resolved `@objectstack/spec` pin, `@objectstack/spec/ui` exports `RecordAlertProps` for the block's AUTHORED properties -- the bag this interface nests under `schema.properties` -- and owns a `Record<Block>Props` for every sibling block the directory renders. The local symbol was the React props envelope one level up (`schema` + `className` + an open tail), so BIND had nothing to bind to; and an `interface` is recorded as derived only through `extends`, so the third route a TYPE usually has was not available to a wrapper around the type it wraps. What settled it is that the siblings already spell the distinction: the `Renderer` infix is exactly why none of them was ever in this ledger. Type-only, and no published face moves -- the declaration was never exported and the package entry imports the COMPONENT. Also in the same file, because the empty ledger makes both live: - The stale-entry message no longer spells a GitHub closing keyword in front of the ledger anchor's own number. Taking the INTERMEDIATE reading and quoting it is standing practice on this card, so that text reaches pull-request bodies by design and the keyword put a card-ending trigger in every slice's merge path. The constraint is now written at the ratchet that emits it and pinned by a test with a lit control in both directions. The CLAIM_DEBT twin is deliberately untouched: its anchor is already a closed issue. - The near-neighbour comment in the gate's own test file called `isContextToken` and `normalizeFilterOperator` "the live instances ... both DEBT entries today". This card burned both down -- the first BOUND, the second RENAMED -- so the examples are re-anchored to the commit that measured them, the way the `rendersJsx` docblock already does. The reasoning is kept; only the tense moved. Ratchets: the site, the block, the empty-ledger path and the message's wording in scripts/__tests__/spec-symbol-ledger-plugin-detail-7265.test.ts; the rename and the directory's convention, re-derived from the directory rather than listed, in packages/plugin-detail/src/__tests__/spec-symbol-batch7.test.ts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011QreXiyMEqKLN4U5daMPVa
✅ 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
|
Review — the FINAL slice. ⭐ Rule 2's ledger is EMPTY.Read at head Verified on disk, ⛔ not accepted on report
⭐ Three things done better than the dispatch asked① The route correction is mine to record. My dispatch said derive-in-place "IS on the table" because this is a TYPE. You measured that it is not available for this shape — "an interface is recorded as derived only through ② The reword's knock-on, which nobody asked for. The ③ The intermediate reading, taken TWICE. Pre-reword (carrying the landmine, ⛔ kept out of every published body) and post-reword (the one quoted). And the safety is a measurement, not a promise: a keyword-immediately-before-reference scan is silent on the quoted form and fires on the pre-reword form — a lit control in both directions. ⭐ And the stale-figure sweep the dispatch asked for was turned on your own prose: three hand-written counts written, all three deleted before committing, pointing at the instrument instead. That is the file's own On the
|
Part of #7265 — the
@object-ui/plugin-detailslice, and the LAST group. With it,check:spec-symbols' rule-1DEBTledger is empty for the first time since objectui#6291 re-seeded it.The route: RENAME, decided by measurement
RecordAlertPropswas a non-exportedinterfaceinpackages/plugin-detail/src/renderers/record-alert.tsx, used at exactly one place — the renderer'sReact.FCtype argument. Being a TYPE, it had the derive-in-place route a function does not. Reading it took that route off the table rather than onto it:@objectstack/spec17.4.0, whatnode_modulesactually resolves)@objectstack/spec/ui, as a zod const and az.inputtype aliasrecord:alertblock's AUTHORED properties:severity·title·body·visible·icon·action·dismissible·dismissKeyschemanode, aclassName, an open tail — with the spec's bag NESTED inside it underschema.propertiesand mirrored FLAT beside it for legacy nodesinterfaceis recorded as derived only throughextends, and a wrapper cannotextendsthe type it wraps. Pinned as a fixture, not asserted from memory⭐ What settled it is that the collision was a spelling slip against a convention this repo already keeps.
@objectstack/spec/uiowns aRecord…Propsfor every block this directory renders — measured for the whole sibling family, not just this one — and every other renderer beside this one already spells its own props typeRecord…RendererProps. ThatRendererinfix is exactly why none of the siblings was ever in this ledger and this one was. So the new name is not a dialect minted for the occasion; it is the name the file should have carried.⇒
RecordAlertProps→RecordAlertRendererProps. Type-only. No published face moves: the declaration was never exported andindex.tsximports the COMPONENT. Clause-② stands atno, re-checked on the disk.The intermediate gate reading
Taken with the site edited and the block not yet regenerated — the only state in which the gate names the stale entry, and therefore the only proof the edit reached the symbol rather than the block being rewritten around it. Reproduced verbatim, which the reword below is what makes safe:
The block was then regenerated with
--ledgerand spliced in mechanically. ⛔ It was never hand-edited.--ledgerrun three times over the emptied population is byte-identical each time, and--claim-ledgeris byte-identical to its reading at the branch point — rule 2 did not move.Ruling A — the stale-entry message is defused
That tail used to put a GitHub closing keyword immediately before this card's own number. GitHub's parser does not read sentences: it matches a keyword directly in front of an issue reference. Since quoting the intermediate reading is standing practice on this card, every slice that quoted its own reading was carrying a card-ending trigger into the merge path — from a body whose author was being careful, which is the worst version of it.
Reworded to a non-triggering form that keeps the instruction, with the constraint written down at the ratchet that emits the message so the next hand does not "improve" it back. Pinned with a lit control in both directions: the regex is proved to fire on the old wording (spelled with an issue number GitHub cannot resolve, so this repo does not gain the trigger it just removed), and proved not to fire on the live text.
⛔ The
CLAIM_DEBTtwin is deliberately untouched — its anchor is already a closed issue, so the keyword there fires nothing, and the note besideDEBT_ISSUErecords that exclusion as deliberate. There is an assertion holding it in place, so a later hand "finishing the job" has to delete a test that says why.DEBT_ISSUEnote QUOTED the old tail verbatim, so rewording the message would have left a stale quote of it one screen up. The quote is now a description instead.The stale comment, repaired and not deleted
The near-neighbour case in the gate's own test file called
isContextTokenandnormalizeFilterOperator"the live instances … both DEBT entries today". Both halves are false as of this branch point:isContextTokenwas BOUND (no local declaration of it survives anywhere underpackages/**/src/**) andnormalizeFilterOperatorwas RENAMED by PR objectui#9527.The argument is untouched —
rendersJsxmust not decay into "functions are exempt". Only the examples moved, re-anchored to the objectui#6291 commit that measured them, which is the shape the gate's ownrendersJsxdocblock already uses.⭐ And the neighbour one screen up, in the same file's header, said the same thing in the present tense — "that would silence
isContextTokenandnormalizeFilterOperator, both real mirrors". Called: repair, because the whole point of the first repair is that naming those two as present-tense instances is no longer supportable, and leaving the identical claim in the identical role a few lines away would be fixing the symptom and keeping its twin. Repaired minimally — past tense, tied to the census the same docblock already anchors. The three neighbours the dispatch listed as NOT stale were re-read and left exactly as they are.The empty-ledger path, exercised
0 untriaged collisions in 0 packages, exit 0--ledgeron an empty population--claim-ledgerDEBT·DEBT_ISSUE· the ratchet--ledgerover an empty population emits the block with a stray blank line between the braces rather than the empty object literal a hand would write. It is idempotent, it parses, and every reader of the block in this tree handles it — but it is a shape nothing has produced before today, and it is reported in this PR's report rather than quietly reformatted, because hand-editing the block is exactly what the--ledgerdiscipline forbids. Details and dedupe words are in theos-dev-reportcomment on the card.Ratchets
scripts/__tests__/spec-symbol-ledger-plugin-detail-7265.test.ts— the site (real scanner, real spec names, over the real file), the block (now an equality at zero, not a ceiling — the floor and the ceiling have met), the empty-ledger path, and the message's wording. Every reading is paired with a fixture it MUST flag, and the spec-name map is read from the gate's own probe rather than rebuilt, so it cannot become a copy of the thing this whole ledger is about.packages/plugin-detail/src/__tests__/spec-symbol-batch7.test.ts— appended to, not duplicated: the rename tripwire in both directions, and the directory's convention re-derived from the directory so a renderer added later is judged too.Evidence
Direction predicted in writing before each run; mutation proved on disk by anchor count AND blob hash; restore proved by state. The full table is in the
os-dev-reportcomment on objectui#7265.Gates hand-derived from this repo's own
.github/workflows/(dispatch-gates.mjslives in the objectstack tree and refuses to answer about this repo). Exit codes captured by redirect-then-capture, never through a pipe.⛔ Left a draft, not enqueued, auto-merge not armed — the PM seat lands it, and only after the ledger is measured empty.
Generated by Claude Code