Skip to content

refactor(spec)!: retire pass-through-only list-view keys striped/bordered/virtualScroll (ADR-0049, #7176) - #8252

Merged
huangyiirene merged 5 commits into
mainfrom
claude/issue-7176-retire-list-passthrough-keys
Aug 13, 2026
Merged

refactor(spec)!: retire pass-through-only list-view keys striped/bordered/virtualScroll (ADR-0049, #7176)#8252
huangyiirene merged 5 commits into
mainfrom
claude/issue-7176-retire-list-passthrough-keys

Conversation

@huangyiirene

Copy link
Copy Markdown
Collaborator

Fixes#7176

Retires list.striped / list.bordered / list.virtualScroll from the view.json list face under ADR-0049 enforce-or-remove, executing the maintainer ruling of 2026-08-10 (issue comment 5236139723): every measured reader copies the key forward and none applies it — copy-without-apply is dead in effect. Per the ruling, if objectui wants any of the three as real behavior, that is an implementation card filed first, and the key stays retired pending it.

Note for the PM:#7132 closes as absorbed when this lands (its three remaining citation-repair rows are these keys; the ledger rows now carry the retirement verdict).

Route: retiredKey() tombstones — the playbook fork, justified

All three are parseable authorable keys on a live schema face today, so plain deletion would trade one silent no-op for another. ListViewSchema already carries the #3896responsive/performance tombstones, so retiredKey() on this exact face is the proven house route: the key stays declared (the strict container does not report it as unknown), tsc types it never, and the parse rejects any authored value with the prescription itself — why the key never did anything, the one-line fix, and the pinned os migrate meta --from 16 sentence.

The kit

  • Schema (packages/spec/src/ui/view.zod.ts): three tombstones beside the POST /data/sharing/rules 绕过 SharingRuleSchema:criteria 缺失或拼错静默变成"共享该对象全部记录",与 ADR-0049 "never seeded as a permissive match-all" 直接冲突 #3896 pair, with the in-schema comment naming the measured forwarding chains. The tombstones radiate into ObjectListViewSchema (an .omit().extend() copy), so the authorable surface moves by exactly six [RETIRED] marks — ui/ListView:* and ui/ObjectListView:* — each registered per key in RETIRED_KEYS_BY_MAJOR[17] via six entry files under migrations/entries/retired-keys/.
  • ADR-0087 D2 + D3: conversion view-list-passthrough-keys-removed (toMajor: 17, retiredFromLoadPath: true) strips the keys from list and named listViews slots via the shared stripKeys walker (idempotent by construction); wired into MIGRATIONS_BY_MAJOR[17].conversionIds with the step rationale extended. Fixture is disjoint from every other entry's keys and passes the live-window load path untouched.
  • Liveness ledger (liveness/view.json): the three rows flip livedead with the house REMOVED note — the live grade was the card's finding (pass-through citations); the rows stay because retiredKey keeps the keys in the walked shape (the rls.priority precedent). state-counts.md regenerated.
  • Forms: view.form.ts loses the striped/bordered inputs (the UI half of false compliance); virtualScroll never had one. i18n bundles regenerated in merge mode (4 metadata-forms files).
  • Advisory lint: ledger-driven, so it stays silent by itself; packages/lint/src/lint-liveness-properties.test.ts now pins the non-warn for all three (the strict parse owns them).
  • Pin tests (view.test.ts): per-key negative asserting the prescription substance, a shared pin on #7176 + the pinned migrate sentence, byte-identical acceptance of the live siblings (resizable/rowHeight/selection/pagination compared with toStrictEqual), a no-resurrection positive, and an ObjectListViewSchema rejection pin.
  • Docs: content/docs/protocol/objectui/widget-contract.mdx's Performance section stops pointing authors at view.virtualScroll — that pointer was installed this same unreleased major (the widget-contract-performanceconfig changeset) and aimed at a switch nothing read. content/docs/references/ui/view.mdx regenerated with the [REMOVED] rows. content/docs/releases/ untouched.
  • Changeset: @objectstack/spec major with the FROM → TO table and the retirement kit; carries the marker adr-0087: registered view-list-passthrough-keys-removed.

Census (in-repo authored usage)

Near-zero, as the card predicted (no appliers measured, and almost no authors): zero authored usages in examples/**, apps/**, platform fixtures and skills. The only spellings found were four view.test.ts fixtures — re-judged individually per the triage discipline: the "grid features" fixture pinned partly the deleted limb (re-shaped onto surviving keys resizable/compactToolbar); three real-world fixtures merely spelled the keys (re-spelled without them). packages/lint/src/validate-react-page-props.test.ts's striped={true} fixture is untouched on purpose — it tests a NON-contract React prop with no near match, and the keys were never in the react-blocks contract (verified: zero hits in react-blocks.contract.json before and after).

Different surfaces deliberately not touched: dashboard.widgets[].options.striped (an open renderer bag, its own contract), ui/PageCardProps:bordered (live page-card key), DetailSection's virtualScroll component prop (objectui-internal VirtualScrollOptions).

Verification (all local, exit codes captured)

  • @objectstack/spec suite: 387 files / 10203 tests — one first-run failure was this PR's own new pin test (regex casing vs the prescription), fixed; view.test.ts re-run 245/245, pnpm typecheck clean.
  • check:generated 13/13 up to date; retirement loop all PASS: check:liveness, check:empty-state, check:authorable-surface, check:docs, check:api-surface, check:spec-changes, check:upgrade-guide, check:skill-refs, check:skill-docs, check:skill-examples, check:migration-registry; the seven not-run source audits run as one group: check:template-manifests, check:variant-docs, check:exported-any, check:dual-source-exports, check:scripts-typecheck all PASS.
  • Gate farm: check:adr-anchors, check:changeset-gate-self-tests, check:cross-package-test-inputs, check:docs-audit-scope, check:i18n, check:merge-driver, check:release-body, check:spec-parsed-alias, check:nul-bytes, check:adr-0087-registration all PASS; check:doc-formula-expressions lives in packages/lint (not the repo root the dispatch assumed) and PASSES there.
  • Consumer smoke (downstream direction — consumers of @objectstack/spec): metadata-protocol 75 files / 1100 tests PASS; rest 105 files / 1756 tests PASS; dogfood 103 files / 716 passed, 3 skipped; CLI migrate-meta.e2e 12/12 (chain replay + idempotence); examples validate ×3 (app-crm / app-showcase / app-todo) all PASS; @objectstack/lint tests + typecheck PASS.
  • Reverse verification (direction predicted RED before running): a probe assigning striped: true to a ListView-typed literal against the rebuilt dist/*.d.ts fails tsc (Type 'true' is not assignable to type 'undefined'); the sibling control probe with resizable: true compiles clean against the same dist — proving the narrowing is in the rebuilt declarations, not a cached copy. The parse-channel red is pinned by the new tests.

Ratchet visibility (route-appropriate readings)

authorable-surface/ui.json moves by exactly the six [RETIRED] marks; api-surface/ is byte-identical (key-level narrowing is invisible to a reference-printing snapshot — the expected reading for the tombstone route, no orphaned value schema exists here since all three keys are bare booleans); json-schema.manifest/ unchanged (no def added or removed). One PM mechanism assumption partially falsified: gen:schema no longer rewrites authorable-surface.base.json as a side effect — since #5358 it reports anchor/baseline divergence as an informational line and re-anchoring is its own deliberate command; nothing needed reverting, and check:authorable-surface is green with the lagging baseRev.

Cross-repo residue (report only, no objectui edits)

objectui's packages/components/metadata/ObjectGrid.component.yml:45,49 still declaresstriped/bordered with defaults — a declaration its implementation never reads (already noted in #7132). For the objectui seat to prune; nothing in this PR touches that repo.

Out-of-scope finding

Filed #8251: layout-dsl.mdx teaches section-level virtualScroll/itemHeight/lazy/renderStrategy keys that exist on no schema (flagged in the 2026-06 docs-accuracy audit followups but never filed).


Generated by Claude Code

…ered/virtualScroll (ADR-0049, #7176)
Maintainer ruling 2026-08-10: every measured reader copies the key forward
and ObjectGrid, where the chains end, never applies any of the three —
copy-without-apply is dead in effect. retiredKey() tombstones on
ListViewSchema (radiating into ObjectListViewSchema), ADR-0087 D2 conversion
view-list-passthrough-keys-removed + D3 chain step + six
RETIRED_KEYS_BY_MAJOR[17] entries, ledger rows flipped to dead with the
retirement note, form inputs pruned, docs updated, changeset with FROM->TO.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0123k4cam2jEAkPmbJeoaY3r
@vercel

vercelBot commented Aug 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 13, 2026 3:07am

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/spec.

106 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/agents.mdx(via @objectstack/spec)
  • content/docs/ai/skills-reference.mdx(via @objectstack/spec)
  • content/docs/ai/skills.mdx(via @objectstack/spec)
  • content/docs/api/client-sdk.mdx(via @objectstack/spec)
  • content/docs/api/environment-routing.mdx(via @objectstack/spec)
  • content/docs/api/error-catalog.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-client.mdx(via @objectstack/spec)
  • content/docs/api/error-handling-server.mdx(via @objectstack/spec)
  • content/docs/api/index.mdx(via @objectstack/spec)
  • content/docs/automation/approvals.mdx(via @objectstack/spec)
  • content/docs/automation/connectors.mdx(via @objectstack/spec)
  • content/docs/automation/flows.mdx(via @objectstack/spec)
  • content/docs/automation/hook-bodies.mdx(via packages/spec)
  • content/docs/automation/hooks.mdx(via @objectstack/spec)
  • content/docs/automation/index.mdx(via @objectstack/spec)
  • content/docs/automation/webhooks.mdx(via @objectstack/spec)
  • content/docs/automation/workflows.mdx(via @objectstack/spec)
  • content/docs/concepts/architecture.mdx(via @objectstack/spec)
  • content/docs/concepts/design-principles.mdx(via packages/spec)
  • content/docs/concepts/index.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-driven.mdx(via @objectstack/spec)
  • content/docs/concepts/metadata-lifecycle.mdx(via packages/spec)
  • content/docs/concepts/north-star.mdx(via @objectstack/spec)
  • content/docs/data-modeling/analytics.mdx(via @objectstack/spec)
  • content/docs/data-modeling/drivers.mdx(via @objectstack/spec)
  • content/docs/data-modeling/external-datasources.mdx(via @objectstack/spec)
  • content/docs/data-modeling/field-types.mdx(via @objectstack/spec)
  • content/docs/data-modeling/fields.mdx(via @objectstack/spec)
  • content/docs/data-modeling/formulas.mdx(via @objectstack/spec)
  • content/docs/data-modeling/index.mdx(via @objectstack/spec)
  • content/docs/data-modeling/objects.mdx(via @objectstack/spec)
  • content/docs/data-modeling/queries.mdx(via @objectstack/spec)
  • content/docs/data-modeling/schema-design.mdx(via @objectstack/spec)
  • content/docs/data-modeling/seed-data.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation-rules.mdx(via @objectstack/spec)
  • content/docs/data-modeling/validation.mdx(via @objectstack/spec)
  • content/docs/deployment/cli.mdx(via @objectstack/spec)
  • content/docs/deployment/tenancy-modes.mdx(via @objectstack/spec)
  • content/docs/deployment/troubleshooting.mdx(via @objectstack/spec)
  • content/docs/deployment/validating-metadata.mdx(via @objectstack/spec)
  • content/docs/getting-started/build-with-claude-code.mdx(via @objectstack/spec)
  • content/docs/getting-started/common-patterns.mdx(via @objectstack/spec)
  • content/docs/getting-started/examples.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-reference.mdx(via @objectstack/spec)
  • content/docs/getting-started/quick-start.mdx(via @objectstack/spec)
  • content/docs/getting-started/your-first-project.mdx(via @objectstack/spec)
  • content/docs/kernel/cluster.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/auth-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/cache-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/index.mdx(via @objectstack/spec)
  • content/docs/kernel/contracts/metadata-service.mdx(via packages/spec)
  • content/docs/kernel/contracts/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/data-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/email-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/examples.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/index.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/queue-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/sharing-service.mdx(via @objectstack/spec)
  • content/docs/kernel/runtime-services/sms-service.mdx(via packages/spec)
  • content/docs/kernel/runtime-services/storage-service.mdx(via @objectstack/spec)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/spec)
  • content/docs/kernel/services.mdx(via @objectstack/spec)
  • content/docs/permissions/authorization.mdx(via @objectstack/spec)
  • content/docs/permissions/permission-sets.mdx(via @objectstack/spec)
  • content/docs/permissions/permissions-matrix.mdx(via @objectstack/spec)
  • content/docs/permissions/positions.mdx(via @objectstack/spec)
  • content/docs/permissions/rls.mdx(via @objectstack/spec)
  • content/docs/permissions/sharing-rules.mdx(via @objectstack/spec)
  • content/docs/permissions/system-context.mdx(via packages/spec)
  • content/docs/plugins/adding-a-metadata-type.mdx(via @objectstack/spec)
  • content/docs/plugins/development.mdx(via @objectstack/spec)
  • content/docs/plugins/index.mdx(via @objectstack/spec)
  • content/docs/plugins/packages.mdx(via @objectstack/platform-objects, @objectstack/spec)
  • content/docs/protocol/backward-compatibility.mdx(via @objectstack/spec)
  • content/docs/protocol/diagram.mdx(via packages/spec)
  • content/docs/protocol/kernel/config-resolution.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/http-protocol.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/i18n-standard.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/lifecycle.mdx(via @objectstack/spec)
  • content/docs/protocol/kernel/plugin-spec.mdx(via @objectstack/spec)
  • content/docs/protocol/knowledge.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/query-syntax.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/schema.mdx(via @objectstack/spec)
  • content/docs/protocol/objectql/security.mdx(via packages/spec)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/actions.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/concept.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/index.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/layout-dsl.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/record-alert.mdx(via @objectstack/spec)
  • content/docs/protocol/objectui/widget-contract.mdx(via @objectstack/spec)
  • content/docs/ui/actions.mdx(via @objectstack/spec)
  • content/docs/ui/apps.mdx(via @objectstack/spec)
  • content/docs/ui/create-vs-edit-form.mdx(via @objectstack/spec)
  • content/docs/ui/dashboards.mdx(via @objectstack/spec)
  • content/docs/ui/field-grouping-and-order.mdx(via @objectstack/spec)
  • content/docs/ui/forms.mdx(via @objectstack/spec)
  • content/docs/ui/index.mdx(via @objectstack/spec)
  • content/docs/ui/public-data-collection.mdx(via @objectstack/spec)
  • content/docs/ui/setup-app.mdx(via @objectstack/platform-objects, @objectstack/spec)
  • content/docs/ui/translations.mdx(via @objectstack/spec)
  • content/docs/ui/views.mdx(via @objectstack/spec)

7 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx(via @objectstack/spec)
  • content/docs/releases/index.mdx(via @objectstack/spec)
  • content/docs/releases/v12.mdx(via @objectstack/spec)
  • content/docs/releases/v13.mdx(via @objectstack/spec)
  • content/docs/releases/v16.mdx(via @objectstack/spec)
  • content/docs/releases/v17.mdx(via @objectstack/spec)
  • content/docs/releases/v9.mdx(via @objectstack/spec)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@huangyiirene
huangyiirene marked this pull request as ready for review August 13, 2026 03:27
@huangyiirene
huangyiirene added this pull request to the merge queueAug 13, 2026
Merged via the queue into main with commit 289d04aAug 13, 2026
27 checks passed
@huangyiirene
huangyiirene deleted the claude/issue-7176-retire-list-passthrough-keys branch August 13, 2026 03:49
os-zhuang pushed a commit that referenced this pull request Aug 13, 2026
…view-level retirement
PR #8252 landed while this branch was open, retiring the pass-through-only
list-view virtualScroll under ADR-0049. The replacement section pointed at
that key as the real switch; it is no longer authorable (zero entries across
the whole authorable surface). Re-pointed at the view's pagination block,
matching the wording widget-contract.mdx now carries.
Refs #8251
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

2 participants

@huangyiirene@claude