Skip to content

finding(types,plugin-ai): the three AI schemas carry six zero-read members (formId, objectName×3, fields, maxResults) plus a dead autoFill destructure — and the registry advertises five of them to the designer #8178

Description

@baozhoutao

Measured while compiling packages/plugin-ai/README.md's snippets for objectui#5174 batch 27 (PR to follow). Not fixed there — that batch's licence is the README and one ledger entry, and ⛔ no edit to packages/plugin-ai/src/** or packages/types/src/**. Filing so the shape is not lost.

This is the plugin-ai instance of the class objectui#7742 already carries for KanbanSchema (three zero-read members + one undeclared read, enforce-or-remove). objectui#5098 was the plugin-form README instance of the same thing. Nothing here is a duplicate of either: different package, different keys.

What was measured

Every key below is declared by its schema type in packages/types/src/ai.ts and never read by the component that the schema drives. The three components in packages/plugin-ai/src/ are the only consumers of these three types repo-wide (grep -rln over packages/*/src and apps/*/src returns the three components plus the declaration and the barrel).

Key Declared Read at runtime? Note
AIFormAssistSchema.formId ai.ts:97 no — zero occurrences in AIFormAssist.tsx
AIFormAssistSchema.objectName ai.ts:102 no — zero occurrences
AIFormAssistSchema.fields ai.ts:107 no — zero occurrences
AIFormAssistSchema.autoFill ai.ts:127 dead read — destructured at AIFormAssist.tsx:31 with a default, never referenced again the only occurrence of the identifier in the file is that destructure
AIRecommendationsSchema.objectName ai.ts:209 no — zero occurrences in AIRecommendations.tsx
AIRecommendationsSchema.maxResults ai.ts:229 no — zero occurrences see below
NLQuerySchema.objectName ai.ts:321 no — zero occurrences in NLQueryInput.tsx

What each component does read, for contrast (the destructure is the whole surface in all three):

  • AIFormAssist.tsx:27-32suggestions, showConfidence, showReasoning, autoFill (dead).
  • AIRecommendations.tsx:27-33recommendations, showScores, layout, loading, emptyMessage.
  • NLQueryInput.tsx:25-32placeholder, result, suggestions, showHistory, history, loading.

Why maxResults is the sharp one

Its doc comment reads Maximum number of results to display. AIRecommendations renders every item in recommendations — there is no slice, no cap, no read of the key at all. An author who writes maxResults: 5 against a 50-item list gets 50 rows and no diagnostic. That is a declared capability the runtime does not honour, which is the exact failure mode the coding standards' contract-first rule and the dispatch framework's third axis (making it structurally hard for an AI to write wrong metadata) exist to prevent.

grep -rn maxResults packages/*/src returns exactly three hits: the declaration (types/src/ai.ts:229), the designer input below, and nothing else.

The designer amplifies five of the seven

packages/plugin-ai/src/index.tsx advertises these keys as authorable inputs in its ComponentRegistry.register metadata, so the field designer offers them and a metadata author can pick them from a list:

  • ai-form-assist (index.tsx:24-30) — offers formId, objectName, fields, autoFill.
  • ai-recommendations (index.tsx:41-51) — offers objectName, maxResults.
  • nl-query (index.tsx:60-65) — offers objectName.

So the loop is closed the wrong way: the type declares it, the designer offers it, the JSON validates, and the renderer ignores it — silently, at every depth (objectui#7869 explains why nesting makes even the value check vacuous). This is the mirror image of objectui#7712 / #8171 / #8172 / #8174, which all report a key the renderer reads but the registration does not declare; here the registration and the type declare what nothing reads.

Not decided here

Enforce-or-remove is a maintainer call and the two directions have different costs, so this card does not pick one:

  • Remove — retire the seven members and their designer inputs. Cheapest, matches the startup-stage focus principle (an unpulled declaration surface defaults to strict) and the immediate-retirement ruling. Cost: objectName reads like context an AI backend would eventually want, and removing it is visible in a published .d.ts.
  • Enforce — implement the reads (maxResults as a slice, fields/formId/objectName as the context the suggestion call needs). Larger, and it is only worth it if a real caller wants it — which is the first axis, and nothing in the repo currently pulls on these.

The measurement above is what the decision needs either way; note that until one is chosen, packages/plugin-ai/README.md teaches five of the seven keys in its examples (they are declared, so the repaired snippets compile — the gate cannot see inertness, only types).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lanedomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatenhancementNew feature or requestpriority:p3

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions