Found while extending the react-page adapter-contract guard's population to content/docs
(#10751, PR #11584). Recording the mechanism; not proposing a rush.
What is there
Both surviving repairs of the .records class landed as a tolerant ??/|| alias
rather than as the contract:
examples/app-showcase/src/ui/pages/crm-workbench.page.ts:49
constrows=Array.isArray(all) ? all : (all&&(all.data||all.records))||[];
with a comment three lines above that states the intent outright: "Read .data first,
with .records/array fallbacks for robustness."
content/docs/ui/react-pages.mdx:147
constrecords=result?.data??result?.records??(Array.isArray(result) ? result : []);
Neither is broken at runtime — .data is read first and always wins, so both render
correctly, and this is not a fourth instance of the drop-shaped defect. The swept
corpus is green today.
Why it is worth recording anyway
ObjectStackAdapter.find() resolves a normalized QueryResult that declares data and
never records. The ?? result?.records limb is therefore unreachable by contract —
dead code that teaches a shape the producer cannot emit, sitting in the page a customer
copies from. Consumer-side tolerance is exactly where a wrong shape hides: the next author
who "simplifies" that chain has a 1-in-3 chance of keeping the wrong limb, which is how the
original defect reached three files.
The part that makes it a class rather than two lines
The guard cannot see it, by construction. recordsOnlyReads() (now in
scripts/check-react-page-adapter-contract.mjs) skips any line carrying .data:
if(!trimmed.includes('.records'))continue;if(trimmed.includes('.data'))continue;// <- thisMeasured: that carve-out is load-bearing for exactly one line in the swept corpus today —
crm-workbench.page.ts:49. So it is not an oversight, it is the shape the first repair
chose, and the gate was written to accept it. Tightening the detector without deciding
about that landed fix would turn a file red that a maintainer already signed off, which is
why #10751 did not fold this in.
What needs deciding
- Is
data ?? records an acceptable published pattern, or does contract-first apply here
(the alias goes, and the detector's .data-beside carve-out goes with it)? These stand
or fall together — removing the alias without tightening the detector leaves nothing to
stop its return, and tightening without removing it turns crm-workbench red. - If the alias goes: is
result.data alone right, or does the docs sample keep the
Array.isArray(result) limb? That limb is also unreachable against the current
contract.
Both .data reads are correct today, so nothing is on fire — this is a teaching-surface
and blind-spot question, not a bug report.
Follows #10751.
Generated by Claude Code
Generated by Claude Code
Found while extending the react-page adapter-contract guard's population to
content/docs(#10751, PR #11584). Recording the mechanism; not proposing a rush.
What is there
Both surviving repairs of the
.recordsclass landed as a tolerant??/||aliasrather than as the contract:
examples/app-showcase/src/ui/pages/crm-workbench.page.ts:49with a comment three lines above that states the intent outright: "Read .data first,
with .records/array fallbacks for robustness."
content/docs/ui/react-pages.mdx:147Neither is broken at runtime —
.datais read first and always wins, so both rendercorrectly, and this is not a fourth instance of the drop-shaped defect. The swept
corpus is green today.
Why it is worth recording anyway
ObjectStackAdapter.find()resolves a normalizedQueryResultthat declaresdataandnever
records. The?? result?.recordslimb is therefore unreachable by contract —dead code that teaches a shape the producer cannot emit, sitting in the page a customer
copies from. Consumer-side tolerance is exactly where a wrong shape hides: the next author
who "simplifies" that chain has a 1-in-3 chance of keeping the wrong limb, which is how the
original defect reached three files.
The part that makes it a class rather than two lines
The guard cannot see it, by construction.
recordsOnlyReads()(now inscripts/check-react-page-adapter-contract.mjs) skips any line carrying.data:Measured: that carve-out is load-bearing for exactly one line in the swept corpus today —
crm-workbench.page.ts:49. So it is not an oversight, it is the shape the first repairchose, and the gate was written to accept it. Tightening the detector without deciding
about that landed fix would turn a file red that a maintainer already signed off, which is
why #10751 did not fold this in.
What needs deciding
data ?? recordsan acceptable published pattern, or does contract-first apply here(the alias goes, and the detector's
.data-beside carve-out goes with it)? These standor fall together — removing the alias without tightening the detector leaves nothing to
stop its return, and tightening without removing it turns
crm-workbenchred.result.dataalone right, or does the docs sample keep theArray.isArray(result)limb? That limb is also unreachable against the currentcontract.
Both
.datareads are correct today, so nothing is on fire — this is a teaching-surfaceand blind-spot question, not a bug report.
Follows #10751.
Generated by Claude Code
Generated by Claude Code