Releases: objectstack-ai/objectstack
Release list
@objectstack/plugin-reports@16.0.0-rc.1
@objectstack/plugin-pinyin-search@16.0.0-rc.1
Patch Changes
- Updated dependencies [674457a]
- @objectstack/objectql@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
- @objectstack/types@16.0.0-rc.1
@objectstack/plugin-hono-server@16.0.0-rc.1
Minor Changes
-
bfa3c3f: Broadcast a
transactionalBatchcapability bit in discovery so clients negotiate the atomic cross-object batch declaratively, instead of runtime-probing 404/405/501 (#3298).The atomic cross-object batch endpoint (
POST {basePath}/batch, #1604 / ADR-0034 item 4) and its typed SDK surface (client.data.batchTransaction, #3271) already shipped, but discovery never told a client whether a backend actually supports it. Consumers (notably ObjectUI'sObjectStackAdapter) had to probe: fire a/batch, read404/405(no route) or501(no runtime transaction), and only then fall back to non-atomic client-side simulation. That is "find out by calling", not capability negotiation — it cannot be decided at connect time and cannot serve as the "minimum backend supports/batch" gate that blocks hard-deleting the non-atomic fallback downstream.WellKnownCapabilitiesSchemagains a requiredtransactionalBatch: boolean, and every discovery producer fills it honestly (declared === enforced), so it never becomes a declared-but-unpopulated bit:@objectstack/metadata-protocol(getDiscovery) — reports whether the runtime engine can honour a transaction (typeof engine.transaction === 'function'). The/batchhandler runs its ops insideengine.transaction(), which degrades to a non-atomic passthrough (or 501) without one.@objectstack/rest(/discovery) — ANDs the engine signal with whether it actually mounts the route (api.enableBatch), so a server with batch disabled reportsfalseeven on a transaction-capable engine (never advertise an endpoint that would 404).@objectstack/plugin-hono-server(standalone discovery) — reportsfalse: this minimal surface registers CRUD only and does not mount/batch(that ships with@objectstack/rest). Under-reporting is the safe direction — a client keeps its correct-but-slower fallback rather than losing atomicity.@objectstack/client— already normalizes hierarchicalcapabilitiesto flat booleans, soclient.capabilities.transactionalBatchis exposed (and now typed) for declarative consumers.
The bit follows the existing capability semantics:
true⟺ the/batchroute is mounted and the runtime can honour a transaction — the exact condition under which the endpoint returns200rather than404/405/501. Additive and behavior-preserving; only the discovery payload gains a field. -
62a2117: Split the overloaded
managedBy: 'system'bucket with an explicitengine-ownedvalue (ADR-0103 addendum, #3343). ADR-0103 deferred the enum split ("revisitable later as a rename") because a newmanagedByvalue would fall through to the fully-editableplatformdefault on deployed Console clients. Both reasons against it are now retired — the server-side write guard /apiMethodsreconciliation //me/permissionsclamp make that fallthrough cosmetic (the write is rejected regardless of what the client renders), and objectui#2712 closed the UI union — so v16 lands it, additively.- New enum value
engine-ownedwith the same all-locked default affordance row assystem(create/import/edit/delete: false,exportCsv: true). It joinsENGINE_OWNED_BUCKETS(the engine write guard) andGUARDED_WRITE_BUCKETS(the/me/permissionsclamp); the guard,reconcileManagedApiMethods, and the clamp mechanisms are unchanged —engine-ownedis an explicit member of the set they already covered by resolved affordance. - 20 objects relabelled
system → engine-owned— the ones the engine owns end to end and that declared no write-openinguserActions(the metadata store, jobs, approval runtime rows, sharing rows,sys_automation_run, the messaging delivery/receipt pipeline,sys_secret, settings). One-line, behaviour-identical per object. - 8 admin/user-writable objects keep
managedBy: 'system'(the RBAC link tables,sys_user_preference,sys_approval_delegation, the messaging config grids) —systemnow reads as "engine-managed schema, writable viauserActions".
Behaviour-, enforcement- and wire-identical: resolved affordances, the guard verdict, the 405
apiMethodsreconciliation, and the permissions clamp are the same before and after — this is a self-documenting relabel, not a policy change. No data migration (managedByis schema metadata) and no code branches on the'system'literal. Retiring the overloadedsystementirely (moving the 8 writable objects to a dedicated bucket) is a breaking rename deferred to v17. - New enum value
Patch Changes
@objectstack/plugin-email@16.0.0-rc.1
Patch Changes
- Updated dependencies [6289ec3]
- Updated dependencies [8efa395]
- Updated dependencies [bfa3c3f]
- Updated dependencies [7125007]
- Updated dependencies [62a2117]
- Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/platform-objects@16.0.0-rc.1
- @objectstack/formula@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
@objectstack/plugin-dev@16.0.0-rc.1
Patch Changes
- Updated dependencies [6289ec3]
- Updated dependencies [8efa395]
- Updated dependencies [bfa3c3f]
- Updated dependencies [ee0a499]
- Updated dependencies [9d897b3]
- Updated dependencies [62a2117]
- Updated dependencies [674457a]
- Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/rest@16.0.0-rc.1
- @objectstack/plugin-hono-server@16.0.0-rc.1
- @objectstack/runtime@16.0.0-rc.1
- @objectstack/plugin-security@16.0.0-rc.1
- @objectstack/objectql@16.0.0-rc.1
- @objectstack/account@16.0.0-rc.1
- @objectstack/setup@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
- @objectstack/driver-memory@16.0.0-rc.1
- @objectstack/plugin-auth@16.0.0-rc.1
- @objectstack/service-i18n@16.0.0-rc.1
- @objectstack/types@16.0.0-rc.1
@objectstack/plugin-auth@16.0.0-rc.1
Patch Changes
- Updated dependencies [6289ec3]
- Updated dependencies [8efa395]
- Updated dependencies [bfa3c3f]
- Updated dependencies [62a2117]
- Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/platform-objects@16.0.0-rc.1
- @objectstack/rest@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
- @objectstack/types@16.0.0-rc.1
@objectstack/plugin-audit@16.0.0-rc.1
Patch Changes
-
ee0a499: feat(i18n): localize collaboration notification titles and the storage objects; wire the notifications REST routes
Three gaps behind one report (a
sys_file "repro.png" assigned to you
notification that was English on an all-Chinese workspace, opened an English
detail page, and never cleared its unread state):-
plugin-audit — the assignment (
collab.assignment) and @mention
(collab.mention) bell titles were hardcoded English literals built from the
raw object API name. They now resolve through the i18n service with the same
key shapes as the activity summaries (framework#3039): new
messages.assignedToYou/messages.mentionedYou/
messages.mentionedYouAnonymoustemplates (en / zh-CN / ja-JP / es-ES), the
object named by its translated label (objects.{name}.label→ authored def
label → API name), and the locale resolved for the recipient (they read
the bell), not the acting user. Every step stays best-effort: no locale / no
i18n / key miss degrades to the English literal — which now also prefers the
authored object label over the API name. -
service-storage —
sys_file/sys_upload_sessionhad no translation
bundle at all, so the file detail page (labels, and the Pending Upload /
Committed / Deleted status pipeline) rendered English on every locale. The
service now ships its own ADR-0029 D8 bundle (en / zh-CN / ja-JP / es-ES,
src/translations+scripts/i18n-extract.config.ts) and contributes it via
i18n.loadTranslationsonkernel:ready, matching service-messaging.
(sys_attachmentstays in platform-objects' bundles pending the
storage-domain decomposition.) -
runtime — the in-app notifications REST surface (
GET /api/v1/notifications,POST /api/v1/notifications/read,POST /api/v1/notifications/read/all; ADR-0030) had itshandleNotification
dispatch branch and discovery entry, but noserver.<verb>()mount in
dispatcher-plugin, so only the cloud hosts' hono catch-all reached it — the
standalone /os devserver 404'd every request. That left mark-read with no
working endpoint (the console's directsys_notification_receiptwrite is
rejected by ADR-0103's engine-owned gate), so unread notifications could never
clear. The three routes are now mounted explicitly, guarded by the
route-registration regression test.
-
-
Updated dependencies [6289ec3]
-
Updated dependencies [8efa395]
-
Updated dependencies [bfa3c3f]
-
Updated dependencies [62a2117]
-
Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/platform-objects@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
@objectstack/plugin-approvals@16.0.0-rc.1
Minor Changes
-
e412fb6: feat(approvals): declare file attachments on approve/reject decisions
The declared
approval_approve/approval_rejectactions on
sys_approval_requestgain an optional multi-fileattachmentsparam
(type: 'file',multiple). The console renderstype:'file'action params
through the shared upload widget (objectui ADR-0059) and POSTs the resolved
attachments: string[], so a reviewer can attach supporting files to a
decision through the generic declared-action dialog — letting the approvals
inbox retire its hand-wired attachment composer (objectui#2698).Purely additive metadata: the decision route already forwards
body.attachmentstoApprovalService.decide, and the
sys_approval_action.attachmentscolumn (file, multiple) already persists them
(#3266/#3274). No service or route change. -
8efa395: feat(approvals): server-computed
viewercapability for precise decision-action gatinggetRequest/listRequestsnow attach a per-viewer block —
viewer: { can_act, is_submitter }— computed from the caller's context
(ApprovalRequestRow.viewer):can_act— the caller is a current pending approver (their user id is in the
request's resolvedpending_approverswhile it is stillpending). This is
the same check the decision methods authorize with, so it already reflects
position/team/manager resolution — strictly more accurate than a client-side
identity guess.is_submitter— the caller submitted the request.
The declared decision actions on
sys_approval_requestnow gate on it: approver
actions (approve/reject/reassign/send-back/request-info) use
record.viewer.can_act; submitter levers (remind/recall/resubmit) use
record.viewer.is_submitter. Previously approver actions only trimmed the
non-pending case, so a submitter viewing their own pending request saw buttons
they couldn't use (the backend 403'd); a position-addressed approver could be
wrongly hidden by the old client heuristic. Wherevieweris absent (a row
surfaced outside a service read with a user context), the predicate fails closed.
Patch Changes
-
62a2117: Split the overloaded
managedBy: 'system'bucket with an explicitengine-ownedvalue (ADR-0103 addendum, #3343). ADR-0103 deferred the enum split ("revisitable later as a rename") because a newmanagedByvalue would fall through to the fully-editableplatformdefault on deployed Console clients. Both reasons against it are now retired — the server-side write guard /apiMethodsreconciliation //me/permissionsclamp make that fallthrough cosmetic (the write is rejected regardless of what the client renders), and objectui#2712 closed the UI union — so v16 lands it, additively.- New enum value
engine-ownedwith the same all-locked default affordance row assystem(create/import/edit/delete: false,exportCsv: true). It joinsENGINE_OWNED_BUCKETS(the engine write guard) andGUARDED_WRITE_BUCKETS(the/me/permissionsclamp); the guard,reconcileManagedApiMethods, and the clamp mechanisms are unchanged —engine-ownedis an explicit member of the set they already covered by resolved affordance. - 20 objects relabelled
system → engine-owned— the ones the engine owns end to end and that declared no write-openinguserActions(the metadata store, jobs, approval runtime rows, sharing rows,sys_automation_run, the messaging delivery/receipt pipeline,sys_secret, settings). One-line, behaviour-identical per object. - 8 admin/user-writable objects keep
managedBy: 'system'(the RBAC link tables,sys_user_preference,sys_approval_delegation, the messaging config grids) —systemnow reads as "engine-managed schema, writable viauserActions".
Behaviour-, enforcement- and wire-identical: resolved affordances, the guard verdict, the 405
apiMethodsreconciliation, and the permissions clamp are the same before and after — this is a self-documenting relabel, not a policy change. No data migration (managedByis schema metadata) and no code branches on the'system'literal. Retiring the overloadedsystementirely (moving the 8 writable objects to a dedicated bucket) is a breaking rename deferred to v17. - New enum value
-
Updated dependencies [6289ec3]
-
Updated dependencies [8efa395]
-
Updated dependencies [bfa3c3f]
-
Updated dependencies [7125007]
-
Updated dependencies [62a2117]
-
Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/platform-objects@16.0.0-rc.1
- @objectstack/formula@16.0.0-rc.1
- @objectstack/metadata-core@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
@objectstack/platform-objects@16.0.0-rc.1
Patch Changes
-
6289ec3: feat(i18n): translation slot for action
resultDialogcopy — the one-shot secret-reveal dialogs are now localizableThe post-success
resultDialog(temporary passwords, 2FA backup codes, OAuth
client secrets) had no slot in the translation protocol, so its title /
description / acknowledge button / field labels always rendered the hardcoded
English metadata literals even on fully-translated locales.- spec.
_actions.<action>(object + object-first node) and
globalActions.<action>gain an optionalresultDialogtranslation node
(ActionResultDialogTranslationSchema):title,description,
acknowledge, andfieldskeyed by the literal result-field path
(e.g."user.email"— keys may contain dots; resolvers index the record
directly, never split on.). NewresolveActionResultDialogoverlay
resolver, wired intotranslateActionfor API-boundary translation. - cli.
os i18n extractemits the newresultDialog.*keys (title /
description / acknowledge /fields.<path>for labelled fields), so
coverage and skeleton generation see them. - platform-objects. en / zh-CN / ja-JP / es-ES bundles ship the
resultDialog copy for all six shipped dialogs:sys_user.create_user,
sys_user.set_user_password,sys_two_factor.enable_two_factor,
sys_two_factor.regenerate_backup_codes,
sys_oauth_application.create_oauth_application, and
sys_oauth_application.rotate_client_secret.
Client-side rendering lands in objectui (
actionResultDialogresolver in
@object-ui/i18n+ result-dialog handlers). Purely additive — untranslated
locales keep falling back to the metadata literals. - spec.
-
62a2117: Split the overloaded
managedBy: 'system'bucket with an explicitengine-ownedvalue (ADR-0103 addendum, #3343). ADR-0103 deferred the enum split ("revisitable later as a rename") because a newmanagedByvalue would fall through to the fully-editableplatformdefault on deployed Console clients. Both reasons against it are now retired — the server-side write guard /apiMethodsreconciliation //me/permissionsclamp make that fallthrough cosmetic (the write is rejected regardless of what the client renders), and objectui#2712 closed the UI union — so v16 lands it, additively.- New enum value
engine-ownedwith the same all-locked default affordance row assystem(create/import/edit/delete: false,exportCsv: true). It joinsENGINE_OWNED_BUCKETS(the engine write guard) andGUARDED_WRITE_BUCKETS(the/me/permissionsclamp); the guard,reconcileManagedApiMethods, and the clamp mechanisms are unchanged —engine-ownedis an explicit member of the set they already covered by resolved affordance. - 20 objects relabelled
system → engine-owned— the ones the engine owns end to end and that declared no write-openinguserActions(the metadata store, jobs, approval runtime rows, sharing rows,sys_automation_run, the messaging delivery/receipt pipeline,sys_secret, settings). One-line, behaviour-identical per object. - 8 admin/user-writable objects keep
managedBy: 'system'(the RBAC link tables,sys_user_preference,sys_approval_delegation, the messaging config grids) —systemnow reads as "engine-managed schema, writable viauserActions".
Behaviour-, enforcement- and wire-identical: resolved affordances, the guard verdict, the 405
apiMethodsreconciliation, and the permissions clamp are the same before and after — this is a self-documenting relabel, not a policy change. No data migration (managedByis schema metadata) and no code branches on the'system'literal. Retiring the overloadedsystementirely (moving the 8 writable objects to a dedicated bucket) is a breaking rename deferred to v17. - New enum value
-
Updated dependencies [6289ec3]
-
Updated dependencies [8efa395]
-
Updated dependencies [bfa3c3f]
-
Updated dependencies [62a2117]
-
Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/metadata-core@16.0.0-rc.1