Skip to content

docs(protocol): correct the two wrong defaultValue samples in schema.mdx - #7376

Merged
os-help merged 1 commit into
mainfrom
claude/issue-7244-schema-mdx-default-samples
Aug 10, 2026
Merged

docs(protocol): correct the two wrong defaultValue samples in schema.mdx#7376
os-help merged 1 commit into
mainfrom
claude/issue-7244-schema-mdx-default-samples

Conversation

@os-help

@os-help os-help commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Fixes #7244

Docs-only. content/docs/protocol/objectql/schema.mdx is the only file touched — no schema, no engine, no driver, no gate.

What changed

# revenue (currency)
- defaultValue: { value: 0, currency: 'USD' }
+ defaultValue: 0   # currency stores a bare number — never { value, currency }

# due_datetime (datetime)
- defaultValue: "daysFromNow(7)"  # 7 days from now (CEL)
+ # A CEL default needs the explicit `{ dialect, source }` envelope. Unlike a
+ # formula field's `expression`, `defaultValue` has NO bare-string shorthand —
+ # a bare string is stored as that literal text.
+ defaultValue: { dialect: 'cel', source: 'daysFromNow(7)' }  # 7 days from now, at UTC midnight

The card's originals — confirmed wrong

valueSchemaFor(...).safeParse(...), the probe the card used:

ORIGINAL  datetime  < - "daysFromNow(7)": FAIL :: ["expected an ISO-8601 instant with explicit zone (e.g. 2026-03-15T14:30:00.000Z)"]
ORIGINAL  currency  < - { value: 0, currency: "USD" }: FAIL :: ["Invalid input: expected number, received object"]
NUMERIC_VALUE_TYPES.has("currency") = true

End-to-end insert of both current samples through the engine (memory driver) is refused, not silently stored:

CURRENT SAMPLES insert REJECTED: VALIDATION_FAILED
  bad_dt must be a valid datetime (ISO-8601); bad_cur must be a number

And the SQL DDL, better-sqlite3, real CREATE TABLE:

`cur_due_datetime` datetime default 'daysFromNow(7)',   -- the CEL source text as a physical column DEFAULT
`cur_revenue` float,                                     -- the object silently dropped: no default at all

Both halves of the card's trace reproduce exactly.

The replacements — measured, not assumed

This is what the card supplied but never probed.

REPLACE  currency  < - 0: PASS
CEL evaluate ok = true | value = Mon Aug 17 2026 00:00:00 GMT+0000 | ctor = Date
REPLACEMENTS insert OK. stored due_datetime = "2026-08-17T00:00:00.000Z"
REPLACEMENTS stored revenue = 0 | typeof number

DDL for the same two replacement declarations:

`new_due_datetime` datetime,             -- no column DEFAULT: the envelope is evaluated app-side
`new_revenue` float default '0',         -- a real literal default

So the envelope does not leak the source text into the DDL, which was the failure to rule out. daysFromNow is a genuinely registered stdlib function (packages/formula/src/stdlib.ts:117), not invented from a doc comment — an unregistered name is refused loudly:

CEL unregistered-fn probe ok = false | error = { kind: 'runtime',
  message: "found no matching overload for 'noSuchFn(int)'" }

daysFromNow(n) returns the calendar day at UTC midnight (ADR-0053 D1), so the inline comment now says so rather than the bare "7 days from now" — the old comment was true of neither the old sample nor, precisely, the new one. now() + duration("168h") was measured as the sub-day alternative (Mon Aug 17 2026 09:30:00 GMT+0000) and deliberately not used: daysFromNow is the helper the card named and the skills teach.

One thing the measurement did not confirm

The card says the bare string "stores the 14 characters into the datetime field". applyFieldDefaults does assign it, but the record validator refuses the insert immediately after, so on an ordinary field the user-visible symptom is a failed write, not silent bad data. The silent-storage reading holds only where validateRecord is skipped (readonly/system fields, isSystem writes) and for the physical column DEFAULT above, which is emitted regardless. The sample is wrong either way; the mechanism is worth stating accurately.

