Found by the os-dev seat implementing objectui#9370 (PR #9378), while enumerating rather than inferring: the card's census named three files, and re-measurement against origin/main 69aa9c017 turned up a fourth carrying the same retired claim in its own words.
⛔ Not addressed in PR #9378 because PR #9374 holds this file (.changeset/9350-auth-permissions-useauth-guard-both.md + skills/objectui/guides/auth-permissions.md), so an in-place edit would collide with a live claim.
What is false
The maintainer ruling of 2026-09-13 on objectui#9308 (option B, landing in PR #9369) stops SchemaRenderer publishing the injected DataSource adapter as the expression root data, and stops useDataScope walking that adapter. skills/objectui/guides/auth-permissions.md still teaches both halves. Measured on origin/main 69aa9c017:
| line |
text |
why it is now false |
| 279 |
"derive permission flags in the dataSource object" |
the dataSource object publishes no expression root |
| 310 |
a scope-table row: data comes from "the dataSource passed to SchemaRendererProvider" |
data is a root only if the HOST published one |
| 317 |
"With no host scope mounted, data and page are all you get" |
with no host scope mounted, data is exactly what you do NOT get |
| 319 |
"Keys of the dataSource object are reachable only under the data. root" |
they are reachable under no root at all |
Why it is worse than a stale sentence
Lines 319-327 are a trap paragraph, and the trap it warns about is now the OUTCOME of following its own advice. It tells the reader that writing ${!canDeleteContacts} instead of ${!data.canDeleteContacts} fails silently and hides the button for every user. After the ruling, the spelling it RECOMMENDS fails too — and differently, which is the part a reader cannot guess. Measured by me on the built evaluator (packages/core/dist, tree 69aa9c017), over ${data.status == 'draft'}:
| scope |
evaluateExpression |
evaluateCondition |
{ data: {} } — adapter-shaped |
false |
false |
{ data: undefined } |
false |
false |
{} — no data root |
returns the raw source text, logs data is not defined |
true |
So the hidden gate at line 300 (${!data.canDeleteContacts}) used to be permanently true by the paragraph's own argument, and is now true for a second, unrelated reason — the root is gone, the condition path fail-softs, and objectui#5454's reporter warns. The page's promise that the data. spelling is the safe one no longer holds.
Suggested shape
The same one PR #9369 used for content/docs/guide/schema-rendering.md and packages/react/README.md, and PR #9378 for the other three skill files: publish the host values under real names through PredicateScopeProvider, read them by those names, and state that dataSource is the adapter and not a root. The scope table at 304-317 needs a record row as well — ADR-0089 D3 makes record the runtime-layer row root.
⚠️ Sequencing: PR #9374 first (it holds the file), then this.
⚠️ Governed surface (skills/**, GOVERNED_SURFACES skills-catalog): an agent drafts, a human merges. ⛔ No ready-flip, no queue, no auto-merge. Likely clause-② as well, on the same limb that put objectui#9311 and objectui#9370 through contract review.
Dedup
Run over the 83 cards this repository's issue-list endpoint returns for labels=domain:skills&state=all (the query includes non-open cards), with objectui#9370 as the known-hit control — the control was found, so the zero is a reading. Nearest neighbours are all different teachings: objectui#9350 is the useAuth guard in the same file (PR #9374), objectui#8393 was the retired user.roles, and objectui#8810 was the app root in two other guides.
⛔ Filed without labels — routing and priority are the PM seat's.
Generated by Claude Code
Found by the
os-devseat implementing objectui#9370 (PR #9378), while enumerating rather than inferring: the card's census named three files, and re-measurement againstorigin/main69aa9c017turned up a fourth carrying the same retired claim in its own words.⛔ Not addressed in PR #9378 because PR #9374 holds this file (
.changeset/9350-auth-permissions-useauth-guard-both.md+skills/objectui/guides/auth-permissions.md), so an in-place edit would collide with a live claim.What is false
The maintainer ruling of 2026-09-13 on objectui#9308 (option B, landing in PR #9369) stops
SchemaRendererpublishing the injectedDataSourceadapter as the expression rootdata, and stopsuseDataScopewalking that adapter.skills/objectui/guides/auth-permissions.mdstill teaches both halves. Measured onorigin/main69aa9c017:dataSourceobject publishes no expression rootdatacomes from "thedataSourcepassed toSchemaRendererProvider"datais a root only if the HOST published onedataandpageare all you get"datais exactly what you do NOT getdataSourceobject are reachable only under thedata.root"Why it is worse than a stale sentence
Lines 319-327 are a trap paragraph, and the trap it warns about is now the OUTCOME of following its own advice. It tells the reader that writing
${!canDeleteContacts}instead of${!data.canDeleteContacts}fails silently and hides the button for every user. After the ruling, the spelling it RECOMMENDS fails too — and differently, which is the part a reader cannot guess. Measured by me on the built evaluator (packages/core/dist, tree69aa9c017), over${data.status == 'draft'}:evaluateExpressionevaluateCondition{ data: {} }— adapter-shapedfalsefalse{ data: undefined }falsefalse{}— nodatarootdata is not definedtrueSo the
hiddengate at line 300 (${!data.canDeleteContacts}) used to be permanentlytrueby the paragraph's own argument, and is nowtruefor a second, unrelated reason — the root is gone, the condition path fail-softs, and objectui#5454's reporter warns. The page's promise that thedata.spelling is the safe one no longer holds.Suggested shape
The same one PR #9369 used for
content/docs/guide/schema-rendering.mdandpackages/react/README.md, and PR #9378 for the other three skill files: publish the host values under real names throughPredicateScopeProvider, read them by those names, and state thatdataSourceis the adapter and not a root. The scope table at 304-317 needs arecordrow as well — ADR-0089 D3 makesrecordthe runtime-layer row root.skills/**,GOVERNED_SURFACESskills-catalog): an agent drafts, a human merges. ⛔ No ready-flip, no queue, no auto-merge. Likely clause-② as well, on the same limb that put objectui#9311 and objectui#9370 through contract review.Dedup
Run over the 83 cards this repository's issue-list endpoint returns for
labels=domain:skills&state=all(the query includes non-open cards), with objectui#9370 as the known-hit control — the control was found, so the zero is a reading. Nearest neighbours are all different teachings: objectui#9350 is theuseAuthguard in the same file (PR #9374), objectui#8393 was the retireduser.roles, and objectui#8810 was theapproot in two other guides.⛔ Filed without labels — routing and priority are the PM seat's.
Generated by Claude Code