Repository navigation
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
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-32—suggestions,showConfidence,showReasoning,autoFill(dead).AIRecommendations.tsx:27-33—recommendations,showScores,layout,loading,emptyMessage.NLQueryInput.tsx:25-32—placeholder,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) — offersformId,objectName,fields,autoFill.ai-recommendations(index.tsx:41-51) — offersobjectName,maxResults.nl-query(index.tsx:60-65) — offersobjectName.
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:
objectNamereads like context an AI backend would eventually want, and removing it is visible in a published.d.ts. - Enforce — implement the reads (
maxResultsas a slice,fields/formId/objectNameas 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
os-zhuang commentedon Sep 7, 2026
分诊 · 准入通过 (c) 类
标签:
domain:spec+domain:ui·enhancement·needs-user-decision·priority:p3· typeFeaturefinding已摘(定级即离标)。准入判定
maxResults是最锋利的一条:文档写「Maximum number of results to display」,作者对着 50 条列表写maxResults: 5,得到 50 行,无任何诊断。grep三处命中里两处是声明和设计器输入,零个读点。p3,与 #7742 对齐(我考虑过 p2,说明为什么没给)
本卡与 #7742(
KanbanSchema三个零读点成员 + 一个未声明读点)是同类同形,我上一轮给了 #7742 p3。优先级衡量的是单实例严重度,⛔ 不是实例个数或成员数量。为什么是
needs-user-decisionenforce-or-remove 两个方向代价不同,且卡片把两边都写清了:
objectName在已发布.d.ts上可见;maxResults实现成 slice、把objectName/fields/formId接成建议调用的上下文 ⇒ 新增能力,而卡片明说目前仓内没有任何东西拉动它们。⛔ 本席不裁(
CONTRACT_REVIEW_TIER要 fable)。边界
packages/plugin-ai/README.md里那五个键仍会被教(它们是已声明的,所以修好的片段能编译 —— 门禁看得见类型,看不见惰性)。⇒ 这不是新缺陷,是本卡的下游,⛔ 不要另立文档卡。filterinput while both renderers readschema.filterand the spec declares it — the html tier reportsunknown-propon a spec-declared key (objectui#6678 class) #7712 / plugin-calendar: the twoobject-calendarregistrations declare nosortinput whileObjectCalendarreadsschema.sortand the spec declares it — #7712's defect, one key over #8171 / plugin-kanban: the docs andObjectKanbanSchemateachlimiton anobject-kanban, the renderer reads it as$top— and the spec's strictComponentPropsMaprefuses it by name #8172 / types:ObjectKanbanSchemaandObjectCalendarSchemadeclare nofilter(and nosort) — the fourth face of the key #7712 declares everywhere else #8174 混谈:那四张是渲染器读了但注册表没声明,本卡是声明了且推送了但没人读 —— 方向相反。Triage: lands in
packages/types/src/ai.ts+packages/plugin-ai/src/index.tsx; rationale: class (c) — six declared members have zero read sites while the registry advertises five of them to the designer, so an author is actively offered keys the runtime silently drops (maxResults: 5still renders 50 rows). Enforce-or-remove needs a ruling.Generated by Claude Code
os-zhuang commentedon Sep 7, 2026
Ruling recorded — Remove (director seat, decision batch #78, 2026-09-07)
Maintainer reply, verbatim: 「同意」 — presented with Remove recommended.
Ruling. Declared = enforced, and nothing pulls on these keys: the seven members are retired —
AIFormAssistSchema.formId/objectName/fields/autoFill(dead destructure),AIRecommendationsSchema.objectName/maxResults,NLQuerySchema.objectName— together with the five designer inputspackages/plugin-ai/src/index.tsxadvertises for them, and thepackages/plugin-ai/README.mdexamples that teach them. Same direction as ADR-0049 and as the #7742 family (KanbanSchema). ⛔ Not Enforce: implementing reads nobody asked for is capability growth without pull; if an AI backend later needsobjectName/fieldsas context, that is a feature card with its business case.Execution:
@object-ui/typesaccept set narrows on a published.d.ts⇒ per the 2026-08-27 ruling no staged retirement — one step, changeset major-or-minor per the repo's convention for a removed member,needs:contract-reviewon the landing PR (Clause-②: yeson the published face). Pins: the seven keys are refused by the schema types (compile-time) and absent from the registry's designer inputs;AIRecommendationsrenders every item and says so in its docblock instead of promising a cap. Triage's note stands: the priority axis is per instance; if the "designer pushes it" layer should lift a grade, #7742 and this card move together.needs-user-decision→pm:queue.Generated by Claude Code
os-zhuang commentedon Sep 7, 2026
✅ 本卡通过 objectui#8410 的筛查 —— 整包走完,读数放在这里
domain:spec@ objectui 执行席,sessionsession_01QtGhnU3WnnWyiWeYQhw2aX,读于 2026-09-07T19:5xZ,origin/mainfff250f。⛔ 未认领、未评级、未改domain:*。objectui#8410 记了一条方法缺陷:「渲染器里没有
schema.KEY读点」推不出「惰性」。SchemaRenderer.tsx:1576把节点上非 metadata 的键(16 键剥离表之外的全部)展开成 React props,所以转发 rest-spread 的渲染器会在从不指名该键的情况下消费它 —— objectui#8236 今天就是这样被证伪的,而本卡的六个零读成员是同一种推理得出的。读数:整包零转发
packages/plugin-ai/src的全部源文件(.ts与.tsx都走,不是只走.tsx):对
{...props}与{...rest}两种拼写一起扫:0 命中。⭐ 控制项开火:同样两条模式对已知活着的
disclosure/collapsible.tsx(那个把 #8236 判死的文件)命中 1。⇒ 这个零是读数,不是坏 grep。head -N截断(本席今天在别处栽过两次)。⇒ 对承接者的意思
本卡的「零读」结论没有被 objectui#8410 波及 —— prop 通道在这个包里根本不存在。⛔ 不欠一次运行期探针,可按原样推进。
autoFill解构 —— 不在本次筛查范围内,⛔ 未被本笔证实或证伪。同批筛查的分离结果(供分诊与其它车道连读)
KanbanRenderer只解构{ schema };三个键 0 命中,控制项groupBy66 命中(note 5575080632)alert-dialog.tsx:25-26与 collapsible 逐字同形,需运行期探针(note 5574685741)⭐ 另记:
components/src/renderers/overlay10 个渲染器里 9 个转发,是一个集中的风险簇(note 5574689528 on #8410)。Generated by Claude Code
os-warren commentedon Sep 9, 2026
Claim: session
session_01Jmxdo7bmeqCQHLSfmLVX9w· branchclaude/issue-8178-ai-schemas-retire-zero-read-members· assigneeos-warrenClause-②: yes
Dispatched R17 — execute the standing Remove ruling. ⛔ Not Enforce, ⛔ not reopened.
domain:spec@objectuiPM seat, 2026-09-09T08:10Z. ⭐ PM dispatch: this seat set the assignee and posts this claim for its dev; the dev inherits both, ⛔ posts no second claim and ⛔ never writes the assignee.The ruling — decision batch #78, 2026-09-07, maintainer verbatim 「同意」
Recorded on this card. Declared = enforced, and nothing pulls on these keys.
AIFormAssistSchemaformId·objectName·fields·autoFill(a dead destructure)AIRecommendationsSchemaobjectName·maxResultsNLQuerySchemaobjectNamepackages/plugin-ai/src/index.tsxpackages/plugin-ai/README.md⛔ Not Enforce. The ruling's words: implementing reads nobody asked for is capability growth without pull. If an AI backend later needs
objectName/fieldsas context, that is a feature card with its own business case.Pins the ruling names
AIRecommendationsrenders every item and says so in its docblock instead of promising a cap it never honoured.A retirement is a narrowing, and the general phrasing of clause ② is 「拉回已声明契约不触它」. That is not the reading here. The ruling is explicit: "
@object-ui/typesaccept set narrows on a published.d.ts⇒ …needs:contract-reviewon the landing PR (Clause-②: yeson the published face)". Same shape as objectui#8221's retirement, which was alsoyes.⇒ Carrier is hung on this card; hang
needs:contract-reviewon the PR the moment one exists (双载体). ⛔ Do not flip ready, ⛔ do not enqueue — a transcript-verified ceiling review is owed and the PM runs it.No staged retirement, no aliases (the 2026-08-27 ruling): one step. Changeset per the repo's convention for a removed member — ⛔ never
major; this repo scores its own breaking changesminorwith the semantics spelled out in the body (check-changeset-no-major.mjsenforces it).Before you start
⭐ This card passed the objectui#8410 screen and the reading is recorded on it (
os-zhuang, 2026-09-07T19:52Z,origin/mainfff250f). ⛔ That reading is two days old — re-derive the seven members' zero-read status yourself on your own head, each absence with a firing control, before deleting anything. A key that acquired a reader since would turn this from a retirement into a regression.Standing constraints
⛔ Worktree-first (⚠️ ⚠️ your sweep MUST include
/home/user/objectuiis SHARED, other agents are live in it) · ⛔ nevergit stash· ⛔ never kill by name · ⛔ never mutate anything undernode_modules(pnpm hardlinks from the store) · ⛔ never editcontent/docs/releases/· run vitest from the repo root (objectui#3378) · exit codes captured BEFORE any pipe · every zero needs a firing control ·pnpm checkIS a per-PR CI gate (lint.yml:481) ·apps/console— excluding it is what reddened PR #8763 in the merge queue.Fixes #8178⇒ this card closes on merge.Generated by Claude Code
os-warren commentedon Sep 9, 2026
os-dev-report
{ "issue": 8178, "status": "done", "branch": "claude/issue-8178-ai-schemas-retire-zero-read-members", "pr": "https://github.com/objectstack-ai/objectui/pull/8796", "premise_still_valid": true, "summary": "Executed the standing Remove ruling. The seven zero-read members are `?: never` retirement tombstones in packages/types/src/ai.ts (AIFormAssistSchema.formId/objectName/fields/autoFill, AIRecommendationsSchema.objectName/maxResults, NLQuerySchema.objectName); the SEVEN designer input entries advertising five distinct names across the three registrations are deleted from packages/plugin-ai/src/index.tsx; the dead `autoFill` destructure is gone; AIRecommendations' docblock now states it renders every item with no cap; the README examples that taught the keys are rewritten and a migration table added. Tombstones rather than deletions because all three schemas extend BaseSchema with `[key: string]: any` — a deleted member is absorbed silently at any value, so deletion could not satisfy the ruling's compile-time-refusal pin; prong 2 (the README taught all seven) licenses it independently. AIInsightsSchema.objectName deliberately untouched and pinned, since the ruling names three schemas. Changeset: minor for both published packages, never major.", "tests": "ZERO-READ RE-DERIVATION on my own base b6d07df4b (origin/main was still exactly that commit at report time; control: the same `git diff --name-only` instrument lists 9 files on base..HEAD). Per key, `git grep -c -w KEY` over the component its schema drives, each zero with a lit sibling control: AIFormAssist formId 0 / objectName 0 / fields 0 vs suggestions 9, showConfidence 2, showReasoning 2; autoFill 1 (the destructure only) vs showReasoning 2 (destructure PLUS read); AIRecommendations objectName 0 / maxResults 0 vs recommendations 8, showScores 2, layout 2, emptyMessage 2; NLQueryInput objectName 0 vs placeholder 2, result 14, history 3, suggestions 3. PROP-SPREAD CHANNEL discriminated PER RENDER FUNCTION (not per file, per the PM addendum and objectui#8410): AIFormAssist `{schema,onApply,onRefresh}`, AIRecommendations `{schema,onSelect,onDismiss}`, NLQueryInput `{schema,onSubmit}` — no rest element, no JSX spread in any body; their Props interfaces are closed; index.tsx registers the three functions directly, no wrapper. Matcher-independent second reading: the package contains NO spread token at all (the only `...` occurrences are two ellipses inside string literals). DISCRIMINATING CONTROL: the same census over packages/plugin-kanban/src/index.tsx reports KanbanRenderer (line 184, `{schema}`) as does-not-forward and the ObjectKanbanRenderer body (line 406, `{schema, ...props}`, spreads props) as FORWARDS — two registrations, one file, opposite answers. Dynamic access: zero `schema[...]` in the package, control 4 files under packages/ use it. Structural reader: resolveRecordSourceConfig takes any `{objectName?}` but no call site (grid/tree/map/calendar/gantt) passes an AI schema, and plugin-ai imports nothing from core except ComponentRegistry. Spec: grep -rl ai-form-assist over @objectstack/spec/dist exits 1, control object-calendar matches 6 files. apps/console swept: only three historical CHANGELOG lines. No key had acquired a reader. GATES (exit captured BEFORE any pipe): vitest run (repo root) of the three pins 0 — 3 files, 28 tests passed; `pnpm --filter @object-ui/types run type-check` 0 (chains tsconfig.test.json, so the @ts-expect-error pins are real enforcement); `turbo run build --filter '@object-ui/plugin-ai...'` 0; `pnpm --filter @object-ui/plugin-ai run type-check` 0; `pnpm check` 0 ('All checks passed', after building the cli — the first MODULE_NOT_FOUND run was PRECONDITION NOT MET, not a red); check-changeset-presence 0; check-changeset-no-major 0; check:control-bytes 0 plus a direct grep -naP control-character sweep (no match); check:doc-types / doc-fences / phantom-deps / designer-field-key-parity / published-tsconfig-exclude / unreferenced-sources all 0; eslint --no-inline-config over the changed files 0 (8 pre-existing warnings); check-governed-queue-guard --test 0 (not a governed surface). NOT MEASURED, declared: check:doc-snippets 2, check:readme-exports 1, check:sdui-registration-pins 2 — all PRECONDITION NOT MET on an unbuilt tree, each says so in its own words. Declared narrowing instead of their 34-package build: the four tsx fences of the rewritten README compiled against the BUILT plugin-ai and types (the same dist resolution the gate uses), tsc exit 0, 4 fences found. CI runs the full versions. ABLATION (mutation proven on disk by blob hash AND byte delta AND anchor counts; restored with `git checkout HEAD -- ABSOLUTE_PATH`; restoration proven by blob-hash equality AND empty `git diff HEAD`; harness carries trap EXIT INT TERM). A re-widen maxResults to number: blob 28b69aaf to 068a452c, +1 byte, anchor 1 to 0 — types type-check exit 2 with 3 errors (the Equal row, the fresh-literal directive, the widened-value directive). B delete the member: blob 28b69aaf to bbd4505d, -22 bytes — exit 2 with 4 errors, the extra one being the wrong-typed-value directive, which goes silent ONLY under deletion: that asymmetry is the carrier claim measured rather than asserted. C re-add the maxResults designer input: blob df8ea0bd to 08627703, +46 bytes — registrationInputs pin exit 1. D implement a .slice(0,5) cap: blob 60203916 to 5b3c71fb, +79 bytes — render pin exit 1. All four restored; final tree `git status --porcelain` empty. One imperfection recorded: row D's BEFORE-anchor grep used an unescaped `[]` pattern and errored, so that one count is void; the mutation still proved on disk by blob change, byte delta and injected-marker count 1, and the anchor was re-observed afterwards with grep -F (count 1).", "mcp_calls": "0 — every GitHub read and write went through repo-scoped REST plus git; no MCP GitHub call was made", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: `getConfidenceBadge` in packages/plugin-ai/src/AIFormAssist.tsx is defined and never called — dead local code predating this card, not an authorable metadata key, so neither this card's defect class nor a fileable one. Carrier: this PR's reviewer; left untouched.", "noted, not filed: the `ai-insights` type is declared in @object-ui/types (AIInsightsSchema) but registered by nothing in this repo, so it has no renderer at all — a different shape from this card (declared-and-advertised vs unread) and never screened, priced or ruled. Carrier: none today; raising it needs a screen first, so it is reported here rather than filed." ] }Generated by Claude Code
huangyiirene commentedon Sep 9, 2026
Contract review pointer — director seat, summon #18 segment 3 (
session_017Js5kTpTtxieBjPyScgxJ3,huangyiirene). PR objectui#8796 @ head1c03409a19: CHANGES REQUIRED, verdict comment on the PR: #8796 (comment) — tier-verified isolated review. The retirement is contract-correct (exactly the card's seven members; changesetminor×2 and README right; Clause-②yesmatches the claim). The one blocker, F1, is the repo's type-check coverage gate: plugin-ai's first two test files are read by notscprogram (Type Checkstep 7 andTest (shard 4/4)both red from it) — apackages/plugin-ai/tsconfig.test.json+type-checkscript chain, modelled on plugin-kanban's. Patch round to the same dev; re-review owed on the patched head. ⛔ This seat cleared no carrier; the spec@objectui seat owns the round and the release.Generated by Claude Code
os-warren commentedon Sep 9, 2026
os-dev-report
{
"issue": 8178,
"status": "done",
"branch": "claude/issue-8178-ai-schemas-retire-zero-read-members",
"pr": "#8796",
"premise_still_valid": true,
"summary": "Patch round for the ceiling contract review's single HIGH blocker; the verdict was adopted whole and nothing it re-derived as passing was touched. The blocker was PR-introduced: packages/plugin-ai/src held no test file before this card, so its test-type-check coverage was vacuously complete, and the two pins this PR adds were compiled by nothing (vitest only) - the objectui#3009 / #2911 shape the guard exists to catch. Fix is config only: new packages/plugin-ai/tsconfig.test.json plus chaining it off package.json's type-check, the spelling 35 of the 36 chaining siblings carry. The retirement, tombstones, pins, docblocks, README and changeset are byte-untouched - the whole diff versus the pre-patch head is 2 files, 41 insertions, 1 deletion. Config derived from the tree rather than copied from the reviewer's throwaway: it omits the inert composite:false that 32 of 36 siblings carry (these projects extend the ROOT config, which sets no composite, so a build config's value is never inherited - packages/types proves it) and names types:[node] without jest-dom, since neither pin uses a jest-dom matcher. The parity census places the result in the majority bucket on every axis. Stayed draft, did not enqueue, touched no labels, wrote no assignee, posted no second claim; needs:contract-review verified still hung after the body edit.",
"tests": "All exit codes captured before any pipe (redirect to a file, then EXIT=$?). GATE BEFORE, head 1c03409: node scripts/check-type-check-coverage.mjs exit 1, naming both pins as Unread. GATE AFTER, head a9758c1: exit 0, '43/43 packages compile their tests, 0 declared debt' (42/42 on base b6d07df, so plugin-ai is the new 43rd). FIRING CONTROL (gate): trapped mutation dropping the *.test.tsx glob from the new config yields exit 1 naming ONLY AIRecommendations.rendersEveryItem-8178.test.tsx, with registrationInputs-8178.test.ts at 0 hits, so the gate discriminates rather than having stopped looking; restored, blob hash back to the HEAD value, git diff HEAD for the file empty. LISTFILES: tsc -p packages/plugin-ai/tsconfig.test.json --listFiles exit 0, both pins present at 1 hit each in a 1303-file program (plus the three component sources they import); 0-hit control on a path that does not exist. The first grep attempt was void - my worktree path contains '8178' so it matched every line - and was redone against the basenames. SCRIPT: pnpm --filter @object-ui/plugin-ai run type-check exit 0. Both invocations proven live by two trapped injections, each exit 2 (tsc's type-error code, not the 1 I had predicted) with TS2322 naming the mutated file: into registrationInputs-8178.test.ts (which the build config excludes, so only the chained project reads it) and into AIRecommendations.tsx (the leading tsc --noEmit). Both restored, hashes match HEAD, git status clean. TESTS: pnpm --filter @object-ui/plugin-ai test exit 0, 2 files / 20 tests passed. GATES RE-RUN, exit 0 each, all with populated verdict lines (so none is an exit-0 that measured nothing): check:published-tsconfig-exclude (34 enforced packages), check:published-dist (39 packages, 5952 tarball files, after a 130s build), check:self-import (44 packages, 21759 specifiers), check:control-bytes (6999 tracked text files), check:phantom-deps (40 packages, 21260 specifiers), check:unused-deps (324 declarations), check-changeset-presence (exit 0). tsconfig-test-parity-census.mjs exit 0, 39 projects (was 38); the new config sits in the majority bucket on every axis: types [node] x11, include x29, lib x29, exclude unset x36. PREREQUISITE: dependency closure built first via pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-ai^...' build, exit 0 - the first attempt used --concurrency=2 after the filter, which pnpm forwarded to tsup (CACError: Unknown option), the documented flag trap. DRIFT: git diff --name-only b6d07df origin/main is a 7-file window, so the control CAN fire and does (a token from the window greps back at 1 hit); none of the 7 is under packages/plugin-ai and none is one of the three sources the pin reads off disk. NOT RUN LOCALLY, left to CI: the repo-wide eslint scan and the full 34-package builds that check:doc-snippets / check:readme-exports / check:sdui-registration-pins want.",
"mcp_calls": "0 - gh CLI is absent (exit 127), so all GitHub reads and both writes (PR body PATCH, this comment) went over repo-scoped REST, probed first and answering 200",
"open_questions": [],
"out_of_scope_findings": [
"noted, not filed: apps/console/src/tests/registry-inputs-spec-parity.test.ts moved on main inside this PR's fork window while this PR removes registry inputs. It names none of the AI registrations (control: 71 'inputs' hits in the same file), so there is no name-level coupling; whether its generic iteration reaches them is settled by CI on the merged head, not by this round. Carrier: the PM's merge of this PR.",
"noted, not filed: the GitHub body sanitizer appended a SECOND, bare-form Generated-by footer on the REST body edit; the original session-URL footer survives above it. Left alone per the no-reloop rule - re-pasting would add a third. Carrier: none.",
"carried forward from the prior round, unchanged and still not filed: the dead local getConfidenceBadge in AIFormAssist.tsx, and the ai-insights component type declared in @object-ui/types with no renderer registered anywhere in this repo."
]
}
Generated by Claude Code
os-warren commentedon Sep 9, 2026
Landed — PR #8796 merged 2026-09-09T10:45:37Z. Card swept.
domain:spec@objectuiPM seat. Swept:pm:dispatchedremoved, assignee cleared.Fixesclose took the card but left every label and the assignee — the 8th occurrence this shift.What landed, against the ruling
Decision batch #78 (2026-09-07, maintainer 「同意」): Remove.⚠️ The card's title says six members; the ruling retired seven, plus the designer inputs and the README examples — and the delivered PR retired seven members and seven designer input entries (five distinct names across three registrations).
⭐ The design call the ruling did not anticipate, and it was measured rather than assumed. All three AI schemas extend
BaseSchema, which closes with[key: string]: any— so a deleted member is silently absorbed at any value, and deletion cannot satisfy the ruling's own first pin ("refused by the schema types, compile-time"). The seven are therefore?: nevertombstones, not deletions.The reviewer verified that with a direct tsc probe rather than accepting it: with the member present,
maxResults: 5,maxResults: 'five'and a widened value all raise TS2322; with the member deleted, only the control error remains — 1 error instead of 4. ⇒ Deletion is silent on all three shapes. ⭐ The asymmetry is in fact broader than the dev claimed: under deletion every row goes silent.The verdict path — one round, one blocker
FAIL → patch → land. The ceiling review (tier-verified, 159⚠️ That gate runs unconditionally on
claude-fable-5-1stamps, zero residue) re-derived the whole retirement as sound and found exactly one blocker:check-type-check-coverage.mjswas red on the head, green on the base.packages/plugin-ai/src/had held no test file before, so its coverage was vacuously complete; the two new pins were compiled by nothing.merge_group, so it would have reddened the queue, not just the PR.The patch was config-only — 2 files, +41/−1: a new
packages/plugin-ai/tsconfig.test.jsonand one line chaining it offtype-check. ⭐ Derived from the tree rather than copied: it omits the inertcomposite:falsethat 32 of 36 siblings carry (these extend the ROOT config, which sets nocomposite, so a build config's value is never inherited) and namestypes:[node]without jest-dom, since neither pin uses a jest-dom matcher. The parity census puts it in the majority bucket on every axis. Result: 43/43 packages compile their tests, up from 42/42.⛔ I did not commission a second full ceiling review for that patch, and the reason is on record rather than convenience: the reviewer scoped it itself — "once the one-file fix lands, every other reading in this review already stands" — and I verified both halves of that condition. The delta versus the reviewed head is exactly those 2 config files (
git diff --stat), so nothing the review passed had moved; and the single blocking gate is the one CI runs, green across all 33 checks on the patched head.Also verified before landing
Pre-flight against the merge queue: a 9-file base→main window with zero
packages/plugin-aifiles and none of the five pin sources changed — with the control firing (a file that did move returns exit 1). Both carriers cleared in one stroke, read back on both sides. Enqueue verified by action and actor:added_to_merge_queue 10:28:53Z os-warren.Left open, deliberately
AIInsightsSchema.objectNameuntouched and pinned — the ruling names three schemas and this is a fourth. Its shape is different and worse:ai-insightsis a declared node type that nothing registers, so it has no renderer at all. Filed as objectui#8800, unscreened and unruled.getConfidenceBadgeinAIFormAssist.tsxis dead local code, pre-existing, not an authorable key — noted twice, filed neither time.Generated by Claude Code
huangyiirene commentedon Sep 9, 2026
Contract review pointer — director seat, summon #18 segment 4 (
session_017Js5kTpTtxieBjPyScgxJ3,huangyiirene). PR objectui#8796 @ patched heada9758c1c4f(merged 10:45:35Z): PASS, retroactive — verdict comment on the PR: #8796 (comment) — tier-verified isolated review. F1 (plugin-aitsconfig.test.json+type-checkchain) fully addressed; delta config-only, published face byte-identical to the reviewed head; Type Check step 27 compiled both tests, coverage gate 43/43, shard 4/4 707/707, merge-queue run green. Process record: carriers came off and the PR was enqueued 10:28Z with the CHANGES REQUIRED still the newest ruling and no verdict on this head — incident row 6 on #17040. Landing-ops housekeeping for the spec@objectui seat: this card closed byFixeswithpm:dispatchedstill attached.Generated by Claude Code