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
Replaces the #2252 coerce-to-null stopgap with an actionable rejection, and
generalizes isLoadedPackage into isWritablePackage (drops the owns-an-object
heuristic that was the read-only-after-publish trap). Updates the repo-path
tests to assert rejection. Null stays a legacy overlay destination (D5 retires).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
// GUARD — a brand-new, DB-only ("runtime-only") metadata item must
3728
-
// not be bound to a *loaded code package*. Studio sends the
3729
-
// currently-selected package via `?package=`; when a user authors a
3730
-
// new object while browsing a code package (e.g. `app.objectstack.hotcrm`),
3731
-
// persisting that id as the new row's `package_id` makes the org
3732
-
// object read back as "provided by a code package" and become
3733
-
// read-only after publish — the user can no longer edit what they
3734
-
// just created. Drop the binding so it is a plain org overlay
3735
-
// (`package_id = null`, editable).
3722
+
// D1 (ADR-0070) — a brand-new, DB-only ("runtime-only") metadata
3723
+
// item MUST resolve to a WRITABLE base. Binding it to a read-only
3724
+
// code/installed package makes it read back as "code-provided" and
3725
+
// lock read-only after publish (the #2252 bug). We used to silently
3726
+
// coerce such a binding to `null`, but that scattered orphans into a
3727
+
// package-less bucket with no container to delete; ADR-0070 replaces
3728
+
// the coercion with an actionable rejection so the authoring surface
3729
+
// (Studio / AI) redirects the user to pick or create a base first.
3736
3730
//
3737
-
// Two scopes are deliberately left bound:
3731
+
// Left untouched (the binding survives):
3738
3732
// • `override-artifact` writes — an org overlay OF a packaged item
3739
-
// must keep pointing at that package.
3740
-
// • runtime writes into a package that is NOT loaded as code — an
3741
-
// ADR-0048 #1824 package *authoring workspace* is a bare id with
3742
-
// no registered manifest, and per-package scoping must survive.
3743
-
// `isLoadedPackage` distinguishes the two: only a booted code
3744
-
// package has a manifest / registered artifacts.
3745
-
// Mutate `request.packageId` (not a local copy) so every downstream
3746
-
// consumer — the repo write, the parent-version lookup, the live
3747
-
// registry mutation on publish, and the audit record — sees the
3748
-
// coerced value consistently. Coercing only the repo write left the
3749
-
// in-memory object stamped with the code package, so it still read
3750
-
// back as code-provided / read-only.
3733
+
// must keep pointing at the package it customizes (ADR-0005).
3734
+
// • a project-scoped base, or a bare ADR-0048 authoring-workspace
3735
+
// id — both are writable; `isWritablePackage` returns true.
3736
+
// A `null` packageId is still accepted here (legacy org-overlay
3737
+
// destination); ADR-0070 D5 retires it once the surfaces always
3738
+
// resolve a base and the orphan migration has run.
3751
3739
if(
3752
3740
intent==='runtime-only'&&
3753
3741
request.packageId!=null&&
3754
-
this.isLoadedPackage(request.packageId)
3742
+
!this.isWritablePackage(request.packageId)
3755
3743
){
3756
-
console.warn(
3757
-
`[Protocol] dropping package binding '${request.packageId}' from runtime-authored ${singularTypeForRepo}/${request.name} (it belongs to a loaded code package); persisting as an org overlay (package_id = null) so it stays editable.`,
3744
+
consterr=newError(
3745
+
`[writable_package_required] Cannot author ${singularTypeForRepo}/${request.name} into `
3746
+
+`'${request.packageId}': it is a read-only code/installed package, not a writable base. `
3747
+
+`Create or select a writable base (package) first, then retry. `
0 commit comments