Skip to content

chore: version packages#2785

Closed
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main
Closed

chore: version packages#2785
github-actions[bot] wants to merge 1 commit into
mainfrom
changeset-release/main

Conversation

@github-actions

@github-actions github-actions Bot commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@objectstack/spec@15.0.0

Major Changes

  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.

Minor Changes

  • 2a71f48: feat(auth): admin direct user management, phone sign-in, and identity bulk import (feat(auth): 管理员直建用户 + 手机号登录 + sys_user 批量导入 —— 分阶段实施(#2758 重排) #2766, re-scoped feat(auth): sys_user 批量导入接口 —— 导入用户的密码处理策略 #2758)

    sys_user is managed by better-auth and its generic CRUD is suppressed, so
    until now the only way to add a teammate was the email-dependent invite flow.
    This ships three staged capabilities:

    • Admin direct user managementPOST /api/v1/auth/admin/create-user
      and a wrapped POST /api/v1/auth/admin/set-user-password (ADR-0068
      platform-admin gate; better-auth pipeline so credentials are real). Optional
      generated temporary password (returned once, never persisted or logged) and
      a new sys_user.must_change_password flag enforced through the ADR-0069
      authGate (403 PASSWORD_EXPIRED until the user changes it). New
      create_user action and upgraded set_user_password action on the Users
      list — pure schema, no frontend changes.
    • Phone sign-in (opt-in auth.plugins.phoneNumber) — better-auth
      phoneNumber plugin, phone+password only (POST /sign-in/phone-number);
      OTP flows stay off until SMS infrastructure exists. Adds
      sys_user.phone_number (unique) / phone_number_verified. Phone-only
      accounts get an undeliverable placeholder email
      (u-<random>@placeholder.invalid, never derived from the phone number);
      all auth mail callbacks refuse placeholder recipients.
    • Identity bulk importPOST /api/v1/auth/admin/import-users accepts
      the same payloads as the generic import routes (rows/csv/xlsx, dryRun,
      upsert by email or phone) but writes every row through better-auth.
      Password policies: invite (reset-link email per created user; requires an
      EmailService) and temporary (per-row one-time passwords + forced change).
      Sync only, ≤500 rows per request; no undo; upsert updates touch profile
      fields only and can never reset an existing user's password.
      prepareImportRequest and the CSV/xlsx parsers moved from rest-server.ts
      to an exported import-prepare.ts module (behavior unchanged).

@objectstack/cli@15.0.0

Minor Changes

  • 8f0b9df: fix(cli,plugin-security): os meta resync to re-materialize default permission sets from dist ([cli/plugin-security] dev 元数据物化不一致:默认权限集 insert-if-not-exists 不重物化(声明集走 upsert) #2705)

    The default permission sets (admin_full_access / member_default /
    viewer_readonly …) were seeded insert-once at boot: bootstrapPlatformAdmin
    skipped any row that already existed and never wrote the shipped declaration
    back. So editing a default set's source, recompiling, and restarting os dev
    without --fresh left the runtime serving the OLD value — silently, because
    the runtime authz resolver hydrates permission sets from the sys_permission_set
    row (resolve-authz-context.ts), not from the in-memory dist. A permission-gated
    surface (e.g. setup.access) would keep its stale behavior with no error, which
    repeatedly misled debugging. Every other metadata seed (declared permission
    sets, positions, built-in roles, capabilities) already upserts on boot, leaving
    the platform-default path the lone insert-once holdout — a gap ADR-0090 widened
    by persisting more facets (system_permissions, delegated-admin admin_scope)
    onto the same row.

    The insert-once posture is deliberate for prod (it protects an admin's Setup
    edits and keeps the defaults env-authored — the exact posture
    bootstrapDeclaredPermissions relies on), so this is not switched to a blind
    upsert. Instead:

    • bootstrapPlatformAdmin gains a resync option. Default boot behavior is
      unchanged (insert-once). Under resync, an existing row is reconciled to the
      shipped dist only when the platform still owns it (managed_by absent or
      'platform'); a row an admin took over (managed_by:'user') or a package owns
      ('package') is an intentional override and is left untouched.
    • New os meta resync command boots the runtime, reconciles the default
      permission-set rows to the compiled dist, and reports what was reconciled /
      preserved / newly seeded — without touching business data and without a
      --fresh wipe. Gated behind a confirmation prompt (--yes to skip; --json
      for scripting).

    Prod boot is unaffected; the fix is entirely opt-in via the new command.

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [8f0b9df]
  • Updated dependencies [ff648ad]
  • Updated dependencies [bea4b92]
    • @objectstack/plugin-auth@15.0.0
    • @objectstack/platform-objects@15.0.0
    • @objectstack/rest@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/plugin-security@15.0.0
    • @objectstack/lint@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/verify@15.0.0
    • @objectstack/account@15.0.0
    • @objectstack/setup@15.0.0
    • @objectstack/plugin-approvals@15.0.0
    • @objectstack/plugin-audit@15.0.0
    • @objectstack/plugin-email@15.0.0
    • @objectstack/plugin-reports@15.0.0
    • @objectstack/plugin-sharing@15.0.0
    • @objectstack/service-job@15.0.0
    • @objectstack/service-queue@15.0.0
    • @objectstack/service-realtime@15.0.0
    • @objectstack/service-settings@15.0.0
    • @objectstack/service-storage@15.0.0
    • @objectstack/client@15.0.0
    • @objectstack/cloud-connection@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0
    • @objectstack/mcp@15.0.0
    • @objectstack/observability@15.0.0
    • @objectstack/driver-memory@15.0.0
    • @objectstack/driver-mongodb@15.0.0
    • @objectstack/driver-sql@15.0.0
    • @objectstack/driver-sqlite-wasm@15.0.0
    • @objectstack/plugin-hono-server@15.0.0
    • @objectstack/plugin-webhooks@15.0.0
    • @objectstack/service-analytics@15.0.0
    • @objectstack/service-automation@15.0.0
    • @objectstack/service-cache@15.0.0
    • @objectstack/service-datasource@15.0.0
    • @objectstack/service-messaging@15.0.0
    • @objectstack/service-package@15.0.0
    • @objectstack/trigger-api@15.0.0
    • @objectstack/trigger-record-change@15.0.0
    • @objectstack/trigger-schedule@15.0.0
    • @objectstack/types@15.0.0
    • @objectstack/console@15.0.0

@objectstack/lint@15.0.0

Minor Changes

  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/formula@15.0.0
    • @objectstack/sdui-parser@15.0.0

@objectstack/metadata@15.0.0

Minor Changes

  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/metadata-core@15.0.0
    • @objectstack/types@15.0.0
    • @objectstack/metadata-fs@15.0.0

@objectstack/platform-objects@15.0.0

Minor Changes

  • 2a71f48: feat(auth): admin direct user management, phone sign-in, and identity bulk import (feat(auth): 管理员直建用户 + 手机号登录 + sys_user 批量导入 —— 分阶段实施(#2758 重排) #2766, re-scoped feat(auth): sys_user 批量导入接口 —— 导入用户的密码处理策略 #2758)

    sys_user is managed by better-auth and its generic CRUD is suppressed, so
    until now the only way to add a teammate was the email-dependent invite flow.
    This ships three staged capabilities:

    • Admin direct user managementPOST /api/v1/auth/admin/create-user
      and a wrapped POST /api/v1/auth/admin/set-user-password (ADR-0068
      platform-admin gate; better-auth pipeline so credentials are real). Optional
      generated temporary password (returned once, never persisted or logged) and
      a new sys_user.must_change_password flag enforced through the ADR-0069
      authGate (403 PASSWORD_EXPIRED until the user changes it). New
      create_user action and upgraded set_user_password action on the Users
      list — pure schema, no frontend changes.
    • Phone sign-in (opt-in auth.plugins.phoneNumber) — better-auth
      phoneNumber plugin, phone+password only (POST /sign-in/phone-number);
      OTP flows stay off until SMS infrastructure exists. Adds
      sys_user.phone_number (unique) / phone_number_verified. Phone-only
      accounts get an undeliverable placeholder email
      (u-<random>@placeholder.invalid, never derived from the phone number);
      all auth mail callbacks refuse placeholder recipients.
    • Identity bulk importPOST /api/v1/auth/admin/import-users accepts
      the same payloads as the generic import routes (rows/csv/xlsx, dryRun,
      upsert by email or phone) but writes every row through better-auth.
      Password policies: invite (reset-link email per created user; requires an
      EmailService) and temporary (per-row one-time passwords + forced change).
      Sync only, ≤500 rows per request; no undo; upsert updates touch profile
      fields only and can never reset an existing user's password.
      prepareImportRequest and the CSV/xlsx parsers moved from rest-server.ts
      to an exported import-prepare.ts module (behavior unchanged).

Patch Changes

  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.
  • Updated dependencies [2a71f48]

  • Updated dependencies [02f6af4]

    • @objectstack/spec@15.0.0
    • @objectstack/metadata-core@15.0.0

@objectstack/plugin-auth@15.0.0

Minor Changes

  • 2a71f48: feat(auth): admin direct user management, phone sign-in, and identity bulk import (feat(auth): 管理员直建用户 + 手机号登录 + sys_user 批量导入 —— 分阶段实施(#2758 重排) #2766, re-scoped feat(auth): sys_user 批量导入接口 —— 导入用户的密码处理策略 #2758)

    sys_user is managed by better-auth and its generic CRUD is suppressed, so
    until now the only way to add a teammate was the email-dependent invite flow.
    This ships three staged capabilities:

    • Admin direct user managementPOST /api/v1/auth/admin/create-user
      and a wrapped POST /api/v1/auth/admin/set-user-password (ADR-0068
      platform-admin gate; better-auth pipeline so credentials are real). Optional
      generated temporary password (returned once, never persisted or logged) and
      a new sys_user.must_change_password flag enforced through the ADR-0069
      authGate (403 PASSWORD_EXPIRED until the user changes it). New
      create_user action and upgraded set_user_password action on the Users
      list — pure schema, no frontend changes.
    • Phone sign-in (opt-in auth.plugins.phoneNumber) — better-auth
      phoneNumber plugin, phone+password only (POST /sign-in/phone-number);
      OTP flows stay off until SMS infrastructure exists. Adds
      sys_user.phone_number (unique) / phone_number_verified. Phone-only
      accounts get an undeliverable placeholder email
      (u-<random>@placeholder.invalid, never derived from the phone number);
      all auth mail callbacks refuse placeholder recipients.
    • Identity bulk importPOST /api/v1/auth/admin/import-users accepts
      the same payloads as the generic import routes (rows/csv/xlsx, dryRun,
      upsert by email or phone) but writes every row through better-auth.
      Password policies: invite (reset-link email per created user; requires an
      EmailService) and temporary (per-row one-time passwords + forced change).
      Sync only, ≤500 rows per request; no undo; upsert updates touch profile
      fields only and can never reset an existing user's password.
      prepareImportRequest and the CSV/xlsx parsers moved from rest-server.ts
      to an exported import-prepare.ts module (behavior unchanged).

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [bea4b92]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/rest@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/plugin-security@15.0.0

Minor Changes

  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.
  • 8f0b9df: fix(cli,plugin-security): os meta resync to re-materialize default permission sets from dist ([cli/plugin-security] dev 元数据物化不一致:默认权限集 insert-if-not-exists 不重物化(声明集走 upsert) #2705)

    The default permission sets (admin_full_access / member_default /
    viewer_readonly …) were seeded insert-once at boot: bootstrapPlatformAdmin
    skipped any row that already existed and never wrote the shipped declaration
    back. So editing a default set's source, recompiling, and restarting os dev
    without --fresh left the runtime serving the OLD value — silently, because
    the runtime authz resolver hydrates permission sets from the sys_permission_set
    row (resolve-authz-context.ts), not from the in-memory dist. A permission-gated
    surface (e.g. setup.access) would keep its stale behavior with no error, which
    repeatedly misled debugging. Every other metadata seed (declared permission
    sets, positions, built-in roles, capabilities) already upserts on boot, leaving
    the platform-default path the lone insert-once holdout — a gap ADR-0090 widened
    by persisting more facets (system_permissions, delegated-admin admin_scope)
    onto the same row.

    The insert-once posture is deliberate for prod (it protects an admin's Setup
    edits and keeps the defaults env-authored — the exact posture
    bootstrapDeclaredPermissions relies on), so this is not switched to a blind
    upsert. Instead:

    • bootstrapPlatformAdmin gains a resync option. Default boot behavior is
      unchanged (insert-once). Under resync, an existing row is reconciled to the
      shipped dist only when the platform still owns it (managed_by absent or
      'platform'); a row an admin took over (managed_by:'user') or a package owns
      ('package') is an intentional override and is left untouched.
    • New os meta resync command boots the runtime, reconciles the default
      permission-set rows to the compiled dist, and reports what was reconciled /
      preserved / newly seeded — without touching business data and without a
      --fresh wipe. Gated behind a confirmation prompt (--yes to skip; --json
      for scripting).

    Prod boot is unaffected; the fix is entirely opt-in via the new command.

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0

@objectstack/rest@15.0.0

Minor Changes

  • 2a71f48: feat(auth): admin direct user management, phone sign-in, and identity bulk import (feat(auth): 管理员直建用户 + 手机号登录 + sys_user 批量导入 —— 分阶段实施(#2758 重排) #2766, re-scoped feat(auth): sys_user 批量导入接口 —— 导入用户的密码处理策略 #2758)

    sys_user is managed by better-auth and its generic CRUD is suppressed, so
    until now the only way to add a teammate was the email-dependent invite flow.
    This ships three staged capabilities:

    • Admin direct user managementPOST /api/v1/auth/admin/create-user
      and a wrapped POST /api/v1/auth/admin/set-user-password (ADR-0068
      platform-admin gate; better-auth pipeline so credentials are real). Optional
      generated temporary password (returned once, never persisted or logged) and
      a new sys_user.must_change_password flag enforced through the ADR-0069
      authGate (403 PASSWORD_EXPIRED until the user changes it). New
      create_user action and upgraded set_user_password action on the Users
      list — pure schema, no frontend changes.
    • Phone sign-in (opt-in auth.plugins.phoneNumber) — better-auth
      phoneNumber plugin, phone+password only (POST /sign-in/phone-number);
      OTP flows stay off until SMS infrastructure exists. Adds
      sys_user.phone_number (unique) / phone_number_verified. Phone-only
      accounts get an undeliverable placeholder email
      (u-<random>@placeholder.invalid, never derived from the phone number);
      all auth mail callbacks refuse placeholder recipients.
    • Identity bulk importPOST /api/v1/auth/admin/import-users accepts
      the same payloads as the generic import routes (rows/csv/xlsx, dryRun,
      upsert by email or phone) but writes every row through better-auth.
      Password policies: invite (reset-link email per created user; requires an
      EmailService) and temporary (per-row one-time passwords + forced change).
      Sync only, ≤500 rows per request; no undo; upsert updates touch profile
      fields only and can never reset an existing user's password.
      prepareImportRequest and the CSV/xlsx parsers moved from rest-server.ts
      to an exported import-prepare.ts module (behavior unchanged).
  • 02f6af4: ADR-0090 follow-through wave: enforce book audience at the read layer; finish the D2/D3 cleanup the P1 rename missed.

    • rest: /meta/book, /meta/doc, and /meta/book/:name/tree now ENFORCE
      the ADR-0046 §6.7 audience model (ADR-0049 — no unenforced security
      properties): anonymous callers see only public books/docs;
      { permissionSet }-gated books require the caller to hold the named set;
      a doc's effective audience is the union over the books that CLAIM it
      (unclaimed docs default to org; orphan rendering never inherits public).
      Gated evaluation fails CLOSED when holdings cannot be resolved. doc/book
      single-item reads bypass the shared meta cache (per-caller gate vs shared ETag).
    • spec: new pure helpers powering that gate — audienceAllows,
      resolveDocAudiences, docAudienceAllows, resolveBookClaimedDocs
      (+ AudienceCaller/AudienceBook types). BREAKING (launch window):
      METADATA_FORM_REGISTRY keys role/profile are gone — position is the
      registered form (the position type had LOST its form layout in the P1
      rename); EnvironmentArtifactMetadataSchema declares positions instead of
      retired roles/profiles.
    • plugin-security: the security service exposes
      resolvePermissionSetNames(ctx) — the same resolution as data-plane
      enforcement, for the docs gate.
    • metadata: artifact ingestion maps positions → 'position' (the stale
      roles → 'role' mapping matched nothing since the P1 rename, silently
      dropping compiled positions from metadata registration).
    • lint: books join the D3 role-word scan (their audience is a
      permission-model reference now), and a new advisory rule
      security-book-audience-unknown-set flags a { permissionSet } audience
      naming a set the stack does not declare (runtime fails closed — the typo
      cost is "nobody can read the book", so say it at author time).
    • platform-objects: metadata-form translations regain position (all four
      locales) and drop the retired role/profile groups, with a vocabulary
      regression test.
  • bea4b92: feat(rest): colour select/radio cells in xlsx exports with their option colour

    The data export route (GET /data/:object/export) now carries a select /
    radio field's option color into the generated Excel workbook as the cell's
    font colour (white cell background), so an exported sheet reads like the
    in-app coloured badges instead of plain black text. csv / json output is
    unchanged.

    • export-format.ts gains toArgb() (hex #RGB / #RRGGBB → exceljs ARGB
      FFRRGGBB, undefined for anything not plain hex) and cellFontColor()
      (resolves the matched select/radio option's colour for one cell; returns
      undefined — i.e. leave it unstyled — for non-option fields, unmatched
      values, colourless options, or invalid hex). ExportFieldMeta.options now
      carries the option color.
    • createXlsxStream(res, useStyles) takes the flag through to exceljs'
      WorkbookWriter; the route enables styling and sets cell.font.color
      per-cell only for xlsx.

    Styling is heavier than a bare value dump, so it is gated behind a 10 000-row
    cap
    (STYLE_ROW_CAP): exports whose effective limit exceeds it stream
    without colours (all rows intact) and set X-Export-Styles: dropped; coloured
    exports set X-Export-Styles: applied. This mirrors the "formatted export has a
    lower ceiling than a raw dump" pattern used by Salesforce / ServiceNow. The
    existing 50 000-row hard cap is unchanged.

    Closes Excel 导出支持 select/status 字段颜色(白底+选项色作字体色) #2757.

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/service-package@15.0.0
    • @objectstack/types@15.0.0

@objectstack/hono@15.0.0

Patch Changes

  • @objectstack/runtime@15.0.0
  • @objectstack/plugin-hono-server@15.0.0
  • @objectstack/types@15.0.0

@objectstack/account@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0

@objectstack/setup@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0

@objectstack/studio@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0

@objectstack/client@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/client-react@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/client@15.0.0
    • @objectstack/core@15.0.0

@objectstack/cloud-connection@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/connector-mcp@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/connector-openapi@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/connector-rest@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/connector-slack@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/core@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/formula@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/mcp@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/metadata-core@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/metadata-fs@15.0.0

Patch Changes

  • @objectstack/metadata-core@15.0.0

@objectstack/metadata-protocol@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0
    • @objectstack/metadata-core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/objectql@15.0.0

Patch Changes

  • ff648ad: fix(data): resolve field defaultValues BEFORE the beforeInsert hook ([objectql] 字段 defaultValue 解析晚于 beforeInsert hook,派生字段 hook 读到 null #2703)

    Declarative field defaults (including the current_user token) were resolved
    by applyFieldDefaults after the user beforeInsert hook ran. A hook that
    DERIVED one field from another therefore read a stale null for any field that
    was about to be defaulted — e.g. sales_person: Field.user({ defaultValue: 'current_user' }) left sales_person == null inside the hook, so a derived
    current_status computed to unassigned unless the client passed the field
    explicitly.

    applyFieldDefaults now runs at record-initialization time, before
    beforeInsert, matching the industry-standard order of execution (Salesforce
    field defaults / ServiceNow dictionary defaults are populated before before-
    triggers; engine-owned generation — autonumber sequences, encryption, timestamps
    — stays after the hook). The hook still has final say: it runs after and may
    override any defaulted field. Defaults still only fill fields left undefined,
    so client-supplied values are untouched, and the caller's input object is no
    longer mutated in place.

    Behavior note: a beforeInsert hook can no longer distinguish "client omitted
    field X" from "field X received its default" for fields that declare a
    defaultValue — the hook now always sees the resolved default. This matches how
    Salesforce/ServiceNow behave (before logic sees a fully-initialized record) and
    is the intended fix.

  • Updated dependencies [2a71f48]

  • Updated dependencies [02f6af4]

    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0
    • @objectstack/metadata-core@15.0.0
    • @objectstack/metadata-protocol@15.0.0
    • @objectstack/types@15.0.0

@objectstack/observability@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/driver-memory@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/driver-mongodb@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/driver-sql@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/driver-sqlite-wasm@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/driver-sql@15.0.0

@objectstack/embedder-openai@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/knowledge-memory@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/service-knowledge@15.0.0

@objectstack/knowledge-ragflow@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/service-knowledge@15.0.0

@objectstack/plugin-approvals@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @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

@objectstack/plugin-audit@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/plugin-dev@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [8f0b9df]
  • Updated dependencies [ff648ad]
  • Updated dependencies [bea4b92]
    • @objectstack/plugin-auth@15.0.0
    • @objectstack/rest@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/plugin-security@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/account@15.0.0
    • @objectstack/setup@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/driver-memory@15.0.0
    • @objectstack/plugin-hono-server@15.0.0
    • @objectstack/service-i18n@15.0.0
    • @objectstack/types@15.0.0

@objectstack/plugin-email@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0

@objectstack/plugin-hono-server@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/observability@15.0.0
    • @objectstack/types@15.0.0

@objectstack/plugin-reports@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/plugin-sharing@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [ff648ad]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0

@objectstack/plugin-webhooks@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/service-messaging@15.0.0

@objectstack/runtime@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [8f0b9df]
  • Updated dependencies [ff648ad]
  • Updated dependencies [bea4b92]
    • @objectstack/plugin-auth@15.0.0
    • @objectstack/rest@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/plugin-security@15.0.0
    • @objectstack/metadata@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0
    • @objectstack/observability@15.0.0
    • @objectstack/driver-memory@15.0.0
    • @objectstack/driver-sql@15.0.0
    • @objectstack/driver-sqlite-wasm@15.0.0
    • @objectstack/service-cluster@15.0.0
    • @objectstack/service-datasource@15.0.0
    • @objectstack/service-i18n@15.0.0
    • @objectstack/types@15.0.0

@objectstack/service-analytics@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-automation@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/formula@15.0.0

@objectstack/service-cache@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/observability@15.0.0

@objectstack/service-cluster@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-cluster-redis@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/service-cluster@15.0.0

@objectstack/service-datasource@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-i18n@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-job@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-knowledge@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-messaging@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-package@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-queue@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-realtime@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/service-settings@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/types@15.0.0

@objectstack/service-storage@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/platform-objects@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/observability@15.0.0

@objectstack/trigger-api@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/trigger-record-change@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/trigger-schedule@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/core@15.0.0

@objectstack/types@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@objectstack/verify@15.0.0

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [8f0b9df]
  • Updated dependencies [ff648ad]
  • Updated dependencies [bea4b92]
    • @objectstack/plugin-auth@15.0.0
    • @objectstack/rest@15.0.0
    • @objectstack/spec@15.0.0
    • @objectstack/plugin-security@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/plugin-sharing@15.0.0
    • @objectstack/service-settings@15.0.0
    • @objectstack/core@15.0.0
    • @objectstack/driver-sqlite-wasm@15.0.0
    • @objectstack/plugin-hono-server@15.0.0
    • @objectstack/service-analytics@15.0.0
    • @objectstack/service-automation@15.0.0
    • @objectstack/service-datasource@15.0.0

@objectstack/console@15.0.0

create-objectstack@15.0.0

@objectstack/sdui-parser@15.0.0

objectstack-vscode@15.0.0

@objectstack/example-crm@4.0.81

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/runtime@15.0.0

@objectstack/example-showcase@0.3.3

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/cloud-connection@15.0.0
    • @objectstack/connector-rest@15.0.0
    • @objectstack/connector-slack@15.0.0
    • @objectstack/driver-sql@15.0.0

@objectstack/example-todo@4.0.81

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [ff648ad]
    • @objectstack/spec@15.0.0
    • @objectstack/metadata@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/runtime@15.0.0
    • @objectstack/client@15.0.0
    • @objectstack/mcp@15.0.0
    • @objectstack/driver-sqlite-wasm@15.0.0
    • @objectstack/knowledge-memory@15.0.0
    • @objectstack/service-knowledge@15.0.0

@objectstack/example-embed-objectql@0.0.21

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [ff648ad]
    • @objectstack/spec@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/driver-memory@15.0.0

@objectstack/dogfood@0.0.29

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
  • Updated dependencies [8f0b9df]
  • Updated dependencies [ff648ad]
    • @objectstack/spec@15.0.0
    • @objectstack/plugin-security@15.0.0
    • @objectstack/objectql@15.0.0
    • @objectstack/verify@15.0.0
    • @objectstack/example-crm@4.0.81
    • @objectstack/example-showcase@0.3.3

@objectstack/downstream-contract@0.0.27

Patch Changes

  • Updated dependencies [2a71f48]
  • Updated dependencies [02f6af4]
    • @objectstack/spec@15.0.0

@vercel

vercel Bot commented Jul 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jul 10, 2026 12:11pm

Request Review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Excel 导出支持 select/status 字段颜色(白底+选项色作字体色)

1 participant