Description
domain:spec#2 · os-steve · session_01ADHkmSduNGC2SZXszyrNut
Filing gate: ② an out-of-scope finding the #29366 dev reported on PR #29513 (round 2, head fb1c5bc9) and the seat's delta review confirmed in the tree (6585110935). ⛔ Not a claim. No grade: triage sets it.
What happens
applyConversionsToStoredItem (packages/spec/src/conversions/stored.ts) wraps a stored row in the stack collection named by SINGULAR_TO_PLURAL[type] ?? STORED_ONLY_COLLECTIONS[type] and returns the row untouched when neither names one. object_extension is in neither map, so a stored object_extension row is never wrapped as objectExtensions: [row]. As a result:
- no ADR-0087 conversion that walks
objectExtensions[]replays over a stored extension row at any rehydration seam; - no
REFUSED_STORED_SHAPESdetector can list one, soos migrate meta --storedreads every stored extension as already on protocol. PR feat(spec)!: key an object extension's fieldPatches by the field map's own key grammar #29513's entryobject-extension-field-patch-key-grammar-refusedhas to name a manual check for exactly this reason.
The dev's probe: an object_extension row with fieldPatches.Industry and a time default came back as the same reference, 0 TODOs, 0 notices; the control object row had its time default rewritten (1 notice).
Done when
- First measure which stored-row type name the extension rows carry (
object_extension, and any plural spelling the protocol read fallback finds) and whether the manifest map omits it deliberately (as it doestranslations). STORED_ONLY_COLLECTIONS(or the shared map, if the omission is not deliberate) maps it toobjectExtensions, with a test that a stored extension row now gets anobjectExtensionsconversion and a control that other types are unchanged.- Then a
REFUSED_STORED_SHAPESdetector forobject-extension-field-patch-key-grammar-refused, and that entry'sacceptanceCriteriaand changeset sentence that say--storeddoes not list such a row are corrected.
Serial: after PR #29513 (it touches that entry).
Related: #29366 / PR #29513, #19620 (STORED_ONLY_COLLECTIONS), #29523.
Activity
objectstack-fleet commentedon Nov 2, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: p2 ·
domain:spec·pm:queue· 2026-11-02T18:55Z⛔ Not a claim.
object_extensionrow ontoobjectExtensions, so no conversion and no refused-shape detector ever runs over a stored extension. An upgrade silently skips those rows. p2.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir
Claim: PM loop round 4 · 2026-11-02T19:27Z
Session:
session_01JQwxbahe4v7GBD94QeSnir(seat); dev = card threadsession_01JQwxbXpawDQBhgKU2ssyrwAccount:
os-warrenBranch:
claude/project-thread-e9cv0wWorktree: the card thread's own checkout of
objectstack-ai/objectstackDomain:
domain:specSeat:
domain:spec#3File surface:
packages/spec/src/conversions/stored.ts(the stored-only map, or the shared map if the omission is measured as not deliberate),packages/spec/src/conversions/refused-shapes.ts(one detector forobject-extension-field-patch-key-grammar-refused), their tests,packages/spec/src/migrations/entries/semantic/18.object-extension-field-patch-key-grammar-refused.ts(header,acceptanceCriteriaand any sentence saying--storeddoes not list such a row), the #29513 changeset's matching sentence, any artifact the gates regenerate, root.changeset/; ⛔ notpackages/metadata-protocol/src/protocol.ts,packages/spec/src/api/protocol.zod.tsorpackages/spec/src/identity/protocol.ts(frozen by server seat 5 until 06:00 UTC on 3 November) (stop on breach; explain in the report)Container & model:
M,mode:thread(platform exception: the seat container pushes only its mailbox branch),model: TIER_DEFAULT(build;--tieratff827bcf:packages/spec/src/**clause-② SUSPECT hint), reviewed atCONTRACT_REVIEW_TIER(migration entry text + stored detector),effort: highClause-②: no (no accept set moves; the stored pass and the
--storedlisting widen) — the dev measures and corrects if wrongMetadata-protocol: none
Responsibility: n/a — out-of-scope finding of PR #29513 (delta review 6585110935)
Thread-read: 6585608827
Premise: holds (read on
origin/mainff827bcf:STORED_ONLY_COLLECTIONSatstored.ts~L63 maps onlytranslation/translations; the entry ~L11-14 and ~L40-42 says--storeddoes not list such a row)Serial constraints cleared: PR #29513 merged 19:07Z; no open PR touches these files, read over every open PR this patrol. Spec seat 5's #29541 will also add a detector to
refused-shapes.ts: additive, seat 5 lands after this PR (agreed in thread). #29523 (same seat) is held serial behind this card.Generated by Claude Code
objectstack-fleet commentedon Nov 2, 2026
domain:spec#3 · os-warren · session_01JQwxbXpawDQBhgKU2ssyrw
os-dev-report
{ "issue": 29554, "status": "done", "branch": "claude/project-thread-e9cv0w", "pr": "https://github.com/objectstack-ai/objectstack/pull/29589", "session": "session_01JQwxbXpawDQBhgKU2ssyrw", "premise_still_valid": true, "summary": "Premise held on origin/main ff827bcf: applyConversionsToStoredItem returned a stored object_extension row by reference with 0 notices and 0 TODOs, while the control object row got a time-default-utc-suffix-dropped notice. Measured: object_extension is the only stored spelling (the save door folds object_extensions and objectExtensions to it; the read fallback finds no other; migrateStoredMetadata skips a non-canonical stored type before reading the body), and the manifest map's omission of objectExtensions is deliberate (check:stack-collection-maps waiver: extensions merge into their target, not named items). So STORED_ONLY_COLLECTIONS maps object_extension to objectExtensions beside translation; one REFUSED_STORED_SHAPES detector for object-extension-field-patch-key-grammar-refused, appended last, whose predicate is ObjectExtensionSchema.safeParse keeping each invalid_key issue at fieldPatches.KEY; the entry header, acceptanceCriteria and the #29366 changeset sentence now say --stored lists such a row. patch changeset added. No protocol.ts file touched.", "tests": "pnpm --filter @objectstack/spec exec vitest run src/conversions/stored.test.ts src/conversions/refused-shapes.test.ts: Test Files 2 passed, Tests 110 passed. vitest run src/conversions src/migrations: 28 files, 981 tests passed. Spec typecheck exit 0. Ablation 1 (scripts/ablation-replace.mjs deleting the object_extension map line, committed first): 3 failed / 107 passed, restored, blob e26e3a1e equals HEAD, git diff HEAD empty. Ablation 2 (deleting the detector from REFUSED_STORED_SHAPES): 3 failed / 84 passed, restored, blob d205cc7d equals HEAD. End-to-end probe (throwaway copy of the protocol.stored-migration.test.ts harness on the built objectql closure, not committed): an extension with only fieldPatches.Industry reads skipped with 1 TODO at objectExtensions[0].fieldPatches.Industry; with a Z-suffixed time default too it previews pending with both lines and fails on apply at the save door; a packaged extension with only the time default on opens_at__c is rewritten and stored as 12:00.", "gates": "At head 91fbde28 (branch merged with origin/main dbca3ef0). dispatch-gates --commands --repo objectstack-ai/objectstack: 81 derived; --ran reconciliation 81 accounted, 80 run, 1 NOT MEASURED, 0 unrun. All exit 0 except: node scripts/check-empty-changeset.mjs --base origin/main exit 1 (deliberate correction of the pending #29366 changeset, red by design until a person confirms); pnpm check:dual-build-cjs-loads exit 3 NOT MEASURED (needs every package built; CI Lint and Repo Gates runs it). check-plugin-teardown-shape --self-test exit 3 on the shallow clone, exit 0 after fetching its pinned fixture commit; check:lean-entry-closure exit 3, exit 0 after the objectql closure build. Extra, outside the derivation, all exit 0: check:stack-collection-maps, spec check:meta-url-spelling, spec typecheck, spec vitest src/conversions src/migrations. CI check-runs: in_progress at report time.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "3: git push of claude/project-thread-e9cv0w (2 pushes, not REST); relay pr_create (fleet-write run 41518249483) opening PR 29589; this os-dev-report comment via post-stamped.mjs on issue 29554", "open_questions": [ { "question": "The deliberate correction of the pending changeset .changeset/29366-field-patches-key-grammar.md reds check-empty-changeset by design. Keep it?", "options": [ "A keep the corrected sentence and have a person confirm it on the PR, as the gate prescribes", "B restore the base sentence and let only this PR's changeset say the row is listed" ], "recommendation": "A, because the order and the card ask for the correction and B ships a false sentence next to a true one in the same release notes" } ], "security_findings": "none", "out_of_scope_findings": [ "carrier: none · noted, not filed: the missing-direction waiver reason in scripts/check-stack-collection-maps.mjs still says objectExtensions has no singular metadata-type name, though ADR-0146 D10 added object_extension; the waiver stays right, only its reason text is dated (wording)" ], "deviations": "Clause-② line copied from the Claim without its trailing instruction to the dev (measured: no accept set moves, Metadata-protocol none holds). Commit trailer is the model-free pair the pre-push hook requires. The branch carries one merge of origin/main (stale dispatch-gates engine files). Platform PR body footer and attribution lines kept as the harness requires.", "body_amendments": "none" }objectstack-fleet commentedon Nov 3, 2026
domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir
Landed · 2026-11-03T01:13Z
57958aabonmaincompletedbyFixes #29554; no other closing keyword in the bodyState change:
pm:dispatchedremoved from #29554 (a stay-behind tail of the stood-down seat). Delivered: a storedobject_extensionrow is read as anobjectExtensionsentry, so conversions replay over it, andos migrate meta --storedlists eachfieldPatcheskey no field name can be; the pending #29366 changeset sentence was corrected on Warren's written confirmation (PR comment 6591818192). Unblocked: #29523 (was serial behind this PR, stillpm:queue), spec seat 5's #29541, and server card #29596.Generated by Claude Code