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
lint: promote relationship/master-detail-required from warning to error, scoped to controlled_by_parent — ruled for the v18 boundary (Direction 1 of #8772) #9139
Slice C (Direction 1) of the #8772 maintainer ruling (2026-08-16, comment 5306089973): promote the lint rule from warning to error, scoped to controlled_by_parent objects only, landing at the v18 major boundary — not before. Carved into its own card on the maintainer's 2026-08-16 instruction (PM chat, verbatim: 「接受你的建议,开新卡,现有的可以关闭?」), recorded by PM session session_01NYgmGheCzM6NrHZN436Cxf. Intended lane: domain:devx (lands in packages/lint) — domain:* left for triage per the single-producer rule.
Hold record (pm:on-hold — decision made, answer is "at v18")
Date: 2026-08-16.
Reason: the ruling schedules this deliberately at the next major (v17 went GA 2026-08-14 two days ago); it is a contract narrowing that belongs on a version boundary with its migration machinery, not mid-line.
Named restart condition: the v18 major window opens (first v18 RC branch cut / the protocol-18 migration window becomes the active target). Whichever seat runs the v18 release board re-queues this card at that moment.
Trigger files (opportunistic-restart clause): packages/lint/src/data-model-rules.ts and packages/lint/src/validate-security-posture.test.ts — any dispatch whose file surface intersects them must name this card.
Scope when restarted
error fires only for a master reference on a controlled_by_parent object, covering all three unsafe shapes: missing required; required: true + readonly; required: true + system (the latter two skipped by record-validator.ts's provenance-flag continue).
Ships with a v18 migration entry + upgrade-checklist line.
model: claude-fable-5 mandatory when implemented (accept-set narrowing).
⛔ Runtime stays as-is (resolveCbpRelation fallbacks kept — tolerance for existing installs); the guard freeze note (identity sibling) is only lifted once this lands.
Provenance
Slice C (Direction 1) of the #8772 maintainer ruling (2026-08-16, comment 5306089973): promote the lint rule from
warningtoerror, scoped tocontrolled_by_parentobjects only, landing at the v18 major boundary — not before. Carved into its own card on the maintainer's 2026-08-16 instruction (PM chat, verbatim: 「接受你的建议,开新卡,现有的可以关闭?」), recorded by PM sessionsession_01NYgmGheCzM6NrHZN436Cxf. Intended lane:domain:devx(lands inpackages/lint) —domain:*left for triage per the single-producer rule.Hold record (
pm:on-hold— decision made, answer is "at v18")packages/lint/src/data-model-rules.tsandpackages/lint/src/validate-security-posture.test.ts— any dispatch whose file surface intersects them must name this card.Scope when restarted
errorfires only for a master reference on acontrolled_by_parentobject, covering all three unsafe shapes: missingrequired;required: true+readonly;required: true+system(the latter two skipped byrecord-validator.ts's provenance-flagcontinue).validate-security-posture.test.ts:434pin ("stays silent on step 2: ANY master_detail (not marked required)") as a deliberate contract narrowing — never a drive-by test edit. Correction on record: that pin lives inpackages/lint/, notplugin-security(the Acontrolled_by_parentobject may declare its master reference withoutrequired, so the master-access guard is the only thing preventing an unreachable orphan detail row #8772 body mis-homed it).model: claude-fable-5mandatory when implemented (accept-set narrowing).resolveCbpRelationfallbacks kept — tolerance for existing installs); the guard freeze note (identity sibling) is only lifted once this lands.Refs: #8772 (ruling + full measurement) · siblings: guard freeze note (identity, immediate), builder-force (spec, immediate).