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
v18 upgrade: stored controlled_by_parent objects without exactly one master_detail (two masters, none, a required lookup, required:false) are denied after upgrade with no conversion or fate #23270
Filed by the repo:cloud#1 seat (seat post #6026, session session_01WVbr5J6u8BHh8EyFtcWciH) under ruling objectstack-ai/cloud#2866 A (6146394952). The maintainer ruled that tenant databases are migrated by the platform's v18 upgrade script, not by cloud. The maintainer's lane rule: anything that blocks cloud's v18 upgrade is high priority. Source: the cloud re-pin report objectstack-ai/cloud#2709 6145524807 (data_shape_changes), at framework 01a3421f42.
Every other stored controlled_by_parent shape fails ObjectSchema at hydration: two masters, no master, a required lookup only, or an explicit required: false.
Measured on a tenant kernel at 01a3421f42 (objectstack-ai/cloud#2865 6146363767, two boots):
the row registers under [metadata_spec_invalid], and a member then reads 0 rows and an insert answers 422 INVALID_METADATA;
the object's data is unreachable to users after the upgrade.
Why it blocks
Cloud's AI build gave controlled_by_parent to any object with a master_detail before objectstack-ai/cloud#2854 and #2865, so stored AI-built junctions with two masters exist in tenant databases. Under cloud#2866 A their migration belongs to the platform's script.
Ask
A fate for each non-conforming stored shape in the v18 upgrade. For example, a junction with two masters becomes public_read_write with its references kept, or the ceremony refuses and reports it for an owner's choice. The lane decides; the ask is that the upgrade handles or reports them rather than leaving the object silently denied.
Triage: first grade, bug · priority:p1 · target:v18 · domain:spec, into pm:queue (finding removed). Each non-conforming stored controlled_by_parent shape gets one fate in the v18 upgrade: converted, or refused and listed
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-13T14:04Z. ⛔ Not a claim, ⛔ not a dispatch.
Why p1 target:v18: ruling A on objectstack-ai/cloud#2866 (6146394952) says the platform's v18 upgrade migrates tenant databases. The maintainer's lane rule is that whatever blocks cloud's v18 upgrade is high priority. The filer's p1 stands.
an entry of the spec's migration chain (packages/spec/src/migrations/entries/semantic/), applied by os migrate meta;
or a refusal listed in the ADR-0131 D10 ceremony's report.
So this is domain:spec. The lane chooses the route per shape, as the card says. A D2 conversion must stay lossless, declared, loud and tested; a shape that cannot be converted losslessly is refused and listed.
⛔ No guessed master. Where two master_detail fields exist, choosing one is the owner's call. The card's example (a two-master junction becomes public_read_write with its references kept) changes who can read the rows, so it is a listed fate for the owner, not a silent rewrite.
Pins: one per shape, plus a conforming object that the upgrade leaves untouched.
Triage: lands in packages/spec/src/conversions/registry.ts or packages/spec/src/migrations/ (domain:spec); rationale: stored v17 rows must reach the v18 refusal through the upgrade, not at boot.
Claim: PM loop round 1 (#23270, folded into the v18 stored-row family dispatch whose chain head is #23269) · 2026-10-13T14:37Z
Session: session_01BRQ9Mp1yH7R1az6MaUM18H
Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-23269-v18-stored-row-fates (shared; this card keeps its own Fixes #23270 line in the family PR)
Worktree: objectstack-issue-23269
Domain: domain:spec
Seat: domain:spec#2 (seat post #18549)
File surface: as the chain head's claim on #23269 states (packages/spec/src/conversions/**, packages/spec/src/migrations/entries/semantic/**, their tests and generated projections, one changeset); stop on breach and explain in the report.
Container & model: one family dispatch, mode:subagent, model: default tier. A CONTRACT_REVIEW_TIER review precedes the queue.
Clause-②: no (stored v17 rows are converted into what the v18 doors already accept, or refused and listed)
Responsibility: as the chain head's claim states, for this card's shape
Thread-read: 6147368827
Serial constraints cleared: the fold and its five gates are answered in the chain head's claim on #23269.
This act moves the card pm:queue → pm:dispatched and assigns os-justin.
Landed with #23269 · PR #23315 → 572ecfb2e; the landing record is on #23269. pm:dispatched is removed in this act. · domain:spec seat 2 · session session_01BRQ9Mp1yH7R1az6MaUM18H
Activity
objectstack-fleet commentedon Oct 13, 2026
Triage: first grade,
bug·priority:p1·target:v18·domain:spec, intopm:queue(findingremoved). Each non-conforming storedcontrolled_by_parentshape gets one fate in the v18 upgrade: converted, or refused and listedTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-13T14:04Z. ⛔ Not a claim, ⛔ not a dispatch.Why p1
target:v18: ruling A on objectstack-ai/cloud#2866 (6146394952) says the platform's v18 upgrade migrates tenant databases. The maintainer's lane rule is that whatever blocks cloud's v18 upgrade is high priority. The filer's p1 stands.Lane: every route the card names is spec-owned:
packages/spec/src/conversions/registry.ts, as finding(security): controlled_by_parent derives its master through a REQUIRED LOOKUP (runtime and lint, third tier) where ADR-0055 §1 requires exactly one required master_detail and fails closed — a widening no record states #23100 shippedcbp-master-detail-required-defaulted;packages/spec/src/migrations/entries/semantic/), applied byos migrate meta;So this is
domain:spec. The lane chooses the route per shape, as the card says. A D2 conversion must stay lossless, declared, loud and tested; a shape that cannot be converted losslessly is refused and listed.Family: v18 upgrade: stored flows whose get/update/delete_record filter operand is a {…} token are refused at boot with no conversion — every deployment's automations built on the old spelling stop running #23269, v18 upgrade: stored controlled_by_parent objects without exactly one master_detail (two masters, none, a required lookup, required:false) are denied after upgrade with no conversion or fate #23270 and v18 upgrade: stored views with data.provider 'api' are refused at rehydration with no conversion — the upgrade should migrate or report them #23271 share one report channel: what the upgrade converts, and what it refuses and lists. One family dispatch is fine, with the chain head's claim naming the shared branch and each card keeping its own
Fixesline.⛔ A runtime that tolerates the old spelling is not the ask, on any of the three cards.
Clause ②: no. A conversion of stored rows into what the v18 doors already accept widens nothing.
Direction:
76815b9013) converts one shape: exactly onemaster_detailwithrequiredomitted. The card names the rest: two masters, no master, a required lookup only, and an explicitrequired: false. Each gets exactly one fate, written down: a lossless conversion where one exists, otherwise refused and listed by object.master_detailfields exist, choosing one is the owner's call. The card's example (a two-master junction becomespublic_read_writewith its references kept) changes who can read the rows, so it is a listed fate for the owner, not a silent rewrite.Related: spec: export the controlled_by_parent master predicate, so a producer does not restate ADR-0055 §1's exactly-one-master rule #23272 asks the spec to export the exactly-one-master predicate. The entry may use the same predicate, so the two do not drift.
Triage: lands in
packages/spec/src/conversions/registry.tsorpackages/spec/src/migrations/(domain:spec); rationale: stored v17 rows must reach the v18 refusal through the upgrade, not at boot.objectstack-fleet commentedon Oct 13, 2026
Claim: PM loop round 1 (#23270, folded into the v18 stored-row family dispatch whose chain head is #23269) · 2026-10-13T14:37Z
Session:
session_01BRQ9Mp1yH7R1az6MaUM18HAccount:
os-justin(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-23269-v18-stored-row-fates(shared; this card keeps its ownFixes #23270line in the family PR)Worktree:
objectstack-issue-23269Domain:
domain:specSeat:
domain:spec#2(seat post #18549)File surface: as the chain head's claim on #23269 states (
packages/spec/src/conversions/**,packages/spec/src/migrations/entries/semantic/**, their tests and generated projections, one changeset); stop on breach and explain in the report.Container & model: one family dispatch,
mode:subagent,model: default tier. ACONTRACT_REVIEW_TIERreview precedes the queue.Clause-②: no (stored v17 rows are converted into what the v18 doors already accept, or refused and listed)
Responsibility: as the chain head's claim states, for this card's shape
Thread-read: 6147368827
Serial constraints cleared: the fold and its five gates are answered in the chain head's claim on #23269.
This act moves the card
pm:queue→pm:dispatchedand assignsos-justin.Generated by Claude Code
objectstack-fleet commentedon Oct 13, 2026
Landed with #23269 · PR #23315 →
572ecfb2e; the landing record is on #23269.pm:dispatchedis removed in this act. ·domain:specseat 2 · sessionsession_01BRQ9Mp1yH7R1az6MaUM18HGenerated by Claude Code