v6.1.0-edge.6: CodeGen reproducibility, IsA subtype composition, and privilege-escalation guards
The seventh Edge build of the 6.1 line — 95 changesets across 306 packages, and unusually inward-looking. The dominant theme is CodeGen telling the truth about a database built only from what the repo ships: a run of fixes that each began as “this works on my dev database and fails on a fresh install,” which is the class of defect that reaches customers first and developers last. Alongside it, IS-A subtype composition becomes declarative — an entity can now describe how to resolve its own subtype in metadata rather than in registered runtime code — and a sustained pass over privilege escalation, SQL-fragment injection surfaces, and undrained fetch bodies.
Edge builds are prereleases. They publish under the edge dist-tag and never move latest.
New Features
Section titled “New Features”Entity.SubtypeSelector— declarative IS-A subtype resolution. An entity can carry a dotted foreign-key dereference path ending at the column that names its target subtype entity (ProductID.ProductTypeID.OrderLineExtensionEntity).BaseEntity.ResolveSubtypeEntityName()reads it when no runtimeEntitySubtypeResolveris registered, and offline tooling — Loom, CodeGen — can determine conditional IS-A children without executing application code. Prospective subtype resolution and sync composition axes land alongside it.- Conversation-scoped skill activation.
AISkill.ActivationScopedistinguishes a one-shot capability (Run) from a persona or mode that persists (Conversation). A skill activated in a run belonging to a conversation stays active for that conversation via anMJ: Conversation Skillsrow and is re-requested at the start of every later root run until ended — still subject to every availability gate on each run. Authorization.Checkas a remotable operation, with composite-filter evaluation, so authorization decisions are callable across the wire rather than only in-process.- Image, Color and JSON
EntityField.ExtendedTypes, withPhotoURL/LogoURLrendering as linked thumbnails in the entity viewer. - Host-controllable whiteboard
ToolRosterthat gates the toolbar, keyboard shortcuts and context menu together, plus hostReadOnlysupport. - Form section indicators — an unsaved-edits dot and an invalid-field count on the form rail and panel headers, re-resolving automatically when field visibility changes.
- Writable geo — a real write path, isolated parallel providers, and
skipGeoCodingfor callers that already have coordinates. - Open App server packages load in every MJ process, with per-process scoping, so a dynamic package behaves the same in MJAPI, the CLI and CodeGen.
- Artifacts without a viewer plugin now get a file card and a working download instead of an empty frame.
BaseEntity.FieldIsDirtyfor per-field edited checks.- The installer defaults to pnpm, with an explicit
npmoverride.
Improvements
Section titled “Improvements”- CodeGen is idempotent against database state. Two runs over an unchanged database produce zero diffs; a single new column touches only that entity’s artifacts. Field-categorisation decisions persist to
metadata/entities/decisions/, so a clean-room build matches a warm one. - Fresh-database drift eliminated. A cluster of fixes for output that differed between a long-lived dev database and one built only from migrations — pending
EntityFielddiscovery scoped toincludeSchemas,IdentityClaimmetadata tail and relationship dedupe, and UTC default normalisation. - Recurring reconcilers no longer leak into versioned migrations.
omitRecurringScriptsFromLognow defaults totrue. CodeGen’s SQL log was capturingspDeleteUnneededEntityFields, which then replayed from an intermediate schema state on a fresh install and deletedEntityFieldrows the migrations had correctly created — surfacing much later asMsg 213on everySave(). A CI gate now refuses a migration carrying that prune. - PostgreSQL counterparts for the full v6 backlog, bringing
migrations/v6↔migrations-pg/v6to complete parity. ExtraFilteracceptsIN (SELECT … FROM entity BaseView), so a subquery against a base view is expressible without dropping to custom SQL.- One provider per JSON graph in sync, so nested children share the parent transaction.
- Deterministic save-call SQL variable suffixes on SQL Server, and nested savepoints moved onto
GenericDatabaseProviderwhere both dialects can use them. - The AI-model research routine prompt is checked in, including the cost-status rule that has twice broken a sync push.
Bug Fixes
Section titled “Bug Fixes”- Privilege-escalation and role-elevation guards on
MJ: Users,MJ: RolesandMJ: User Roles— a non-Owner administrator can no longer create or delete users, or modify privileged columns on a user row. - Security hardening across request surfaces: CORS defaults, an OAuth error open redirect, consent scope grants,
CustomWhereClausegating, client SQL fragments screened for subqueries, the Conditional action, the artifact iframe, and Gmail header handling. - Six recurring undrained-fetch-body leaks closed, and
RemoteBrowserActionResolver’s session maps bounded. - Generated
Validate()overrides are no longer silently deleted.mj codegen --no-aiemitted every entity subclass as though it had no validators, removing 56 committed overrides rather than declining to add new ones — because the load of persistedGeneratedCodewas reachable on only one code path, and then gated behind the AI feature flag even there. Reading approved generated code is a database read; it is no longer treated as an AI call. EntityFieldINSERTs no longer carry a literalSequence. A literal collides onUQ_EntityField_EntityID_Sequenceon any database built only from migrations, and reports itself as an unrelated foreign-key error.InstanceConnectionStringcollapsed every connection to one identity in the SQL Server provider.- RLS exemption honours the permission row’s
Can*flags rather than exempting wholesale. - The polymorphic
EntityID/RecordIDsoft-link path works, instead of assuming every record pointer holds a single bare key value. - Five form controls stopped latching their disabled state, and the related-grid reserves horizontal-scrollbar height.
- Cognito OAuth endpoints resolve from the hosted-UI domain in the MCP server.
- Agent-generated media is stored in configured file storage rather than inline.
- Conversation diagnostic logging is opt-in instead of unconditional.
- Open App CodeGen_Run SQL is written to the app’s own
migrations/codegen, not the core repo’s.