- Updated dependencies [212b66a]
- Updated dependencies [d10c4dc]
- Updated dependencies [9e45b63]
- Updated dependencies [b20201f]
- @objectstack/platform-objects@16.1.0
- @objectstack/spec@16.1.0
- @objectstack/core@16.1.0
- @objectstack/formula@16.1.0
- @objectstack/metadata-core@16.1.0
-
e412fb6: feat(approvals): declare file attachments on approve/reject decisions
The declared
approval_approve/approval_rejectactions onsys_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 resolvedattachments: 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 thesys_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) userecord.viewer.can_act; submitter levers (remind/recall/resubmit) userecord.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. -
3a18b60: feat(approvals): rename the
roleapprover type toorg_membership_level(#3133)ApproverType.rolewas the last platform surface projecting the reserved word "role" (ADR-0090 D3). It is not covered by D3's better-auth exception: that exception protects better-auth's ownsys_member.rolecolumn, which we do not own —ApproverTypeis our own enum, an authoring surface, and D3 mandates that the projection of that concept is spelledorg_membership_leveland labelled "organization membership", never "role".The sentence licensing the leak was also false: ADR-0090 D3 claims
sys_member.roleis "already relabelledorg_membership_levelin the platform projection", butorg_membership_levelexisted nowhere in the codebase and ADR-0057 D7 lists that relabel under "Deferred (evidence-gated, P4)". The projection never landed, so the word reached authors.The name manufactured a real, silent failure — "hotcrm class": every other surface renamed to
position(sys_role,ShareRecipientType.role,ctx.roles[]), so{ type: 'role', value: 'sales_manager' }reads as the legacy spelling of a position. It resolves against the membership tier, finds no member row, falls back to an inertrole:sales_managerliteral, and the request waits forever on an approver that cannot exist.- spec:
ApproverTypegainsorg_membership_level;rolestays as a deprecated alias for one window (a published 15.x flow keeps loading) withDEPRECATED_APPROVER_TYPES+canonicalApproverType()as the single source for the mapping. Removed in the next major. - plugin-approvals: resolves on the canonical type and warns on the
deprecated spelling. The
type:valuefallback literal keeps the authored spelling — storedsys_approval_approverrows andpending_approversslots from 15.x carryrole:<v>, and rewriting it would orphan them. - lint:
approval-role-not-membership-tier→approval-approver-not-membership-tier(the rule id carried the reserved word too), plus a newapproval-approver-type-deprecated. The two are mutually exclusive: a bad value wins, because prescribingorg_membership_levelfor a position name would be wrong advice — the fix there isposition.
Authoring
type: 'role'keeps working and now says so out loud. Rewrite it asorg_membership_level; if the value is an org position, the fix isposition. - spec:
-
22013aa: Split the overloaded
managedBy: 'system'bucket into engine-owned vs. admin-writable, and enforce engine-owned writes (ADR-0103, #3220). Thesystembucket conflated two incompatible write policies: rows a platform service owns end to end (never user-written), and platform-defined schema whose rows are legitimately admin/user-writable. It carried the same all-false affordance row asbetter-auth/append-onlybut, unlikebetter-auth, had no engine enforcement — a wildcard admin could raw-write these rows through the generic data API (ADR-0049 gap).Rather than add a new
managedByenum value (which would fall through to fully-editableplatformdefaults on already-deployed Console clients), the write policy is now the resolved affordance (resolveCrudAffordances= bucket default +userActions), and engine-owned is defined as asystem/append-onlyobject that grants no write:- Writable set declares
userActions— the RBAC link tables (sys_user_position,sys_user_permission_set,sys_position_permission_set),sys_user_preference,sys_approval_delegation, and the messaging config grids (sys_notification_preference/…_subscription/…_template) now declareuserActions: { create, edit, delete: true }. The affordance is a declaration only — theDelegatedAdminGate/ RLS / permission sets remain the authz. - Engine-owned objects locked to reads —
apiMethods: ['get','list']added where absent (jobs, notifications, approval request/approver/token/action,sys_record_share,sys_automation_run, mail/settings/secret audit, the messaging delivery pipeline).sys_secretis explicitly read-locked (an emptyapiMethodsarray fails open). sys_import_jobstays engine-owned: the REST import route now writes its job rowsisSystem-elevated (attribution preserved via the explicitcreated_bystamp) and the object is locked to['get','list'].- New engine write guard (
assertEngineOwnedWriteAllowed, plugin-security) fail-closed rejects user-context generic writes to engine-ownedsystem/append-onlyobjects, keyed off the resolved affordance;isSystemand context-less engine/service writes bypass by construction. Wired into the security middleware alongside the other data-layer gates. reconcileManagedApiMethods(objectql registry) now runs for every managed bucket, not justbetter-auth: any advertised write verb an object's resolved affordances forbid is stripped at registration with a warning (the drift backstop, ADR-0049)./me/permissionsclamp (plugin-hono-server) now clampssystem/append-onlyas well asbetter-auth, so the client hint reflectspermission ∩ guard.
Potentially breaking: a downstream/third-party
systemobject that advertised generic write verbs relying on today's fail-open behaviour will have those verbs stripped (with a warning) and user-context generic writes to it rejected. DeclareuserActionsopening the verbs the object legitimately takes from a user context.better-authkeeps plugin-auth's identity write guard unchanged; the row-levelmanaged_byprovenance vocabulary (ADR-0066) is a different axis and is untouched. - Writable set declares
-
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 [f972574]
-
Updated dependencies [6289ec3]
-
Updated dependencies [22013aa]
-
Updated dependencies [3ad3dd5]
-
Updated dependencies [8efa395]
-
Updated dependencies [3a18b60]
-
Updated dependencies [a8aa34c]
-
Updated dependencies [e057f42]
-
Updated dependencies [a3823b2]
-
Updated dependencies [bc65105]
-
Updated dependencies [43a3efb]
-
Updated dependencies [524696a]
-
Updated dependencies [6b51346]
-
Updated dependencies [80273c8]
-
Updated dependencies [bfa3c3f]
-
Updated dependencies [5e3301d]
-
Updated dependencies [dd9f223]
-
Updated dependencies [46e876c]
-
Updated dependencies [7125007]
-
Updated dependencies [5f05de2]
-
Updated dependencies [021ba4c]
-
Updated dependencies [158aa14]
-
Updated dependencies [62a2117]
-
Updated dependencies [d2723e2]
-
Updated dependencies [fefcd54]
-
Updated dependencies [beaf2de]
-
Updated dependencies [06cb319]
-
Updated dependencies [369eb6e]
-
Updated dependencies [06ff734]
-
Updated dependencies [b659111]
-
Updated dependencies [5754a23]
-
Updated dependencies [6c270a6]
-
Updated dependencies [290e2f0]
-
Updated dependencies [668dd17]
-
Updated dependencies [8abf133]
-
Updated dependencies [e0859b1]
-
Updated dependencies [04ecd4e]
-
Updated dependencies [4d5a892]
-
Updated dependencies [16cebeb]
-
Updated dependencies [86d30af]
-
Updated dependencies [8923843]
-
Updated dependencies [ea32ec7]
-
Updated dependencies [a2795f6]
-
Updated dependencies [f16b492]
-
Updated dependencies [4b6fde8]
-
Updated dependencies [2018df9]
-
Updated dependencies [fc5a3a2]
-
Updated dependencies [8ff9210]
- @objectstack/spec@16.0.0
- @objectstack/platform-objects@16.0.0
- @objectstack/core@16.0.0
- @objectstack/formula@16.0.0
- @objectstack/metadata-core@16.0.0
-
e412fb6: feat(approvals): declare file attachments on approve/reject decisions
The declared
approval_approve/approval_rejectactions onsys_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 resolvedattachments: 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 thesys_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) userecord.viewer.can_act; submitter levers (remind/recall/resubmit) userecord.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.
-
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
-
3a18b60: feat(approvals): rename the
roleapprover type toorg_membership_level(#3133)ApproverType.rolewas the last platform surface projecting the reserved word "role" (ADR-0090 D3). It is not covered by D3's better-auth exception: that exception protects better-auth's ownsys_member.rolecolumn, which we do not own —ApproverTypeis our own enum, an authoring surface, and D3 mandates that the projection of that concept is spelledorg_membership_leveland labelled "organization membership", never "role".The sentence licensing the leak was also false: ADR-0090 D3 claims
sys_member.roleis "already relabelledorg_membership_levelin the platform projection", butorg_membership_levelexisted nowhere in the codebase and ADR-0057 D7 lists that relabel under "Deferred (evidence-gated, P4)". The projection never landed, so the word reached authors.The name manufactured a real, silent failure — "hotcrm class": every other surface renamed to
position(sys_role,ShareRecipientType.role,ctx.roles[]), so{ type: 'role', value: 'sales_manager' }reads as the legacy spelling of a position. It resolves against the membership tier, finds no member row, falls back to an inertrole:sales_managerliteral, and the request waits forever on an approver that cannot exist.- spec:
ApproverTypegainsorg_membership_level;rolestays as a deprecated alias for one window (a published 15.x flow keeps loading) withDEPRECATED_APPROVER_TYPES+canonicalApproverType()as the single source for the mapping. Removed in the next major. - plugin-approvals: resolves on the canonical type and warns on the
deprecated spelling. The
type:valuefallback literal keeps the authored spelling — storedsys_approval_approverrows andpending_approversslots from 15.x carryrole:<v>, and rewriting it would orphan them. - lint:
approval-role-not-membership-tier→approval-approver-not-membership-tier(the rule id carried the reserved word too), plus a newapproval-approver-type-deprecated. The two are mutually exclusive: a bad value wins, because prescribingorg_membership_levelfor a position name would be wrong advice — the fix there isposition.
Authoring
type: 'role'keeps working and now says so out loud. Rewrite it asorg_membership_level; if the value is an org position, the fix isposition. - spec:
-
22013aa: Split the overloaded
managedBy: 'system'bucket into engine-owned vs. admin-writable, and enforce engine-owned writes (ADR-0103, #3220). Thesystembucket conflated two incompatible write policies: rows a platform service owns end to end (never user-written), and platform-defined schema whose rows are legitimately admin/user-writable. It carried the same all-false affordance row asbetter-auth/append-onlybut, unlikebetter-auth, had no engine enforcement — a wildcard admin could raw-write these rows through the generic data API (ADR-0049 gap).Rather than add a new
managedByenum value (which would fall through to fully-editableplatformdefaults on already-deployed Console clients), the write policy is now the resolved affordance (resolveCrudAffordances= bucket default +userActions), and engine-owned is defined as asystem/append-onlyobject that grants no write:- Writable set declares
userActions— the RBAC link tables (sys_user_position,sys_user_permission_set,sys_position_permission_set),sys_user_preference,sys_approval_delegation, and the messaging config grids (sys_notification_preference/…_subscription/…_template) now declareuserActions: { create, edit, delete: true }. The affordance is a declaration only — theDelegatedAdminGate/ RLS / permission sets remain the authz. - Engine-owned objects locked to reads —
apiMethods: ['get','list']added where absent (jobs, notifications, approval request/approver/token/action,sys_record_share,sys_automation_run, mail/settings/secret audit, the messaging delivery pipeline).sys_secretis explicitly read-locked (an emptyapiMethodsarray fails open). sys_import_jobstays engine-owned: the REST import route now writes its job rowsisSystem-elevated (attribution preserved via the explicitcreated_bystamp) and the object is locked to['get','list'].- New engine write guard (
assertEngineOwnedWriteAllowed, plugin-security) fail-closed rejects user-context generic writes to engine-ownedsystem/append-onlyobjects, keyed off the resolved affordance;isSystemand context-less engine/service writes bypass by construction. Wired into the security middleware alongside the other data-layer gates. reconcileManagedApiMethods(objectql registry) now runs for every managed bucket, not justbetter-auth: any advertised write verb an object's resolved affordances forbid is stripped at registration with a warning (the drift backstop, ADR-0049)./me/permissionsclamp (plugin-hono-server) now clampssystem/append-onlyas well asbetter-auth, so the client hint reflectspermission ∩ guard.
Potentially breaking: a downstream/third-party
systemobject that advertised generic write verbs relying on today's fail-open behaviour will have those verbs stripped (with a warning) and user-context generic writes to it rejected. DeclareuserActionsopening the verbs the object legitimately takes from a user context.better-authkeeps plugin-auth's identity write guard unchanged; the row-levelmanaged_byprovenance vocabulary (ADR-0066) is a different axis and is untouched. - Writable set declares
-
Updated dependencies [f972574]
-
Updated dependencies [22013aa]
-
Updated dependencies [3ad3dd5]
-
Updated dependencies [3a18b60]
-
Updated dependencies [a8aa34c]
-
Updated dependencies [e057f42]
-
Updated dependencies [a3823b2]
-
Updated dependencies [bc65105]
-
Updated dependencies [43a3efb]
-
Updated dependencies [524696a]
-
Updated dependencies [6b51346]
-
Updated dependencies [80273c8]
-
Updated dependencies [5e3301d]
-
Updated dependencies [dd9f223]
-
Updated dependencies [46e876c]
-
Updated dependencies [5f05de2]
-
Updated dependencies [021ba4c]
-
Updated dependencies [158aa14]
-
Updated dependencies [d2723e2]
-
Updated dependencies [fefcd54]
-
Updated dependencies [beaf2de]
-
Updated dependencies [06cb319]
-
Updated dependencies [369eb6e]
-
Updated dependencies [b659111]
-
Updated dependencies [5754a23]
-
Updated dependencies [6c270a6]
-
Updated dependencies [290e2f0]
-
Updated dependencies [668dd17]
-
Updated dependencies [8abf133]
-
Updated dependencies [e0859b1]
-
Updated dependencies [04ecd4e]
-
Updated dependencies [4d5a892]
-
Updated dependencies [16cebeb]
-
Updated dependencies [86d30af]
-
Updated dependencies [8923843]
-
Updated dependencies [ea32ec7]
-
Updated dependencies [a2795f6]
-
Updated dependencies [f16b492]
-
Updated dependencies [4b6fde8]
-
Updated dependencies [2018df9]
-
Updated dependencies [fc5a3a2]
- @objectstack/spec@16.0.0-rc.0
- @objectstack/platform-objects@16.0.0-rc.0
- @objectstack/core@16.0.0-rc.0
- @objectstack/formula@16.0.0-rc.0
- @objectstack/metadata-core@16.0.0-rc.0
- @objectstack/spec@15.1.1
- @objectstack/core@15.1.1
- @objectstack/metadata-core@15.1.1
- @objectstack/formula@15.1.1
- @objectstack/platform-objects@15.1.1
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [3fe9df1]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [4109153]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [627f225]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- Updated dependencies [f531a26]
- @objectstack/spec@15.1.0
- @objectstack/platform-objects@15.1.0
- @objectstack/core@15.1.0
- @objectstack/formula@15.1.0
- @objectstack/metadata-core@15.1.0
- Updated dependencies [02a014b]
- Updated dependencies [28b7c28]
- Updated dependencies [13749ec]
- Updated dependencies [e62c233]
- Updated dependencies [ed61c9b]
- Updated dependencies [31d04d4]
- @objectstack/platform-objects@15.0.0
- @objectstack/spec@15.0.0
- @objectstack/core@15.0.0
- @objectstack/formula@15.0.0
- @objectstack/metadata-core@15.0.0
- Updated dependencies [16b4bf6]
- Updated dependencies [16b4bf6]
- Updated dependencies [10e8983]
- Updated dependencies [607aaf4]
- Updated dependencies [bb71321]
- @objectstack/spec@14.8.0
- @objectstack/platform-objects@14.8.0
- @objectstack/core@14.8.0
- @objectstack/formula@14.8.0
- @objectstack/metadata-core@14.8.0
- Updated dependencies [d6a72eb]
- @objectstack/spec@14.7.0
- @objectstack/core@14.7.0
- @objectstack/formula@14.7.0
- @objectstack/metadata-core@14.7.0
- @objectstack/platform-objects@14.7.0
- Updated dependencies [609cb13]
- Updated dependencies [ce6d151]
- @objectstack/spec@14.6.0
- @objectstack/platform-objects@14.6.0
- @objectstack/core@14.6.0
- @objectstack/formula@14.6.0
- @objectstack/metadata-core@14.6.0
- Updated dependencies [526805e]
- Updated dependencies [d79ca07]
- Updated dependencies [33ebd34]
- Updated dependencies [c044f08]
- Updated dependencies [01274eb]
- Updated dependencies [8f23746]
- Updated dependencies [b97af7e]
- Updated dependencies [6da03ee]
- @objectstack/spec@14.5.0
- @objectstack/platform-objects@14.5.0
- @objectstack/core@14.5.0
- @objectstack/formula@14.5.0
- @objectstack/metadata-core@14.5.0
- Updated dependencies [7953832]
- Updated dependencies [82e745e]
- Updated dependencies [f3035bd]
- Updated dependencies [82c0d94]
- Updated dependencies [7449476]
- @objectstack/spec@14.4.0
- @objectstack/platform-objects@14.4.0
- @objectstack/metadata-core@14.4.0
- @objectstack/core@14.4.0
- @objectstack/formula@14.4.0
- Updated dependencies [2a71f48]
- Updated dependencies [02f6af4]
- Updated dependencies [c1064f1]
- @objectstack/platform-objects@14.3.0
- @objectstack/spec@14.3.0
- @objectstack/core@14.3.0
- @objectstack/formula@14.3.0
- @objectstack/metadata-core@14.3.0
- Updated dependencies [ac8f029]
- Updated dependencies [4ab9958]
- @objectstack/spec@14.2.0
- @objectstack/platform-objects@14.2.0
- @objectstack/core@14.2.0
- @objectstack/formula@14.2.0
- @objectstack/metadata-core@14.2.0
-
5a8465f: SLA escalation
escalateTois position-first (ADR-0090 D3 follow-up to thepositionapprover type).- spec:
ApprovalEscalationSchema.escalateTois documented as a position machine name or a specific user id (was "User id, role, or manager level" — the same pre-D3 'role' trap thepositionapprover type fixed); the Studio xRef picker kind movesrole→position. - plugin-approvals: on escalation,
escalateTonow expands position holders viasys_user_position∪ thesys_member.roletransition source (ADR-0057 D4) for both thereassignapprover hand-off and thenotifyaudience. An empty expansion falls back to treating the value as a literal user id, so configs naming a specific user keep working unchanged. The audit trail keeps the authored target. - lint: new
approval-escalation-reassign-no-targetwarning —escalation.action: 'reassign'with noescalateTosilently degrades to a notify at runtime; the fix-it prescribes a position or user id target (oraction: 'notify').
- spec:
- Updated dependencies [5a8465f]
- Updated dependencies [7f8620b]
- Updated dependencies [82ba3a6]
- @objectstack/spec@14.1.0
- @objectstack/core@14.1.0
- @objectstack/formula@14.1.0
- @objectstack/metadata-core@14.1.0
- @objectstack/platform-objects@14.1.0
-
216fa9a: Add a
positionapprover type so approvals can route to org positions (ADR-0090 D3 fallout).Post ADR-0090 D3 the
roleapprover type resolves against the better-auth org-membership tier (sys_member.role:owner/admin/member) — it was never a position. Downstream apps that authored{ type: 'role', value: 'sales_manager' }silently routed approvals to nobody. Now:- spec:
ApproverTypegains'position'—valueis the position machine name; the approver expands to its holders viasys_user_position. Authoring guidance: keeptype: 'role'ONLY for membership tiers; for org positions use{ type: 'position', value: '<position_name>' }(one-line fix for the mismatch above). - plugin-approvals: the engine resolves
positionapprovers viasys_user_position∪ thesys_member.roletransition source (same semantics asPositionGraphServicein plugin-sharing). Thedepartmentapprover type is now honored by its spec spelling (previously only the off-specbusiness_unit/budialect matched). - lint: new
validateApprovalApproversrule —approval-role-not-membership-tierwarns when aroleapprover's value is not a membership tier and prescribes thepositionrewrite;approval-approver-type-unknownflags off-spec approver types (with abusiness_unit→departmentfix-it). Wired intoos lint.
- spec:
- Updated dependencies [0a8e685]
- Updated dependencies [afa8115]
- Updated dependencies [80f12ca]
- Updated dependencies [332b711]
- Updated dependencies [e2fa074]
- Updated dependencies [23c8668]
- Updated dependencies [29f017d]
- Updated dependencies [216fa9a]
- Updated dependencies [6c22b12]
- Updated dependencies [d0531c4]
- Updated dependencies [cff5aac]
- @objectstack/spec@14.0.0
- @objectstack/platform-objects@14.0.0
- @objectstack/core@14.0.0
- @objectstack/formula@14.0.0
- @objectstack/metadata-core@14.0.0
- Updated dependencies [6d83431]
- Updated dependencies [01917c2]
- Updated dependencies [b271691]
- Updated dependencies [a5a1e41]
- Updated dependencies [466adf6]
- Updated dependencies [5be00c3]
- Updated dependencies [466adf6]
- Updated dependencies [2bee609]
- Updated dependencies [9fa84f9]
- Updated dependencies [fc7e7f7]
- @objectstack/spec@13.0.0
- @objectstack/core@13.0.0
- @objectstack/formula@13.0.0
- @objectstack/platform-objects@13.0.0
- @objectstack/metadata-core@13.0.0
- Updated dependencies [6cebf22]
- Updated dependencies [21420d9]
- @objectstack/spec@12.6.0
- @objectstack/core@12.6.0
- @objectstack/formula@12.6.0
- @objectstack/metadata-core@12.6.0
- @objectstack/platform-objects@12.6.0
- Updated dependencies [8b3d363]
- @objectstack/spec@12.5.0
- @objectstack/core@12.5.0
- @objectstack/formula@12.5.0
- @objectstack/metadata-core@12.5.0
- @objectstack/platform-objects@12.5.0
- Updated dependencies [60dc3ba]
- @objectstack/spec@12.4.0
- @objectstack/metadata-core@12.4.0
- @objectstack/core@12.4.0
- @objectstack/formula@12.4.0
- @objectstack/platform-objects@12.4.0
- Updated dependencies [e7eceec]
- @objectstack/spec@12.3.0
- @objectstack/core@12.3.0
- @objectstack/formula@12.3.0
- @objectstack/metadata-core@12.3.0
- @objectstack/platform-objects@12.3.0
- Updated dependencies [fce8ff4]
- Updated dependencies [3962023]
- Updated dependencies [2bb193d]
- Updated dependencies [0426d27]
- Updated dependencies [da807f7]
- Updated dependencies [4f5b791]
- @objectstack/spec@12.2.0
- @objectstack/metadata-core@12.2.0
- @objectstack/core@12.2.0
- @objectstack/formula@12.2.0
- @objectstack/platform-objects@12.2.0
- Updated dependencies [93e6d02]
- @objectstack/spec@12.1.0
- @objectstack/core@12.1.0
- @objectstack/formula@12.1.0
- @objectstack/metadata-core@12.1.0
- @objectstack/platform-objects@12.1.0
- Updated dependencies [a8df396]
- Updated dependencies [e695fe0]
- Updated dependencies [07f055c]
- Updated dependencies [7c09621]
- Updated dependencies [7709db4]
- Updated dependencies [2082109]
- Updated dependencies [7c09621]
- Updated dependencies [9860de4]
- Updated dependencies [069c205]
- @objectstack/spec@12.0.0
- @objectstack/platform-objects@12.0.0
- @objectstack/core@12.0.0
- @objectstack/formula@12.0.0
- @objectstack/metadata-core@12.0.0
-
6a9397e: Retire the deprecated
compactLayoutalias forhighlightFields(framework#2536, closes the ADR-0085 deprecation window).ObjectSchemano longer declarescompactLayout:create()rejects it like any unknown key; lenientparse()strips it (no silent aliasing).- The parse-time alias AND the
highlightFields → compactLayoutback-fill transition mirror are removed fromnormalizeSemanticRoleAliases. Served metadata now carries the canonical key only. - All remaining first-party authors (27 system objects across plugin-audit / approvals / security / sharing / webhooks / service-storage / automation / messaging / realtime — missed by the #2521 sweep, caught by the type gate) renamed to
highlightFields. - The downstream smoke pin moves to hotcrm v1.2.2 (hotcrm#424: same rename + deps ^11.7.0).
- Consumers were switched in objectui#2168 and shipped via the console pin bump (#2526); this closes the window scheduled there. The dogfood mirror assertion (#2528) flips to
compactLayout: undefinedin this same change, per the plan it carried.
Version note: minor, not major — the key was deprecated-with-alias for a full release window, all first-party consumers/authors are migrated, and the spec api-surface gate reports no export changes (same documented-exception path as the ADR-0085 removals in 11.7.0). External metadata still authoring
compactLayoutwill now failcreate()loudly with the standard unknown-key error naming the key. -
Updated dependencies [6a9397e]
-
Updated dependencies [c0efe5d]
- @objectstack/spec@11.10.0
- @objectstack/core@11.10.0
- @objectstack/formula@11.10.0
- @objectstack/metadata-core@11.10.0
- @objectstack/platform-objects@11.10.0
- Updated dependencies [d3595d9]
- @objectstack/spec@11.9.0
- @objectstack/core@11.9.0
- @objectstack/formula@11.9.0
- @objectstack/metadata-core@11.9.0
- @objectstack/platform-objects@11.9.0
- Updated dependencies [53d491a]
- Updated dependencies [b84726b]
- @objectstack/platform-objects@11.8.0
- @objectstack/spec@11.8.0
- @objectstack/core@11.8.0
- @objectstack/metadata-core@11.8.0
- @objectstack/formula@11.8.0
- Updated dependencies [5178906]
- @objectstack/spec@11.7.0
- @objectstack/platform-objects@11.7.0
- @objectstack/core@11.7.0
- @objectstack/formula@11.7.0
- @objectstack/metadata-core@11.7.0
- @objectstack/spec@11.6.0
- @objectstack/core@11.6.0
- @objectstack/metadata-core@11.6.0
- @objectstack/formula@11.6.0
- @objectstack/platform-objects@11.6.0
- Updated dependencies [6ee4f04]
- Updated dependencies [c1e3a65]
- @objectstack/spec@11.5.0
- @objectstack/core@11.5.0
- @objectstack/formula@11.5.0
- @objectstack/metadata-core@11.5.0
- @objectstack/platform-objects@11.5.0
- Updated dependencies [5821c51]
- Updated dependencies [a0fce3f]
- @objectstack/spec@11.4.0
- @objectstack/core@11.4.0
- @objectstack/formula@11.4.0
- @objectstack/metadata-core@11.4.0
- @objectstack/platform-objects@11.4.0
- Updated dependencies [58e8e31]
- Updated dependencies [b4a5df0]
- @objectstack/spec@11.3.0
- @objectstack/core@11.3.0
- @objectstack/formula@11.3.0
- @objectstack/metadata-core@11.3.0
- @objectstack/platform-objects@11.3.0
- Updated dependencies [d0f4b13]
- Updated dependencies [302bdab]
- @objectstack/spec@11.2.0
- @objectstack/core@11.2.0
- @objectstack/formula@11.2.0
- @objectstack/metadata-core@11.2.0
- @objectstack/platform-objects@11.2.0
- Updated dependencies [cbc8c02]
- Updated dependencies [07c2773]
- Updated dependencies [d7a88df]
- Updated dependencies [4f8f108]
- Updated dependencies [ce0b4f6]
- Updated dependencies [90bce88]
- Updated dependencies [3209ec6]
- Updated dependencies [e011d42]
- Updated dependencies [6e5bdd5]
- Updated dependencies [9ccfcd6]
- Updated dependencies [ecf193f]
- Updated dependencies [51bec81]
- Updated dependencies [3e593a7]
- Updated dependencies [63d5403]
- @objectstack/platform-objects@11.1.0
- @objectstack/core@11.1.0
- @objectstack/spec@11.1.0
- @objectstack/formula@11.1.0
- @objectstack/metadata-core@11.1.0
-
d980f0d: feat: add a first-class
userfield type (person picker)A new
userfield type — the equivalent of Airtable's Collaborator / Notion's Person / Salesforce'sLookup(User). Authored asField.user({ ... }); use{ multiple: true }for collaborators/watchers and{ defaultValue: 'current_user' }to auto-fill the acting user on create.Why a distinct type rather than telling authors to
Field.lookup('sys_user'): selecting a person is table-stakes, but the value is in modelling discoverability — a "User" entry in the Studio/AI field palette instead of requiring authors (and AI) to know to reference the internalsys_usersystem object — pluscurrent_userdefaults and a user-search picker. Storage and runtime are unchanged.Deliberately NOT a new storage primitive.
useris a semantic specialization oflookupwith the target fixed tosys_user: it shares the exact lookup code path — same FK string column (multiple⇒ JSON), same$expandresolution, same indexing — so referential integrity and fresh display names come for free, and nothing is re-implemented. An existingField.lookup('sys_user')is therefore equivalent at the storage layer (zero data migration to adoptField.user).Ownership semantics are unchanged: the existing
owner_idconvention +plugin-securityauto-stamp/RLS still apply. A declarativeownerflag is a possible future follow-up; intentionally not added here to avoid a second field type for what is a system role (rationale: keep theFieldTypesurface lean — see related ADR-0059 freeze discipline).Changes:
FieldTypegains'user'+Field.user()builder; the SQL/Mongo drivers treatuserexactly likelookup; the engine resolves$expandforuserfields and honours a newdefaultValue: 'current_user'token (resolved app-side from the execution context, mirroring theNOW()convention); kanban group-by and symbolic seed references acceptuser; approvals enrichuserreferences. The public API surface is unchanged (additive enum member). -
Updated dependencies [4d99a5c]
-
Updated dependencies [9b5bf3d]
-
Updated dependencies [cb5b393]
-
Updated dependencies [ab5718a]
-
Updated dependencies [4845c12]
-
Updated dependencies [c1a754a]
-
Updated dependencies [6fbe91f]
-
Updated dependencies [715d667]
-
Updated dependencies [5eef4cf]
-
Updated dependencies [72759e1]
-
Updated dependencies [6c4fbd9]
-
Updated dependencies [ef3ed67]
-
Updated dependencies [cd51229]
-
Updated dependencies [7697a0e]
-
Updated dependencies [e7e04f1]
-
Updated dependencies [cfd5ac4]
-
Updated dependencies [2be5c1f]
-
Updated dependencies [ad143ce]
-
Updated dependencies [5c4a8c8]
-
Updated dependencies [3afaeed]
-
Updated dependencies [5737261]
-
Updated dependencies [a619a3a]
-
Updated dependencies [f44c1bd]
-
Updated dependencies [8801c02]
-
Updated dependencies [3d04e06]
-
Updated dependencies [4a84c98]
-
Updated dependencies [c715d25]
-
Updated dependencies [aa33b02]
-
Updated dependencies [d980f0d]
-
Updated dependencies [a658523]
-
Updated dependencies [82ff91c]
-
Updated dependencies [638f472]
- @objectstack/metadata-core@11.0.0
- @objectstack/platform-objects@11.0.0
- @objectstack/spec@11.0.0
- @objectstack/formula@11.0.0
- @objectstack/core@11.0.0
- @objectstack/spec@10.3.0
- @objectstack/core@10.3.0
- @objectstack/metadata-core@10.3.0
- @objectstack/formula@10.3.0
- @objectstack/platform-objects@10.3.0
- Updated dependencies [b496498]
- @objectstack/spec@10.2.0
- @objectstack/core@10.2.0
- @objectstack/formula@10.2.0
- @objectstack/metadata-core@10.2.0
- @objectstack/platform-objects@10.2.0
- Updated dependencies [49da36e]
- Updated dependencies [ac79f16]
- @objectstack/spec@10.1.0
- @objectstack/core@10.1.0
- @objectstack/formula@10.1.0
- @objectstack/metadata-core@10.1.0
- @objectstack/platform-objects@10.1.0
-
e16f2a8: BREAKING: the system object
sys_departmentis renamed tosys_business_unit— object + member table (sys_department_member→sys_business_unit_member), fields, and i18n — with no compatibility alias. Any deployment holdingsys_departmentrows, or metadata that references the object by name (lookups, list views, queries, sharing/approval scopes), must migrate tosys_business_unit. A renamed shipped system object is a breaking change to the platform's public data surface, so this lands as a major. Verified per ADR-0059's pre-publish hotcrm gate: no published downstream consumer references the old name.ADR-0057 — ERP authorization core. Adds permission-grant access DEPTH (
own/own_and_reports/unit/unit_and_below/org), renamessys_department→sys_business_unit(no aliases — see BREAKING above), introduces the platform-ownedsys_user_positionassignment, and seeds stack-declaredroles/sharingRulesintosys_position/sys_sharing_ruleat boot (closes #2077). Hierarchy-relative scopes are delegated to a pluggableIHierarchyScopeResolver(open edition fails closed to owner-only;defineStackerrors withoutrequires: ['hierarchy-security']). Also fixes a latent over-grant whereengine.find({ filter })was ignored (driver readswhere) — normalizedfilter→wherein the engine. -
Updated dependencies [d7ff626]
-
Updated dependencies [2a1b16b]
-
Updated dependencies [2256e93]
-
Updated dependencies [7108ff3]
-
Updated dependencies [30c0313]
-
Updated dependencies [e16f2a8]
-
Updated dependencies [cfd86ce]
-
Updated dependencies [e411a82]
-
Updated dependencies [ae271d0]
-
Updated dependencies [61ed5c7]
-
Updated dependencies [a581385]
-
Updated dependencies [d5f6d29]
-
Updated dependencies [220ce5b]
-
Updated dependencies [3efe334]
-
Updated dependencies [0df063e]
-
Updated dependencies [ce13bb8]
-
Updated dependencies [feead7e]
-
Updated dependencies [6ca20b3]
-
Updated dependencies [5f875fe]
-
Updated dependencies [b469950]
-
Updated dependencies [47d978a]
-
Updated dependencies [48a307a]
-
Updated dependencies [25fc0e4]
- @objectstack/spec@10.0.0
- @objectstack/platform-objects@10.0.0
- @objectstack/formula@10.0.0
- @objectstack/core@10.0.0
- @objectstack/metadata-core@10.0.0
- Updated dependencies [e7f6539]
- Updated dependencies [2365d07]
- Updated dependencies [6595b53]
- Updated dependencies [fa8964d]
- Updated dependencies [36138c7]
- Updated dependencies [a8e4f3b]
- Updated dependencies [4c213c2]
- Updated dependencies [2afb612]
- @objectstack/spec@9.11.0
- @objectstack/core@9.11.0
- @objectstack/formula@9.11.0
- @objectstack/metadata-core@9.11.0
- @objectstack/platform-objects@9.11.0
- Updated dependencies [db02bd5]
- Updated dependencies [641675d]
- Updated dependencies [1f88fd9]
- Updated dependencies [94e9040]
- Updated dependencies [4331adb]
- Updated dependencies [1f88fd9]
- Updated dependencies [1f88fd9]
- @objectstack/spec@9.10.0
- @objectstack/formula@9.10.0
- @objectstack/platform-objects@9.10.0
- @objectstack/core@9.10.0
- @objectstack/metadata-core@9.10.0
- @objectstack/spec@9.9.1
- @objectstack/core@9.9.1
- @objectstack/metadata-core@9.9.1
- @objectstack/formula@9.9.1
- @objectstack/platform-objects@9.9.1
- Updated dependencies [84249a4]
- Updated dependencies [11af299]
- Updated dependencies [d5774b5]
- Updated dependencies [134043a]
- Updated dependencies [90108e0]
- Updated dependencies [9afeb2d]
- Updated dependencies [6bec07e]
- Updated dependencies [601cc11]
- Updated dependencies [d99a75a]
- Updated dependencies [575448d]
- @objectstack/spec@9.9.0
- @objectstack/core@9.9.0
- @objectstack/formula@9.9.0
- @objectstack/metadata-core@9.9.0
- @objectstack/platform-objects@9.9.0
- Updated dependencies [c17d2c8]
- Updated dependencies [97c55b3]
- Updated dependencies [1b1f490]
- @objectstack/formula@9.8.0
- @objectstack/spec@9.8.0
- @objectstack/core@9.8.0
- @objectstack/metadata-core@9.8.0
- @objectstack/platform-objects@9.8.0
- Updated dependencies [82c7438]
- Updated dependencies [417b6ac]
- Updated dependencies [ff0a87a]
- @objectstack/formula@9.7.0
- @objectstack/spec@9.7.0
- @objectstack/core@9.7.0
- @objectstack/metadata-core@9.7.0
- @objectstack/platform-objects@9.7.0
- Updated dependencies [d1e930a]
- Updated dependencies [71578f2]
- Updated dependencies [bb00a50]
- Updated dependencies [5e3a301]
- Updated dependencies [5db2742]
- @objectstack/spec@9.6.0
- @objectstack/formula@9.6.0
- @objectstack/core@9.6.0
- @objectstack/metadata-core@9.6.0
- @objectstack/platform-objects@9.6.0
- Updated dependencies [ee72aae]
- @objectstack/spec@9.5.1
- @objectstack/core@9.5.1
- @objectstack/formula@9.5.1
- @objectstack/metadata-core@9.5.1
- @objectstack/platform-objects@9.5.1
- Updated dependencies [d08551c]
- Updated dependencies [5be7102]
- Updated dependencies [707aeed]
- Updated dependencies [7a103d4]
- Updated dependencies [4b01250]
- @objectstack/spec@9.5.0
- @objectstack/platform-objects@9.5.0
- @objectstack/core@9.5.0
- @objectstack/formula@9.5.0
- @objectstack/metadata-core@9.5.0
- Updated dependencies [060467a]
- Updated dependencies [0856476]
- Updated dependencies [fef38ec]
- Updated dependencies [b678d8c]
- Updated dependencies [b678d8c]
- Updated dependencies [b678d8c]
- @objectstack/spec@9.4.0
- @objectstack/metadata-core@9.4.0
- @objectstack/core@9.4.0
- @objectstack/formula@9.4.0
- @objectstack/platform-objects@9.4.0
- 3219191: ADR-0043 actionable approval links (#1743).
remind()now fans out per approver: every concrete identity gets its own single-use approve/reject links in the notification payload. Tokens are 256-bit, stored as SHA-256 hashes only (sys_approval_token), scoped to one request + action + approver, 72h TTL, consumed-before-decide (replay burns), and re-validated at redemption against the live request (decided/recalled/reassigned ⇒ dead link). The plugin mounts a session-less bilingual confirm page atGET /api/v1/approvals/act(renders only — mail-gateway prefetch safe) and redeems exclusively on thePOST, auditing the decision as the bound approver. - f3c1735: Approver join table — the #1745 follow-up that makes approver-filtered pagination exact. New
sys_approval_approverobject holds one row per (pending request, approver identity); the service mirrors everypending_approverschange into it (open / decide / recall / send-back / reassign / SLA-escalate) and clears the rows when a request leavespending, so the table tracks the live work queue, not the append-only history.listRequests/countRequestsnow resolve approver filters through this index ($inon indexed equality instead of a per-row CSV scan) and push status arrays down as$in— every filter is engine-side, so the page window and totals are correct at any table size; the old 500-row bounded-scan residual is gone.rebuildApproverIndex()rebuilds the index from the CSV source of truth, and runs idempotently at plugin start to backfill rows written before the index existed. - 290f631: ADR-0044 flow-level send-back-for-revision (#1744). The approval node gains a third flow movement beyond approve/reject:
sendBack()finalizes the pending request asreturned(newApprovalStatus), resumes the run down itsreviseedge to a wait point where the record lock releases, and the submitter'sresubmit()re-enters the approval node over a declared back-edge, opening the next round's request (fresh approver slate, re-locked,roundstamped via the config snapshot). Engine:FlowEdgeSchema.typegains'back'— cycle validation now requires the graph minus back-edges to be a DAG (unmarked cycles still rejected), node re-entry overwrites outputs/appends steps, a 100-re-entry runaway guard backstops misauthored loops, andcancelRun(runId, reason)lands as the first run-cancel primitive (recall crossing a revise window cancels the parked run).maxRevisions(default 3) on the approval node config auto-rejects send-backs past the budget. REST:POST /approvals/requests/:id/reviseand/resubmit. Audit kindsrevise/resubmitjoinApprovalActionKindand thesys_approval_actionenum. - 50b7b47: Approvals server-side pagination + search pushdown (#1745).
listRequestsacceptsq/limit/offset— free-text search pushes into the engine query as an$orof$containsterms (thepayload_jsonsnapshot carries record titles, so titles match without a join), and the page window pushes down whenever the filter is fully pushable; approver/status-array filters still post-filter their bounded scan and window in memory (the documented residual until the approver join-table follow-up). NewcountRequestsreturns the unwindowed total (enginecountwhen pushable). REST:GET /approvals/requestsgainsq/limit/offsetand returns{data, total}when paging. - f15d6f6: ADR-0042 SLA auto-escalation + ADR-0041 mechanical landing. plugin-approvals now owns a jobs-backed escalation scanner (
runEscalations, interval jobapprovals-sla-escalation+ boot catch-up): overdue pending requests escalate at most once (theescalateaudit row is the idempotency marker, written audit-first) executing the node'sescalation.action— notify / reassign-to-escalateTo/ auto_approve / auto_reject as the reserved actorsystem:sla. The trigger packages drop theirplugin-prefix (@objectstack/trigger-record-change,@objectstack/trigger-schedule) per ADR-0041, andActionDescriptorgains an optionalmaturity: 'ga' | 'beta' | 'reserved'field so designers can grey out contract-ahead-of-runtime surfaces. - f8684ea: Approvals thread interactions — the collaboration layer between submit and decide.
reassign()hands a pending-approver slot to someone else (audit-first ordering, new approver notified via the optionalmessagingservice),remind()nudges every pending approver with a 4h per-request throttle (THROTTLED→ HTTP 429),requestInfo()sends a request back to the submitter for more material while it stays pending, andcomment()adds free-form thread replies. Rows exposesla_due_at(created_at + escalation.timeoutHours, display-only) and single reads attachflow_steps(the owning flow's approval trunk with done/current/upcoming states). REST grows the four matching POST routes; thesys_approval_action.actionenum gains the new kinds.
- Updated dependencies [1ada658]
- Updated dependencies [3219191]
- Updated dependencies [290f631]
- Updated dependencies [50b7b47]
- Updated dependencies [f15d6f6]
- Updated dependencies [f8684ea]
- Updated dependencies [c802327]
- Updated dependencies [b4765be]
- @objectstack/spec@9.3.0
- @objectstack/platform-objects@9.3.0
- @objectstack/core@9.3.0
- @objectstack/formula@9.3.0
- @objectstack/metadata-core@9.3.0
- Updated dependencies [2f57b75]
- Updated dependencies [2f57b75]
- @objectstack/spec@9.2.0
- @objectstack/core@9.2.0
- @objectstack/formula@9.2.0
- @objectstack/metadata-core@9.2.0
- @objectstack/platform-objects@9.2.0
- Updated dependencies [b9062c9]
- @objectstack/spec@9.1.0
- @objectstack/core@9.1.0
- @objectstack/formula@9.1.0
- @objectstack/metadata-core@9.1.0
- @objectstack/platform-objects@9.1.0
- Updated dependencies [1817845]
- @objectstack/spec@9.0.1
- @objectstack/core@9.0.1
- @objectstack/formula@9.0.1
- @objectstack/metadata-core@9.0.1
- @objectstack/platform-objects@9.0.1
- Updated dependencies [4c3f693]
- Updated dependencies [0bf39f1]
- Updated dependencies [f533f42]
- Updated dependencies [1c83ee8]
- @objectstack/spec@9.0.0
- @objectstack/core@9.0.0
- @objectstack/formula@9.0.0
- @objectstack/metadata-core@9.0.0
- @objectstack/platform-objects@9.0.0
- @objectstack/spec@8.0.1
- @objectstack/core@8.0.1
- @objectstack/metadata-core@8.0.1
- @objectstack/formula@8.0.1
- @objectstack/platform-objects@8.0.1
- Updated dependencies [a46c017]
- Updated dependencies [b990b89]
- Updated dependencies [99111ec]
- Updated dependencies [d5a8161]
- Updated dependencies [5cf1f1b]
- Updated dependencies [9ef89d4]
- Updated dependencies [3306d2f]
- Updated dependencies [c262301]
- Updated dependencies [bc44195]
- Updated dependencies [9e2e229]
- @objectstack/spec@8.0.0
- @objectstack/core@8.0.0
- @objectstack/formula@8.0.0
- @objectstack/metadata-core@8.0.0
- @objectstack/platform-objects@8.0.0
- @objectstack/spec@7.9.0
- @objectstack/core@7.9.0
- @objectstack/metadata-core@7.9.0
- @objectstack/formula@7.9.0
- @objectstack/platform-objects@7.9.0
- Updated dependencies [06f2bbb]
- Updated dependencies [f01f9fa]
- Updated dependencies [36719db]
- Updated dependencies [424ab26]
- @objectstack/spec@7.8.0
- @objectstack/formula@7.8.0
- @objectstack/core@7.8.0
- @objectstack/metadata-core@7.8.0
- @objectstack/platform-objects@7.8.0
- Updated dependencies [b391955]
- Updated dependencies [f06b64e]
- Updated dependencies [825ab06]
- Updated dependencies [023bf93]
- Updated dependencies [764c747]
- @objectstack/spec@7.7.0
- @objectstack/formula@7.7.0
- @objectstack/platform-objects@7.7.0
- @objectstack/metadata-core@7.7.0
- @objectstack/core@7.7.0
- Updated dependencies [955d4c8]
- Updated dependencies [c4a4cbd]
- Updated dependencies [b046ec2]
- Updated dependencies [2170ad9]
- Updated dependencies [02d6359]
- Updated dependencies [7648242]
- Updated dependencies [8fa1e7f]
- Updated dependencies [7ae6abc]
- Updated dependencies [55866f5]
- Updated dependencies [60f9c45]
- @objectstack/spec@7.6.0
- @objectstack/formula@7.6.0
- @objectstack/platform-objects@7.6.0
- @objectstack/core@7.6.0
- @objectstack/metadata-core@7.6.0
- @objectstack/spec@7.5.0
- @objectstack/core@7.5.0
- @objectstack/metadata-core@7.5.0
- @objectstack/formula@7.5.0
- @objectstack/platform-objects@7.5.0
- @objectstack/spec@7.4.1
- @objectstack/core@7.4.1
- @objectstack/metadata-core@7.4.1
- @objectstack/formula@7.4.1
- @objectstack/platform-objects@7.4.1
-
4cc2ced: ADR-0029 K2.b — approvals domain ownership + Setup nav contribution.
Moves
sys_approval_request/sys_approval_actionout of the@objectstack/platform-objectsmonolith into@objectstack/plugin-approvals, which already registers and operates them — so the plugin now owns its data model, behavior, and admin menu as one unit.- The object definitions move to
plugin-approvals;platform-objectsno longer exports them from/audit. Runtime is unchanged (the plugin already registered them at runtime). - D7 navigation — the Setup app's
group_approvalsentries (Requests,Action History) move out ofplatform-objects'SETUP_NAV_CONTRIBUTIONSintoplugin-approvals'navigationContributions. The plugin fills the slot it owns; when the plugin is absent the slot stays empty. - i18n (D8) — the objects are removed from the
platform-objectsi18n extract config; their existing generated translation bundles keep working at runtime (object-name keyed). Migrating the i18n extraction/bundles to the plugin remains the tracked cross-cutting follow-up (best done with theos i18n extracttooling, not hand-edited generated files).
- The object definitions move to
-
4404572: ADR-0029 D8 — migrate i18n ownership for the moved domains to their plugins.
The object translations for the domains decomposed in K2.a/K2.b/K2 previously lived in the
@objectstack/platform-objectsgenerated bundles even though the objects now live in their capability plugins. This moves each domain's i18n extraction + bundles to the owning plugin, preserving every hand-translated string (zh-CN / ja-JP / es-ES):- Each plugin gains a build-time
scripts/i18n-extract.config.tsand asrc/translations/bundle ({locale}.objects.generated.ts+ anindex.tsbarrel), generated withos i18n extractand self-baselined so re-runs preserve translations. - Each plugin loads its bundle at runtime on
kernel:readyviai18n.loadTranslations(the i18n service is optional — load is best-effort).plugin-webhooks←sys_webhook,sys_webhook_deliveryplugin-approvals←sys_approval_request,sys_approval_actionplugin-security←sys_position,sys_permission_set,sys_user_permission_set,sys_position_permission_setplugin-sharing←sys_record_share,sys_sharing_rule,sys_share_link
@objectstack/platform-objectstranslation bundles are regenerated to drop those objects' keys (its extract config already excluded them); all other objects' translations and the metadata-form bundles are preserved.
Net runtime effect is unchanged (same translations load, now contributed by the package that owns each object) — closing the D8 follow-up tracked since K2.a.
- Each plugin gains a build-time
-
Updated dependencies [23c7107]
-
Updated dependencies [c72daad]
-
Updated dependencies [4404572]
-
Updated dependencies [eea3f1b]
-
Updated dependencies [e478e0c]
-
Updated dependencies [4cc2ced]
-
Updated dependencies [13632b1]
-
Updated dependencies [f115182]
-
Updated dependencies [2faf9f2]
-
Updated dependencies [2faf9f2]
-
Updated dependencies [2faf9f2]
-
Updated dependencies [58b450b]
-
Updated dependencies [82eb6cf]
-
Updated dependencies [c381977]
-
Updated dependencies [13d8653]
-
Updated dependencies [ff3d006]
-
Updated dependencies [5e831de]
- @objectstack/spec@7.4.0
- @objectstack/platform-objects@7.4.0
- @objectstack/core@7.4.0
- @objectstack/formula@7.4.0
- @objectstack/metadata-core@7.4.0
- Updated dependencies [5e7c554]
- @objectstack/spec@7.3.0
- @objectstack/core@7.3.0
- @objectstack/formula@7.3.0
- @objectstack/platform-objects@7.3.0
- @objectstack/metadata-core@7.3.0
- @objectstack/spec@7.2.1
- @objectstack/core@7.2.1
- @objectstack/metadata-core@7.2.1
- @objectstack/formula@7.2.1
- @objectstack/platform-objects@7.2.1
- @objectstack/spec@7.2.0
- @objectstack/core@7.2.0
- @objectstack/metadata-core@7.2.0
- @objectstack/formula@7.2.0
- @objectstack/platform-objects@7.2.0
- Updated dependencies [6228609]
- Updated dependencies [47a92f4]
- @objectstack/platform-objects@7.1.0
- @objectstack/spec@7.1.0
- @objectstack/core@7.1.0
- @objectstack/formula@7.1.0
- @objectstack/metadata-core@7.1.0
- Updated dependencies [74470ad]
- Updated dependencies [d29617e]
- Updated dependencies [dc72172]
- Updated dependencies [d29617e]
- Updated dependencies [010757b]
- Updated dependencies [257954d]
- @objectstack/spec@7.0.0
- @objectstack/platform-objects@7.0.0
- @objectstack/core@7.0.0
- @objectstack/formula@7.0.0
- @objectstack/metadata-core@7.0.0
- @objectstack/spec@6.9.0
- @objectstack/core@6.9.0
- @objectstack/metadata-core@6.9.0
- @objectstack/formula@6.9.0
- @objectstack/platform-objects@6.9.0
- @objectstack/spec@6.8.1
- @objectstack/core@6.8.1
- @objectstack/metadata-core@6.8.1
- @objectstack/formula@6.8.1
- @objectstack/platform-objects@6.8.1
- Updated dependencies [6e88f77]
- Updated dependencies [c8b9f57]
- Updated dependencies [45d27c5]
- @objectstack/spec@6.8.0
- @objectstack/platform-objects@6.8.0
- @objectstack/core@6.8.0
- @objectstack/formula@6.8.0
- @objectstack/metadata-core@6.8.0
- @objectstack/spec@6.7.1
- @objectstack/core@6.7.1
- @objectstack/metadata-core@6.7.1
- @objectstack/formula@6.7.1
- @objectstack/platform-objects@6.7.1
- Updated dependencies [430067b]
- Updated dependencies [4f9e9d4]
- Updated dependencies [4f9e9d4]
- @objectstack/spec@6.7.0
- @objectstack/platform-objects@6.7.0
- @objectstack/core@6.7.0
- @objectstack/formula@6.7.0
- @objectstack/metadata-core@6.7.0
- Updated dependencies [a49cfc2]
- @objectstack/spec@6.6.0
- @objectstack/core@6.6.0
- @objectstack/formula@6.6.0
- @objectstack/platform-objects@6.6.0
- @objectstack/metadata-core@6.6.0
- @objectstack/spec@6.5.1
- @objectstack/core@6.5.1
- @objectstack/metadata-core@6.5.1
- @objectstack/formula@6.5.1
- @objectstack/platform-objects@6.5.1
- @objectstack/spec@6.5.0
- @objectstack/core@6.5.0
- @objectstack/metadata-core@6.5.0
- @objectstack/formula@6.5.0
- @objectstack/platform-objects@6.5.0
- Updated dependencies [f8651cc]
- Updated dependencies [f8651cc]
- Updated dependencies [0bf6f9a]
- @objectstack/spec@6.4.0
- @objectstack/core@6.4.0
- @objectstack/formula@6.4.0
- @objectstack/platform-objects@6.4.0
- @objectstack/metadata-core@6.4.0
- @objectstack/spec@6.3.0
- @objectstack/core@6.3.0
- @objectstack/metadata-core@6.3.0
- @objectstack/formula@6.3.0
- @objectstack/platform-objects@6.3.0
- Updated dependencies [b4c74a9]
- @objectstack/spec@6.2.0
- @objectstack/core@6.2.0
- @objectstack/formula@6.2.0
- @objectstack/platform-objects@6.2.0
- @objectstack/metadata-core@6.2.0
- @objectstack/spec@6.1.1
- @objectstack/core@6.1.1
- @objectstack/metadata-core@6.1.1
- @objectstack/formula@6.1.1
- @objectstack/platform-objects@6.1.1
- Updated dependencies [93c0589]
- @objectstack/spec@6.1.0
- @objectstack/core@6.1.0
- @objectstack/formula@6.1.0
- @objectstack/platform-objects@6.1.0
- @objectstack/metadata-core@6.1.0
- Updated dependencies [629a716]
- Updated dependencies [dbc4f7d]
- Updated dependencies [944f187]
- @objectstack/spec@6.0.0
- @objectstack/platform-objects@6.0.0
- @objectstack/core@6.0.0
- @objectstack/formula@6.0.0
- @objectstack/metadata-core@6.0.0
-
bab2b20: feat(approvals): execution-pinned approval processes (ADR-0009)
When an approval request is submitted, the engine now records a
process_hashonsys_approval_request— the sha256 of the approval process body resolved throughMetadataRepository. While the request is in flight,approve/reject/recallresolve the pinned process body viaMetadataRepository.getByHash. Upgrading the approval process definition mid-flight therefore no longer affects requests that already started against the previous version.Behavior:
sys_approval_requestgains aprocess_hashcolumn (text, nullable, read-only). Existing rows keep working — the engine falls back to the currentsys_approval_processprojection when the column is empty.ApprovalServiceOptionsaccepts an optionalmetadataRepo. When omitted (e.g. defining processes purely through the runtime API or in unit tests), pinning is silently disabled and the service behaves as before.ApprovalsServicePluginlooks up the metadata service from the kernel and wires its repository automatically.- The metadata-core local
MetadataTypeSchemaenum was realigned with the canonical@objectstack/spec/kernelenum (drift fix:approval,field,function,service, …).
This is the first user-visible consumer of the
executionPinnedcapability introduced in ADR-0009.
- Updated dependencies [bab2b20]
- Updated dependencies [fa011d8]
- Updated dependencies [f0f7c27]
- Updated dependencies [b806f58]
- @objectstack/platform-objects@5.2.0
- @objectstack/spec@5.2.0
- @objectstack/metadata-core@5.2.0
- @objectstack/core@5.2.0
- @objectstack/formula@5.2.0
- Updated dependencies [75f4ee6]
- Updated dependencies [823d559]
- @objectstack/spec@5.1.0
- @objectstack/platform-objects@5.1.0
- @objectstack/core@5.1.0
- @objectstack/formula@5.1.0
- Updated dependencies [888a5c1]
- Updated dependencies [2f9073a]
- @objectstack/platform-objects@5.0.0
- @objectstack/spec@5.0.0
- @objectstack/core@5.0.0
- @objectstack/formula@5.0.0
- Updated dependencies [2869891]
- @objectstack/spec@4.2.0
- @objectstack/core@4.2.0
- @objectstack/formula@4.2.0
- @objectstack/platform-objects@4.2.0
- @objectstack/spec@4.1.1
- @objectstack/core@4.1.1
- @objectstack/formula@4.1.1
- @objectstack/platform-objects@4.1.1
- Updated dependencies [2108c30]
- Updated dependencies [23db640]
- @objectstack/spec@4.1.0
- @objectstack/core@4.1.0
- @objectstack/formula@4.1.0
- @objectstack/platform-objects@4.1.0