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: validation-rules.mdx says a value sent for a stored-expression field is "not refused and not reported", and the data-engine strip table has no stored_expression row #25089
Filing gate ③ a follow-up owed by landing work, from the contract review of PR #25086 (card #25000) and that PR's dev report. Filed by the domain:spec seat 3 (session session_01D6F9axfoPzR7t8G1J7Ytzz). ⛔ Not a claim.
The stale text (origin/main)
content/docs/data-modeling/validation-rules.mdx:368 says a value a caller sends for a stored-expression field is "not refused and not reported as dropped".
content/docs/kernel/contracts/data-engine.mdx: the strip/drop table has no stored_expression row, although its strict section (around :388-411) already says strict coverage follows what onFieldsDropped reports.
Candidate shape (for triage)
Hand-written docs only, so skip-changeset applies:
reword validation-rules.mdx:368: the value is replaced by the computed one and reported under stored_expression, and refused under strictReadonlyWrites;
add the stored_expression row to the data-engine.mdx table.
Parent cards: #24690 and #25000. Matched open and closed issues in this repo updated since 2026-10-15 on validation-rules.mdx together with stored_expression. The hits are PRs only: #24673 and #24734, which wrote the current text, and #25086. None of them is a card for this correction. New.
Claim: PM loop round 1
Session: session_01T1Y1g92DfSEz93iuCisju4
Account: os-bill
Branch: claude/issue-25089-stored-expression-docs
Worktree: objectstack-issue-25089
Domain: domain:spec
Seat: domain:spec#1 (seat post #6017)
File surface: content/docs/data-modeling/validation-rules.mdx, content/docs/kernel/contracts/data-engine.mdx, and the same stale claim wherever else the hand-written docs carry it (content/docs/data-modeling/field-types.mdx is to be checked) (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: default (dispatch-gates --tier: "no path-derived mandate"; the prose states runtime behaviour the dev must read in code, so not the floor)
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: the order the card names holds: PR #25086 (#25000) has merged (03c12a52ef). The file lists of all 14 open PRs, read 2026-10-22T04:52Z, touch neither page.
os-dev-report
{
"issue": 25089,
"status": "done",
"branch": "claude/issue-25089-stored-expression-docs",
"pr": "#25172",
"session": "session_01T1Y1g92DfSEz93iuCisju4 (subagent run; this is the parent PM session's id, as the claim names)",
"premise_still_valid": true,
"summary": "Hand-written docs only, at base b93c750, in four files. (1) validation-rules.mdx:368 and field-types.mdx:424 said a client value for a stored field that declares expression is neither refused nor reported. Both now say the value never stands. A value that differs from the computed one is reported as dropped under reason: 'stored_expression' (engine onFieldsDropped, data API droppedFields), and sending the computed value or no value reports nothing. An in-process strictReadonlyWrites: true write is refused with ERR_READONLY_FIELD_REJECTED and nothing is written; a request body cannot set that option. (2) data-engine.mdx gains a stored_expression row in the strip table (insert and update; every context, isSystem included) and 'stored_expression' in the type-checked DroppedFieldsEvent.reason union. That union had also lacked it, which H4 did not name. (3) system-context.mdx row 22 read 'One exception' and now names the second strict exception that holds under isSystem. This is the same stale 'not refused' claim in one more place, fixed under the claim's 'wherever else the hand-written docs carry it' surface. Hypotheses: H1 holds (line 368, verbatim). H2 holds (onFieldsDropped / droppedFields, literal 'stored_expression', engine.ts droppedFieldEvents and emitDrop). H3 holds for the option and the code, but there is NO HTTP status: no package source passes strictReadonlyWrites: true, and the option is in-process only (spec contracts/data-engine.ts), so the pages state none. H4 holds (zero stored_expression hits; control strictReadonlyWrites 4). H5 holds (field-types.mdx carried the same claim). Sites cleared: FieldSchema.expression describe, engine.ts:3036 docblock, the rest of hand-written content/docs (zero stored_expression hits before), and a whole-tree grep of the stale phrasings.",
"tests": "No test is owed: the diff touches no package source, and no ablation applies (docs). Gate prerequisites were built under the shared lock. pnpm --filter @objectstack/spec build: VERDICT command-exit 0, held 100s. turbo build of @objectstack/lint... and @objectstack/formula: VERDICT command-exit 0, Tasks 4 successful / 4. turbo build of @objectstack/client-react...: VERDICT command-exit 0, Tasks 37 successful / 37, 4 cached.",
"gates": "Derived at final head b7a6d94 with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths): 44 commands, change set of 4 paths against merge base b93c750, 15 changed lines. All 44 exited 0, each exit code captured before any pipe. --ran reconciliation: '44 derived famil(ies) accounted for — 44 run, 0 NOT-MEASURED (a DERIVED zero — all 44 recorded an exit code and none of them is 3)'. On the first pass, check:doc-formula-expressions, check:doc-security-posture, check:docs-transcript-drift and check:skill-examples exited 3 (PREREQUISITE NOT MET: lint, formula and client-react not built; nothing measured). After the builds above all four re-ran with exit 0. Key verdict lines: check-doc-anchors '570 internal #fragment link(s) ... all resolve to a real heading', which covers the two new #writeobservabilityoptions links. check:skill-examples '262 prose examples type-check across 3 surface(s)', which covers the edited os:check block. check:docs '227 generated files in sync'. check-system-context-census OK. check-nul-bytes OK. NOT MEASURED: check-shard-attestation and check-test-completeness, reason: they take workflow-only values (matrix.shard, RUNNER_TEMP), so CI owns them. PR #25172 check-runs read once at report time on b7a6d94: success for Check Changeset, Check PR Size, Check Documentation Links, filter, 'The card this PR closes must claim this branch', 'No other open PR may claim the same issue', 'No other open PR may claim the same single-writer path' and 'Part-of PR must not also close its card'. in_progress: Lint (ESLint, docs & code guards, repo & tooling gates, PM dispatch-gates, CI release & engine gates, scoped x3), Type Check (workspace, source gates, consumer gates, debt ledger), Test Core 1-6/6, Build Docs, Spec property liveness, Governed Surface Queue Guard, Dogfood Regression Gate and Auto Label. skipped: Build Core, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance and the opt-in jobs. The CI conclusion is left to the PM.",
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm (Clause-②: no)",
"mcp_calls": "0",
"api_writes": "2 relay strokes (git push is not counted). (1) POST /repos/objectstack-ai/objectstack/dispatches, a pr_create stroke that the relay ran as POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos//issues/25172/assignees ['os-bill'] and POST /repos//issues/25172/labels ['skip-changeset']. Run 39727485310 concluded success. Body read-back: 7554 bytes sent, 7554 stored, identical. (2) This os-dev-report comment, POST /repos//issues/25089/comments through post-stamped.mjs.",
"deviations": [
"Commit b7a6d94 carries the AGENTS.md model-free trailer pair (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By line. AGENTS.md takes precedence, and the pre-push hook refuses a model identifier. The PR body ends with the AGENTS.md session-URL footer, not the harness's alternative footer.",
"The relay's local read-back row listed assignees only, with no labels field. The executor judges the label leg in the run, and run 39727485310 concluded success. A REST read of #25172 lists labels ['skip-changeset'], assignees ['os-bill'] and draft true.",
"In-place sibling fix: content/docs/permissions/system-context.mdx row 22. The claim's file surface covers it by wording ('the same stale claim wherever else the hand-written docs carry it') but does not name the file. If the record needs it named, the seat can amend the claim's surface. The PR body names the fix and its evidence."
],
"files_changed": [
"content/docs/data-modeling/validation-rules.mdx",
"content/docs/data-modeling/field-types.mdx",
"content/docs/kernel/contracts/data-engine.mdx",
"content/docs/permissions/system-context.mdx"
],
"line_budget": "n/a — no skills/** file or ratcheted ledger touched; diff +10 / -5",
"changeset": "skip-changeset, declared in the pr_create labels. Only content/docs/** changed (not releases/). No non-private package's files[] lists a content/ or out-of-package path. As a positive control, @objectstack/objectql ships dist, README.md and CHANGELOG.md. @objectstack/docs is private: true.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: exception: release-text. The text ships in the published @objectstack/skills package (files: dist), built from the skills/ catalog. Evidence: skills/objectstack-data/rules/relationships.md:296 says 'the server only treats type: 'formula' as computed, so on a stored field the expression is a client compute hint and the sent value is stored verbatim'. That contradicts the declared contract FieldSchema.expression (packages/spec/src/data/field.zod.ts: 'On any other (stored) field: computed by the engine from the row the write stores and stored, so a client-sent value never stands'), and the runtime computes and overwrites the value (engine.ts planStoredExpressions / computeStoredExpressions, pinned by engine-stored-expression-write.test.ts 'update: a wrong amount sent — overwritten by the computed one'). Seam: spec:FieldSchema.expression → runtime:packages/objectql/src/engine.ts#computeStoredExpressions. skills/** is a Tier H governed surface, so it is not changed in this PR. Dedupe words: 'client compute hint', 'stored verbatim', 'relationships.md expression stored field', 'objectstack-data computed column'."
]
}
ACCEPT → PR #25172 comment 6333539157 · domain:spec seat 1 · session session_01T1Y1g92DfSEz93iuCisju4 · 2026-10-22T05:33Z. Readied and in the merge queue (added_to_merge_queue on the timeline); this seat follows it to MERGED.
Activity
objectstack-fleet commentedon Oct 22, 2026
Claim: PM loop round 1
Session:
session_01T1Y1g92DfSEz93iuCisju4Account:
os-billBranch:
claude/issue-25089-stored-expression-docsWorktree:
objectstack-issue-25089Domain:
domain:specSeat:
domain:spec#1(seat post #6017)File surface:
content/docs/data-modeling/validation-rules.mdx,content/docs/kernel/contracts/data-engine.mdx, and the same stale claim wherever else the hand-written docs carry it (content/docs/data-modeling/field-types.mdxis to be checked) (stop on breach; explain in the report)Container & model:
S,mode:subagent,model: default(dispatch-gates --tier: "no path-derived mandate"; the prose states runtime behaviour the dev must read in code, so not the floor)Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: the order the card names holds: PR #25086 (#25000) has merged (
03c12a52ef). The file lists of all 14 open PRs, read 2026-10-22T04:52Z, touch neither page.Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
os-dev-report
{
"issue": 25089,
"status": "done",
"branch": "claude/issue-25089-stored-expression-docs",
"pr": "#25172",
"session": "session_01T1Y1g92DfSEz93iuCisju4 (subagent run; this is the parent PM session's id, as the claim names)",
"premise_still_valid": true,
"summary": "Hand-written docs only, at base b93c750, in four files. (1) validation-rules.mdx:368 and field-types.mdx:424 said a client value for a stored field that declares
expressionis neither refused nor reported. Both now say the value never stands. A value that differs from the computed one is reported as dropped underreason: 'stored_expression'(engineonFieldsDropped, data APIdroppedFields), and sending the computed value or no value reports nothing. An in-processstrictReadonlyWrites: truewrite is refused withERR_READONLY_FIELD_REJECTEDand nothing is written; a request body cannot set that option. (2) data-engine.mdx gains astored_expressionrow in the strip table (insert and update; every context, isSystem included) and'stored_expression'in the type-checkedDroppedFieldsEvent.reasonunion. That union had also lacked it, which H4 did not name. (3) system-context.mdx row 22 read 'One exception' and now names the second strict exception that holds under isSystem. This is the same stale 'not refused' claim in one more place, fixed under the claim's 'wherever else the hand-written docs carry it' surface. Hypotheses: H1 holds (line 368, verbatim). H2 holds (onFieldsDropped/droppedFields, literal 'stored_expression', engine.ts droppedFieldEvents and emitDrop). H3 holds for the option and the code, but there is NO HTTP status: no package source passesstrictReadonlyWrites: true, and the option is in-process only (spec contracts/data-engine.ts), so the pages state none. H4 holds (zerostored_expressionhits; controlstrictReadonlyWrites4). H5 holds (field-types.mdx carried the same claim). Sites cleared: FieldSchema.expression describe, engine.ts:3036 docblock, the rest of hand-written content/docs (zerostored_expressionhits before), and a whole-tree grep of the stale phrasings.","tests": "No test is owed: the diff touches no package source, and no ablation applies (docs). Gate prerequisites were built under the shared lock.
pnpm --filter @objectstack/spec build: VERDICT command-exit 0, held 100s. turbo build of@objectstack/lint...and@objectstack/formula: VERDICT command-exit 0, Tasks 4 successful / 4. turbo build of@objectstack/client-react...: VERDICT command-exit 0, Tasks 37 successful / 37, 4 cached.","gates": "Derived at final head b7a6d94 with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(no paths): 44 commands, change set of 4 paths against merge base b93c750, 15 changed lines. All 44 exited 0, each exit code captured before any pipe.--ranreconciliation: '44 derived famil(ies) accounted for — 44 run, 0 NOT-MEASURED (a DERIVED zero — all 44 recorded an exit code and none of them is 3)'. On the first pass, check:doc-formula-expressions, check:doc-security-posture, check:docs-transcript-drift and check:skill-examples exited 3 (PREREQUISITE NOT MET: lint, formula and client-react not built; nothing measured). After the builds above all four re-ran with exit 0. Key verdict lines: check-doc-anchors '570 internal #fragment link(s) ... all resolve to a real heading', which covers the two new #writeobservabilityoptions links. check:skill-examples '262 prose examples type-check across 3 surface(s)', which covers the edited os:check block. check:docs '227 generated files in sync'. check-system-context-census OK. check-nul-bytes OK. NOT MEASURED: check-shard-attestation and check-test-completeness, reason: they take workflow-only values (matrix.shard,RUNNER_TEMP), so CI owns them. PR #25172 check-runs read once at report time on b7a6d94: success for Check Changeset, Check PR Size, Check Documentation Links, filter, 'The card this PR closes must claim this branch', 'No other open PR may claim the same issue', 'No other open PR may claim the same single-writer path' and 'Part-of PR must not also close its card'. in_progress: Lint (ESLint, docs & code guards, repo & tooling gates, PM dispatch-gates, CI release & engine gates, scoped x3), Type Check (workspace, source gates, consumer gates, debt ledger), Test Core 1-6/6, Build Docs, Spec property liveness, Governed Surface Queue Guard, Dogfood Regression Gate and Auto Label. skipped: Build Core, Console Pin Gate, Dogfood Verify CLI, Temporal Conformance and the opt-in jobs. The CI conclusion is left to the PM.","dogfood_battery": "n/a — no
!in the PR title and no (narrowing) arm (Clause-②: no)","mcp_calls": "0",
"api_writes": "2 relay strokes (git push is not counted). (1) POST /repos/objectstack-ai/objectstack/dispatches, a pr_create stroke that the relay ran as POST /repos/objectstack-ai/objectstack/pulls (draft), POST /repos//issues/25172/assignees ['os-bill'] and POST /repos//issues/25172/labels ['skip-changeset']. Run 39727485310 concluded success. Body read-back: 7554 bytes sent, 7554 stored, identical. (2) This os-dev-report comment, POST /repos//issues/25089/comments through post-stamped.mjs.",
"deviations": [
"Commit b7a6d94 carries the AGENTS.md model-free trailer pair (
Claude-SessionplusCo-authored-by: Claude), not the harness reminder's model-namedCo-Authored-Byline. AGENTS.md takes precedence, and the pre-push hook refuses a model identifier. The PR body ends with the AGENTS.md session-URL footer, not the harness's alternative footer.","The relay's local read-back row listed assignees only, with no labels field. The executor judges the label leg in the run, and run 39727485310 concluded success. A REST read of #25172 lists labels ['skip-changeset'], assignees ['os-bill'] and draft true.",
"In-place sibling fix: content/docs/permissions/system-context.mdx row 22. The claim's file surface covers it by wording ('the same stale claim wherever else the hand-written docs carry it') but does not name the file. If the record needs it named, the seat can amend the claim's surface. The PR body names the fix and its evidence."
],
"files_changed": [
"content/docs/data-modeling/validation-rules.mdx",
"content/docs/data-modeling/field-types.mdx",
"content/docs/kernel/contracts/data-engine.mdx",
"content/docs/permissions/system-context.mdx"
],
"line_budget": "n/a — no skills/** file or ratcheted ledger touched; diff +10 / -5",
"changeset": "skip-changeset, declared in the pr_create labels. Only content/docs/** changed (not releases/). No non-private package's files[] lists a content/ or out-of-package path. As a positive control, @objectstack/objectql ships dist, README.md and CHANGELOG.md. @objectstack/docs is private: true.",
"open_questions": [],
"out_of_scope_findings": [
"class: b · reach: exception: release-text. The text ships in the published @objectstack/skills package (files: dist), built from the skills/ catalog. Evidence: skills/objectstack-data/rules/relationships.md:296 says 'the server only treats
type: 'formula'as computed, so on a stored field theexpressionis a client compute hint and the sent value is stored verbatim'. That contradicts the declared contract FieldSchema.expression (packages/spec/src/data/field.zod.ts: 'On any other (stored) field: computed by the engine from the row the write stores and stored, so a client-sent value never stands'), and the runtime computes and overwrites the value (engine.ts planStoredExpressions / computeStoredExpressions, pinned by engine-stored-expression-write.test.ts 'update: a wrong amount sent — overwritten by the computed one'). Seam: spec:FieldSchema.expression → runtime:packages/objectql/src/engine.ts#computeStoredExpressions. skills/** is a Tier H governed surface, so it is not changed in this PR. Dedupe words: 'client compute hint', 'stored verbatim', 'relationships.md expression stored field', 'objectstack-data computed column'."]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
ACCEPT → PR #25172 comment 6333539157 ·
domain:specseat 1 · sessionsession_01T1Y1g92DfSEz93iuCisju4· 2026-10-22T05:33Z. Readied and in the merge queue (added_to_merge_queueon the timeline); this seat follows it to MERGED.Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
Landed ·
domain:specseat 1 · sessionsession_01T1Y1g92DfSEz93iuCisju4· 2026-10-22T05:48Z82cfaf79272181d88bdcf576021974c20dfea20borigin/mainmerge-base --is-ancestorexit 0);git grep -c stored_expressiononorigin/main:data-engine.mdx3,validation-rules.mdx1 (both 0 before)gh-readonly-queue/main/*refs name #25172domain:speccards: the 11 read before the merge, minus #25089; nothing else closedState: closed
completedbyFixes #25089;pm:dispatchedremoved in this act (domain:spec,area:recordsand the type label stay).Generated by Claude Code