Skip to content

[决策] readonly 剥离的 strict/reject 模式落在哪一层 —— B(WriteObservabilityOptions)推荐,A/C/D 各有代价(#4903 后续) #5126

Description

@claude

要拍板什么

readonly 剥离的 strict/reject 模式(供 cron/服务端插件在调用点选择「被剥离即响亮失败」而非静默丢列)落在哪一层。#4903(PR #5123)已把可发现性与文档修好,strict 半边因四个候选落点全部触碰 packages/spec/**(本车道冻结)而止步。

四个选项(完整两轴分析见 PR #5123 正文,此处摘要)

选项 落点 要害
A EngineUpdateOptionsSchema(可序列化 Zod 袋) 可跨 RPC/REST —— 但客户端可设置,在安全相邻路径上开新攻击面;拖动生成物
B(推荐) strictReadonlyWritesWriteObservabilityOptions(TS 契约,onFieldsDropped 所在) 进程内、客户端不可达、与既有先例同类;抛 ERR_READONLY_FIELD_REJECTED 带字段清单
C 部署级开关(env/构造配置) 全局改行为 —— REST 边界的伪造输入也从剥离变报错,兼容性变更;无法表达「只这一个 cron 要响」
D objectql 包内私加 ⛔ 实现而不声明 —— PD#12 反形,不建议

推荐 B:两轴同向 —— 唯一让 AI 写的 cron 在调用点拿到点名异常(而非绿调用 + 数周后发现 null 列)、又结构性不给客户端碰的方案。若你想覆盖 RPC/VDE 面,那是 A 的独立放宽,应单独定而非顺手带。

两个关联输入(#5123 报告的,同一次拍板可一并看)

  1. ExecutionContext 无 origin/channel 标记 —— isSystem 是唯一信任位,故剥离接缝无法区分伪造 REST body 与可信服务端代码;任何按来源分级的策略都以补这个标记为前提;
  2. onFieldsDropped 不跨 RPC/VDE 边界(契约已文档化)—— strict 决策应顺带说清远程调用方拿什么。

Blocked-by: objectstack-ai/objectstack#4903(PR #5123 合并后动手)
落点:packages/spec/src/contracts/data-engine.ts + objectql —— spec 车道或维护者授权例外


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions