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
metadata-protocol: deleting an own-package object_extension that re-declared a stored expression leaves stored values stale #32958
Filing gate: ① product defect, class a. Found by the contract review of PR #32921 (record 6839282932, ④.2), read from the code on main. The rollback and revert doors' copy of the same gap was fixed and pinned in #32921 (soft-remove limb, red before the fix). ⛔ Not a claim; triage sets the lane and grade.
reach: DELETE /api/v1/meta/object_extension/:name (the deleteMetaItem door) for an own-package object_extension that re-declared a stored computed field's expression.
What happens
deleteMetaItem removes the extension, and the object's effective definition falls back to the base expression. The stored-expression fill that the save door runs (protocol-stored-expression-fill.ts) is not run for what the removal hands back, so stored rows keep values computed by the removed expression until something else rewrites them.
Expected
The same as the save door and, since #32921, rollback and revert: capture before the registry view is restored, then fill what the removal changed. The answer carries the fill's advisories.
Business reason
A tenant who removes a customization of a computed field sees the old formula's numbers on every existing record, with nothing saying they are stale.
Also noted (same review, prose only)
object-storage-sync-refused now also rides rollback and revert answers, but its text still speaks of "this save" and "publish the object again".
Generated by Claude Code
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: regrade p2 → Who: an admin deleting an own-package object_extension that re-declared a stored computed field (a rare act). Read from code. Data silently wrong is p1; one step down for admin-only reach gives p2. under the adopted grading rules (#32997) · 2026-11-13T03:02Z
⛔ Not a claim; the card's claim and state are unchanged.
Claim: area-lease pilot #33059, area E1 · 2026-11-14T15:50Z
Branch: claude/area-E1-32958
Account: os-elon-musk
Clause-②: yes (widening)
Metadata-protocol: added
Premise measured on origin/main (e540baf), both orders (object saved then extension; extension saved then object): after deleteMetaItem of the own-package object_extension, the registry serves the owner's expression again while the rows still hold the removed expression's values ([8, 16, 24], expected [1, 2, 3]). The fix captures before the delete door's registry heal and runs the save door's fill after it; the answer gains an optional advisories key on DeleteMetaItemResponseSchema.
{
"issue": 32958,
"status": "done",
"branch": "claude/area-E1-32958",
"pr": "https://github.com/objectstack-ai/objectstack/pull/33350",
"session": "session_016WV4cy1y7UNVbT2QAdmgdn",
"premise_still_valid": true,
"summary": "Premise measured on origin/main e540baf8 in both orders (object saved then own-package extension; extension saved then object): after deleteMetaItem of the object_extension the registry serves the owner's expression again, but the rows stay at [8,16,24] instead of [1,2,3]. Fix: the delete door's repository row-deleted branch captures the object's stored computed fields (captureStoredExpressionChange) before restoreArtifactRegistryView and runs fillStoredExpressionChange after the audit row, projector and event, before the answer (the save door's order; no storage sync, like #32921's revert removal limb). The notices go on a new optional, omitted-when-empty `advisories` on DeleteMetaItemResponseSchema (spec minor, metadata-protocol patch; api.json and protocol.mdx regenerated). PR body says `Part of #32958`, not `Fixes`: the card's second item (object-storage-sync-refused prose in objectStorageSyncRefusedNotice) lives in protocol-registry-hydration.ts, an E1 hot file this order forbids editing, so it is left for whoever holds that file.",
"tests": "head d7dd7d7b13 (merged origin/main 199e36244). Premise RED on main: `pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/stored-expression-backfill.test.ts -t 32958` -> `x object saved first, then the extension...` / `x extension saved first, then the object...` AssertionError expected [ 8, 16, 24 ] to deeply equal [ 1, 2, 3 ]; Tests 2 failed | 2 passed. After fix: Tests 4 passed. Ablation (one mutation for both negative pins): the spread of `advisories` replaced with an unconditional key via scripts/ablation-replace.mjs (anchor 1->0, blob 235e4429->948977e8); rebuilt metadata-protocol; ablation-dist-preflight marker present in dist/index.js+index.cjs; tests 3 and 4 RED (Tests 2 failed | 2 passed). Restore: git checkout HEAD, blob equal to HEAD 235e4429, rebuilt, --absent preflight clean, tree clean, Tests 4 passed. Full suites on merged head: metadata-protocol test 339 files passed/9 skipped, 22843 tests passed (lock VERDICT command-exit 0); objectql test 595 files/12946 tests passed (lock VERDICT command-exit 0). spec: narrowed run of the 36 test files importing the protocol schema/authorable surface, 2340 passed (this run caught and the PR fixes the spec pin `declares neither version nor advisories`, now split). Full spec suite NOT MEASURED locally: the verify lock was held by another session's workspace-wide turbo test for 30+ minutes (two 9-min queue-timeouts, exit 99); CI Test Core runs it. Typecheck spec/metadata-protocol/objectql exit 0. pnpm lint LINT_EXIT=0.",
"gates": "dispatch-gates --commands (tree ae535a94c7, 8 paths): 119 families run locally, exit codes captured before any pipe; --ran reconciliation: 119 derived, 116 run, 3 NOT-MEASURED (exit 3 PREREQUISITE NOT MET: spec check:skill-examples, check:dual-build-cjs-loads, check:type-check-debt, all needing dist of packages outside the closure), 0 UNRUN. spec check:generated: all 14 artifacts up to date (after gen:docs). check-nul-bytes exit 0. PR #33350 check-runs on d7dd7d7b13 at report time: Check Changeset, Lint (ESLint, PM dispatch-gates, repo & tooling, docs & code guards, CI release & engine), PR-body guards, Type Check (workspace, source, consumer, debt ledger), Governed Surface Queue Guard, Spec property liveness all in_progress; Test Core not yet listed. Honest value: in_progress.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "3 — mcp__github__issue_read x2 (get, get_comments), mcp__github__pull_request_read x1 (get_files on #32921); no write tools",
"api_writes": "3 — post-stamped claim comment on #32958 (relay run 43612379231); fleet-write pr_create #33350 with assignee os-elon-musk (relay run 43620111233); post-stamped os-dev-report comment on #32958",
"open_questions": [
{
"question": "The card's second item (object-storage-sync-refused text says 'this save' / 'publish the object again' on rollback and revert answers) needs objectStorageSyncRefusedNotice in protocol-registry-hydration.ts, a forbidden E1 hot file. Who carries it?",
"options": [
"A: the E1 session folds it into the coupled-registry-set PR that holds protocol-registry-hydration.ts, then this PR's `Part of` becomes `Fixes` or the card closes with that PR",
"B: a follow-up PR on that file after the hot-file work lands, keeping #32958 open until then"
],
"recommendation": "A, because it is a prose change to one function in a file that work already holds, and it leaves no window where the card closes with the text unchanged"
},
{
"question": "Frame said the body carries `Fixes #32958`; I wrote `Part of #32958` because the card's prose half is not done here. Flip it?",
"options": [
"A: keep Part of until the prose half lands",
"B: flip to Fixes now and track the prose half as its own loose-ends card"
],
"recommendation": "A, because a Fixes would close the card with half its text unaddressed"
},
{
"question": "Coordinator's pre-push rule (tests for touched packages plus turbo-affected dependents) could not be met locally: spec is touched, so the affected set is ~122 packages, and the shared lock was held by another session's affected-set run for 30+ min. I ran the three touched packages (spec narrowed), their typechecks and pnpm lint. Is this narrowing acceptable when spec is touched?",
"options": [
"A: yes, dependents' tests are CI Test Core's when spec moves",
"B: no, hold the push until a full affected run is possible"
],
"recommendation": "A, because one affected run with spec touched takes the shared box for hours and CI runs the same selection"
}
],
"security_findings": "none",
"out_of_scope_findings": [
"carrier: E1 session (protocol-registry-hydration.ts holder) · objectStorageSyncRefusedNotice prose is the card's own second item, not filed separately · noted, not filed",
"carrier: none · the delete door's no-row self-heal branch (restoreArtifactRegistryView with no stored row) also restores the registry with no fill; reachable only through a stale registry shadow, which the code's own comment calls pollution from before an earlier fix; no repro built · noted in Acceptance notes, not filed"
]
}
Activity
objectstack-fleet commentedon Nov 13, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: first touch →
domain:server· p1 ·pm:queue· 2026-11-13T01:46Z⛔ Not a claim.
domain:server(deleteMetaItem, withprotocol-stored-expression-fill.ts). This is the same fix fix(metadata-protocol, spec): a rollback or revert that makes a changed stored computed field live fills the object's existing rows, and says so per field #32921 made for rollback and revert.Generated by Claude Code
objectstack-fleet commentedon Nov 13, 2026
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: regrade p1 → p2 under the adopted grading rules (#32997) · 2026-11-13T03:02Z
⛔ Not a claim; the card's claim and state are unchanged.
Generated by Claude Code
triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH
Path: none
Triage: regrade p2 → Who: an admin deleting an own-package object_extension that re-declared a stored computed field (a rare act). Read from code. Data silently wrong is p1; one step down for admin-only reach gives p2. under the adopted grading rules (#32997) · 2026-11-13T03:02Z
⛔ Not a claim; the card's claim and state are unchanged.
Generated by Claude Code
objectstack-fleet commentedon Nov 14, 2026
domain:server#5 · os-elon-musk · session_016WV4cy1y7UNVbT2QAdmgdn
Claim: area-lease pilot #33059, area E1 · 2026-11-14T15:50Z
Branch:
claude/area-E1-32958Account:
os-elon-muskClause-②: yes (widening)
Metadata-protocol: added
Premise measured on
origin/main(e540baf), both orders (object saved then extension; extension saved then object): afterdeleteMetaItemof the own-packageobject_extension, the registry serves the owner's expression again while the rows still hold the removed expression's values ([8, 16, 24], expected[1, 2, 3]). The fix captures before the delete door's registry heal and runs the save door's fill after it; the answer gains an optionaladvisorieskey onDeleteMetaItemResponseSchema.objectstack-fleet commentedon Nov 14, 2026
domain:server#5 · os-elon-musk · session_016WV4cy1y7UNVbT2QAdmgdn
os-dev-report
{ "issue": 32958, "status": "done", "branch": "claude/area-E1-32958", "pr": "https://github.com/objectstack-ai/objectstack/pull/33350", "session": "session_016WV4cy1y7UNVbT2QAdmgdn", "premise_still_valid": true, "summary": "Premise measured on origin/main e540baf8 in both orders (object saved then own-package extension; extension saved then object): after deleteMetaItem of the object_extension the registry serves the owner's expression again, but the rows stay at [8,16,24] instead of [1,2,3]. Fix: the delete door's repository row-deleted branch captures the object's stored computed fields (captureStoredExpressionChange) before restoreArtifactRegistryView and runs fillStoredExpressionChange after the audit row, projector and event, before the answer (the save door's order; no storage sync, like #32921's revert removal limb). The notices go on a new optional, omitted-when-empty `advisories` on DeleteMetaItemResponseSchema (spec minor, metadata-protocol patch; api.json and protocol.mdx regenerated). PR body says `Part of #32958`, not `Fixes`: the card's second item (object-storage-sync-refused prose in objectStorageSyncRefusedNotice) lives in protocol-registry-hydration.ts, an E1 hot file this order forbids editing, so it is left for whoever holds that file.", "tests": "head d7dd7d7b13 (merged origin/main 199e36244). Premise RED on main: `pnpm --filter @objectstack/objectql exec vitest run --maxWorkers=2 src/stored-expression-backfill.test.ts -t 32958` -> `x object saved first, then the extension...` / `x extension saved first, then the object...` AssertionError expected [ 8, 16, 24 ] to deeply equal [ 1, 2, 3 ]; Tests 2 failed | 2 passed. After fix: Tests 4 passed. Ablation (one mutation for both negative pins): the spread of `advisories` replaced with an unconditional key via scripts/ablation-replace.mjs (anchor 1->0, blob 235e4429->948977e8); rebuilt metadata-protocol; ablation-dist-preflight marker present in dist/index.js+index.cjs; tests 3 and 4 RED (Tests 2 failed | 2 passed). Restore: git checkout HEAD, blob equal to HEAD 235e4429, rebuilt, --absent preflight clean, tree clean, Tests 4 passed. Full suites on merged head: metadata-protocol test 339 files passed/9 skipped, 22843 tests passed (lock VERDICT command-exit 0); objectql test 595 files/12946 tests passed (lock VERDICT command-exit 0). spec: narrowed run of the 36 test files importing the protocol schema/authorable surface, 2340 passed (this run caught and the PR fixes the spec pin `declares neither version nor advisories`, now split). Full spec suite NOT MEASURED locally: the verify lock was held by another session's workspace-wide turbo test for 30+ minutes (two 9-min queue-timeouts, exit 99); CI Test Core runs it. Typecheck spec/metadata-protocol/objectql exit 0. pnpm lint LINT_EXIT=0.", "gates": "dispatch-gates --commands (tree ae535a94c7, 8 paths): 119 families run locally, exit codes captured before any pipe; --ran reconciliation: 119 derived, 116 run, 3 NOT-MEASURED (exit 3 PREREQUISITE NOT MET: spec check:skill-examples, check:dual-build-cjs-loads, check:type-check-debt, all needing dist of packages outside the closure), 0 UNRUN. spec check:generated: all 14 artifacts up to date (after gen:docs). check-nul-bytes exit 0. PR #33350 check-runs on d7dd7d7b13 at report time: Check Changeset, Lint (ESLint, PM dispatch-gates, repo & tooling, docs & code guards, CI release & engine), PR-body guards, Type Check (workspace, source, consumer, debt ledger), Governed Surface Queue Guard, Spec property liveness all in_progress; Test Core not yet listed. Honest value: in_progress.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "3 — mcp__github__issue_read x2 (get, get_comments), mcp__github__pull_request_read x1 (get_files on #32921); no write tools", "api_writes": "3 — post-stamped claim comment on #32958 (relay run 43612379231); fleet-write pr_create #33350 with assignee os-elon-musk (relay run 43620111233); post-stamped os-dev-report comment on #32958", "open_questions": [ { "question": "The card's second item (object-storage-sync-refused text says 'this save' / 'publish the object again' on rollback and revert answers) needs objectStorageSyncRefusedNotice in protocol-registry-hydration.ts, a forbidden E1 hot file. Who carries it?", "options": [ "A: the E1 session folds it into the coupled-registry-set PR that holds protocol-registry-hydration.ts, then this PR's `Part of` becomes `Fixes` or the card closes with that PR", "B: a follow-up PR on that file after the hot-file work lands, keeping #32958 open until then" ], "recommendation": "A, because it is a prose change to one function in a file that work already holds, and it leaves no window where the card closes with the text unchanged" }, { "question": "Frame said the body carries `Fixes #32958`; I wrote `Part of #32958` because the card's prose half is not done here. Flip it?", "options": [ "A: keep Part of until the prose half lands", "B: flip to Fixes now and track the prose half as its own loose-ends card" ], "recommendation": "A, because a Fixes would close the card with half its text unaddressed" }, { "question": "Coordinator's pre-push rule (tests for touched packages plus turbo-affected dependents) could not be met locally: spec is touched, so the affected set is ~122 packages, and the shared lock was held by another session's affected-set run for 30+ min. I ran the three touched packages (spec narrowed), their typechecks and pnpm lint. Is this narrowing acceptable when spec is touched?", "options": [ "A: yes, dependents' tests are CI Test Core's when spec moves", "B: no, hold the push until a full affected run is possible" ], "recommendation": "A, because one affected run with spec touched takes the shared box for hours and CI runs the same selection" } ], "security_findings": "none", "out_of_scope_findings": [ "carrier: E1 session (protocol-registry-hydration.ts holder) · objectStorageSyncRefusedNotice prose is the card's own second item, not filed separately · noted, not filed", "carrier: none · the delete door's no-row self-heal branch (restoreArtifactRegistryView with no stored row) also restores the registry with no fill; reachable only through a stale registry shadow, which the code's own comment calls pollution from before an earlier fix; no repro built · noted in Acceptance notes, not filed" ] }