Tracking issue for the leftover follow-ups after the managedBy taxonomy line landed. The core work is done and merged — this issue captures only the genuinely useful remainder so nothing is lost, with clear priority. None of it is blocking.
What already shipped
Remaining follow-ups
1. Finish the objectui de-dup (recommended — small, completes #2712)
Repo: objectui. #2712 consolidated the three union/set mirrors but deliberately left three small inline userActions handlers that still parse the override shape by hand:
packages/app-shell/src/utils/managedByEmptyState.ts — inline userActions?.create === true + its local EmptyStateUserActions interface. Replace with the shared resolveCrudAffordances({ managedBy, userActions }).create (or a small canCreate helper) from @object-ui/core.
packages/plugin-form/src/ObjectForm.tsx (~the managed = managedBy !== 'platform' lock + userActions unlock) — replace with the shared isObjectInlineEditable / resolved affordance so the form's editability gate matches detail/grid exactly.
packages/plugin-grid/src/rowCrudAffordances.ts — its isOptedOut / predicate-parsing helpers overlap @object-ui/core's normalizeOverride; consolidate the userActions-normalizer so there's one parser.
Acceptance: no package re-parses the userActions override shape locally; existing affordance/edit-gate tests stay green; add coverage for the newly-shared paths. Behavior-preserving.
2. (Optional / future) Enum split as a pure rename
ADR-0103 chose userActions over a new managedBy enum value to avoid the fully-editable fallthrough on deployed Console clients. Now that the resolved-affordance policy is the enforced contract and the objectui type is a closed union, splitting system into an explicit engine-owned bucket value would be a mechanical rename rather than a behavioral change. Low priority — only worth doing if a more self-documenting taxonomy is wanted; the current userActions model is fully sufficient. Would touch: the spec enum + affordance matrix (packages/spec/src/data/object.zod.ts), the objectui union (@object-ui/types), ~30 object declarations, and the badge/empty-state copy.
3. (Optional) Browser dogfood verification of the ADR-0103 write policy
End-to-end validation the unit + dogfood-test suites can't fully cover: boot the showcase app, and as an admin confirm (a) a writable-system object like Notification Preferences is editable, (b) engine-owned objects (audit log, automation run, jobs) render read-only with no New/Edit/Delete, (c) a generic /data write to an engine-owned or better-auth object is rejected. Use the internal dogfood-verification tooling.
Explicitly out of scope
Related
#3220 · #3315 · #3325 · #3326 · #3333 · objectui#2705 · objectui#2712 · ADR-0092 · ADR-0103 · ADR-0049
Tracking issue for the leftover follow-ups after the
managedBytaxonomy line landed. The core work is done and merged — this issue captures only the genuinely useful remainder so nothing is lost, with clear priority. None of it is blocking.What already shipped
managedBy: 'system'bucket is overloaded (engine-only vs. admin-writable) — split the taxonomy; don't guard it wholesale #3220, ADR-0103) — split the overloadedmanagedBy: 'system'bucket into engine-owned vs. admin/user-writable (userActions), added theassertEngineOwnedWriteAllowedengine guard, generalizedreconcileManagedApiMethods+ the/me/permissionsclamp.systemobjects.BETTER_AUTH_MANAGED_OBJECTSdeny-list has already drifted (17/22) — derive managed-object write denies from the registry (ADR-0092/0103 follow-through) #3325) — the default-permission-set managed deny-list is now derived from the live registry (fixed a 17/22 drift) and pinned by test.managedBybucket declarations into a single shared source of truth (@object-ui/typesunion +@object-ui/coreruntime helpers) and tightened the open-ended schema type.Remaining follow-ups
1. Finish the objectui de-dup (recommended — small, completes #2712)
Repo: objectui. #2712 consolidated the three union/set mirrors but deliberately left three small inline
userActionshandlers that still parse the override shape by hand:packages/app-shell/src/utils/managedByEmptyState.ts— inlineuserActions?.create === true+ its localEmptyStateUserActionsinterface. Replace with the sharedresolveCrudAffordances({ managedBy, userActions }).create(or a smallcanCreatehelper) from@object-ui/core.packages/plugin-form/src/ObjectForm.tsx(~themanaged = managedBy !== 'platform'lock + userActions unlock) — replace with the sharedisObjectInlineEditable/ resolved affordance so the form's editability gate matches detail/grid exactly.packages/plugin-grid/src/rowCrudAffordances.ts— itsisOptedOut/ predicate-parsing helpers overlap@object-ui/core'snormalizeOverride; consolidate the userActions-normalizer so there's one parser.Acceptance: no package re-parses the
userActionsoverride shape locally; existing affordance/edit-gate tests stay green; add coverage for the newly-shared paths. Behavior-preserving.2. (Optional / future) Enum split as a pure rename
ADR-0103 chose
userActionsover a newmanagedByenum value to avoid the fully-editable fallthrough on deployed Console clients. Now that the resolved-affordance policy is the enforced contract and the objectui type is a closed union, splittingsysteminto an explicit engine-owned bucket value would be a mechanical rename rather than a behavioral change. Low priority — only worth doing if a more self-documenting taxonomy is wanted; the currentuserActionsmodel is fully sufficient. Would touch: the spec enum + affordance matrix (packages/spec/src/data/object.zod.ts), the objectui union (@object-ui/types), ~30 object declarations, and the badge/empty-state copy.3. (Optional) Browser dogfood verification of the ADR-0103 write policy
End-to-end validation the unit + dogfood-test suites can't fully cover: boot the showcase app, and as an admin confirm (a) a writable-
systemobject like Notification Preferences is editable, (b) engine-owned objects (audit log, automation run, jobs) render read-only with no New/Edit/Delete, (c) a generic/datawrite to an engine-owned or better-auth object is rejected. Use the internaldogfood-verificationtooling.Explicitly out of scope
writeViacapability for third-party-managed objects — deferred ([P0] Metadata property liveness audit: ~half of all spec properties are dead; a cluster of security props is parsed-but-unenforced #1878); no such object exists today, speculative until a concrete need arises.Check Changesetred (an inheritedmajorchangeset onmain,remove-session-tenantid-alias.md/ feat(hooks)!: remove deprecated ctx.session.tenantId alias — converge on organizationId (#3290) #3305) — a release-window decision unrelated to this taxonomy line; not tracked here.Related
#3220 · #3315 · #3325 · #3326 · #3333 · objectui#2705 · objectui#2712 · ADR-0092 · ADR-0103 · ADR-0049