变更日志与版本策略
ObjectOS 的版本规则、各版本间的变化及支持范围。
版本策略
ObjectOS 遵循 语义化版本:MAJOR.MINOR.PATCH。
| 版本号变化 | 含义 | 应对方式 |
|---|---|---|
Patch(14.7.0 → 14.7.1) | 修 bug,不改变行为 | 直接升级,无需改动应用 |
Minor(14.6 → 14.7) | 新增功能,向后兼容 | 直接升级,可选采用新功能 |
Major(13 → 14) | 破坏性变更,发版说明会列出 | 升级前阅读迁移指南 |
所有 @objectstack/* 包按同步的版本号一起发布 —— 作为矩阵一同测试,
而不是各自独立。
兼容性矩阵
| 组件 | 兼容性规则 |
|---|---|
| ObjectOS 镜像 ↔ 编译产物 | 同一 minor 版本。14.7.x 镜像运行 14.7.x 产物;14.7 产物可能使用 14.0 镜像不具备的功能。协议握手(PROTOCOL_VERSION,12.0+)会在安装时拒绝不兼容的软件包。 |
| ObjectOS ↔ CLI | 建议使用同一 minor 版本。npm i -g 安装的 CLI 生成的脚手架会固定为其自身版本。 |
| ObjectOS ↔ 数据库驱动 | 驱动版本由镜像构建固定;请确认 Postgres ≥ 13 / MongoDB ≥ 5 / Turso(当前版本)。 |
| Node.js | 20 LTS 或更新。新部署推荐 22 LTS。 |
支持窗口
| 分支 | 状态 | 截止 |
|---|---|---|
| 14.x(当前) | 活跃开发;新功能与修复 | 至少到 15.0 发布后 12 个月 |
| 13.x | 仅安全修复 | 15.0 发布时 EOL |
| ≤ 12.x | 不再支持 | 已 EOL |
关键安全修复会反向移植到当前 major 与上一个 major;其他变更只进
main。
发版说明
发布的 ObjectOS 版本与其 CHANGELOG 在以下位置发布:
- npm:
@objectstack/runtime - GitHub:github.com/objectstack-ai/objectos/releases
- 源码 CHANGELOG:
CHANGELOG.md - 长文版发版说明:
RELEASE_NOTES.md
在 GitHub 上订阅 Releases 即可收到通知。
近期亮点
16.0
@objectstack 16.0.0 收敛了开发者面,并让已声明的元数据变得诚实:调用者组织只有一个受祝福的名字、审批获得真正的多审批人治理、时间相对自动化真正会触发,以及一次平台级清理,把被静默忽略的元数据在创作时就变成响亮的错误。完整说明见
docs.objectstack.ai/docs/releases。
16.0 的变动:
- hook/action
ctx移除tenantId别名(16.0,破坏性)—— 在所有*.hook.ts/*.action.ts代码体中,改用ctx.user.organizationId/ctx.session.organizationId读取调用者组织(值不变;system 写入时ctx.user为undefined)。驱动层的租户轴(ExecutionContext.tenantId) 是另一个概念,刻意保持不动。 - 审批:法定人数、会签,以及元数据驱动的收件箱——审批步骤支持
M-of-N 法定人数(
minApprovals)和每组一人的会签,基于开启时刻的快照 统计并支持 OOO 替补;单次拒绝仍是一票否决,阈值会自动收紧,错误配置 永远不会造成死锁。决策可附带文件附件,进度("2 of 3 · finance pending")由服务端计算,approve / reject / reassign / send-back / request-info / remind / recall / resubmit 都作为sys_approval_request上声明的type:'api'action —— Console 通过通用 action 运行时渲染它们, 而不是手写按钮。 - 时间相对自动化——流程开始节点可以声明
timeRelative(offsetDays: [60, 30, 7]或withinDays);每日扫描对每条匹配记录 启动一次流程,"合同到期前 60 天提醒我"终于开箱即用——不再依赖只有 恰好在正确的那天有人编辑记录才会触发的日期相等条件。 - 带过滤的汇总字段——
summaryOperations.filter让父级合计只聚合 匹配的子行,并在子行进出谓词范围时重新聚合。 - 严格的仪表盘 widget(16.0,破坏性)——
DashboardWidgetSchema改为.strict():未声明的键(拼写错误或已移除的内联分析键)会成为解析 错误,指名该键并指向数据集形态(dataset+dimensions+values), 而不是静默渲染出一片空白。 - MCP:stdio 获得身份,Agent 获得校验器——stdio 自动启动改由独立的
OS_MCP_STDIO_ENABLED开关控制(默认关闭),并要求OS_MCP_STDIO_API_KEY=osk_...身份主体,fail-closed,通过与 HTTP 相同 的授权链解析(RLS/FLS/租户隔离全部生效;没有system旁路)。新增validate_expression工具,让 Agent 在保存前对照真实对象 schema 校验 公式。 - enforce-or-remove 清理(16.0,破坏性)——声明了却从不强制执行的
元数据现在会大声报错:无效的字段/对象/agent 属性被移除或以带指引的
tombstone 报错,hook 事件从 18 收敛到 8,验证规则移除从不求值的
'delete'事件,webhook 的undelete/api触发器被移除,未知的requires能力 token 在创作时即被拒绝(aiStudio/aiSeat别名已 移除——使用 kebab-case 的ai-studio/ai-seat)。 - 引擎自有的系统行通过通用数据 API 只读(ADR-0103)——作业、通知、
审批运行时行、共享行、审计日志、密钥等被锁定为
get/list, fail-closed 守卫会拒绝经/data的用户上下文写入。确实需要接受用户 写入的第三方system对象必须声明userActions。 - 日期逻辑不再说谎——
record.due_date == today()现在能匹配了 (时间相等比较会被重写以强制转换字段操作数);而公式中的日期算术 (end - start + 1、today() + 30)改为构建期错误,并指向daysBetween/daysFromNow/addDays/addMonths——这些表达式 在运行时本来就总是得到null。 - 批量用户导入默认
passwordPolicy: 'auto'——具有可送达通道的行 (真实邮箱 + 已接通的邮件服务,或手机号 + 短信邀请通道)会被邀请; 只有无法触达的行才得到一次性临时密码(must_change_password)。 想要旧的仅建身份行为,请显式传入passwordPolicy: 'none';每行结果 在rows[].delivery上。
14.x
ObjectOS One 与捆绑的 server 基于 @objectstack 14.7.0 发布。运行时的启动
契约并未变化 —— createStandaloneStack 仍然接收同样的 artifact、环境与数据库
设置 —— 但 13.0 与 14.0 均在授权词汇上有破坏性变更,因此从 ≤ 12.x 升级前请
先审查权限元数据。完整说明见
docs.objectstack.ai/docs/releases。
14.x 的变动:
- ADR-0090 词汇收敛完成(14.0,破坏性)——
book.audience改用{ permissionSet }门控(原为{ profile }),PortalSchema.profiles→positions,RLSUserContextSchema.role→positions(字符串数组),sys_record_share.recipient_type: 'role'→'position'。 - 对象能力开关强制执行(14.0,准破坏性)——
enable.*开关从"解析但不生效" 变为真实闸门。activities与feeds为默认开启、可显式关闭(feeds: false会以 403FEEDS_DISABLED拒绝评论);trackHistory控制 History 选项卡;files需显式开启(否则 403FILES_DISABLED)。 - 成员基线移除删除权(14.2,破坏性)——
member_default不再授予记录删除; 需按对象通过岗位分发的权限集重新授予。 - 管理员用户管理与手机号认证(14.3)—— 直接创建用户
(
POST /api/v1/auth/admin/create-user,一次性密码 + 强制轮换)、批量导入 (行/CSV/XLSX、dry-run、upsert)、通过@objectstack/plugin-sms的可选手机号 登录与短信 OTP(阿里云 / Twilio),以及sms通知通道。 - 数据生命周期契约(14.4,ADR-0057)—— 对象声明
lifecycle(class、retention、rotation、archive);默认开启的 LifecycleService 负责 回收、轮换与归档平台数据(sys_activity14 天,sys_audit_log热存 90 天)。 可用OS_LIFECYCLE_DISABLED=1关闭,通过lifecycle.retention_overrides调整。14.5 移除了插件级retentionDays/retentionSweepMs选项 (JobRunRetention、NotificationRetention),改由生命周期声明接管,并将 生命周期类系统数据拆分到专用 telemetry 数据源(OS_TELEMETRY_DB);os db clean可回收 SQLite 空间。 - 带生效期的授权与委托(14.4,ADR-0091)—— 岗位与权限集分配支持
valid_from/valid_until时间窗口(失败即关闭,无需后台任务);delegatable岗位允许持有者在有限窗口内自助委托(≤ 30 天、必须填写原因、 管理范围永不可委托)。 - MCP 权限上限(14.5,ADR-0090 D10)—— 通过 OAuth 接入的代理在
effective_permission = scope_ceiling ∩ user_grants下运行 (data:read/data:write/actions:execute),失败即关闭。 - 安全修复(14.4–14.5)—— 字段权限键必须带对象限定(裸键会静默匹配不到
任何字段;现在由校验规则拒绝并支持自动修复);settings 与共享链接路由不再
信任可伪造的
x-user-id类请求头;分析查询按调用者的读取过滤器限定范围。
13.x —— 权限模型 v2
@objectstack 13.0 重构了授权模型(ADR-0090)。破坏性变更:
- 角色与简档合并为岗位 ——
sys_role*表、RoleSchema/defineRole、 元数据类型role/profile、ExecutionContext.roles[]均已移除;岗位是 扁平的,层级迁移到业务单元树。共享接收者重命名(role→position、role_and_subordinates→unit_and_subordinates)。 - 自定义对象默认私有 —— 带所有者但未显式声明
sharingModel的对象现在 默认私有;OWD 别名read/read_write/full已移除。声明sharingModel: 'public_read_write'可恢复原行为。 - RBAC 关联表写入受门控 —— 写入
sys_user_position、sys_position_permission_set、sys_user_permission_set、sys_permission_set需要租户管理员或委托管理范围。
新增能力:everyone / guest 受众锚点、委托管理
(PermissionSet.adminScope)、带逐层归因的 explain() 解释引擎、
os compile 的访问矩阵快照闸门、面向 MCP 客户端的自助 OAuth 2.1、
编写期安全校验(validateSecurityPosture)、按操作粒度的
Object.requiredPermissions 映射,以及软件包命名空间前缀强制。从未生效的
schema(合规 / 脱敏 / 全局 RLS 配置)被直接移除。
12.x
@objectstack 12.0 收紧了 API 默认安全态势:
- 匿名数据访问默认拒绝(破坏性)——
api.requireAuth现在默认true; 匿名/data/*请求返回 401。公开数据的部署必须显式退出:api: { requireAuth: false }(启动时告警)。共享链接、公开表单、/auth、/health不受影响。 - 强制协议握手 ——
PROTOCOL_VERSION+checkProtocolCompat()在安装时 拒绝不兼容的软件包。 - 自适应记录表面 —— 记录根据字段复杂度推导页面 vs 模态/抽屉展示;
FormField.span改为响应式('auto'/'full');关联列表支持'primary'选项卡提升。 - 软件包自带权限 —— 软件包可声明默认权限集,启动时自动物化并跟踪来源。
- 构建期校验 ——
lint-view-refs、validateListViewMode、validateFormLayout及破坏性操作的 RBAC 映射成为编译闸门。
10.x
10.x 列车运行于 @objectstack 10.0 – 10.2。所有破坏性变更都落在多组织
(multi-org)租户层,因此单租户的 ObjectOS 部署可从 9.x 无配置改动直接升级。
变动内容如下:
- 行级组织作用域拆分为独立插件(10.0,破坏性)——
organization_id自动标记、按组织的 seed 重放,以及默认组织的 bootstrap,已从@objectstack/plugin-security移出,改到可选启用的@objectstack/plugin-org-scoping。 单组织部署因此更精简(无需在每次查询时剥离通配的 RLS),而OS_MULTI_TENANT=true仍会在plugin-security之前自动注册该插件,因此由 CLI 驱动的项目无需任何代码改动。按 ADR-0002,tenant(租户)是物理隔离 (一个 Environment = 一个数据库);organization_id则是同一数据库内的逻辑 作用域,因此它单独成为一个插件。 - 不再自动创建个人工作区(10.0,破坏性)——
plugin-security不再为每位 新用户创建「<User>'s Workspace」组织。用户现在需要接受邀请,或显式创建 自己的第一个组织(Slack / Linear / GitHub-Orgs 的模式)。第一位注册用户 —— 会被自动提升为平台管理员 —— 在多租户模式下仍会获得一个Default Organization,以便其会话能解析 RLS;单租户部署则不创建任何组织。 record表单字段类型(ADR-0014)——Record<string, X>属性(例如对象的fields映射)现在可在 Studio 中作为一等公民的表单字段编辑,而不再以原始 JSON 的形式泄露出来;对象预览面板也挂载了真正的ObjectGrid渲染器 —— 你预览到的就是最终交付的。- 通过
IEmbedder实现可插拔嵌入(embeddings)—— 新增一套 embedder 协议, 外加@objectstack/embedder-openai; 知识 / RAG 适配器现在消费IEmbedder,并已重命名以去掉plugin-前缀。 - Public Forms(公开表单) —— 服务于
/f/:slug的匿名 Web-to-Lead / Web-to-Case 表单、一个统一的 FormPage(公开的/f/:slug+ 内部的/forms/:name)、一个type: 'form'的 action 变体,以及ObjectSchema上的defaultDetailForm。 - 云身份拆分 ——
os cloud login现在与os login分离,云控制平面已迁至 私有仓库(让 OSS 运行时更精简),而objectstack init再次能脚手架出一个 可构建、可启动的项目。
9.x
9.x 列车在切换到 10.0 之前运行于 @objectstack 9.0 – 9.11。运行时的
启动契约相较 8.0 没有变化 —— createStandaloneStack 仍然接收同样的
artifact、环境与数据库设置 —— 因此 8.0 部署可无配置改动直接升级。变动
集中在面向作者的层面:
- 分析数据集成为唯一的作者层面入口(9.0,破坏性)—— 仪表盘组件、
报表与列表图表现在绑定一个语义化的
dataset(defineDataset(...)), 并按名称选择维度/度量。旧的内联查询字段(组件上的object/valueField/aggregate、报表上的objectName/columns/groupingsDown、列表图表上的xAxisField/yAxisFields)已被移除。迁移方式:把内联查询移入一个defineDataset并按名称引用它。ChartTypeSchema也去掉了 8 个仅以其 基础类型渲染的变体类型(stacked-bar→bar、spline→line、bubble→scatter、…)。 - 更严格的构建期校验(9.6–9.7)——
os compile现在会在遇到裸字段 引用(用amount而非record.amount)、未知的 CEL 函数、以及错误的 flow-value 插值语法时失败,并各自给出 did-you-mean 提示。一个以往 「能构建但默默出错」的栈现在会显式报错 —— 升级后请重新运行os compile并修复它指出的问题。 - 数字字段公式可计算混合算术(9.7)——
record.amount / 100和record.price * 2现在会求值,而不再默默地得到null;不再需要/ 100.0这种浮点字面量的变通写法。 - 对象级 REST 门控,现已强制执行(ADR-0049)—— 对象的
apiEnabled: false会将其从 REST 面移除,apiMethods白名单则限制 哪些操作可达。此前只解析而不强制执行。 - 包文档作为元数据 +
book导航(9.3–9.6)——src/docs/*.md注册为doc元数据;book元素(ADR-0046)声明一条派生成员关系的导航主线, 通过GET /api/v1/meta/book/:name/tree提供,并带受众门控。 os package install(9.3)—— 从目录 id 或内联的隔离网(air-gapped) artifact 将一个包安装进运行中的 runtime,使用--email/--password进行认证。- 审批(9.3)—— 退回修订(
maxRevisions,默认 3)、由 jobs 支撑的 SLA 自动升级、列表搜索/分页,以及无会话的双语批准/拒绝确认链接。 - 入站 webhook 流程触发器(9.3)—— 一个
type: 'api'流程会挂载一个 经 HMAC 校验的POST /api/v1/automation/hooks/:flowName/:hookId端点, 采用幂等、队列支撑的摄入。 - 通知保留默认开启(9.5)—— 通知历史在 90 天自动清理;将消息设置
的
retentionDays: 0设为该值可永久保留历史。 - CLI 捆绑 AI 提供方 SDK(9.0)—— 兼容 OpenAI 的提供方(DeepSeek、 DashScope、SiliconFlow、OpenRouter、Cloudflare)在全局安装的 CLI 上 开箱即用。
有一项流程编写行为变化需要注意:create_record 节点的 outputVariable
现在保存创建出的记录对象(此前是裸 id),因此把原本期望得到 id 的
{var} 引用改为 {var.id}。
8.0.x
ObjectOS One 与捆绑的 server 此前基于 @objectstack 8.0.1。
- MCP over Streamable HTTP —— 每个部署都可作为网络可达的
Model Context Protocol 服务器。
通过
OS_MCP_SERVER_ENABLED=true开启;端点位于/api/v1/mcp,采用 fail-closed 鉴权(匿名请求被拒绝)。插件已从@objectstack/plugin-mcp-server重命名为@objectstack/mcp。 - 自助 API key ——
POST /api/v1/keys生成只显示一次的sys_api_key。REST 数据与元数据 API(/api/v1/data、/api/v1/meta) 现在通过与 MCP 相同的校验器认证 API key,并以 key 所有者的权限与 记录级安全运行。 - 字段级条件规则 ——
visibleWhen、readonlyWhen、requiredWhen由 ObjectQL 在服务端强制执行,而不仅在表单 UI 中生效。 - 可复用的 RLS 读取过滤器 ——
security.getReadFilter(object, context)暴露记录访问的读取范围;分析数据集、仪表盘与报表均桥接到它,无法安全 应用范围时 fail closed。 - Standalone host stack —— 运行时改为单租户的
createStandaloneStackhost;7.x 那种按 hostname 路由的云连接createObjectOSStack封装已移除。云部署改为让OS_ARTIFACT_FILE指向已发布的 artifact URL。
5.0 —— project → environment 重命名(已发布)
运行时中原称 Project 的概念已在全栈范围内重命名为 Environment。 影响范围:
- CLI 参数:
--environment/-e - HTTP 路径:
/api/v1/environments/:environmentId/... - 请求头:
X-Environment-Id - 环境变量:
OS_ENVIRONMENT_ID(OS_PROJECT_ID保留为已弃用的别名) - 数据库列名:
environment_id - JSON schema:
EnvironmentArtifact
升级
机械式的步骤见 升级与回滚。升级前检查:
- 阅读从当前版本到目标版本之间每个 minor 的 CHANGELOG 条目。
- 运行
os diff <old-artifact> <new-artifact>找出破坏性的 schema 变更。 - 针对目标版本运行
os doctor。 - 在全量滚动前先跑一个金丝雀实例。
- 准备好镜像 tag 与产物版本两条独立的回滚方案。
上报回归
如果某个 patch 或 minor 升级使原本可用的功能失效,请到 github.com/objectstack-ai/objectos/issues 提单,并写明你从哪个版本升级到哪个版本。我们把回归视为最高优先级 的缺陷。