Population scan

The card found two defects and did not claim two was all. Every defaultValue on the page was probed:

line field value verdict
112 select draft PASS
272 skeleton null n/a — null means "no default"
371 number 1 PASS
385 currency { value: 0, currency: 'USD' } FAIL — fixed here
399 datetime "daysFromNow(7)" FAIL — fixed here
408 boolean true PASS
413 toggle false PASS
427 select medium PASS
998 boolean true PASS

Two is the complete population on this page. The look-alike at line 706 — expression: "record.first_name + ' ' + record.last_name" on a formula field — is correct and deliberately untouched: expression is typed ExpressionInputSchema, whose union accepts a bare string as shorthand for { dialect: 'cel', source }. defaultValue is z.unknown() and has no such shorthand. That asymmetry, two sections apart on one page, is precisely why the old sample looked plausible, so the new comment names it.

Also checked: the 26 YAML blocks on the page parse identically before and after (3 pre-existing non-parsing blocks are deliberate side-by-side illustrations, untouched).

Gates

gate conclusion
check:doc-authoring green — 374 files clean
check:docs-audit-scope green — 179 hand-written docs in sync
check:nul-bytes green — 6739 files, no raw control bytes
check:adr-links green
check:quick-reference-counts green
check:org-identifier, check:role-word green
pnpm --filter @objectstack/docs build green — full Next.js docs build, 391+ pages prerendered

The docs build matters here: CI's build-docs job filters on content/**, so this change triggers it.

Out of scope

Filed as #7373: a CEL defaultValue stores a raw Date into datetime/date fields, while the stored-value contract names an ISO-8601 string — the NOW() token normalizes via resolveNowDefault and the CEL branch has no counterpart. Reachable by the corrected sample this PR lands, but it is an engine defect, not a docs one, so it is filed rather than fixed here (ruling: file surface is this page and nothing else).

No changeset: docs-only, nothing user-visible ships. skip-changeset is the PM's to apply at accept time.


Generated by Claude Code

…a.mdx (#7244)

Both samples on `content/docs/protocol/objectql/schema.mdx` taught a shape that
today produces a rejected write or a bogus physical column DEFAULT. Measured on
`origin/main` before and after:

  * `due_datetime` carried a BARE CEL source string. `applyFieldDefaults`
    recognises an expression only by `{ dialect, source }`, so the bare string
    fell to the literal branch; an insert was refused
    ("bad_dt must be a valid datetime (ISO-8601)"), and the SQL DDL emitted
    `` `cur_due_datetime` datetime default 'daysFromNow(7)' `` -- the source
    text as a physical column DEFAULT. Replaced with the explicit envelope,
    which evaluates (2026-08-17T00:00:00.000Z from a 2026-08-10 now) and emits
    no column DEFAULT.

  * `revenue` carried `{ value: 0, currency: 'USD' }`. `currency` is in
    `NUMERIC_VALUE_TYPES`, so the stored contract is `z.number().finite()`;
    the object was refused by the record validator and dropped entirely by the
    SQL DDL (no default at all). Replaced with `0`, which stores and emits
    `float default '0'`.

The inline comments now state what the corrected samples actually mean,
including that `defaultValue` -- unlike a formula field's `expression` -- has
no bare-string CEL shorthand, which is the trap the old sample set.

Docs-only: no behaviour change, no changeset.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KJATVrh6V2ysutYUJigh3B
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 10, 2026 8:10am

Request Review

@github-actions github-actions Bot added size/xs documentation Improvements or additions to documentation labels Aug 10, 2026
@os-help os-help added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 10, 2026 — with Claude
@os-help
os-help marked this pull request as ready for review August 10, 2026 08:20
@os-help
os-help added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit f0ac3e4 Aug 10, 2026
24 of 25 checks passed
@os-help
os-help deleted the claude/issue-7244-schema-mdx-default-samples branch August 10, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xs skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants