Skip to content

[finding] 22 object examples across 12 docs pages omit sharingModel — the platform's own os validate rejects every one of them #10581

Description

@os-elon

Found by the docs audit of the first-run path (#10563), content/docs/** card 1/2.

What is wrong

22 ObjectSchema.create() examples across 12 in-scope pages omit sharingModel.
A custom (non-sys_) object that declares no sharingModel is an os validate
error
, not a warning — packages/lint/src/validate-security-posture.ts:266-281:

severity: 'error',
rule: SECURITY_OWD_UNSET, // 'security-owd-unset'
message: `custom object "<name>" declares no sharingModel (OWD). The runtime fails
CLOSED to 'private' (ADR-0090 D1), but the baseline must be an authored
decision, not an accident — this is the exact shape of the leave_request
incident (objectui#2348).`

So the module documentation's canonical object examples are all in a shape the
platform's own gate rejects. A reader who copies one gets a failing os validate
with no hint from the page they copied it from.

The sharpest instance

content/docs/data-modeling/index.mdx:14-30 introduces its snippet as
"A real object definition looks like this (from the CRM example app)" and
reproduces crm_leadminus the one key the gate errors on.
The real file, examples/app-crm/src/objects/lead.object.ts:12, declares
sharingModel: 'public_read_write'. Every one of the 7 example objects in
examples/ declares it; none of the doc snippets on these 12 pages does.

Why no gate caught it

That snippet carries {/* os:check */}, so it IS compiled by
packages/spec/scripts/check-skill-examples.ts. The marker cannot see this:
sharingModel is z.enum([...]).optional() on ObjectSchema with no
.default() (deliberately — see the docblock at
packages/lint/src/validate-sharing-rule-enforceability.ts:223-227), so the
omission type-checks cleanly. The rule that rejects it is an author-time lint
run by os validate, and no docs gate runs os validate over fenced blocks.

All 22 sites

PageLinesname
getting-started/examples.mdx128todo_task
concepts/architecture.mdx96, 402customer, opportunity
concepts/metadata-driven.mdx80, 244, 342, 388, 464, 487user, task, account, todo_task, account, example_object
data-modeling/schema-design.mdx21, 285, 404my_object, account, account
data-modeling/fields.mdx18contact
data-modeling/seed-data.mdx247book
data-modeling/validation.mdx27order
data-modeling/objects.mdx16, 365account, project_task
data-modeling/formulas.mdx94invoice
data-modeling/external-datasources.mdx73, 253ext_customer, (unnamed)
data-modeling/index.mdx16crm_lead
data-modeling/drivers.mdx906audit_log

Note the contrast: the three pages a newcomer actually copies from —
getting-started/build-with-claude-code.mdx, getting-started/your-first-project.mdx,
getting-started/quick-start.mdx — all declare it, and quick-start.mdx:96
even states "The validation gate rejects custom objects that omit it."
The requirement is taught on the first-run path and then contradicted by every
reference page downstream.

Two of the sites are deliberate ❌ Incorrect counter-examples
(metadata-driven.mdx §3–§5); the rest are presented as correct, several under
an explicit ✅ Correct heading.

Suggested shape of the fix

Add sharingModel to every example that is presented as a complete object.
Fragments that are explicitly partial (fields: { /* ... */ }) could instead
carry a one-line note pointing at the requirement. Mechanizing it — running
os validate (not just tsc) over os:check blocks that call
ObjectSchema.create — would close the class rather than the instances.

Back-link: #10563

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions