Uh oh!
There was an error while loading. Please reload this page.
Releases: objectstack-ai/objectstack
Release list
create-objectstack@17.1.0
Minor Changes
1eb28a1: Retire the five remote content templates from the scaffolder's catalog.
todo,compliance,content,contractsandprocurementwere delisted
from the official ObjectStack template marketplace and are no longer
maintained, but the CLI carried its own hardcoded catalog and never learned
that:--helprecommended all five by name with marketing descriptions, and
theAvailable:line on a bad-toffered them too.blank(bundled, offline) is now the whole catalog, so the help text
advertises only what is actually supported.- Asking for one of the five by name —
-t todoin an old script or tutorial —
is refused with a message that says the template was retired, instead of the
generic "Unknown template" error that reads as a typo. - The GitHub tarball-fetch path that served the remote templates is removed
along with itstardependency; nothing else reached it.
Note this corrects the catalog at HEAD only. Already-published versions keep
advertising the retired templates until a new version ofcreate-objectstack
is released.
Patch Changes
4906c90: Fix scaffolded projects describing themselves as the blank template (#9263)
rewriteProjectIdentityrewroteid/namespace/namein bothobjectstack.config.tsandobjectstack.manifest.jsonfrom the project name,
but leftdescriptionuntouched — every scaffolded project carried the blank
template's own line verbatim ("Minimal ObjectStack environment — a clean
slate for building."), confidently wrong rather than empty, and printed by
the first command the getting-started flow tells people to run (os validate).The scaffolder now drops
descriptionfrom both files instead of rewriting
it. There is nothing but the project name to derive a replacement from, and a
name-derived sentence (e.g. "Support Desk — an ObjectStack environment.")
would be a bare restatement of thename/displayNamerow already shown —
worse than no sentence at all.os validatealready omits the description
line entirely when the field is unset, so a freshly scaffolded project now
prints cleanly:Support Desk v0.1.0instead of
Support Desk v0.1.0 Minimal ObjectStack environment — a clean slate for building.f2f09e4: fix(create-objectstack): the scaffolded Dockerfile pins the runtime image to the CLI that builds the artifact, instead of
latestunder a comment saying to pin (#9017)src/templates/blank/DockerfileshippedFROM ghcr.io/objectstack-ai/objectstack:latest
directly beneath a comment instructing the reader to "pin the tag to the@objectstack/cliversion in your package.json so the runtime matches the CLI that built
the artifact" — an instruction the scaffold itself did not follow. Every app made withnpx create-objectstackshipped that contradiction from day one, anddocker/README.md's
tag table already scopeslatestto quick starts while documentingX.Y.Zas the
production pin.Measured on scaffolded output rather than the template's bytes, before the fix:
emitted package.json cli range : ^17.0.0 emitted Dockerfile FROM : FROM ghcr.io/objectstack-ai/objectstack:latest agreement (tag vs cli range) : DISAGREEThe tag is resolved after
install, from the installed CLI — not from the generatedpackage.json. That file carries a caret RANGE, and the two are not interchangeable:
npm resolves^17.0.0to the newest 17.x, so pinning the range's floor would ship a
runtime image older than the CLI that built the artifact — breaking the same promise in
a new way. The rolling:17tag does match the range's float window but is exactly what
the tag table tells production not to use. The resolved version is the only value that
makes the sentence true, and it is the rule the repo already applies for this purpose in.github/workflows/scaffold-e2e.yml("Pin the runtime's CLI to the SAME version the
generated project actually resolved to — NOT a hardcodedlatest").Both halves move together. Pinning the line while leaving an imperative to pin by hand
would relocate the contradiction rather than remove it, so the comment above theFROM
line is replaced in the same rewrite. With--skip-installthere is no resolved version:
the tag stayslatestand the comment keeps telling the reader to pin — which is true on
that path, because there the user really must do it by hand.The regression proof asserts on scaffolded output, never on the template: it scaffolds
with the real copy/sync/pin path, plants an installed CLI whose version is deliberately
not the range's floor (the normal case, and the one that a package.json-derived tag
would get wrong), and checks the emittedFROMtag against the emittedpackage.json
range with a satisfies-check rather than equality..github/workflows/scaffold-e2e.ymlnow reads the tag it builds its local runtime image
under out of the generated Dockerfile instead of hardcoding:latest. Those were two
hand-matched literals; had they skewed, Docker would have quietly pulled the last
published image instead of the one built from this checkout, and the job's own stated
hermeticity would have been false while it stayed green.0a5adba: fix(create-objectstack): the blank template's
specVersionstops shipping eleven majors stale, and the version-time sync covers every declared surface on every template (#9264)The one bundled template declared the platform it targets in two places that
disagreed by eleven majors:file key was objectstack.manifest.jsonspecVersion^6.0.0objectstack.config.tsengines.protocol^17scripts/sync-template-versions.mjsre-stamped the config key and the template's@objectstack/*dependency ranges, and never opened the manifest at all. Soengines.protocoltracked every major bump whilespecVersionsat at the value
it held when the script was written — and a greensync-template-versionsrun
was never evidence about it, because the script's failure mode was loud for the
keys it covered and mute for the key it did not.This is not confined to the registry contract.
create-objectstackcopies
the manifest into every scaffolded project, rewritingname,displayNameandnamespaceand droppingdescription— it has never touchedspecVersion. So
every project scaffolded since v7 was stamped with a^6.0.0spec range while
installing@objectstack/spec@^17.0.0.The two keys are two facts, and the fix keeps them apart.
engines.protocol
is the ADR-0087 D1 runtime handshake range and carries the protocol major
(^17).specVersionis documented byTemplateManifestSchemaas the
"Compatible@objectstack/specsemver range" and carries the package range
(^17.0.0) — the same value the script already writes into the template's own@objectstack/specdependency, so the manifest and thepackage.jsonnow state
one fact once. They agree on the major only because the spec package's major and
the protocol major are kept in lockstep; they are stamped from two different
values.Deleting the key was not available:
specVersionis required byTemplateManifestSchema, and every shipped manifest is parsed against it bycheck:template-manifests.Two structural changes, because one-key-one-file coverage is what let this
sit:- the sync script's file list is now discovered, not hard-coded — templates
are found by walkingsrc/templates/, the same waycheck-template-manifests
finds the manifests it parses, so a second template is covered on the day it
lands; - every stamp is required. A template whose file is missing, whose stamp is
absent, or whosepackage.jsondeclares no@objectstack/*dependency is a
hard failure naming the path — never a skip. A skipped stamp is
indistinguishable from a synced one in the log, which is the invisibility this
fixes.
The manifest is rewritten as text rather than parsed and re-serialized:
objectstack.manifest.jsonkeepsscaffold.variablescompact on one line, andJSON.stringify(…, null, 2)would reformat unrelated structure on every release.CI coverage lands as four per-template ratchets in
template-consistency.test.ts,
generalized offblankonto the same directory walk — including the invariant
that catches this exact class: the manifest'sspecVersionmust equal the@objectstack/specrange the template actually installs. Either file alone can
be self-consistently stale; only comparing them catches a stamp that covered one
and not the other.- the sync script's file list is now discovered, not hard-coded — templates
@objectstack/verify@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [c9f5950]
- Updated dependencies [d6e80b2]
- Updated dependencies [07e630e]
- Updated dependencies [66beee0]
- Updated dependencies [2f65b1b]
- Updated dependencies [ca2e020]
- Updated dependencies [720ee95]
- Updated dependencies [e717ba1]
- Updated dependencies [f287435]
- Updated dependencies [e7bccaa]
- Updated dependencies [2782805]
- Updated dependencies [e43d63a]
- Updated dependencies [e374b4d]
- Updated dependencies [5047cb8]
- Updated dependencies [ed4ca59]
- Updated dependencies [445ae4d]
- Updated dependencies [5aadce3]
- Updated dependencies [f2920e1]
- Updated dependencies [bcf2755]
- Updated dependencies [a433122]
- Updated dependencies [bc6434b]
- Updated dependencies [96f397a]
- Updated dependencies [9aa8890]
- Updated dependencies [48032c9]
- Updated dependencies [7c9c1dd]
- Updated dependencies [03520eb]
- Updated dependencies [2277443]
- Updated dependencies [a751f7d]
- Updated dependencies [eccb8b2]
- Updated dependencies [650cd3d]
- Updated dependencies [b735507]
- Updated dependencies [91c6c28]
- Updated dependencies [75b7c24]
- Updated dependencies [cf0d902]
- Updated dependencies [498f4e8]
- Updated dependencies [cc5c07b]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [4c178c1]
- Updated dependencies [8640fb2]
- Updated dependencies [5c38492]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [3508678]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [04d03c3]
- Updated dependencies [6a51704]
- Updated dependencies [2d0af57]
- Updated dependencies [c1731d0]
- Updated dependencies [c766ec3]
- Updated dependencies [7337f30]
- Updated dependencies [420804d]
- Updated dependencies [8656d67]
- Updated dependencies [51a46a4]
- Updated dependencies [c8e85fc]
- Updated dependencies [3d61924]
- Updated dependencies [5244fd7]
- Updated dependencies [716ac9b]
- Updated dependencies [a38408a]
- Updated dependencies [e9534a4]
- Updated dependencies [6feac91]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [b2789ad]
- Updated dependencies [5f5e234]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [27a567d]
- Updated dependencies [4ea921c]
- Updated dependencies [42b05af]
- Updated dependencies [0ccea4a]
- Updated dependencies [3ab2488]
- Updated dependencies [2b292ce]
- Updated dependencies [185c7bd]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [66dbec4]
- Updated dependencies [6aceca9]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [45862a5]
- Updated dependencies [79c46da]
- Updated dependencies [1e050a5]
- Updated dependencies [152bff8]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [24173e9]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [b705a6c]
- Updated dependencies [f8eb736]
- Updated dependencies [11b779e]
- Updated dependencies [4e71ae1]
- Updated dependencies [739fe5b]
- Updated dependencies [20067c5]
- Updated dependencies [d09d0fd]
- Updated dependencies [5ed8ee6]
- Updated dependencies [e783e16]
- Updated dependencies [4bfe1a5]
- Updated dependencies [b537855]
- Updated dependencies [2065e31]
- Updated dependencies [6cb88d9]
- Updated dependencies [b69d0f5]
- Updated dependencies [4dc8a61]
- Updated dependencies [4d47afe]
- Updated dependencies [4fc4a3c]
- Updated dependencies [90a12fb]
- Updated dependencies [e4e5c6e]
- Updated dependencies [72050cc]
- Updated dependencies [d70428a]
- Updated dependencies [4dfa369]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [5e2f594]
- Updated dependencies [e2899f6]
- Updated dependencies [7ff5aa2]
- Updated dependencies [b6c7690]
- Updated dependencies [2a6ebaf]
- Updated dependencies [855591f]
- Updated dependencies [17854cb]
- Updated dependencies [e6e1de4]
- Updated dependencies [6a12e5e]
- Updated dependencies [3851f87]
- Updated dependencies [09b880b]
- Updated dependencies [c73eacd]
- Updated dependencies [f8537df]
- Updated dependencies [712e185]
- Updated dependencies [88e1bac]
- Updated dependencies [693c788]
- Updated dependencies [0961065]
- Updated dependencies [2a29caa]
- Updated dependencies [9e2e682]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [0425db9]
- Updated dependencies [cd455c8]
- Updated dependencies [e1bb0ca]
- Updated dependencies [05864fb]
- Updated dependencies [326f5de]
- Updated dependencies [501ed0e]
- Updated dependencies [f047810]
- Updated dependencies [30d3752]
- Updated dependencies [21995d7]
- Updated dependencies [c80e7ae]
- Updated dependencies [499f55e]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [6a5e6ad]
- Updated dependencies [30b1c63]
- Updated dependencies [7fc01db]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [c86799f]
- Updated dependencies [b030055]
- Updated dependencies [03fa4c9]
- Updated dependencies [5989b0d]
- Updated dependencies [19db5fa]
- Updated dependencies [8f266f1]
- Updated dependencies [2b9d33a]
- Updated dependencies [ad217b1]
- Updated dependencies [f01c0ee]
- Updated dependencies [fab693b]
- Updated dependencies [b53d38e]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [b5f6b26]
- Updated dependencies [04f8fdb]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [b2a451f]
- Updated dependencies [c25b2d5]
- Updated dependencies [6158146]
- Updated dependencies [84cb121]
- Updated dependencies [ca19ee8]
- Updated dependencies [147eadc]
- Updated dependencies [a675b4d]
- Updated dependencies [b887013]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [402c125]
- Updated dependencies [7901b2d]
- Updated dependencies [7c2f386]
- Updated dependencies [56bca91]
- Updated dependencies [b3f9831]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [8a9e7f4]
- Updated dependencies [3d0ded8]
- Updated dependencies [44bc51d]
- Updated dependencies [bbbfcfc]
- Updated dependencies [1258dca]
- Updated dependencies [4639cec]
- Updated dependencies [91c4ff5]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- Updated dependencies [682b86b]
- Updated dependencies [6a1b45e]
- @objectstack/spec@17.1.0
- @objectstack/platform-objects@17.1.0
- @objectstack/plugin-auth@17.1.0
- @objectstack/types@17.1.0
- @objectstack/runtime@17.1.0
- @objectstack/plugin-security@17.1.0
- @objectstack/rest@17.1.0
- @objectstack/core@17.1.0
- @objectstack/objectql@17.1.0
- @objectstack/service-automation@17.1.0
- @objectstack/service-datasource@17.1.0
- @objectstack/plugin-sharing@17.1.0
- @objectstack/plugin-hono-server@17.1.0
- @objectstack/service-settings@17.1.0
- @objectstack/service-analytics@17.1.0
@objectstack/types@17.1.0
Minor Changes
2f65b1b:
error.codeis a closed vocabulary at every door (#9106, maintainer ruling
2026-08-16): the runtime dispatcher's thrown-error exits
(HttpDispatcher.errorFromThrown,dispatcher-plugin'serrorResponseBase,endpoint-executor'sendpointErrorAnswer— the actions door among them) now
serve the narrowedcodethe shared resolver (resolveThrownHttpError,@objectstack/types) has always computed, exactly as the REST door has since
#8016. A thrown code that is not a member ofStandardErrorCode ∪ ERROR_CODE_LEDGERno longer reacheserror.code.It is not dropped:
ApiErrorSchemadeclares a new optionaldeclaredCode
field — the open, author-authored channel — and the demoted spelling rides
there. Presence means demotion: the field is absent whenever the producer's
code is a vocabulary member (it is already inerror.code) or the producer
declared none. The #7867 sandbox passthrough capability is preserved — a
metadata app's own thrown.codestill crosses the QuickJS boundary and still
reaches the wire.For a metadata app that throws its own code (e.g.
Object.assign(new Error('pick another'), { code: 'DUPLICATE' })in an action
body) and reads it back from an actions-door failure:- FROM:
error.code === 'DUPLICATE' - TO:
error.codeis the closed member the status derives (e.g.VALIDATION_ERRORon a 400) anderror.declaredCode === 'DUPLICATE'.
One-line fix: branch onerror.declaredCodefor app-specific spellings;
branch onerror.codefor platform conditions.
Platform producers are unaffected: every registered code reaches
error.code
verbatim, as before (post-#8846 the dispatcher-vocabulary gate holds that set
registered). Measured before landing (the ruling's binding precondition): no
existing consumer of the actions door branches on author-authored strings inerror.code.@objectstack/typesaddsdemotedDeclaredCode(thrown)— the one definition of
"which spelling a boundary surfaces beside the closedcode".- FROM:
79c46da: feat(contract): a hook refusal can mark its message user-facing —
userMessage, the producer-side opt-in channel (#9934, producer half of objectui#5210)The console form deliberately discards the server
messageon 403 and
substitutes a generic string — the recorded #3821 fix for platform diagnostics
leaking to end users. That substitution also suppressed every deliberate,
localized refusal an application hook author wrote (11 real hook guards in the
objectui#5210 report), and incentivized misusing 400 for permission refusals.
The maintainer-accepted ruling (2026-08-19, option 1): give the AUTHOR a
producer-side way to mark a refusal message user-facing, once, at the contract
level — status-agnostic, with #3821 preserved by construction for everything
unmarked.The marking: set
userMessage(non-empty string) on the thrown error at
throw time. It is a text-carrying field, not a boolean besidemessage— the
mark and the marked text are one value, so no boundary that rewraps or
substitutesmessagecan promote platform prose into the marked channel, and
platform/driver code never sets it.@objectstack/spec:ApiErrorSchema.userMessageandEnhancedApiErrorSchema.userMessage(optional, additive).@objectstack/types:declaredUserMessage(error)— the ONE "is this
marked?" read (non-empty string, nothing invented) — andThrownHttpError.userMessageonresolveThrownHttpError.@objectstack/rest:mapDataError/resolveErrorResponseride a declared
marking onto whatever envelope classification chose (flat body top-leveluserMessage, truncated at the same #5423 bound as the 4xx message).@objectstack/runtime: the QuickJS side-channel carriesuserMessage
across the sandbox boundary (both directions, joiningcode/fields/status), and the dispatcher door emits it as a declared sibling in the
nested envelope.@objectstack/client: the SDK attacheserr.userMessagefrom both wire
dialects, so a UI renders it verbatim when present and keeps its generic
substitution when absent.
The consumer half — the console form rendering a marked message instead of the
genericform.noPermissionToSave— is objectui#5210.
Patch Changes
2d0af57: fix(tests): give two default-vitest-timeout cases real margin instead of a bare default (#9311)
Two cases only passed
pnpm testwhen they were not competing for CPU — the
same defect class as the already-closed precedents #3662, #4186, #4485,
#5421, #6329: a test running under vitest's defaulttestTimeout/hookTimeoutwith no margin for anything heavier than an idle box.packages/types/src/node.test.ts—"falls back to the importing package's own resolution when the host does not declare"is the only case
in the file that performs a real dynamicimport()of@objectstack/spec(a
multi-megabyte package); every sibling in the samedescribeblock resolves
a small on-disk fixture or fails fast, all under 10ms. Measured on this box:
~0.9-1.1s unloaded, already observed failing at 5061ms against the 5000ms
default under nothing heavier thanturbo run test --concurrency=2(#9311's
own isolation runs). Gave that one case an explicit 30stestTimeout— the
same order of magnitude the repo already uses for subprocess/real-load cases
(#3662precedent) — and left every sub-10ms sibling alone.packages/qa/dogfood/test/semantic-roles.dogfood.test.ts— itsbeforeAllboots the full showcase stack (ObjectQL + ~45 plugins) through@objectstack/verify'sbootStack, which does not fit vitest's 10shookTimeoutdefault with any margin at all: observed failing at 10027ms
against the 10000ms budget, and this file's own isolated run measured 18.3s
(vitestDuration) / 19.5s wall clock for the whole file even with the box
otherwise idle. Gave the hook an explicit 180s timeout, matching this
package's own existing house pattern for the identicalbootStack(showcaseStack, …)call
(admin-identity-audit-trail.dogfood.test.ts'sbeforeAll(…, 180_000))
rather than inventing a new number for the same operation.No behaviour change — both suites already pass; this only gives the two
timeout-sensitive cases room to finish on a loaded box. The repo's full test
suite is confirmed green at low concurrency (#9311), so this is margin
repair, not a product fix.turbo.json's default concurrency is out of scope
for this change (a maintainer-level default, per #9311's own filing).27a567d: fix(types): teach the internal-leak predicate MySQL's three error templates (#8739)
looksLikeInternalErrorLeakdecides whether a message is a driver dump that
must not reach an API client. It is applied at three HTTP boundaries
(@objectstack/rest'smapDataError,@objectstack/runtime's
dispatcher-plugin and endpoint-executor, the hono adapter) and by@objectstack/objectql's log redactor. Its dialect list covered the SQLite
family and Postgres; on a MySQL deployment it returnedfalsefor every one of
these conditions — silent, not clearing.Under the maintainer's 2026-08-15 ruling on #8739, MySQL is a supported
deployment target, not merely a tested dialect — the answer already implied by
what is published (OS_DATABASE_DRIVER=mysqlas a documented deployment knob,MysqlConfigas authorable datasource config, per-field MySQL DDL intypes.mdx) and by a required CI check that stands up a livemysql:8.0. A
supported target's driver text reaches those boundaries in production, so its
templates belong in the list.Now recognised — one per condition the other two dialects were already
covered for, each anchored on MySQL's own errmsg template rather than on a bare
substring:Table 'app.t' doesn't exist(ER_NO_SUCH_TABLE 1146). MySQL's contracted
spelling quotesdb.tableas one identifier, so the Postgresrelation "t" does not existlimb could never reach it.Unknown column 'c' in 'field list'(ER_BAD_FIELD_ERROR 1054). Both quoted
parts are required; the second is MySQL's clause name (field list,where clause,order clause,on clause), and it is what distinguishes the
driver's template from a sentence that merely calls a column unknown.Duplicate entry 'x' for key 'i'(ER_DUP_ENTRY 1062). Thefor keytail plus
a quoted index is the anchor. This is the one MySQL template whose text embeds
a caller's value rather than an identifier — SQLite'sUNIQUE constraint failed: t.cand Postgres'violates unique constraint "…"
both name only an index — which is why closing this gap was worth a behaviour
change rather than another comment.
Deliberately still NOT recognised, so the boundary of the change is on the
record rather than inferred:- MySQL's ACL family —
Access denied for user 'u'@'h' to database 'd'
(1044),SELECT command denied to user … for table 't'(1142) — the
counterpart of the Postgrespermission denied for tablelimb. Nothing in
this repo has raised one off a live server, and the standing rule in this
neighbourhood (unique-violation.ts) is that a dialect's spelling is added
once it has been MEASURED off a thrown error, never from a reading of the
manual.Access deniedalso collides with this platform's own security prose
(`[Security] Acce...
@objectstack/trigger-schedule@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [07e630e]
- Updated dependencies [2f65b1b]
- Updated dependencies [720ee95]
- Updated dependencies [f287435]
- Updated dependencies [2782805]
- Updated dependencies [e43d63a]
- Updated dependencies [9aa8890]
- Updated dependencies [7c9c1dd]
- Updated dependencies [75b7c24]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [8640fb2]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [420804d]
- Updated dependencies [716ac9b]
- Updated dependencies [a38408a]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [5f5e234]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [42b05af]
- Updated dependencies [2b292ce]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [79c46da]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [24173e9]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [f8eb736]
- Updated dependencies [11b779e]
- Updated dependencies [739fe5b]
- Updated dependencies [4bfe1a5]
- Updated dependencies [2065e31]
- Updated dependencies [b69d0f5]
- Updated dependencies [4d47afe]
- Updated dependencies [e4e5c6e]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [e2899f6]
- Updated dependencies [3851f87]
- Updated dependencies [2a29caa]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [cd455c8]
- Updated dependencies [e1bb0ca]
- Updated dependencies [30d3752]
- Updated dependencies [c80e7ae]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [30b1c63]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [402c125]
- Updated dependencies [7901b2d]
- Updated dependencies [56bca91]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [44bc51d]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- @objectstack/spec@17.1.0
- @objectstack/core@17.1.0
@objectstack/trigger-record-change@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [07e630e]
- Updated dependencies [2f65b1b]
- Updated dependencies [720ee95]
- Updated dependencies [f287435]
- Updated dependencies [2782805]
- Updated dependencies [e43d63a]
- Updated dependencies [9aa8890]
- Updated dependencies [7c9c1dd]
- Updated dependencies [75b7c24]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [8640fb2]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [420804d]
- Updated dependencies [716ac9b]
- Updated dependencies [a38408a]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [5f5e234]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [42b05af]
- Updated dependencies [2b292ce]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [79c46da]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [24173e9]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [f8eb736]
- Updated dependencies [11b779e]
- Updated dependencies [739fe5b]
- Updated dependencies [4bfe1a5]
- Updated dependencies [2065e31]
- Updated dependencies [b69d0f5]
- Updated dependencies [4d47afe]
- Updated dependencies [e4e5c6e]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [e2899f6]
- Updated dependencies [3851f87]
- Updated dependencies [2a29caa]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [cd455c8]
- Updated dependencies [e1bb0ca]
- Updated dependencies [30d3752]
- Updated dependencies [c80e7ae]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [30b1c63]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [402c125]
- Updated dependencies [7901b2d]
- Updated dependencies [56bca91]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [44bc51d]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- @objectstack/spec@17.1.0
- @objectstack/core@17.1.0
@objectstack/trigger-api@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [07e630e]
- Updated dependencies [2f65b1b]
- Updated dependencies [720ee95]
- Updated dependencies [f287435]
- Updated dependencies [2782805]
- Updated dependencies [e43d63a]
- Updated dependencies [9aa8890]
- Updated dependencies [7c9c1dd]
- Updated dependencies [75b7c24]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [8640fb2]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [420804d]
- Updated dependencies [716ac9b]
- Updated dependencies [a38408a]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [5f5e234]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [42b05af]
- Updated dependencies [2b292ce]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [79c46da]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [24173e9]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [f8eb736]
- Updated dependencies [11b779e]
- Updated dependencies [739fe5b]
- Updated dependencies [4bfe1a5]
- Updated dependencies [2065e31]
- Updated dependencies [b69d0f5]
- Updated dependencies [4d47afe]
- Updated dependencies [e4e5c6e]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [e2899f6]
- Updated dependencies [3851f87]
- Updated dependencies [2a29caa]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [cd455c8]
- Updated dependencies [e1bb0ca]
- Updated dependencies [30d3752]
- Updated dependencies [c80e7ae]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [30b1c63]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [402c125]
- Updated dependencies [7901b2d]
- Updated dependencies [56bca91]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [44bc51d]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- @objectstack/spec@17.1.0
- @objectstack/core@17.1.0
@objectstack/studio@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [c9f5950]
- Updated dependencies [d6e80b2]
- Updated dependencies [07e630e]
- Updated dependencies [66beee0]
- Updated dependencies [2f65b1b]
- Updated dependencies [720ee95]
- Updated dependencies [f287435]
- Updated dependencies [e43d63a]
- Updated dependencies [9aa8890]
- Updated dependencies [7c9c1dd]
- Updated dependencies [03520eb]
- Updated dependencies [75b7c24]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [8640fb2]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [420804d]
- Updated dependencies [716ac9b]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [42b05af]
- Updated dependencies [2b292ce]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [79c46da]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [11b779e]
- Updated dependencies [739fe5b]
- Updated dependencies [4bfe1a5]
- Updated dependencies [2065e31]
- Updated dependencies [b69d0f5]
- Updated dependencies [4d47afe]
- Updated dependencies [e4e5c6e]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [e2899f6]
- Updated dependencies [3851f87]
- Updated dependencies [2a29caa]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [cd455c8]
- Updated dependencies [30d3752]
- Updated dependencies [c80e7ae]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [30b1c63]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [04f8fdb]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [6158146]
- Updated dependencies [84cb121]
- Updated dependencies [ca19ee8]
- Updated dependencies [a675b4d]
- Updated dependencies [b887013]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [7901b2d]
- Updated dependencies [56bca91]
- Updated dependencies [b3f9831]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [44bc51d]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- @objectstack/spec@17.1.0
- @objectstack/platform-objects@17.1.0
@objectstack/spec@17.1.0
Important
This release note is truncated. The changelog entry for @objectstack/spec@17.1.0 is
194,013 characters; the GitHub Releases API rejects any body over
125,000. The complete entry is in packages/spec/CHANGELOG.md.
Minor Changes
07e630e: feat(spec):
ActionSchema.onSuccess— post-success navigation forapi/scriptactions, with${result.*}joining the navigate template's interpolation scope (#9566, #9474)The maintainer's 2026-08-18 ruling (recorded on #9566, mirrored on #9474)
declares ONE post-success navigation contract for both server-executing action
types instead of two per-type conventions:onSuccess: { navigate, openIn? }— a strict object, read fortype: 'api'andtype: 'script'only (a refinement refuses it onurl/modal/flow/form, where no success event exists for it to ride —
the ADR-0078 posture, same enforcement shape as thebody-on-non-script
refinement).navigateis a route/URL template. Its documented interpolation scope is${param.*}+${ctx.*}(existing) +${result.*}— NEW: the action's
server response payload (anapiaction's response body, ascript
handler's return value), which is what makes "server clones a record → jump
to the new record" declarable:navigate: '/apps/crm/tasks/${result.id}'.
The interpolation ENGINE stays the renderer's (objectuiinterpolateTarget);
the spec records the contract.openInis the closed enum'self' | 'newTab', defaulting'self'
(materialized, the file's default convention) — no general navigation DSL.- The shipped handler-return convention (
{ redirectUrl, openIn? },
objectui#2967/#2904) keeps its 17.0.0 semantics: absentopenInstill means
new-tab (no silent behavior flip for existing handlers); a handler may returnopenIn: 'self'explicitly.
The console consumer is the downstream objectui half (SPA navigation branch,
executeAPInavigation handling,${result.*}interpolation), filed
Blocked-by these cards; the liveness ledger records the key atplanned
strength with the amend-on-landing instruction.2f65b1b:
error.codeis a closed vocabulary at every door (#9106, maintainer ruling
2026-08-16): the runtime dispatcher's thrown-error exits
(HttpDispatcher.errorFromThrown,dispatcher-plugin'serrorResponseBase,endpoint-executor'sendpointErrorAnswer— the actions door among them) now
serve the narrowedcodethe shared resolver (resolveThrownHttpError,@objectstack/types) has always computed, exactly as the REST door has since
#8016. A thrown code that is not a member ofStandardErrorCode ∪ ERROR_CODE_LEDGERno longer reacheserror.code.It is not dropped:
ApiErrorSchemadeclares a new optionaldeclaredCode
field — the open, author-authored channel — and the demoted spelling rides
there. Presence means demotion: the field is absent whenever the producer's
code is a vocabulary member (it is already inerror.code) or the producer
declared none. The #7867 sandbox passthrough capability is preserved — a
metadata app's own thrown.codestill crosses the QuickJS boundary and still
reaches the wire.For a metadata app that throws its own code (e.g.
Object.assign(new Error('pick another'), { code: 'DUPLICATE' })in an action
body) and reads it back from an actions-door failure:- FROM:
error.code === 'DUPLICATE' - TO:
error.codeis the closed member the status derives (e.g.VALIDATION_ERRORon a 400) anderror.declaredCode === 'DUPLICATE'.
One-line fix: branch onerror.declaredCodefor app-specific spellings;
branch onerror.codefor platform conditions.
Platform producers are unaffected: every registered code reaches
error.code
verbatim, as before (post-#8846 the dispatcher-vocabulary gate holds that set
registered). Measured before landing (the ruling's binding precondition): no
existing consumer of the actions door branches on author-authored strings inerror.code.@objectstack/typesaddsdemotedDeclaredCode(thrown)— the one definition of
"which spelling a boundary surfaces beside the closedcode".- FROM:
720ee95: fix(security): the shipped admin permission sets no longer grant export on the
*wildcard (#8681)BREAKING for any deployment whose administrators export today. Landing after
the v17.0.0 cut, so it ships asminorunder the lockstep launch-window
convention; the migration prescription is registered under protocol major 18,
whereobjectstack migrate metausers will look.admin_full_access,organization_adminand the derivedorganization_admin_no_bypassshippedobjects['*'].allowExport = true. That
single line made the 17.0 export axis undeniable for anyone holding an admin
set: an application could declare an object exportable by nobody, ship it, and
the platform would export it anyway.Measured on 17.0.0 GA — 40 export probes, 5 principals, 8 objects, real Bearer
tokens — an org owner exportedcrm_quote(9 rows),crm_campaign(13) andcrm_task(15) with 200 and full data. No app permission set granted export on
any of the three, and the app had no way to say no:- the wildcard lives in code-package metadata, so editing it answers
403 [not_overridable] Metadata item 'permission/admin_full_access' is provided by a code package; - the org admin holds no app-authored permission set, so there is nowhere to
author the per-objectallowExport: falsethat would otherwise have won.
This was never a gate defect. The same run proves the export gate exact for
every other principal: a token refused on one object exports another on the same
route, grantingallowExportat runtime flips 403 to 200, and revoking it flips
it back. A plain member carrying'*': { allowExport: true }exported too — the
wildcard was simply doing what it said. What changes is that the platform stops
shipping that grant.This is #5491 applied to the export axis. That change removed
member_default's
CRUD wildcard because a wildcard in a set every principal resolves is not a
default but a floor no app can get under; the export wildcard survived by
omission rather than by decision, one tier up.Migration — grant
allowExportexplicitly in an app permission set where
admin export is intended. There is no automatic replacement, deliberately:
which principals may take a bulk machine-readable copy of a table is the
segregation-of-duties judgement the axis exists to make explicit.// In YOUR app's permission set — not a platform set (those are not overridable).{name: 'system_admin',objects: {crm_account: {allowRead: true,allowExport: true},// export intendedcrm_quote: {allowRead: true},// export withheld},}
⚠️ Nothing fails at parse time, and the shipped sets are re-seeded on
upgrade. A deployment that upgrades without editing anything is valid metadata
whose administrators have quietly lost export on every object no app set names —
the first sign is a support report, not an error. Verify behaviourally: sign in
as an org owner and callGET /api/v1/data/<object>/export, expecting 200 where
export is intended and 403EXPORT_NOT_PERMITTEDwhere it is not.What is deliberately unchanged. READ is untouched — an admin still sees
every record they saw before; this narrows bulk egress only.allowExporton a'*'entry remains a supported, honoured authoring shape in an app's own sets.
Specific-over-wildcard precedence is unchanged (an explicit per-object entry
still overrides the wildcard). TheviewAllRecords/modifyAllRecords
super-user bits still do not imply export, exactly as before. And an app's own
admin set already gets precisely its declared posture — declaredfalseanswers
403, declaredtrueanswers 200 — which is what makes withdrawing the platform
grant safe rather than merely restrictive.Both admin sets are fixed together, and the org-admin pair from one declaration
(organization_admin_no_bypassis derived fromorganization_admin). Fixing
one and not the other was rejected outright: a half-closed export boundary reads
as closed and is not.- the wildcard lives in code-package metadata, so editing it answers
f287435: feat(spec): refuse undeclared keys on the analytics authoring surface (#4001 data batch D)
BREAKING accept-set narrowing, landing after the v17.0.0 cut (the lockstep
launch-window convention ships it asminor; the migration prescription is
registered under protocol major 18, whereos migrate metausers will look).All 8
data/analytics.zod.tssites are strict: the cube family (CubeSchema+
itsrefreshKeyblock,MetricSchema+ itsfilters[]items,DimensionSchema,CubeJoinSchema) and the query family
(AnalyticsQuerySchema+ itstimeDimensions[]items). Before this change an
undeclared key on any of them was silently dropped: a join authored with a
typo'drelationshipregistered with themany_to_onedefault — a different
join shape than the author declared — and a cube's misspelled key vanished
under a successful parse.The subtle half is the query:
/analytics/query's TOP level has been strict
since #3878 (AnalyticsQueryRequestSchema), but top-level strictness does not
rec...
@objectstack/setup@17.1.0
Patch Changes
- Updated dependencies [56656aa]
- Updated dependencies [c9f5950]
- Updated dependencies [d6e80b2]
- Updated dependencies [07e630e]
- Updated dependencies [66beee0]
- Updated dependencies [2f65b1b]
- Updated dependencies [720ee95]
- Updated dependencies [f287435]
- Updated dependencies [e43d63a]
- Updated dependencies [9aa8890]
- Updated dependencies [7c9c1dd]
- Updated dependencies [03520eb]
- Updated dependencies [75b7c24]
- Updated dependencies [d5552ca]
- Updated dependencies [d9813a9]
- Updated dependencies [8640fb2]
- Updated dependencies [2420641]
- Updated dependencies [2ad91c3]
- Updated dependencies [f57fb38]
- Updated dependencies [00777a0]
- Updated dependencies [d491625]
- Updated dependencies [420804d]
- Updated dependencies [716ac9b]
- Updated dependencies [62b1427]
- Updated dependencies [7ea1372]
- Updated dependencies [23abe27]
- Updated dependencies [985a9cd]
- Updated dependencies [a8189ae]
- Updated dependencies [26e70fb]
- Updated dependencies [42b05af]
- Updated dependencies [2b292ce]
- Updated dependencies [abcf853]
- Updated dependencies [8b9eba5]
- Updated dependencies [d575779]
- Updated dependencies [94f7ef8]
- Updated dependencies [c5ac5e4]
- Updated dependencies [a777944]
- Updated dependencies [dd88e1c]
- Updated dependencies [856527c]
- Updated dependencies [870f710]
- Updated dependencies [79c46da]
- Updated dependencies [7ff3975]
- Updated dependencies [29d055b]
- Updated dependencies [65589d6]
- Updated dependencies [2c86fe3]
- Updated dependencies [e196c6a]
- Updated dependencies [4ab7523]
- Updated dependencies [19539b4]
- Updated dependencies [11b779e]
- Updated dependencies [739fe5b]
- Updated dependencies [4bfe1a5]
- Updated dependencies [2065e31]
- Updated dependencies [b69d0f5]
- Updated dependencies [4d47afe]
- Updated dependencies [e4e5c6e]
- Updated dependencies [9a56784]
- Updated dependencies [d00d2f6]
- Updated dependencies [df0c12d]
- Updated dependencies [d31785f]
- Updated dependencies [c308a4f]
- Updated dependencies [e2899f6]
- Updated dependencies [3851f87]
- Updated dependencies [2a29caa]
- Updated dependencies [09a6eee]
- Updated dependencies [1a7f907]
- Updated dependencies [cd455c8]
- Updated dependencies [30d3752]
- Updated dependencies [c80e7ae]
- Updated dependencies [09a9a8a]
- Updated dependencies [07026cf]
- Updated dependencies [5d4f3d5]
- Updated dependencies [4d80e8b]
- Updated dependencies [30b1c63]
- Updated dependencies [079b457]
- Updated dependencies [e43b211]
- Updated dependencies [890b38f]
- Updated dependencies [8bee54b]
- Updated dependencies [04f8fdb]
- Updated dependencies [7a537ce]
- Updated dependencies [593c4bf]
- Updated dependencies [6158146]
- Updated dependencies [84cb121]
- Updated dependencies [ca19ee8]
- Updated dependencies [a675b4d]
- Updated dependencies [b887013]
- Updated dependencies [ff08691]
- Updated dependencies [60e0f90]
- Updated dependencies [90c5285]
- Updated dependencies [7901b2d]
- Updated dependencies [56bca91]
- Updated dependencies [b3f9831]
- Updated dependencies [79394d7]
- Updated dependencies [730fd9a]
- Updated dependencies [44bc51d]
- Updated dependencies [73cfddf]
- Updated dependencies [d634e66]
- @objectstack/spec@17.1.0
- @objectstack/platform-objects@17.1.0
@objectstack/service-storage@17.1.0
Patch Changes
bbd86ed: Attachment access hooks: read the caller's org under the blessed
organizationIdnamecallerContext()in thesys_attachmentaccess kit built its fallback
execution envelope fromsession.tenantId— an alias removed from the
hook/action session surface in v11 (#3290).HookContextSchemastrips atenantIdkey and the engine'sbuildSessiononly ever emitsorganizationId, so on every call that reached the session fallback (no
execution context riding along) the envelope handed toISharingService.canEditcarried no organization at all. Parent-record
access for attachments was therefore evaluated without the caller's active
org on that path. It now readssession.organizationId, matching thesys_commentkit, which already did.The
sys_commentkit's owncallerContext()had the same read as a dead
first arm (s.tenantId ?? s.organizationId); the arm is removed. That half
is behaviour-neutral — the fallback already carried the value.Both kits gain coverage of the session-fallback path in both directions: the
blessed name is read, and a stray removed-alias key does not become the org.593c4bf: feat(spec):
storagebecomes the canonicalCoreServiceNameslot;file-storagestays a deprecated v17 alias (#9683)Maintainer ruling, 2026-08-18, verbatim: 「9683 file-storage 可以叫 storage」.
Thefile-storageslot was the onlyCoreServiceNamemember whose spelling
diverged from its documented accessor (services.storage), with no recorded
reason anywhere in the tree.CoreServiceNamegainsstorageas the canonical member;file-storage
stays an accepted, deprecated alias within v17 (it is a published enum
member — existinggetService('file-storage')callers keep working).CORE_SERVICE_PROVIDERandServiceRequirementDefcarry both.@objectstack/service-storageregisters the same instance under both
names (thehttp.server/http-serverpattern), pinned by an
alias-equivalence test.- Every internal consumer resolves
storage: the HTTP dispatcher, the email
plugin's attachment store, andos migrate files-to-references. Discovery
reports the service under the canonicalstoragekey and mirrors the row
verbatim under thefile-storagekey for the alias's v17 lifetime, so
existing discovery readers (e.g. the console endpoint catalog) keep
working. - Docs (
kernel/runtime-services,kernel/contracts) now document the
canonical slot; a custom v17 provider for this slot should register both
names.
1258dca: Restore the #4757 unscoped multi-delete refusal on
sys_attachmentthrough the wired engine (#9719).ObjectQL.registerHookgains an opt-indispatchUnscopedMultiDeletedeclaration (valid onbeforeDeleteregistrations only — anything else is refused at registration): when amulti: truedelete arrives with nowhereat all (absent ornull), the engine's predicate path dispatches the whole-operation context ONCE to declaring registrations — before any matched row is resolved, zero-match included — so a guard about the operation's shape can refuse it. Bindinginput.idon that context is refused (HookTargetRebindError, path'unscoped-multi'). Undeclared registrations, scoped deletes (including the match-allwhere: {}), and by-id deletes see no new dispatch.The
sys_attachmentaccess guard declares the flag, so its documented refusal of a predicate-less multi-delete fires again with its declared envelope (ATTACHMENT_DELETE_DENIED, HTTP 403): since the per-row dispatch contract (#5038/#5574) that branch was unreachable, and a predicate-lessmulti: truedelete quietly removed every row the caller happened to be entitled to. System-context and context-less programmatic deletes bypass the guard exactly as before.4639cec: Behaviour change: an unscoped
multi: trueUPDATE ofsys_commentis now refused, where it previously succeeded for a caller entitled to every row (#9974).This is not the restoration of a guard that used to work — it is a deliberate narrowing of what the engine accepts, ruled by the maintainer on 2026-08-19. If you issue
ql.update('sys_comment', data, { multi: true })with nowhereat all, that call works today and will start failing withRECORD_NOT_ACCESSIBLE/ 403. The fix at the call site is to say which rows you mean — pass awhere. The explicit match-allwhere: {}is still accepted and still authorizes every matched row individually; only an absent ornullpredicate is refused.Why the accept set narrowed rather than the declaration:
resolveTargetRowshas declared this refusal for both write verbs since #4630, but on update it could only ever fire by accident — when the sweep happened to touch a row the caller lacked rights to, and then with a per-row message (Cannot update comment c2: …) naming a row rather than the shape. A caller who owned every row had the whole table rewritten, and a zero-match probe resolved silently. A guard that fires by accident reads as enforcement while enforcing nothing. The ruling weighed recoverability: a delete leaves a trace of who removed what, an overwrite leaves none — the old value is gone on the spot with nothing to restore from — and a forgottenwhereis the mistake generated code makes most often.Engine (
@objectstack/objectql).#9719's opt-in whole-operation dispatch now coversbeforeUpdate's predicate path as well asbeforeDelete's, and the registration flag is renameddispatchUnscopedMultiDelete→dispatchUnscopedMultiWrite(one flag generalized to both events rather than a second flag; it is per-registration and per-event, so a delete-only guard still says "delete only" by declaring it onbeforeDeletealone). Declaring it on any other event is still refused at registration time. Bindinginput.idon the whole-operation context is refused on both verbs (HookTargetRebindError, pathunscoped-multi), and the error now names the caller's event.Blast radius. The dispatch is delivered ONLY to registrations that declare the flag, so
sys_commentis the only object whose update accept set changes; every other object's unscopedmulti: trueupdate behaves exactly as before.sys_attachmentkeeps its delete-only declaration and is unaffected on update. A repo-wide structural sweep of 4 663 source files found no in-tree caller — none inexamples/, none in the dogfood apps, none inpackages/source — that issues an unscopedmulti: trueupdate against a declaring object.@objectstack/service-storageis a rename-only follow: itssys_attachmentguard declares the renamed flag on the same event, with the same behaviour.Updated dependencies [56656aa]
Updated dependencies [c9f5950]
Updated dependencies [d6e80b2]
Updated dependencies [07e630e]
Updated dependencies [66beee0]
Updated dependencies [2f65b1b]
Updated dependencies [720ee95]
Updated dependencies [f287435]
Updated dependencies [2782805]
Updated dependencies [e43d63a]
Updated dependencies [9aa8890]
Updated dependencies [7c9c1dd]
Updated dependencies [03520eb]
Updated dependencies [899052a]
Updated dependencies [75b7c24]
Updated dependencies [d5552ca]
Updated dependencies [d9813a9]
Updated dependencies [8640fb2]
Updated dependencies [2420641]
Updated dependencies [2ad91c3]
Updated dependencies [f57fb38]
Updated dependencies [00777a0]
Updated dependencies [d491625]
Updated dependencies [2d0af57]
Updated dependencies [420804d]
Updated dependencies [716ac9b]
Updated dependencies [a38408a]
Updated dependencies [62b1427]
Updated dependencies [7ea1372]
Updated dependencies [23abe27]
Updated dependencies [985a9cd]
Updated dependencies [5f5e234]
Updated dependencies [a8189ae]
Updated dependencies [26e70fb]
Updated dependencies [27a567d]
Updated dependencies [42b05af]
Updated dependencies [2b292ce]
Updated dependencies [abcf853]
Updated dependencies [8b9eba5]
Updated dependencies [d575779]
Updated dependencies [94f7ef8]
Updated dependencies [c5ac5e4]
Updated dependencies [a777944]
Updated dependencies [dd88e1c]
Updated dependencies [856527c]
Updated dependencies [870f710]
Updated dependencies [79c46da]
Updated dependencies [1e050a5]
Updated dependencies [7ff3975]
Updated dependencies [29d055b]
Updated dependencies [65589d6]
Updated dependencies [2c86fe3]
Updated dependencies [e196c6a]
Updated dependencies [24173e9]
Updated dependencies [4ab7523]
Updated dependencies [19539b4]
Updated dependencies [f8eb736]
Updated dependencies [11b779e]
Updated dependencies [739fe5b]
Updated dependencies [4bfe1a5]
Updated dependencies [2065e31]
Updated dependencies [b69d0f5]
Updated dependencies [4d47afe]
Updated dependencies [e4e5c6e]
Updated dependencies [9a56784]
Updated dependencies [d00d2f6]
Updated dependencies [df0c12d]
Updated dependencies [d31785f]
Updated dependencies [c308a4f]
Updated dependencies [e2899f6]
Updated dependencies [3851f87]
Updated dependencies [2a29caa]
Updated dependencies [09a6eee]
Updated dependencies [1a7f907]
Updated dependencies [cd455c8]
Updated dependencies [e1bb0ca]
Updated dependencies [30d3752]
Updated dependencies [c80e7ae]
Updated dependencies [09a9a8a]
Updated dependencies [07026cf]
Updated dependencies [5d4f3d5]
Updated dependencies [4d80e8b]
Updated dependencies [30b1c63]
U...