Uh oh!
There was an error while loading. Please reload this page.
docs(kernel): teach the dot-qualified view item name in metadata-service.mdx - #13133
Merged
Merged
Conversation
`metadata-service.mdx` taught `account_list` as a view name at four sites —
the `get('view', ...)` read, both `saveOverlay` `baseName`s, and the
`getEffective(...)` resolve. A view row written as a standalone ViewItem
record is governed by `ViewItemNameSchema`, which pins identity on
`QUALIFIED_ITEM_NAME_PATTERN` (dot REQUIRED), so a reader following the page
gets a schema rejection naming the very field the page told them to fill.
The replacement name is derived, not invented: `expandViewContainer('account',
{ list, form })` emits `account.default` + `account.form`, which is what the
in-tree fixtures carry. All four sites move together — they address one
logical row, so moving two would leave the page overlaying a row it does not
read back.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4
This was referenced Aug 29, 2026
os-trump
marked this pull request as ready for review
August 29, 2026 06:03
os-trump
enabled auto-merge
August 29, 2026 06:03
Contributor
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 33238180927 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
跨 PR 相同签名(24h,按失败测试文件聚合):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
github-merge-queueBot
removed this pull request from the merge queue due to failed status checks
Aug 29, 2026
Uh oh!
There was an error while loading. Please reload this page.
os-trump
commented
Aug 29, 2026
CollaboratorAuthor
Queue ejection triaged (domain:spec seat,
Generated by Claude Code |
This was referenced Aug 29, 2026
Merged
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 29, 2026
Merged
This was referenced Aug 29, 2026
This was referenced Aug 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#12384
Branch 2 of the maintainer ruling (comment 5459698917, verbatim 「同意」), executed after the census it made a precondition.
The ruling
ViewItemNameSchemais untouched, as the dispatch requires on every branch.Census — method
A window scan, then hand adjudication. A view item row is the shape
{ name, object, viewKind, config }(ViewItemSchema/ViewItemWireSchema, ADR-0017 §3.1), so the discriminatorviewKindis the anchor: for every occurrence ofviewKindin a tracked file, the plus/minus 8 lines around it were harvested for everyname:string literal, plus the explicit authoring door (defineViewItem). CHANGELOGs, the strictness-ledger audit and release notes were excluded as narrative rather than stored rows. The net over-collects deliberately — every hit was then read and adjudicated.Result: 90 distinct names, 37 dot-qualified, 51 flat, 2 neither.
Positive control:
crm_lead.pipelinewas FOUND by the same scan (20 sites) — a zero-hit scan would not have been a reading.Census — adjudication
The 51 flat names are not counter-examples. Read individually they fall into four classes, none of them a flat-named view item:
crm_lead,crm_case,crm_task,iojn_customer), field names (name,amount,count), app/package names (sales,crm,Repair), a dashboard (sales_overview), hooks and services (probe_hook,probe_item,whatever), a locale (zh_cn). Caught by the wide net, discarded on reading.broken(config: null, whose own test comment says it "matches noViewMetadataSchemamember"),mystery(noviewKind, no container slot — the walker must not invent a view),garbage_view(theview的 spec 校验闸门形同虚设:saveMetaItem({ item: { nope: 1 } })返回 success 并把{"nope":1}存成一个 active view #5599 write-path probe),x,qa_dead_view.saveMetaItem({ type: 'view', name: 'crm_lead', item: leadContainer }). Flat by design: ADR-0017's dual-read registers the aggregated container under the bare object key for backward-compatible reads.case_grid,cases,shared_grid,org_grid,overdue_grid,myapp_case_grid. Bodies of the form{ name, type: 'grid', columns, object, viewKind }— a raw ListView config at the top level plus its binding.Every name on a genuine ViewItem record is dot-qualified:
crm_lead.all,crm_lead.pipeline,crm_lead.edit,crm_lead.mine,crm_lead.tasks,crm_lead.hot,crm_lead.intake,crm_lead.all_leads,crm_lead.default,crm_account.pipeline,crm_account.custom,crm_account.edit,crm_case.pipeline,crm_case.mine,crm_case.custom,crm_case.edit,account.default,account.form,account.hot,account.junk,showcase_task.default,showcase_task.open,showcase_task.all,showcase_task.in_progress,lead.contact,lead.contact_us,lead.list,expense.all,iojn_repair_ticket.all,adhoc.view,other_object.all_accounts,o.default,a.b, and the seedPLACEHOLDER_OBJECT.new_view.One fixture is worth naming:
packages/spec/src/conversions/view-spelling-walk.test.ts:429carries{ name: 'clean', object: 'crm_lead', viewKind: 'list', config: {...} }— record-shaped with a flat name. It is a copy-on-write identity probe for the conversion walker and never reaches the parse door, so it is not a live row; noted as fixture hygiene, not fixed here.Why this is branch 2 and not branch 3
Branch 3 fires on a live flat-named row that constitutes a published-contract conflict. Measured against the built schema (
packages/spec/dist, not read off source), the flat-named rows that do exist parse clean — so they are not a conflict and no narrowing is implied:This is the answer to the card's title question. A stored view row's name is governed by the body's spelling, not by one grammar:
namedeclared asViewItemNameSchema(dot REQUIRED)z.string().optional()— no grammarSo
ViewItemNameSchemais not too tight, and the docs were not describing a legal-but-undocumented spelling: the page taught a name that the canonical authoring path never produces.The change
Four sites, one file, all addressing the same logical row. Moving only the two the card named would have left the page overlaying a row it does not read back, so all four move together (same defect, same page, same pass).
The replacement name is derived, not invented. The page's object is
account(the next line readslistViews('account')).expandViewContainer('account', { list, form })emitsaccount.defaultandaccount.form—packages/spec/src/ui/assembled-views.test.tsstates it in its own fixture comment ("a default list and a default form → expands toaccount.default+account.form"), andaccount.defaultappears in-tree atassembled-views.test.ts:66/:145andengine-nested-plugin-view-expansion.test.ts:255.Left alone deliberately:
listViews('account')(an object name, correct) andget('dashboard', 'sales_overview')(typedashboard, governed byMETADATA_ITEM_NAME_PATTERN, where the qualifier is optional — flat is legal).Other pages
None found. Sweeping
content/docs/for view-name teaching outside this page turns up one sibling site,content/docs/api/client-sdk.mdx:225, which already teaches the dot-qualified form (getItem('view', 'crm_lead.pipeline')).metadata-service.mdxwas the only page carrying the defect.Verification
Gate family derived from the real diff by
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack(no paths passed — the script takes its own change set from the merge base), which matched 25 families and printed "Once a changeset exists, 9 more families apply — write one unless this card is docs-only".Union re-run after the final commit, at
d6e72f149: 25 pass, 1 not-measured. Exit codes captured before any pipe. Verdict lines quoted from the gates themselves:Three of these (
check:skill-examples,check:doc-formula-expressions,check:doc-security-posture) first returnedPREREQUISITE NOT METbecause@objectstack/client-react,@objectstack/formulaand@objectstack/lintwere unbuilt. Those gates say so themselves — "Nothing was measured: this gate exited before running a single check" — so they were NOT recorded as failures; the three packages were built and the gates re-run, and the readings above are from the real run.The one non-pass is
scripts/check-test-completeness.mjs, which printed a usage line demanding a TURBO_TEST_LOG positional argument. It is a CI-invoked gate needing a turbo test log argument; run bare it measures nothing. Recorded as NOT MEASURED, not as a failure.No typecheck leg is owed — the diff is four prose lines in one
.mdxfile and touches no TypeScript program. No ablation is owed — there is no guard to delete and no runtime behaviour to mutate; the change is documentation prose.No changeset. The changeset gate is path-blind (zero changesets plus no
skip-changesetlabel is red), so this is a label decision, not an omission:apps/docsis"private": trueand no package manifest listscontent/docs, so this diff publishes nothing from any package. Precedent agrees — the five docs-only commits in the last 300 onmaineach landed with no changeset. Theskip-changesetlabel is applied to this PR.Generated by Claude Code