You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs(data-modeling): field-types and validation-rules describe expression under formula only — once PR #24673 lands, a stored field's declared expression is computed on every write and the hand-written pages never say so #24716
Filing gate ①, class (a): a shipped-doc gap with a named producer. Filed by domain:devx seat 1 (os-warren, session_01FM29ZqLTrnPNXxijioZwMp, seat post #6023), from domain:engine seat 1's addendum 6280927836 on #6023. The addendum offers it to this lane: "A gap for domain:devx, not this PR's … a docs follow-up for that lane to take up or not". ⛔ Not a claim. The lane is self-labelled under rule B; grade and area:* are triage's.
Measured (origin/main after 73d4cc7391)
content/docs/data-modeling/field-types.mdx documents expression only under the formula type: :407–:415, "Calculated field using a CEL expression", with the type: 'formula' example.
content/docs/data-modeling/validation-rules.mdx documents it the same way: :354 "Required. CEL formula expression", :357 "Read-only. Value computed at runtime from expression", and the :552 table row formula → expression.
The generated reference pages (references/data/field.mdx, object.mdx, system/migration.mdx) are regenerated by that PR. The two hand-written pages are not, and nothing in them is falsified: the stored-field meaning is simply absent.
Wanted (after PR #24673 merges, on its landed describe)
Each page says what expression means on a stored field, in the landed describe's terms, next to its formula meaning:
when it is computed (insert, update by id, predicate update);
that the value is stored;
the predicate-update refusal.
Use one short subsection or table row per page, with a link to the generated references/data/field.mdx row instead of restating it at length.
An author reading only these pages, an authoring agent included, learns that expression belongs to formula. They then either never use it on a stored field or are surprised by a refused predicate update. Declared-but-undocumented behaviour on an authoring surface is the AI-error axis: the contract tightens, and the docs should say so.
Dedupe
The engine seat's declaration and addendum (6279265790, 6280927836 on #6023) are the only mentions. A search for "stored field expression computed on write docs field-types validation-rules" finds no card.
Claim: PM loop round 15 · unblocked by PR #24673 merging (c0803b04d2); runs beside objectstack-ai/objectui#13108 under the maintainer's 「并发2」
Session: session_01FM29ZqLTrnPNXxijioZwMp
Account: os-warren (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-24716-stored-field-expression-docs
Worktree: objectstack-issue-24716
Domain: domain:devx
Seat: domain:devx#1
File surface: content/docs/data-modeling/field-types.mdx and content/docs/data-modeling/validation-rules.mdx. Each gets a stored-field expression meaning in the landed describe's terms (packages/spec/src/data/field.zod.tsexpression), with a link to the generated references/data/field.mdx row. Stop on breach and explain in the report. ⛔ No package code, and no generated page (references/** is gen:docs output).
Container & model: S (two docs passages), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate)
Clause-②: no
Responsibility: two hand-written data-modeling pages describe expression under formula only, while a stored field's expression is now computed on every write (PR #24673) | none: the generated reference carries the meaning | every author reading the data-modeling guide, authoring agents included
Thread-read: none
Serial constraints cleared: no open PR touches the two pages (read at 2026-10-20T02:37Z). PR #24673 merged at 2026-10-20T02:14:19Z. objectstack-ai/objectui#13108 (in flight) is objectui-only.
{
"issue": 24716,
"status": "done",
"branch": "claude/issue-24716-stored-field-expression-docs",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24734",
"session": "session_01FM29ZqLTrnPNXxijioZwMp — the parent PM seat's id (mode:subagent); the relay envelope carried the same id",
"premise_still_valid": true,
"summary": "Identity: the newest Claim (6282040610) names branch claude/issue-24716-stored-field-expression-docs, which matches. No second claim was posted, the card's assignee was not written, and the PR assignee is os-warren. BASE ec2694dc194c27357deb2f0a26fda0d1b9e684e1; the FieldSchema.expression describe (field.zod.ts:1840) is byte-identical to the dispatch's d20bf9b09b reading. Files changed: content/docs/data-modeling/field-types.mdx (+9 lines: a short subsection, `expression` on a stored field, under `### formula`, with one Field.currency example) and content/docs/data-modeling/validation-rules.mdx (+2 lines: one paragraph under its `formula` section). Total +11/-0, docs only, one commit 9dc3aba0af. PASSAGE field-types BEFORE: the only expression text is the formula row at :411 ('CEL calculation expression') and the example at :415. AFTER (:418-:425): '`expression` is not only a `formula` key. On a field of any other type, the engine computes it from the row each write stores and stores the result in the field's column, so a summary can roll the column up. It is computed on every insert and every update by id (the stored row merged with the patch). On a predicate update it is computed only when the patch moves an input: one value is stored for every matched row, and the update is refused (VALIDATION_FAILED, an invalid_value error on the field) when the rows would compute different values. Update those rows by id instead. A value a client sends for the field never stands: it is overwritten by the computed one, with no refusal and no dropped-field report.' The subsection ends with a link to the FieldSchema reference and the example Field.currency({ label: 'Amount', expression: 'record.quantity * record.unit_price' }). PASSAGE validation-rules BEFORE: :354 'Required. CEL formula expression', :357 'Read-only. Value computed at runtime from expression. Not directly writable.', and the :552 row formula to expression, all formula-only. AFTER (:368): 'expression on a stored field. A field of any other type may declare expression too, and it validates differently from a formula. The engine computes the value on every insert and every update by id, and stores it. A value a client sends for the field is not refused and not reported as dropped: it is overwritten by the computed one. The one refusal is a predicate update that moves an input: when the matched rows would compute different values, the update is refused with VALIDATION_FAILED and an invalid_value error naming the field, and nothing is written.' The paragraph links to field-types#expression-on-a-stored-field and the FieldSchema reference. The existing sentences (field-types :407-:415, validation-rules :354, :357, :552) are not rewritten; each now has the stored meaning beside it. MEASURED FACT 1, client write: the field is not read-only; a client-sent value is overwritten, not refused and not reported. (a) stripComputedWriteFields (engine.ts:2274) selects type === 'formula' only. (b) RUNTIME_OWNED_FIELD_TYPES is ['autonumber'] (field.zod.ts:291). (c) test engine-stored-expression-write.test.ts:142-152: amount 2999.4 is sent and 299.94 stored, and the events equal only [quantity] readonly_when. (d) Predicate update: settleBulkStoredExpressions (engine.ts:2979) deletes the caller's key, stores one value only when moved and equal on every row, and otherwise throws VALIDATION_FAILED/invalid_value before any write (test :251-:271). (e) Only with readonly: true as well is the value reported as a readonly drop and refused under strictReadonlyWrites (test :229-:247). MEASURED FACT 2, eligible types: every type other than formula. (a) planStoredExpressions (engine.ts:2921) plans any field where type !== 'formula' and expression is set. (b) FieldSchema.safeParse with an expression accepts all 49 FieldType members and refuses 0 (a one-off tsx probe on packages/spec/src, not kept). (c) The lint field-formula pass (validate-expressions.ts:2873) judges any field's expression, with no type condition. HYPOTHESIS 1 measured: check:doc-formula-expressions admits only Field.* calls (rule A) or literals with type: 'formula' (rule B). Probe through the gate's own extractor: a raw { type: 'currency', expression: 'quantity * unit_price' } is admitted 0 times, trips no tripwire, and would pass unjudged; Field.currency({ expression: 'quantity * unit_price' }) is admitted and judged red. So the example uses Field.currency (the spelling both example apps use), and the gate judges it: field-types sites go from 1 to 2, the new one at :424 with 0 errors. HYPOTHESIS 2: validation-rules.mdx is the right page for the validation half (overwritten not refused; the one refusal), and it points to field-types for the rest. The two-page acceptance is kept. Deviations and notes: (1) origin/main moved two commits past BASE (0904d856e3, d0514e6863); neither touches these pages, the describe or the engine, so the branch was not merged. (2) Commit trailers are the model-free pair AGENTS.md prescribes; the harness reminder's model-named trailer was not used, and PR body uses the AGENTS.md session-URL footer. (3) The worktree /home/user/objectstack-issue-24716 is removed (node_modules first) as the step right after this comment posts; the branch stays on origin.",
"tests": "Docs-only diff; no package test is owed (the diff touches no package). Probes, all one-off and not kept: (1) tsx over packages/spec/src: FieldSchema accepts expression on 49/49 FieldType members (exit 0). (2) The gate's own extractFormulaExpressions/judge, run on both pages at BASE and HEAD (exit 0): field-types BASE 1 site, HEAD 2 sites ('424 Field.currency(...) errors=0'); validation-rules 1 site at both. (3) Admission probe (exit 0): raw currency literal admitted 0 / tripwire false; bare-ref Field.currency admitted 1 / errors [1]. No ablation: no tested behaviour changed (docs only). All readings were taken on head 9dc3aba0af (git rev-parse --short HEAD), after the final commit.",
"gates": "Derivation: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, exit 0. It derived 40 commands for 2 paths against merge base ec2694dc1, at commit 9dc3aba0af. First pass: 35 exit 0; check:doc-formula-expressions, check:doc-security-posture, check:skill-examples and check:docs-transcript-drift exit 3 (PREREQUISITE NOT MET: unbuilt lint/formula/spec/client-react); spec check:docs exit 1 (its own refusal on the missing gen:schema tree, before measuring). Builds, under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-24716-build: turbo run build --filter='@objectstack/lint...' --concurrency=2 read 'VERDICT command-exit 0' (held 106s); --filter='@objectstack/client-react...' --filter='@objectstack/client...' read 'VERDICT command-exit 0' (held 207s, 37/37 tasks). Re-runs: all 5 exit 0. Final: 40/40 exit 0, every exit code captured before any pipe. --ran: '✓ dispatch-gates --ran: 40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3).' (exit 0). Verdict lines: check:doc-formula-expressions '23 record-scoped formula example(s) across 476 files / 1394 TS blocks judged clean'; check:doc-anchors '539 internal #fragment link(s) across 423 source file(s) all resolve to a real heading'; spec check:docs '227 generated files in sync'; check:skill-examples '262 prose examples type-check across 3 surface(s)'; check:doc-authoring '19128 customer-facing string(s) ... clean'; check:nul-bytes 'OK ... no raw ASCII control bytes'. Local-only families, readings kept local: check:skill-frame-freshness exit 0 (frame byte-identical; md5 ac3c5bd716f1f09dd2ce0ed0c30c6adb matches the dispatch); check:dev-prereqs exit 1 '33 of 70 workspace packages ... not on disk'. That is machine build state, and this diff builds nothing. It was not owed (no packages/spec build input touched) and ran anyway. PR check-runs at report time on head 9dc3aba0af: Check Changeset success; Governed Surface Queue Guard success; Check Documentation Links success; Spec property liveness success; Lint · PM dispatch-gates success; Dogfood Regression Gate success; Build Core skipped. In progress: Lint · docs & code guards, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · ESLint, Type Check · source gates, Type Check · consumer gates, Test Core (1..6/6), Build Docs. CI convergence is the PM's. Labels read back: documentation, size/s, skip-changeset.",
"mcp_calls": "0 — no MCP tool called",
"api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot]. (1) pr_create, run 39362163596, success: POST /repos/objectstack-ai/objectstack/pulls (draft) then POST /issues/24734/assignees [os-warren] then POST /issues/24734/labels [skip-changeset]. The body read back 10879/10879 bytes identical. (2) This os-dev-report comment, via scripts/pm/post-stamped.mjs: POST /repos/objectstack-ai/objectstack/issues/24716/comments. Plus git push (not REST): the empty-branch probe and one content push.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed · packages/spec/src/data/object.form.ts:363: the object designer's field grid shows `expression` only when data.type == 'formula' (help text 'CEL formula expression'), so a stored expression is neither visible nor editable there. field.form.ts:340 shows it for every type with help text '... (makes it read-only)', although the field is not readonly in the engine's sense. Not driven in a browser; a read-only inference, in the PR's Acceptance notes.",
"carrier: none (承接者:无) · noted, not filed · check:doc-formula-expressions rule B keys on type: 'formula', so a raw non-formula literal carrying expression is never judged (measured: bare-ref raw currency literal admitted 0, tripwire false). Current population is 0: a one-line grep of content/ and skills/ finds 12 lines, all formula or cron. No new gate, per the dispatch ruling. In the PR's Acceptance notes."
]
}
PR #24734 merged at 2026-10-20T03:49:19Z as 4a2ca57e74 (not governed). This seat landed it on its ACCEPT 6282562437
origin/main, by content
content/docs/data-modeling/field-types.mdx and validation-rules.mdx are byte-identical to the PR head 9dc3aba0af. git diff 9dc3aba0af origin/main over the two pages is empty. The new subsection heading #### `expression` on a stored field sits at field-types.mdx:418 on main
State change: PR #24734 closed this card through Fixes #24716 (completed). pm:dispatched comes off in this act.
Routed, not this lane's: the field form's help text says expression "makes it read-only", and the object field grid shows it for formula only. Both live in packages/spec/src/data/field.form.ts and object.form.ts, which belong to domain:spec. They are filed as #24735 (the PR's out-of-scope finding 1). The silent overwrite of a client value has its own card, #24690.
Activity
objectstack-fleet commentedon Oct 20, 2026
Claim: PM loop round 15 · unblocked by PR #24673 merging (
c0803b04d2); runs beside objectstack-ai/objectui#13108 under the maintainer's 「并发2」Session:
session_01FM29ZqLTrnPNXxijioZwMpAccount:
os-warren(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-24716-stored-field-expression-docsWorktree:
objectstack-issue-24716Domain:
domain:devxSeat:
domain:devx#1File surface:
content/docs/data-modeling/field-types.mdxandcontent/docs/data-modeling/validation-rules.mdx. Each gets a stored-fieldexpressionmeaning in the landed describe's terms (packages/spec/src/data/field.zod.tsexpression), with a link to the generatedreferences/data/field.mdxrow. Stop on breach and explain in the report. ⛔ No package code, and no generated page (references/**isgen:docsoutput).Container & model:
S (two docs passages),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate)Clause-②: no
Responsibility:
two hand-written data-modeling pages describe expression under formula only, while a stored field's expression is now computed on every write (PR #24673)|none: the generated reference carries the meaning|every author reading the data-modeling guide, authoring agents includedThread-read: none
Serial constraints cleared: no open PR touches the two pages (read at 2026-10-20T02:37Z). PR #24673 merged at 2026-10-20T02:14:19Z. objectstack-ai/objectui#13108 (in flight) is objectui-only.
Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
os-dev-report
{ "issue": 24716, "status": "done", "branch": "claude/issue-24716-stored-field-expression-docs", "pr": "https://github.com/objectstack-ai/objectstack/pull/24734", "session": "session_01FM29ZqLTrnPNXxijioZwMp — the parent PM seat's id (mode:subagent); the relay envelope carried the same id", "premise_still_valid": true, "summary": "Identity: the newest Claim (6282040610) names branch claude/issue-24716-stored-field-expression-docs, which matches. No second claim was posted, the card's assignee was not written, and the PR assignee is os-warren. BASE ec2694dc194c27357deb2f0a26fda0d1b9e684e1; the FieldSchema.expression describe (field.zod.ts:1840) is byte-identical to the dispatch's d20bf9b09b reading. Files changed: content/docs/data-modeling/field-types.mdx (+9 lines: a short subsection, `expression` on a stored field, under `### formula`, with one Field.currency example) and content/docs/data-modeling/validation-rules.mdx (+2 lines: one paragraph under its `formula` section). Total +11/-0, docs only, one commit 9dc3aba0af. PASSAGE field-types BEFORE: the only expression text is the formula row at :411 ('CEL calculation expression') and the example at :415. AFTER (:418-:425): '`expression` is not only a `formula` key. On a field of any other type, the engine computes it from the row each write stores and stores the result in the field's column, so a summary can roll the column up. It is computed on every insert and every update by id (the stored row merged with the patch). On a predicate update it is computed only when the patch moves an input: one value is stored for every matched row, and the update is refused (VALIDATION_FAILED, an invalid_value error on the field) when the rows would compute different values. Update those rows by id instead. A value a client sends for the field never stands: it is overwritten by the computed one, with no refusal and no dropped-field report.' The subsection ends with a link to the FieldSchema reference and the example Field.currency({ label: 'Amount', expression: 'record.quantity * record.unit_price' }). PASSAGE validation-rules BEFORE: :354 'Required. CEL formula expression', :357 'Read-only. Value computed at runtime from expression. Not directly writable.', and the :552 row formula to expression, all formula-only. AFTER (:368): 'expression on a stored field. A field of any other type may declare expression too, and it validates differently from a formula. The engine computes the value on every insert and every update by id, and stores it. A value a client sends for the field is not refused and not reported as dropped: it is overwritten by the computed one. The one refusal is a predicate update that moves an input: when the matched rows would compute different values, the update is refused with VALIDATION_FAILED and an invalid_value error naming the field, and nothing is written.' The paragraph links to field-types#expression-on-a-stored-field and the FieldSchema reference. The existing sentences (field-types :407-:415, validation-rules :354, :357, :552) are not rewritten; each now has the stored meaning beside it. MEASURED FACT 1, client write: the field is not read-only; a client-sent value is overwritten, not refused and not reported. (a) stripComputedWriteFields (engine.ts:2274) selects type === 'formula' only. (b) RUNTIME_OWNED_FIELD_TYPES is ['autonumber'] (field.zod.ts:291). (c) test engine-stored-expression-write.test.ts:142-152: amount 2999.4 is sent and 299.94 stored, and the events equal only [quantity] readonly_when. (d) Predicate update: settleBulkStoredExpressions (engine.ts:2979) deletes the caller's key, stores one value only when moved and equal on every row, and otherwise throws VALIDATION_FAILED/invalid_value before any write (test :251-:271). (e) Only with readonly: true as well is the value reported as a readonly drop and refused under strictReadonlyWrites (test :229-:247). MEASURED FACT 2, eligible types: every type other than formula. (a) planStoredExpressions (engine.ts:2921) plans any field where type !== 'formula' and expression is set. (b) FieldSchema.safeParse with an expression accepts all 49 FieldType members and refuses 0 (a one-off tsx probe on packages/spec/src, not kept). (c) The lint field-formula pass (validate-expressions.ts:2873) judges any field's expression, with no type condition. HYPOTHESIS 1 measured: check:doc-formula-expressions admits only Field.* calls (rule A) or literals with type: 'formula' (rule B). Probe through the gate's own extractor: a raw { type: 'currency', expression: 'quantity * unit_price' } is admitted 0 times, trips no tripwire, and would pass unjudged; Field.currency({ expression: 'quantity * unit_price' }) is admitted and judged red. So the example uses Field.currency (the spelling both example apps use), and the gate judges it: field-types sites go from 1 to 2, the new one at :424 with 0 errors. HYPOTHESIS 2: validation-rules.mdx is the right page for the validation half (overwritten not refused; the one refusal), and it points to field-types for the rest. The two-page acceptance is kept. Deviations and notes: (1) origin/main moved two commits past BASE (0904d856e3, d0514e6863); neither touches these pages, the describe or the engine, so the branch was not merged. (2) Commit trailers are the model-free pair AGENTS.md prescribes; the harness reminder's model-named trailer was not used, and PR body uses the AGENTS.md session-URL footer. (3) The worktree /home/user/objectstack-issue-24716 is removed (node_modules first) as the step right after this comment posts; the branch stays on origin.", "tests": "Docs-only diff; no package test is owed (the diff touches no package). Probes, all one-off and not kept: (1) tsx over packages/spec/src: FieldSchema accepts expression on 49/49 FieldType members (exit 0). (2) The gate's own extractFormulaExpressions/judge, run on both pages at BASE and HEAD (exit 0): field-types BASE 1 site, HEAD 2 sites ('424 Field.currency(...) errors=0'); validation-rules 1 site at both. (3) Admission probe (exit 0): raw currency literal admitted 0 / tripwire false; bare-ref Field.currency admitted 1 / errors [1]. No ablation: no tested behaviour changed (docs only). All readings were taken on head 9dc3aba0af (git rev-parse --short HEAD), after the final commit.", "gates": "Derivation: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack, exit 0. It derived 40 commands for 2 paths against merge base ec2694dc1, at commit 9dc3aba0af. First pass: 35 exit 0; check:doc-formula-expressions, check:doc-security-posture, check:skill-examples and check:docs-transcript-drift exit 3 (PREREQUISITE NOT MET: unbuilt lint/formula/spec/client-react); spec check:docs exit 1 (its own refusal on the missing gen:schema tree, before measuring). Builds, under scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-24716-build: turbo run build --filter='@objectstack/lint...' --concurrency=2 read 'VERDICT command-exit 0' (held 106s); --filter='@objectstack/client-react...' --filter='@objectstack/client...' read 'VERDICT command-exit 0' (held 207s, 37/37 tasks). Re-runs: all 5 exit 0. Final: 40/40 exit 0, every exit code captured before any pipe. --ran: '✓ dispatch-gates --ran: 40 derived famil(ies) accounted for — 40 run, 0 NOT-MEASURED (a DERIVED zero — all 40 recorded an exit code and none of them is 3).' (exit 0). Verdict lines: check:doc-formula-expressions '23 record-scoped formula example(s) across 476 files / 1394 TS blocks judged clean'; check:doc-anchors '539 internal #fragment link(s) across 423 source file(s) all resolve to a real heading'; spec check:docs '227 generated files in sync'; check:skill-examples '262 prose examples type-check across 3 surface(s)'; check:doc-authoring '19128 customer-facing string(s) ... clean'; check:nul-bytes 'OK ... no raw ASCII control bytes'. Local-only families, readings kept local: check:skill-frame-freshness exit 0 (frame byte-identical; md5 ac3c5bd716f1f09dd2ce0ed0c30c6adb matches the dispatch); check:dev-prereqs exit 1 '33 of 70 workspace packages ... not on disk'. That is machine build state, and this diff builds nothing. It was not owed (no packages/spec build input touched) and ran anyway. PR check-runs at report time on head 9dc3aba0af: Check Changeset success; Governed Surface Queue Guard success; Check Documentation Links success; Spec property liveness success; Lint · PM dispatch-gates success; Dogfood Regression Gate success; Build Core skipped. In progress: Lint · docs & code guards, Lint · repo & tooling gates, Lint · CI, release & engine gates, Lint · ESLint, Type Check · source gates, Type Check · consumer gates, Test Core (1..6/6), Build Docs. CI convergence is the PM's. Labels read back: documentation, size/s, skip-changeset.", "mcp_calls": "0 — no MCP tool called", "api_writes": "2 relay strokes, each one POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot]. (1) pr_create, run 39362163596, success: POST /repos/objectstack-ai/objectstack/pulls (draft) then POST /issues/24734/assignees [os-warren] then POST /issues/24734/labels [skip-changeset]. The body read back 10879/10879 bytes identical. (2) This os-dev-report comment, via scripts/pm/post-stamped.mjs: POST /repos/objectstack-ai/objectstack/issues/24716/comments. Plus git push (not REST): the empty-branch probe and one content push.", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted, not filed · packages/spec/src/data/object.form.ts:363: the object designer's field grid shows `expression` only when data.type == 'formula' (help text 'CEL formula expression'), so a stored expression is neither visible nor editable there. field.form.ts:340 shows it for every type with help text '... (makes it read-only)', although the field is not readonly in the engine's sense. Not driven in a browser; a read-only inference, in the PR's Acceptance notes.", "carrier: none (承接者:无) · noted, not filed · check:doc-formula-expressions rule B keys on type: 'formula', so a raw non-formula literal carrying expression is never judged (measured: bare-ref raw currency literal admitted 0, tripwire false). Current population is 0: a one-line grep of content/ and skills/ finds 12 lines, all formula or cron. No new gate, per the dispatch ruling. In the PR's Acceptance notes." ] }objectstack-fleet commentedon Oct 20, 2026
Landed ·
domain:devxseat 1 ·session_01FM29ZqLTrnPNXxijioZwMp· 2026-10-20T03:49Zgh-readonly-queue/main/pr-24734-*heads)4a2ca57e74(not governed). This seat landed it on its ACCEPT6282562437origin/main, by contentcontent/docs/data-modeling/field-types.mdxandvalidation-rules.mdxare byte-identical to the PR head9dc3aba0af.git diff 9dc3aba0af origin/mainover the two pages is empty. The new subsection heading#### `expression` on a stored fieldsits atfield-types.mdx:418onmainState change: PR #24734 closed this card through
Fixes #24716(completed).pm:dispatchedcomes off in this act.Routed, not this lane's: the field form's help text says
expression"makes it read-only", and the object field grid shows it forformulaonly. Both live inpackages/spec/src/data/field.form.tsandobject.form.ts, which belong todomain:spec. They are filed as #24735 (the PR's out-of-scope finding 1). The silent overwrite of a client value has its own card, #24690.Generated by Claude Code