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
lint: the object_extension publish door runs no field-formula judgment, so a computed field os build refuses still publishes through PUT /meta/object_extension #33072
Filing gate: ③ a follow-up a dev report surfaced (#32875, os-dev-report 6847088184, class a, measured at PR #33070 head 7b18b05f). Not reproduced over HTTP by the dev or the filer.
Reader: the lane that owns the runtime authoring-rule roster (runtimeTypes of validateStackExpressions in packages/lint/src/validate-expressions.ts, read by runtimeAuthoringRulesFor).
The object_extension publish door asks the same field-formula judgment the build asks of an extension field (against the extended object as served), so the two doors agree; a refusal at the door carries the same rule id and location the build prints.
Dedupe
repo:objectstack-ai/objectstack is:issue is:open object_extension validateSecurityRoleWord → #32875 only (the build half). Related: #32875, PR #33070, #32529.
⛔ Not a claim. The runtime object_extension publish door skips the field-formula judgment that os build/os validate now run (#32875 / PR #33070), so a Studio or API author gets no signal for a stored computed extension field. It is a missing authoring signal with the CLI as a workaround: p2 (#32997). Lane: domain:spec (runtimeTypes in validate-expressions.ts).
Claim: PM loop round 2 · 2026-11-13T14:12Z
Session: session_01L9qibvfX5bawZKtfa6u7j9 (seat); card thread session_01L9qibwwiSN1TXWjohzCZN9 is the dev
Account: os-tesla
Branch: claude/project-thread-1oe8qz (the card thread's designated branch; the platform lets a thread push only that branch, so not claude/issue-33072-*)
Worktree: objectstack-issue-33072
Domain: domain:spec
Seat: domain:spec#2
File surface: packages/lint/src/validate-expressions.ts; packages/lint/src/runtime-gate.ts / authoring-rules.ts where the runtime roster lives; the runtime object_extension publish door's file if the gate must be handed the served target; their tests; root .changeset/; a semantic-migration entry if the level is narrowed (stop on breach; explain in the report)
Container & model: M, mode:thread, model: default tier (the seat runs the contract review at landing), effort: high (fleet token rule 2, maintainer 2026-11-12)
Clause-②: no
Metadata-protocol: narrowed
Responsibility: validateStackExpressions declares runtimeTypes without object_extension, so runtimeAuthoringRulesFor('object_extension') answers only validateSecurityRoleWord (packages/lint) (objectstack) | none: PR #33070 judges extension fields at build only | every app author and AI agent adding a computed field through Studio's .custom pair or PUT /api/v1/meta/object_extension/TARGET; the door publishes a field os build refuses
Thread-read: 6847222554
Premise: holds at origin/main64551047: PR #33070 (#32875) merged and judges extension fields at build; the runtime roster for object_extension names only validateSecurityRoleWord (seat-filed finding from os-dev report 6847088184, class a). Level is provisional: the dev measures first-party exposure and confirms or corrects Metadata-protocol in the PR.
Serial constraints cleared: sibling cards #32836 / #32837 from this seat edit packages/lint/src/*.user-text.ts and finding-user-text.ts, outside this surface; no other open PR from this seat touches validate-expressions.ts.
{
"issue": 33072,
"status": "done",
"branch": "claude/project-thread-1oe8qz",
"pr": "https://github.com/objectstack-ai/objectstack/pull/33119",
"session": "session_01L9qibwwiSN1TXWjohzCZN9",
"premise_still_valid": true,
"summary": "Premise held at main 2c98485d: runtimeAuthoringRulesFor('object_extension') answered only validateSecurityRoleWord, and the door published an extension formula sqrt(record.amount) with 0 errors while the build refused it with 1 expression-invalid at object 'fx_ticket' · objectExtensions[0] · field 'score' expression (pins committed first at 5dae65b1, 8 of 10 red). validateStackExpressions now declares object_extension in runtimeTypes; on that write runStackExpressionPasses runs only #32875's extension walk (judgeFieldFormula over objectExtensionsByTarget, indexes over objectsAsServed): the object walk and flows walk read empty lists and the function returns after the walk, so no second field walk or fold exists. The host needed no change (the gate already carries live objects). Metadata-protocol narrowed, confirmed by measurement; first-party exposure 0. Semantic entry object-extension-door-computed-field-expression-judged and changeset 33072-object-extension-door-formula.md (minor lint + spec).",
"tests": "At c237a74a: pnpm --filter @objectstack/lint test → Test Files 202 passed (202), Tests 8625 passed (8625); typecheck exit 0. @objectstack/metadata-protocol (consumer, the gate host) vitest run → Test Files 337 passed | 7 skipped (344), Tests 22799 passed | 36 skipped. @objectstack/runtime src/domains/meta-object-extension-item.test.ts → 26 passed, the 3 new #33072 cases verbose-confirmed. Full @objectstack/runtime suite at 8c1950cb (consumer): lock VERDICT command-exit 0 (20m39s), Test Files 600 passed (600), Tests 11920 passed | 19 skipped (11939). New pins: lint runtime-gate.object-formula-writes.test.ts describe #33072 (10: roster, 3 LIT, PARITY door==build on one shared input, CONTROL valid formula, undeclared target, differential, narrowing, CONTROL object door) and runtime meta-object-extension-item.test.ts [#33072] (3, real saveMetaItem+publishMetaItem: 422 INVALID_METADATA, issue expression-invalid at object 'crm_account' · objectExtensions[0] · field 'score__c' expression, row left draft; misspelt read refused; CONTROL publishes and is served). Ablation 1: object_extension dropped from runtimeTypes via ablation-replace (anchor 1→0), lint rebuilt, ablation-dist-preflight --absent read the double-quoted dist marker gone → lint 8 failed / 41 passed, runtime (dist) 2 LIT failed / CONTROL passed; restore blob == HEAD, rebuild, preflight marker present in 4 files, runtime 3/3. A first attempt was a refused anchor miss (no write), not counted. Ablation 2: object-walk fence removed → 1 failed (the narrowing pin), differential green; restore blob == HEAD.",
"gates": "dispatch-gates --commands (objectstack-ai/objectstack at c237a74a, 8 paths vs merge base 2c98485d) → 87 families, each run with stdin from /dev/null, exit codes captured before any pipe: 86 exit 0, check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET, needs every dist). --ran with exit codes: 87 derived, 86 run, 1 NOT-MEASURED (derived), 0 UNRUN. After a full pnpm build at 8c1950cb (lock VERDICT command-exit 0, 7m36s) check:dual-build-cjs-loads exit 0 (123 entries / 72 packages load). The merge of origin/main 9433d4f3 (2 commits: skills/objectstack-data/** and scripts/pm/check-skill-line-ratchet.mjs) changed no derived path. PR check-runs at 8c1950cb when read: all eleven required contexts success: Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard, Lint UI (skipped by its path filter), Type Check UI, Test UI, Build & E2E UI, Live E2E UI, Dogfood Regression Gate; also Check Changeset, Check PR Size, Spec property liveness, PR-body guards, Flag docs affected by code changes success; 0 failures among 67 check-runs.",
"dogfood_battery": "8c1950cb · os-verify-lock: VERDICT command-exit 0 (34m15s) · Test Files 460 passed | 3 skipped (463) · Tests 3874 passed | 42 skipped (3916) · no failures",
"mcp_calls": "4 — mcp__github__issue_read x2 (get, get_comments; one more get_comments before pr_create), mcp__github__pull_request_read x1 (get_check_runs); 0 write tools",
"api_writes": "2 — relay pr_create (objectstack-ai/objectstack#33119, run 43449876536, body 12091 bytes read back identical, assignee os-tesla) and this os-dev-report comment via post-stamped; plus git push (not a REST write)",
"open_questions": [],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: none · noted, not filed · the door does not judge an extension's validations; the build does not judge them as extension items either (#32875 judged fields only), so the two doors agree",
"carrier: none · noted, not filed · location is index-exact only against a one-entry stack: the door's snapshot holds the written entry at objectExtensions[0], a multi-extension build prints that entry's own index; rule id, object, field and message agree in every case"
],
"deviations": [
"Clause-② written 'no (narrowing)' in the PR body and changeset where the claim reads 'no': the order expects the arm, and check-changeset-no-major refuses Metadata-protocol: narrowed beside a bare 'no' (same as #33070).",
"File surface: packages/runtime/src/domains/meta-object-extension-item.test.ts (the publish door's own test file) gained the end-to-end pin; no production file outside packages/lint changed.",
"Release: 18.4.0 had shipped before this card ran, so the change rides the next release, not 18.4.0 as the frame hoped."
]
}
The metadata-protocol file that builds the object_extension gate's snapshot (packages/metadata-protocol/src/protocol-object-extension-item.ts or runtime-authoring-gate.ts, whichever builds objects), and its tests. Use it only to hand the gate the target WITHOUT the written package's own stored extension of it, through the registry's existing fold option (withoutExtensionsOf). ⛔ No new fold.
content/docs/deployment/validating-metadata.mdx: add ᵒˣ to the CEL row's runtime column (~L497) and one sentence in the object_extension door section (~L601–609).
packages/runtime/src/domains/meta-object-extension-item.test.ts (test only; the end-to-end pins).
Declaration:Skills-docs: becomes none owed — … naming that this PR edits validating-metadata.mdx, or the spelling AGENTS.md prescribes for a docs edit in the same PR.
Added to the file surface:packages/metadata-protocol/src/protocol-stored-collection-fold.ts, packages/metadata-protocol/src/protocol-object-extender-fold.ts, and the two private wrappers in packages/metadata-protocol/src/protocol.ts that call them. The only change allowed: one optional pass-through parameter carrying the registry's existing withoutExtensionsOf option, so a target with a stored object row is also judged without the written package's own extension. No behaviour change for any other caller, ⛔ no new fold.
Pin: one real-door case where the target has a stored object row, in addition to the two S1 directions.
MERGED 2026-11-14T00:31Z as 3e19223b, landing head bb8a4622 (ACCEPT 6868149199; contract review 6858831273 + delta 6864935727, both PASS)
This card
closed by Fixes #33072; the runtime object_extension publish door judges an extension's computed-field expressions as os build does, a republish against the target without the package's own stored extension
Follow-ups
#33152 (batch publish pending set lacks extension drafts; stated as a limit in the changeset and entry), #33153 (formula cycles through an extension), #33154 (extension validations judged at neither door)
Activity
objectstack-fleet commentedon Nov 13, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: first touch →
domain:spec· p2 ·pm:queue· 2026-11-13T07:45Z⛔ Not a claim. The runtime object_extension publish door skips the field-formula judgment that
os build/os validatenow run (#32875 / PR #33070), so a Studio or API author gets no signal for a stored computed extension field. It is a missing authoring signal with the CLI as a workaround: p2 (#32997). Lane:domain:spec(runtimeTypesinvalidate-expressions.ts).Generated by Claude Code
objectstack-fleet commentedon Nov 13, 2026
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9
Claim: PM loop round 2 · 2026-11-13T14:12Z
Session:
session_01L9qibvfX5bawZKtfa6u7j9(seat); card threadsession_01L9qibwwiSN1TXWjohzCZN9is the devAccount:
os-teslaBranch:
claude/project-thread-1oe8qz(the card thread's designated branch; the platform lets a thread push only that branch, so notclaude/issue-33072-*)Worktree:
objectstack-issue-33072Domain:
domain:specSeat:
domain:spec#2File surface:
packages/lint/src/validate-expressions.ts;packages/lint/src/runtime-gate.ts/authoring-rules.tswhere the runtime roster lives; the runtimeobject_extensionpublish door's file if the gate must be handed the served target; their tests; root.changeset/; a semantic-migration entry if the level isnarrowed(stop on breach; explain in the report)Container & model: M,
mode:thread,model: default tier(the seat runs the contract review at landing),effort: high(fleet token rule 2, maintainer 2026-11-12)Clause-②: no
Metadata-protocol: narrowed
Responsibility:
validateStackExpressionsdeclaresruntimeTypeswithoutobject_extension, soruntimeAuthoringRulesFor('object_extension')answers onlyvalidateSecurityRoleWord(packages/lint) (objectstack) | none: PR #33070 judges extension fields at build only | every app author and AI agent adding a computed field through Studio's.custompair orPUT /api/v1/meta/object_extension/TARGET; the door publishes a fieldos buildrefusesThread-read: 6847222554
Premise: holds at
origin/main64551047: PR #33070 (#32875) merged and judges extension fields at build; the runtime roster forobject_extensionnames onlyvalidateSecurityRoleWord(seat-filed finding from os-dev report 6847088184, class a). Level is provisional: the dev measures first-party exposure and confirms or correctsMetadata-protocolin the PR.Serial constraints cleared: sibling cards #32836 / #32837 from this seat edit
packages/lint/src/*.user-text.tsandfinding-user-text.ts, outside this surface; no other open PR from this seat touchesvalidate-expressions.ts.objectstack-fleet commentedon Nov 13, 2026
domain:spec#2 · os-tesla · session_01L9qibwwiSN1TXWjohzCZN9
os-dev-report
{ "issue": 33072, "status": "done", "branch": "claude/project-thread-1oe8qz", "pr": "https://github.com/objectstack-ai/objectstack/pull/33119", "session": "session_01L9qibwwiSN1TXWjohzCZN9", "premise_still_valid": true, "summary": "Premise held at main 2c98485d: runtimeAuthoringRulesFor('object_extension') answered only validateSecurityRoleWord, and the door published an extension formula sqrt(record.amount) with 0 errors while the build refused it with 1 expression-invalid at object 'fx_ticket' · objectExtensions[0] · field 'score' expression (pins committed first at 5dae65b1, 8 of 10 red). validateStackExpressions now declares object_extension in runtimeTypes; on that write runStackExpressionPasses runs only #32875's extension walk (judgeFieldFormula over objectExtensionsByTarget, indexes over objectsAsServed): the object walk and flows walk read empty lists and the function returns after the walk, so no second field walk or fold exists. The host needed no change (the gate already carries live objects). Metadata-protocol narrowed, confirmed by measurement; first-party exposure 0. Semantic entry object-extension-door-computed-field-expression-judged and changeset 33072-object-extension-door-formula.md (minor lint + spec).", "tests": "At c237a74a: pnpm --filter @objectstack/lint test → Test Files 202 passed (202), Tests 8625 passed (8625); typecheck exit 0. @objectstack/metadata-protocol (consumer, the gate host) vitest run → Test Files 337 passed | 7 skipped (344), Tests 22799 passed | 36 skipped. @objectstack/runtime src/domains/meta-object-extension-item.test.ts → 26 passed, the 3 new #33072 cases verbose-confirmed. Full @objectstack/runtime suite at 8c1950cb (consumer): lock VERDICT command-exit 0 (20m39s), Test Files 600 passed (600), Tests 11920 passed | 19 skipped (11939). New pins: lint runtime-gate.object-formula-writes.test.ts describe #33072 (10: roster, 3 LIT, PARITY door==build on one shared input, CONTROL valid formula, undeclared target, differential, narrowing, CONTROL object door) and runtime meta-object-extension-item.test.ts [#33072] (3, real saveMetaItem+publishMetaItem: 422 INVALID_METADATA, issue expression-invalid at object 'crm_account' · objectExtensions[0] · field 'score__c' expression, row left draft; misspelt read refused; CONTROL publishes and is served). Ablation 1: object_extension dropped from runtimeTypes via ablation-replace (anchor 1→0), lint rebuilt, ablation-dist-preflight --absent read the double-quoted dist marker gone → lint 8 failed / 41 passed, runtime (dist) 2 LIT failed / CONTROL passed; restore blob == HEAD, rebuild, preflight marker present in 4 files, runtime 3/3. A first attempt was a refused anchor miss (no write), not counted. Ablation 2: object-walk fence removed → 1 failed (the narrowing pin), differential green; restore blob == HEAD.", "gates": "dispatch-gates --commands (objectstack-ai/objectstack at c237a74a, 8 paths vs merge base 2c98485d) → 87 families, each run with stdin from /dev/null, exit codes captured before any pipe: 86 exit 0, check:dual-build-cjs-loads exit 3 (PREREQUISITE NOT MET, needs every dist). --ran with exit codes: 87 derived, 86 run, 1 NOT-MEASURED (derived), 0 UNRUN. After a full pnpm build at 8c1950cb (lock VERDICT command-exit 0, 7m36s) check:dual-build-cjs-loads exit 0 (123 entries / 72 packages load). The merge of origin/main 9433d4f3 (2 commits: skills/objectstack-data/** and scripts/pm/check-skill-line-ratchet.mjs) changed no derived path. PR check-runs at 8c1950cb when read: all eleven required contexts success: Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard, Lint UI (skipped by its path filter), Type Check UI, Test UI, Build & E2E UI, Live E2E UI, Dogfood Regression Gate; also Check Changeset, Check PR Size, Spec property liveness, PR-body guards, Flag docs affected by code changes success; 0 failures among 67 check-runs.", "dogfood_battery": "8c1950cb · os-verify-lock: VERDICT command-exit 0 (34m15s) · Test Files 460 passed | 3 skipped (463) · Tests 3874 passed | 42 skipped (3916) · no failures", "mcp_calls": "4 — mcp__github__issue_read x2 (get, get_comments; one more get_comments before pr_create), mcp__github__pull_request_read x1 (get_check_runs); 0 write tools", "api_writes": "2 — relay pr_create (objectstack-ai/objectstack#33119, run 43449876536, body 12091 bytes read back identical, assignee os-tesla) and this os-dev-report comment via post-stamped; plus git push (not a REST write)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed · the door does not judge an extension's validations; the build does not judge them as extension items either (#32875 judged fields only), so the two doors agree", "carrier: none · noted, not filed · location is index-exact only against a one-entry stack: the door's snapshot holds the written entry at objectExtensions[0], a multi-extension build prints that entry's own index; rule id, object, field and message agree in every case" ], "deviations": [ "Clause-② written 'no (narrowing)' in the PR body and changeset where the claim reads 'no': the order expects the arm, and check-changeset-no-major refuses Metadata-protocol: narrowed beside a bare 'no' (same as #33070).", "File surface: packages/runtime/src/domains/meta-object-extension-item.test.ts (the publish door's own test file) gained the end-to-end pin; no production file outside packages/lint changed.", "Release: 18.4.0 had shipped before this card ran, so the change rides the next release, not 18.4.0 as the frame hoped." ] }objectstack-fleet commentedon Nov 13, 2026
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9
Surface amendment · 2026-11-13T16:30Z · amends Claim 6855427836 (rework r1 for PR #33119, contract review 6858831273 S1 + S2)
metadata-protocolfile that builds theobject_extensiongate's snapshot (packages/metadata-protocol/src/protocol-object-extension-item.tsorruntime-authoring-gate.ts, whichever buildsobjects), and its tests. Use it only to hand the gate the target WITHOUT the written package's own stored extension of it, through the registry's existing fold option (withoutExtensionsOf). ⛔ No new fold.content/docs/deployment/validating-metadata.mdx: addᵒˣto the CEL row's runtime column (~L497) and one sentence in theobject_extensiondoor section (~L601–609).packages/runtime/src/domains/meta-object-extension-item.test.ts(test only; the end-to-end pins).Skills-docs:becomesnone owed — …naming that this PR editsvalidating-metadata.mdx, or the spelling AGENTS.md prescribes for a docs edit in the same PR.objectstack-fleet commentedon Nov 13, 2026
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9
Surface amendment 2 · 2026-11-13T16:32Z · amends Claim 6855427836 and amendment 6858847138 (rework r1, S1)
packages/metadata-protocol/src/protocol-stored-collection-fold.ts,packages/metadata-protocol/src/protocol-object-extender-fold.ts, and the two private wrappers inpackages/metadata-protocol/src/protocol.tsthat call them. The only change allowed: one optional pass-through parameter carrying the registry's existingwithoutExtensionsOfoption, so a target with a stored object row is also judged without the written package's own extension. No behaviour change for any other caller, ⛔ no new fold.objectstack-fleet commentedon Nov 14, 2026
domain:spec#2 · os-tesla · session_01L9qibvfX5bawZKtfa6u7j9
Landed · 2026-11-14T00:32Z
3e19223b, landing headbb8a4622(ACCEPT 6868149199; contract review 6858831273 + delta 6864935727, both PASS)Fixes #33072; the runtimeobject_extensionpublish door judges an extension's computed-field expressions asos builddoes, a republish against the target without the package's own stored extensionvalidationsjudged at neither door)State:
pm:dispatchedremoved.