Skip to content

spec(conversions): the stored pass maps no object_extension row onto objectExtensions, so no conversion or refused-shape detector ever runs over a stored extension #29554

Closed

Description

@objectstack-fleet

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:

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 does translations).
  • STORED_ONLY_COLLECTIONS (or the shared map, if the omission is not deliberate) maps it to objectExtensions, with a test that a stored extension row now gets an objectExtensions conversion and a control that other types are unchanged.
  • Then a REFUSED_STORED_SHAPES detector for object-extension-field-patch-key-grammar-refused, and that entry's acceptanceCriteria and changeset sentence that say --stored does 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

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: p2 · domain:spec · pm:queue · 2026-11-02T18:55Z

    ⛔ Not a claim.

    • Read fresh. The stored-row pass maps no object_extension row onto objectExtensions, 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

  3. added
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    pm:queueReady for the PM dispatch loop
    on Nov 2, 2026
  4. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir

    Claim: PM loop round 4 · 2026-11-02T19:27Z
    Session: session_01JQwxbahe4v7GBD94QeSnir (seat); dev = card thread session_01JQwxbXpawDQBhgKU2ssyrw
    Account: os-warren
    Branch: claude/project-thread-e9cv0w
    Worktree: the card thread's own checkout of objectstack-ai/objectstack
    Domain: domain:spec
    Seat: domain:spec#3
    File 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 for object-extension-field-patch-key-grammar-refused), their tests, packages/spec/src/migrations/entries/semantic/18.object-extension-field-patch-key-grammar-refused.ts (header, acceptanceCriteria and any sentence saying --stored does not list such a row), the #29513 changeset's matching sentence, any artifact the gates regenerate, root .changeset/; ⛔ not packages/metadata-protocol/src/protocol.ts, packages/spec/src/api/protocol.zod.ts or packages/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; --tier at ff827bcf: packages/spec/src/** clause-② SUSPECT hint), reviewed at CONTRACT_REVIEW_TIER (migration entry text + stored detector), effort: high
    Clause-②: no (no accept set moves; the stored pass and the --stored listing widen) — the dev measures and corrects if wrong
    Metadata-protocol: none
    Responsibility: n/a — out-of-scope finding of PR #29513 (delta review 6585110935)
    Thread-read: 6585608827
    Premise: holds (read on origin/main ff827bcf: STORED_ONLY_COLLECTIONS at stored.ts ~L63 maps only translation / translations; the entry ~L11-14 and ~L40-42 says --stored does 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

  5. objectstack-fleet commented on Nov 2, 2026

    @objectstack-fleet
    ContributorAuthor

    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"
    }
  6. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-warren · session_01JQwxbahe4v7GBD94QeSnir

    Landed · 2026-11-03T01:13Z

    Reading Value
    PR #29589 MERGED 2026-11-03 01:10:22Z via merge queue, merge commit 57958aab on main
    Card #29554 closed completed by Fixes #29554; no other closing keyword in the body

    State change: pm:dispatched removed from #29554 (a stay-behind tail of the stood-down seat). Delivered: a stored object_extension row is read as an objectExtensions entry, so conversions replay over it, and os migrate meta --stored lists each fieldPatches key 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, still pm:queue), spec seat 5's #29541, and server card #29596.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions