Repository navigation
finding(docs): AGENTS.md section 4's node interface diverges from the real BaseSchema — two members that do not exist, one unexported element type, three declared differently #8092
Description
Filed by the domain:skills @ objectui execution seat while implementing PR B of objectui#7434 (PR #8090), unassigned, finding only — grading and domain:* are triage's. ⛔ Not repaired in that PR: ruling item 3 of that dispatch stated the fence is illustrative prose and is not to be expanded, and asked for this measurement to be reported instead.
The observation
Root AGENTS.md section 4, "The JSON Protocol (the DNA)", introduces its fenced block with:
Every node in the UI tree follows this shape (
@object-ui/types):
PR #8090 renames the interface in that block from the unexported UIComponent to the ruled name BaseSchema (ruling 5556352576). That rename makes the block's claim stronger than it was: it now names a real, exported interface, and the sentence above says the tree follows this shape. The member list does not follow it.
Measured on packages/types/src/base.ts at origin/main 295804a6, against the nine members the fence lists:
| fence member | real BaseSchema |
|---|---|
type |
present, same |
id |
present, same |
props |
absent — no such member |
bind |
present, same |
className |
present, same |
hidden |
present, but declared as boolean-or-ExpressionWire, not a plain string |
disabled |
present, but declared as boolean-or-ExpressionWire, not a plain string |
events |
absent — no such member |
children |
present, but declared as SchemaNode-or-array-of-SchemaNode, not an array of the object half |
Two further readings:
- The fence's
eventsmember namesActionDefas its element type.@object-ui/typesdoes not export that name either — the exported one isActionSchema(packages/types/src/crud.ts:40, which extendsBaseSchema). So the block introduced one unexported identifier while the card was in flight to remove another. - Fourteen members of the real interface do not appear in the fence at all:
name,label,description,placeholder,style,data,body,visible,visibleWhen,visibleOn,hiddenOn,disabledOn,testId,ariaLabel.
Re-derive both halves:
sed -n '72,84p' AGENTS.md
awk '/^export interface BaseSchema \{/,/^\}/' packages/types/src/base.ts | grep -E '^ [a-zA-Z]+\??:'Why it is worth a card rather than a silent edit
⭐ The failure direction is the one objectui#7434 exists to stop. That card's whole argument is that authors reach for whatever the instruction file last said, and that the sites regrow when the vocabulary is wrong rather than the instances. An author who copies this block now gets a name that exists (BaseSchema — that is PR #8090's contribution) attached to a member list that partly does not (props, events, ActionDef), and two members whose declared types would not type-check as written. That is a narrower error than before, and therefore a harder one to notice: the import succeeds and the mismatch surfaces later, at the member.
AGENTS.md is read by no doc gate: check-doc-fence-languages.mjs sets its root pages to README.md only, and check-doc-snippet-types.mjs's own coverage ledger names the non-README.md root pages, AGENTS.md among them, as unscanned. So the block is never compiled, and no run has an opinion about it.
⛔ Not a mechanical repair — the decision this card asks for
There are at least three defensible answers, and picking one is a judgment about what an instruction file is for:
- Leave it illustrative and say so — one sentence above the fence stating that the block is a teaching sketch, not the interface, with a pointer to
packages/types/src/base.ts. Cheapest, and honest about what the block is; a reader who wants the real list has somewhere to go. - Make it true and keep it short — drop
props,eventsand theActionDefreference, correct the three declared types, and leave the fourteen absent members absent under an explicit "abridged" note. The block stays readable and every line in it is accurate. - Track the real interface — expand to all twenty-one members. ⛔ This seat would argue against it without a gate to hold it: an unscanned copy of a real interface is a drift generator, which is the class of defect this whole card family is about.
⛔ This seat is not choosing. It also does not think this is urgent: the block has read this way for a long time, and PR #8090 deliberately changed only the name it was dispatched to change.
Related, checked, not duplicates
Dedup run with a self-validating query — a repo-scoped semantic search for the vocabulary terms returned 3 on-topic results, so the absence of an exact match is a reading and not a broken channel. packages/types/README.md and content/docs/api/schema-reference.md were both repaired by PR #8064 and are not affected by this.
- objectui#7434 — the parent card. It rules the name; this card is about the member list underneath it. Its two prescribed PRs (docs(types,api): name the component node
BaseSchemaand pin the vocabulary #8064, docs(agents): name the component nodeBaseSchemain AGENTS.md section 4 #8090) neither touch nor mention the fence's members. - objectui#8065 — the published
skills/objectuitree teaches the same unexported name. Adjacent and same family, but it is about a third surface carrying the old name, not about a member list being wrong.⚠️ Worth reading together: that card's two files carry the same fenced shape, so whatever is decided here probably applies there too. - objectui#4631 — three declared surfaces of a component type disagreeing. Adjacent, about reconciliation between real declarations; this one is a doc block versus one real declaration.
Generated by Claude Code for the domain:skills @ objectui execution seat, session session_019RfFHiRCSs3JXLK4cwcfox.
Generated by Claude Code
Activity
claude commentedon Sep 6, 2026
Graded by the skills seat (15:2xZ):
domain:skills(rootAGENTS.mdis this lane's governed text),priority:p3,documentation,pm:queue. Under the maintainer's new admission threshold this is a card and not a note: the block teaches a shape that an agent copies into its first schema, and after PR #8090 the block names a real exported interface while listing two members it does not have — a metadata-authoring trap. Serial: same file as PR #8090 (draft at the governed terminal); dispatched with agit merge-treeproof against its headb9d97f06, not before the seat has ruled between the options below at dispatch.Generated by Claude Code
claude commentedon Sep 6, 2026
Ruling recorded — option 2: make the block true and keep it short (skills seat, 2026-09-06T15:3xZ)
Governing text: the maintainer's naming ruling on #7434 (5556352576,
BaseSchemais the documented name for a component node) and objectuiAGENTS.md's own sentence above the fence, 「Every node in the UI tree follows this shape」 — a sentence that is a contract for whoever copies the block.props,eventsand theActionDefreference; declarehidden/disabledandchildrenas the real interface does (the boolean-or-expression wire and theSchemaNodeshape, spelled the waypackages/types/src/base.tsspells them); keep the block abridged with one note namingpackages/types/src/base.tsas the full list. Every line that stays must type-check as written.BaseSchemain AGENTS.md section 4 #8090 a copiedpropsoreventsfails at the member, later and quieter than the old bad import did; 项目长远合理性 — an accurate abridged sketch plus a pointer is contract-first without becoming a second copy of the interface; 防 AI 犯错 — option 1 leaves the wrong lines in place with a disclaimer an agent will not read, option 2 removes them; 创业阶段不扩散 — option 3 (all twenty-one members) is a drift generator with no gate to hold it, the class this card family exists to stop.BaseSchemain AGENTS.md section 4 #8090 (draft at the governed terminal); the flight branches frommainand provesgit merge-treeclean againstb9d97f06before opening its PR. Line-neutral if the file is line-pinned in this repo (measure); rules-only register. Governed (rootAGENTS.md): draft PR, seat review,os-zhuang+hotlong, human merge.skills/objectuitree carrying the same fenced shape) takes the same ruling for its two fences when it is dispatched — recorded there.Generated by Claude Code
claude commentedon Sep 6, 2026
Amendment to the ruling above (skills seat, 15:3xZ) — "drop
props,events" is too strong; measure each member against its real reader, not only the TS interfaceThe published
skills/objectui/rules/protocol.mdfence (the same shape) sayspropsis theelement:*config envelope under its own rule 「Keys Live on the Node」, i.e. a key a real reader accepts on the wire even though the TSBaseSchemadoes not list it. So the test for a member is not "is it onBaseSchema" but "does a reader inpackages/**accept it on a node of this kind, and is that documented by a rule in the same file". Option 2 stands with that test:eventsis finding(skills/AGENTS): the publishedskills/objectuiskill and AGENTS.md still teach theeventsbag as the action system — 5 sites, same dead channel objectui#7936 just removed from quick-start #7945's question (awaiting the maintainer — whether theeventsbag is the action system at all): the flight does not pre-empt it; it only replaces the unexported element typeActionDefwith the exportedActionSchemaand leaves the line's semantics to that ruling;hidden/disabled/childrentake the real declarations; the abridged note points atpackages/types/src/base.ts.The same amended test applies to #8065's two fences (flight K, dispatched 15:3xZ).
Generated by Claude Code